diff options
author | dzwdz | 2023-12-25 19:08:04 +0100 |
---|---|---|
committer | dzwdz | 2023-12-25 19:08:04 +0100 |
commit | b9f5f92bff69059471a76e73539780eedb356455 (patch) | |
tree | 55302764cbc2a6ab159cf2621dc34aab04ca4085 /src | |
parent | 4e1a6f1b3c543b9fbeb882a9e97551f7c58ca65a (diff) |
kernel: _sys_getnull() (basically /dev/null)
Diffstat (limited to 'src')
-rw-r--r-- | src/cmd/tests/kernel/miscsyscall.c | 19 | ||||
-rw-r--r-- | src/kernel/handle.h | 1 | ||||
-rw-r--r-- | src/kernel/syscalls.c | 22 | ||||
-rw-r--r-- | src/libc/socket.c | 9 | ||||
-rw-r--r-- | src/libc/syscall.c | 4 | ||||
-rw-r--r-- | src/libk/include/camellia/syscalls.h | 3 |
6 files changed, 54 insertions, 4 deletions
diff --git a/src/cmd/tests/kernel/miscsyscall.c b/src/cmd/tests/kernel/miscsyscall.c index 3cf3f2e..c7ce9e0 100644 --- a/src/cmd/tests/kernel/miscsyscall.c +++ b/src/cmd/tests/kernel/miscsyscall.c @@ -304,6 +304,24 @@ static void test_timer(void) { } } +static void test_getnull(void) { + hid_t h, h2; + char buf[16]; + + test((h = _sys_getnull(0)) >= 0); + test((h2 = dup(h))); + + test(_sys_read(h, buf, 16, 0) == -ENOSYS); + test(_sys_write(h, buf, 16, 0, 0) == -ENOSYS); + test(_sys_getsize(h) == -ENOSYS); + test(_sys_remove(h) == -ENOSYS); + test(_sys_fs_respond(h, buf, 16, 0) == -EBADF); + test(_sys_mount(h, "/asdf", 5) == -EGENERIC); + + close(h); + close(h2); +} + void r_k_miscsyscall(void) { run_test(test_await); run_test(test_await2); @@ -315,4 +333,5 @@ void r_k_miscsyscall(void) { run_test(test_sleep); run_test(test_badopen); run_test(test_timer); + run_test(test_getnull); } diff --git a/src/kernel/handle.h b/src/kernel/handle.h index 21b4364..d502d5d 100644 --- a/src/kernel/handle.h +++ b/src/kernel/handle.h @@ -10,6 +10,7 @@ enum handle_type { HANDLE_PIPE, HANDLE_FS_FRONT, HANDLE_FS_REQ, + HANDLE_NULL, }; struct Handle { diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c index e449953..5f53ccb 100644 --- a/src/kernel/syscalls.c +++ b/src/kernel/syscalls.c @@ -166,7 +166,13 @@ static long simple_vfsop( || vfsop == VFSOP_WRITE || vfsop == VFSOP_GETSIZE); Handle *h = proc_handle_get(proc_cur, hid); - if (!h) SYSCALL_RETURN(-EBADF); + if (!h) { + SYSCALL_RETURN(-EBADF); + } + if (h->type != HANDLE_FILE && h->type != HANDLE_PIPE) { + SYSCALL_RETURN(-ENOSYS); + } + // TODO those checks really need some comprehensive tests if (vfsop == VFSOP_READ && !h->readable) SYSCALL_RETURN(-EACCES); @@ -196,7 +202,9 @@ static long simple_vfsop( /* already checked if this is the correct pipe end */ pipe_joinqueue(h, proc_cur, buf, len); } else SYSCALL_RETURN(-ENOSYS); - } else SYSCALL_RETURN(-ENOSYS); + } else { + panic_invalid_state(); + } return 0; } @@ -436,6 +444,15 @@ uint64_t _sys_time(int flags) { SYSCALL_RETURN(now - proc_cur->basetime); } +hid_t _sys_getnull(int flags) { + if (flags != 0) { + SYSCALL_RETURN(-ENOSYS); + } + + hid_t hid = proc_handle_init(proc_cur, HANDLE_NULL, NULL); + SYSCALL_RETURN((0 <= hid) ? hid : -EMFILE); +} + long _sys_execbuf(void __user *ubuf, size_t len) { if (len == 0) SYSCALL_RETURN(0); if (len > EXECBUF_MAX_LEN) @@ -491,6 +508,7 @@ long _syscall(long num, long a, long b, long c, long d, long e) { break; case _SYS_WAIT2: _sys_wait2(a, b, (userptr_t)c); break; case _SYS_GETPROCFS: _sys_getprocfs(a); break; case _SYS_TIME: _sys_time(a); + break; case _SYS_GETNULL: _sys_getnull(a); break; case _SYS_EXECBUF: _sys_execbuf((userptr_t)a, b); break; case _SYS_DEBUG_KLOG: _sys_debug_klog((userptr_t)a, b); break; diff --git a/src/libc/socket.c b/src/libc/socket.c index a8871a3..5ea7266 100644 --- a/src/libc/socket.c +++ b/src/libc/socket.c @@ -1,5 +1,6 @@ #include <arpa/inet.h> #include <camellia.h> +#include <camellia/syscalls.h> #include <errno.h> #include <netdb.h> #include <netinet/in.h> @@ -10,8 +11,12 @@ 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 h = _sys_getnull(0); + if (h < 0) { + return errno = -h, -1; + } else { + return h; + } } int bind(int, const struct sockaddr *, socklen_t) { diff --git a/src/libc/syscall.c b/src/libc/syscall.c index 8142028..f44c775 100644 --- a/src/libc/syscall.c +++ b/src/libc/syscall.c @@ -94,6 +94,10 @@ uint64_t _sys_time(int flags) { return (uint64_t)_syscall(_SYS_TIME, (long)flags, 0, 0, 0, 0); } +hid_t _sys_getnull(int flags) { + return (hid_t)_syscall(_SYS_GETNULL, (long)flags, 0, 0, 0, 0); +} + long _sys_execbuf(void __user *buf, size_t len) { return _syscall(_SYS_EXECBUF, (long)buf, (long)len, 0, 0, 0); } diff --git a/src/libk/include/camellia/syscalls.h b/src/libk/include/camellia/syscalls.h index 6d9286b..3e7576e 100644 --- a/src/libk/include/camellia/syscalls.h +++ b/src/libk/include/camellia/syscalls.h @@ -22,6 +22,7 @@ #define _SYS_WAIT2 21 #define _SYS_GETPROCFS 22 #define _SYS_TIME 23 +#define _SYS_GETNULL 24 #define _SYS_EXECBUF 100 #define _SYS_DEBUG_KLOG 101 @@ -86,6 +87,8 @@ hid_t _sys_getprocfs(int flags); /** Returns the time in nanoseconds since the first _sys_time call in the process */ uint64_t _sys_time(int flags); +hid_t _sys_getnull(int flags); + /* see shared/execbuf.h */ long _sys_execbuf(void __user *buf, size_t len); |