summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/curl/patches/0-autoconf.patch10
-rw-r--r--ports/curl/patches/1-includes.patch10
-rwxr-xr-xports/curl/port22
-rw-r--r--ports/curl/sha256sums1
-rw-r--r--ports/pre2
-rw-r--r--src/libc/arpainet.c20
-rw-r--r--src/libc/fcntl.c4
-rw-r--r--src/libc/include/__errno.h6
-rw-r--r--src/libc/include/arpa/inet.h8
-rw-r--r--src/libc/include/fcntl.h1
-rw-r--r--src/libc/include/netdb.h11
-rw-r--r--src/libc/include/netinet/in.h16
-rw-r--r--src/libc/include/signal.h9
-rw-r--r--src/libc/include/stdlib.h2
-rw-r--r--src/libc/include/sys/select.h13
-rw-r--r--src/libc/include/sys/socket.h38
-rw-r--r--src/libc/include/sys/stat.h11
-rw-r--r--src/libc/include/sys/time.h5
-rw-r--r--src/libc/include/sys/types.h6
-rw-r--r--src/libc/include/unistd.h1
-rw-r--r--src/libc/select.c47
-rw-r--r--src/libc/signal.c2
-rw-r--r--src/libc/socket.c91
-rw-r--r--src/libc/stdlib/stdlib.c4
-rw-r--r--src/libc/unistd/unistd.c3
-rw-r--r--src/libk/include/camellia/errno.h6
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
diff --git a/ports/pre b/ports/pre
index fd77784..c30ddd8 100644
--- a/ports/pre
+++ b/ports/pre
@@ -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