diff options
author | dzwdz | 2023-12-25 18:36:02 +0100 |
---|---|---|
committer | dzwdz | 2023-12-25 18:36:02 +0100 |
commit | 4e1a6f1b3c543b9fbeb882a9e97551f7c58ca65a (patch) | |
tree | 8c2048c751db8b98e3033a61b6ad5bbd11a303a9 /src/libc/socket.c | |
parent | 64d4330810a37dd9c41a82ae6cc420850ca1e7da (diff) |
ports: curl :^)
had to do a lot of hacky stuff, but it's there.
worked on this on and off for a while now
Diffstat (limited to 'src/libc/socket.c')
-rw-r--r-- | src/libc/socket.c | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/src/libc/socket.c b/src/libc/socket.c new file mode 100644 index 0000000..a8871a3 --- /dev/null +++ b/src/libc/socket.c @@ -0,0 +1,91 @@ +#include <arpa/inet.h> +#include <camellia.h> +#include <errno.h> +#include <netdb.h> +#include <netinet/in.h> +#include <stdio.h> +#include <sys/socket.h> + +int socket(int domain, int type, int protocol) { + if (domain != AF_INET || type != SOCK_STREAM || protocol != IPPROTO_TCP) { + return errno = ENOSYS, -1; + } + // TODO! /dev/null + return dup(1); // yolo +} + +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; +} |