diff options
-rw-r--r-- | ports/curl/patches/0-autoconf.patch | 10 | ||||
-rw-r--r-- | ports/curl/patches/1-includes.patch | 10 | ||||
-rwxr-xr-x | ports/curl/port | 22 | ||||
-rw-r--r-- | ports/curl/sha256sums | 1 | ||||
-rw-r--r-- | ports/pre | 2 | ||||
-rw-r--r-- | src/libc/arpainet.c | 20 | ||||
-rw-r--r-- | src/libc/fcntl.c | 4 | ||||
-rw-r--r-- | src/libc/include/__errno.h | 6 | ||||
-rw-r--r-- | src/libc/include/arpa/inet.h | 8 | ||||
-rw-r--r-- | src/libc/include/fcntl.h | 1 | ||||
-rw-r--r-- | src/libc/include/netdb.h | 11 | ||||
-rw-r--r-- | src/libc/include/netinet/in.h | 16 | ||||
-rw-r--r-- | src/libc/include/signal.h | 9 | ||||
-rw-r--r-- | src/libc/include/stdlib.h | 2 | ||||
-rw-r--r-- | src/libc/include/sys/select.h | 13 | ||||
-rw-r--r-- | src/libc/include/sys/socket.h | 38 | ||||
-rw-r--r-- | src/libc/include/sys/stat.h | 11 | ||||
-rw-r--r-- | src/libc/include/sys/time.h | 5 | ||||
-rw-r--r-- | src/libc/include/sys/types.h | 6 | ||||
-rw-r--r-- | src/libc/include/unistd.h | 1 | ||||
-rw-r--r-- | src/libc/select.c | 47 | ||||
-rw-r--r-- | src/libc/signal.c | 2 | ||||
-rw-r--r-- | src/libc/socket.c | 91 | ||||
-rw-r--r-- | src/libc/stdlib/stdlib.c | 4 | ||||
-rw-r--r-- | src/libc/unistd/unistd.c | 3 | ||||
-rw-r--r-- | src/libk/include/camellia/errno.h | 6 |
26 files changed, 335 insertions, 14 deletions
diff --git a/ports/curl/patches/0-autoconf.patch b/ports/curl/patches/0-autoconf.patch new file mode 100644 index 0000000..25ab95f --- /dev/null +++ b/ports/curl/patches/0-autoconf.patch @@ -0,0 +1,10 @@ +--- config.sub.orig 2023-11-20 20:42:24.667820565 +0100 ++++ config.sub 2023-11-20 20:42:38.215040191 +0100 +@@ -1754,6 +1754,7 @@ + | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ + | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ + | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \ ++ | camellia* \ + | fiwix* ) + ;; + # This one is extra strict with allowed versions diff --git a/ports/curl/patches/1-includes.patch b/ports/curl/patches/1-includes.patch new file mode 100644 index 0000000..009ef5c --- /dev/null +++ b/ports/curl/patches/1-includes.patch @@ -0,0 +1,10 @@ +--- lib/select.h.orig 2023-11-20 23:12:27.240289500 +0100 ++++ lib/select.h 2023-11-20 23:12:38.096619073 +0100 +@@ -31,6 +31,7 @@ + #elif defined(HAVE_SYS_POLL_H) + #include <sys/poll.h> + #endif ++#include <sys/select.h> + + /* + * Definition of pollfd struct and constants for platforms lacking them. diff --git a/ports/curl/port b/ports/curl/port new file mode 100755 index 0000000..befd017 --- /dev/null +++ b/ports/curl/port @@ -0,0 +1,22 @@ +#!/bin/sh +. ports/pre + +pkg=curl +tarball=curl-8.4.0.tar.gz +tarball_dir=curl-8.4.0 +url=https://curl.se/download/${tarball} + +configure() { + test -e $tarball_dir/configured && return + (cd $tarball_dir && CFLAGS=-g ./configure \ + --host=x86_64-camellia \ + --without-ssl \ + --disable-threaded-resolver \ + --disable-ipv6 \ + --disable-tftp \ + 'ac_cv_header_termios_h=no' + ) + touch $tarball_dir/configured +} + +. ports/post diff --git a/ports/curl/sha256sums b/ports/curl/sha256sums new file mode 100644 index 0000000..1b0bc2a --- /dev/null +++ b/ports/curl/sha256sums @@ -0,0 +1 @@ +816e41809c043ff285e8c0f06a75a1fa250211bbfb2dc0a037eeef39f1a9e427 curl-8.4.0.tar.gz @@ -39,7 +39,7 @@ patch() { if test -d $portdir/patches/; then for patch in $portdir/patches/*; do echo $patch - command patch -d $tarball_dir/ <$patch + command patch -p0 -d $tarball_dir/ <$patch done fi post_patch diff --git a/src/libc/arpainet.c b/src/libc/arpainet.c new file mode 100644 index 0000000..125a855 --- /dev/null +++ b/src/libc/arpainet.c @@ -0,0 +1,20 @@ +#include <arpa/inet.h> + +uint32_t htonl(uint32_t n) { + return ((n & 0xFF000000) >> 24) + | ((n & 0x00FF0000) >> 8) + | ((n & 0x0000FF00) << 8) + | ((n & 0x000000FF) << 24); +} + +uint16_t htons(uint16_t n) { + return (n >> 8) | (n << 8); +} + +uint32_t ntohl(uint32_t n) { + return htonl(n); +} + +uint16_t ntohs(uint16_t n) { + return htons(n); +} diff --git a/src/libc/fcntl.c b/src/libc/fcntl.c index b2d8685..c06f037 100644 --- a/src/libc/fcntl.c +++ b/src/libc/fcntl.c @@ -20,6 +20,10 @@ int fcntl(int fd, int cmd, ...) { int to = va_arg(argp, int); va_end(argp); return _sys_dup(fd, to, DUP_SEARCH); + } else if (cmd == F_GETFD) { + /* curl fucking dies if this returns -1 */ + /* ideally this would return -1 for nonexistent fds */ + return 0; } else { va_end(argp); _klogf("failing fcntl(%d)", cmd); diff --git a/src/libc/include/__errno.h b/src/libc/include/__errno.h index 7976fba..56bd64a 100644 --- a/src/libc/include/__errno.h +++ b/src/libc/include/__errno.h @@ -26,4 +26,10 @@ E(208, "EAGAIN") E(209, "EIO") E(210, "EDOM domain error") E(211, "EFBIG file too large") +E(212, "EINPROGRESS") +E(213, "EAFNOSUPPORT") +E(214, "EADDRNOTAVAIL") +E(215, "EADDRINUSE") +E(216, "ENOSPC") +E(217, "ECONNREFUSED") #endif diff --git a/src/libc/include/arpa/inet.h b/src/libc/include/arpa/inet.h new file mode 100644 index 0000000..d372467 --- /dev/null +++ b/src/libc/include/arpa/inet.h @@ -0,0 +1,8 @@ +#pragma once +#include <stdint.h> + +uint32_t htonl(uint32_t n); +uint16_t htons(uint16_t n); + +uint32_t ntohl(uint32_t n); +uint16_t ntohs(uint16_t n); diff --git a/src/libc/include/fcntl.h b/src/libc/include/fcntl.h index ba9b9e0..63d301b 100644 --- a/src/libc/include/fcntl.h +++ b/src/libc/include/fcntl.h @@ -4,6 +4,7 @@ #define F_GETFL 2 #define F_DUPFD 3 #define F_SETFD 4 +#define F_GETFD 5 #define FD_CLOEXEC 1 diff --git a/src/libc/include/netdb.h b/src/libc/include/netdb.h new file mode 100644 index 0000000..c88221c --- /dev/null +++ b/src/libc/include/netdb.h @@ -0,0 +1,11 @@ +#pragma once + +struct hostent { + char *h_name; + char **h_aliases; + int h_addrtype; + int h_length; + char **h_addr_list; +}; + +struct hostent *gethostbyname(const char *name); diff --git a/src/libc/include/netinet/in.h b/src/libc/include/netinet/in.h new file mode 100644 index 0000000..b56a22a --- /dev/null +++ b/src/libc/include/netinet/in.h @@ -0,0 +1,16 @@ +#pragma once +#include <sys/socket.h> + +#define IPPROTO_TCP 1 +#define IPPROTO_UDP 2 +#define IPPROTO_IP 4 + +struct in_addr { + in_addr_t s_addr; +}; + +struct sockaddr_in { + sa_family_t sin_family; /* AF_INET */ + in_port_t sin_port; + struct in_addr sin_addr; +}; diff --git a/src/libc/include/signal.h b/src/libc/include/signal.h index 012481e..b01aef3 100644 --- a/src/libc/include/signal.h +++ b/src/libc/include/signal.h @@ -26,14 +26,15 @@ #define NSIG 32 -#define SIG_DFL 0 -#define SIG_ERR 0 -#define SIG_IGN 0 +#define SIG_DFL ((void*)0) +#define SIG_ERR ((void*)0) +#define SIG_IGN ((void*)0) #define SIG_SETMASK 0 typedef int sig_atomic_t; typedef struct {} sigset_t; typedef struct {} siginfo_t; +typedef void (*sighandler_t)(int); extern const char *const sys_siglist[]; struct sigaction { @@ -49,6 +50,6 @@ int sigemptyset(sigset_t *set); int sigfillset(sigset_t *set); int sigprocmask(int how, const sigset_t *set, const sigset_t *oldset); int sigsuspend(const sigset_t *mask); -int signal(int sig, void (*func)(int)); +sighandler_t signal(int sig, void (*func)(int)); int kill(pid_t pid, int sig); int raise(int sig); diff --git a/src/libc/include/stdlib.h b/src/libc/include/stdlib.h index c3fd4bd..61d9734 100644 --- a/src/libc/include/stdlib.h +++ b/src/libc/include/stdlib.h @@ -36,3 +36,5 @@ double strtod(const char *restrict s, char **restrict end); void qsort(void *base, size_t nmemb, size_t size, int (*cmp)(const void *a, const void *b)); void qsort_r(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *, void *), void *arg); void* bsearch(const void* key, const void* base_ptr, size_t nmemb, size_t size, int (*compare)(const void*, const void*)); + +int rand(void); diff --git a/src/libc/include/sys/select.h b/src/libc/include/sys/select.h new file mode 100644 index 0000000..3c1bb90 --- /dev/null +++ b/src/libc/include/sys/select.h @@ -0,0 +1,13 @@ +#pragma once +#include <stdint.h> +#include <sys/time.h> + +typedef uint64_t fd_set; + +#define FD_SETSIZE 64 +void FD_CLR(int fd, fd_set *set); +int FD_ISSET(int fd, fd_set *set); +void FD_SET(int fd, fd_set *set); +void FD_ZERO(fd_set *set); + +int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); diff --git a/src/libc/include/sys/socket.h b/src/libc/include/sys/socket.h new file mode 100644 index 0000000..e3a4752 --- /dev/null +++ b/src/libc/include/sys/socket.h @@ -0,0 +1,38 @@ +#pragma once +#include <stdint.h> +#include <unistd.h> // ssize_t + +typedef int socklen_t; +typedef int sa_family_t; +typedef uint32_t in_addr_t; +typedef uint16_t in_port_t; + +#define AF_UNSPEC 0 +#define AF_UNIX 1 +#define AF_INET 4 +#define PF_INET 4 + +struct sockaddr { + sa_family_t sa_family; + char sa_data[]; +}; + +#define SOCK_STREAM 1 +#define SOCK_DGRAM 2 +int socket(int domain, int type, int protocol); +int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); +int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); +int listen(int sockfd, int backlog); + +int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); +ssize_t send(int sockfd, const void *buf, size_t len, int flags); +ssize_t recv(int sockfd, void *buf, size_t len, int flags); + +#define SOL_SOCKET 1 +#define SO_KEEPALIVE 1 +#define SO_REUSEADDR 2 + +int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen); +int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen); + +int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen); diff --git a/src/libc/include/sys/stat.h b/src/libc/include/sys/stat.h index b9d0e8b..0d828ec 100644 --- a/src/libc/include/sys/stat.h +++ b/src/libc/include/sys/stat.h @@ -4,6 +4,7 @@ #include <sys/types.h> #include <time.h> // struct timespec #include <errno.h> // only for ENOSYS +#include <fcntl.h> // for R_OK etc. (curl) struct stat { dev_t st_dev; @@ -38,7 +39,15 @@ struct stat { #define S_ISGID 02000 #define S_ISVTX 01000 -#define S_IRUSR 0x400 +#define S_IRUSR 0400 +#define S_IWUSR 0200 +#define S_IXUSR 0100 +#define S_IRGRP 0040 +#define S_IWGRP 0020 +#define S_IXGRP 0010 +#define S_IROTH 0004 +#define S_IWOTH 0002 +#define S_IXOTH 0001 /* inode(7) */ #define S_ISREG(m) ((m & S_IFMT) == S_IFREG) diff --git a/src/libc/include/sys/time.h b/src/libc/include/sys/time.h index 54df6b3..5e00fe9 100644 --- a/src/libc/include/sys/time.h +++ b/src/libc/include/sys/time.h @@ -2,6 +2,11 @@ #include <errno.h> #include <sys/types.h> +typedef long long off_t; +typedef int64_t time_t; +typedef int64_t suseconds_t; +typedef uint64_t clock_t; + struct timeval { time_t tv_sec; suseconds_t tv_usec; diff --git a/src/libc/include/sys/types.h b/src/libc/include/sys/types.h index 2e7f54b..d637fd6 100644 --- a/src/libc/include/sys/types.h +++ b/src/libc/include/sys/types.h @@ -1,11 +1,7 @@ #pragma once #include <stddef.h> #include <stdint.h> - -typedef long long off_t; -typedef int64_t time_t; -typedef int64_t suseconds_t; -typedef uint64_t clock_t; +#include <sys/select.h> typedef int mode_t; typedef int dev_t; diff --git a/src/libc/include/unistd.h b/src/libc/include/unistd.h index 2158511..41cf0a0 100644 --- a/src/libc/include/unistd.h +++ b/src/libc/include/unistd.h @@ -5,6 +5,7 @@ #include <getopt.h> // TODO custom stdint.h, ssize_t doesn't belong here +// used from sys/socket.h typedef long long ssize_t; extern char **environ; diff --git a/src/libc/select.c b/src/libc/select.c new file mode 100644 index 0000000..e3e95e4 --- /dev/null +++ b/src/libc/select.c @@ -0,0 +1,47 @@ +#include <errno.h> +#include <sys/select.h> +#include <stdio.h> + +static int +countset(int nfds, fd_set *set) +{ + int count = 0; + if (set == NULL) return 0; + for (int i = 0; i < nfds; i++) { + if (FD_ISSET(i, set)) { + count++; + } + } + return count; +} + +int +select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) +{ + (void)timeout; + FD_ZERO(exceptfds); + if (countset(nfds, readfds) != 0) { + return errno = ENOSYS, -1; + } + return countset(nfds, writefds); /* assume everything is ready for writing */ +} + +void FD_CLR(int fd, fd_set *set) { + if (0 <= fd && fd < FD_SETSIZE) { + *set = *set & ~(1<<fd); + } +} + +int FD_ISSET(int fd, fd_set *set) { + return 0 <= fd && fd < FD_SETSIZE && (*set & (1 << fd)); +} + +void FD_SET(int fd, fd_set *set) { + if (0 <= fd && fd < FD_SETSIZE) { + *set = *set | (1<<fd); + } +} + +void FD_ZERO(fd_set *set) { + *set = 0; +} diff --git a/src/libc/signal.c b/src/libc/signal.c index cc280a6..a276fde 100644 --- a/src/libc/signal.c +++ b/src/libc/signal.c @@ -85,7 +85,7 @@ int sigsuspend(const sigset_t *mask) { __libc_panic("unimplemented"); } -int signal(int sig, void (*func)(int)) { +sighandler_t signal(int sig, void (*func)(int)) { (void)sig; (void)func; return errno = ENOSYS, SIG_ERR; } 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; +} diff --git a/src/libc/stdlib/stdlib.c b/src/libc/stdlib/stdlib.c index 1dee760..2a410d0 100644 --- a/src/libc/stdlib/stdlib.c +++ b/src/libc/stdlib/stdlib.c @@ -125,3 +125,7 @@ double strtod(const char *restrict s, char **restrict end) { (void)s; (void)end; __libc_panic("unimplemented"); } + +int rand(void) { + __libc_panic("unimplemented"); +} diff --git a/src/libc/unistd/unistd.c b/src/libc/unistd/unistd.c index 102e72a..9735df0 100644 --- a/src/libc/unistd/unistd.c +++ b/src/libc/unistd/unistd.c @@ -80,6 +80,5 @@ int getgroups(int size, gid_t list[]) { } int dup(int oldfd) { - (void)oldfd; - __libc_panic("unimplemented"); + return _sys_dup(oldfd, -1, 0); } diff --git a/src/libk/include/camellia/errno.h b/src/libk/include/camellia/errno.h index e148b40..eaeae38 100644 --- a/src/libk/include/camellia/errno.h +++ b/src/libk/include/camellia/errno.h @@ -29,3 +29,9 @@ #define EIO 209 #define EDOM 210 /* domain error */ #define EFBIG 211 /* file too large */ +#define EINPROGRESS 212 +#define EAFNOSUPPORT 213 +#define EADDRNOTAVAIL 214 +#define EADDRINUSE 215 +#define ENOSPC 216 +#define ECONNREFUSED 217 |