#include #include #include #include #include #include #include #include int socket(int domain, int type, int protocol) { if (domain != AF_INET || type != SOCK_STREAM || protocol != IPPROTO_TCP) { return errno = ENOSYS, -1; } int h = _sys_getnull(0); if (h < 0) { return errno = -h, -1; } else { return h; } } int bind(int, const struct sockaddr *, socklen_t) { return errno = ENOSYS, -1; } int accept(int, struct sockaddr *, socklen_t *) { return errno = ENOSYS, -1; } int listen(int, int) { return errno = ENOSYS, -1; } int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { char buf[256]; struct sockaddr_in *addr4 = (void*)addr; uint32_t ip; uint16_t port; int newfd; if (addr->sa_family != AF_INET) { return errno = ENOSYS, -1; } if (addrlen < (ssize_t)sizeof(*addr4)) { return errno = EINVAL, -1; } ip = ntohl(addr4->sin_addr.s_addr); port = ntohs(addr4->sin_port); if (snprintf(buf, 256, "/net/connect/0/%ld/tcp/%d", ip, port) >= 256) { return errno = EGENERIC, -1; } newfd = camellia_open(buf, OPEN_READ | OPEN_WRITE); if (newfd < 0) { return -1; } dup2(newfd, sockfd); close(newfd); return 0; } ssize_t send(int sockfd, const void *buf, size_t len, int flags) { if (flags != 0) { return errno = ENOSYS, -1; } return write(sockfd, buf, len); } ssize_t recv(int sockfd, void *buf, size_t len, int flags) { if (flags != 0) { return errno = ENOSYS, -1; } return read(sockfd, buf, len); } int getsockopt(int, int, int, void *, socklen_t *) { return errno = ENOSYS, -1; } int setsockopt(int, int, int, const void *, socklen_t) { return 0; } int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { // TODO /net/ should expose local address somehow /* dummy output, just to satisfy curl */ (void)sockfd; (void)addrlen; addr->sa_family = AF_UNSPEC; return 0; } struct hostent *gethostbyname(const char *name) { (void)name; return NULL; }