summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cmd/tests/kernel/miscsyscall.c19
-rw-r--r--src/kernel/handle.h1
-rw-r--r--src/kernel/syscalls.c22
-rw-r--r--src/libc/socket.c9
-rw-r--r--src/libc/syscall.c4
-rw-r--r--src/libk/include/camellia/syscalls.h3
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);