diff options
-rw-r--r-- | src/kernel/syscalls.c | 6 | ||||
-rw-r--r-- | src/user/app/tests/kernel/fdlimit.c | 49 | ||||
-rw-r--r-- | src/user/app/tests/tests.c | 1 | ||||
-rw-r--r-- | src/user/app/tests/tests.h | 1 |
4 files changed, 54 insertions, 3 deletions
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c index dc8f9df..1909eb7 100644 --- a/src/kernel/syscalls.c +++ b/src/kernel/syscalls.c @@ -51,11 +51,10 @@ long _syscall_fork(int flags, handle_t __user *fs_front) { child = process_fork(process_current, flags); regs_savereturn(&child->regs, 0); - if ((flags & FORK_NEWFS) && fs_front) { + if (flags & FORK_NEWFS) { struct handle *h; handle_t hid = process_handle_init(process_current, HANDLE_FS_FRONT, &h); if (hid < 0) { - // TODO test child->noreap = true; process_kill(child, -EMFILE); SYSCALL_RETURN(-EMFILE); @@ -87,8 +86,9 @@ handle_t _syscall_open(const char __user *path, long len, int flags) { if (PATH_MAX < len) SYSCALL_RETURN(-1); + // TODO remove this check - it's not worth it w/ threads if (process_find_free_handle(process_current, 0) < 0) - SYSCALL_RETURN(-1); + SYSCALL_RETURN(-EMFILE); path_buf = kmalloc(len); if (!path_buf) goto fail; diff --git a/src/user/app/tests/kernel/fdlimit.c b/src/user/app/tests/kernel/fdlimit.c new file mode 100644 index 0000000..d22af13 --- /dev/null +++ b/src/user/app/tests/kernel/fdlimit.c @@ -0,0 +1,49 @@ +#include "../tests.h" +#include <camellia/flags.h> +#include <errno.h> +#include <unistd.h> + +static void test_fdlimit_pipe(void) { + handle_t ends[2]; + handle_t h[2] = {-1, -1}; + for (;;) { + handle_t cur = _syscall_open("/", 1, OPEN_READ); + if (cur == -EMFILE) break; + test(cur >= 0); + h[0] = h[1]; + h[1] = cur; + } + test(h[0] >= 0); /* we need at least two handles */ + + test(_syscall_pipe(ends, 0) == -EMFILE); + test(_syscall_open("/", 1, OPEN_READ) == -EMFILE); + + close(h[1]); + test(_syscall_pipe(ends, 0) == -EMFILE); + test(_syscall_open("/", 1, OPEN_READ) == h[1]); + test(_syscall_open("/", 1, OPEN_READ) == -EMFILE); + + close(h[0]); + close(h[1]); + test(_syscall_pipe(ends, 0) == 0); +} + +static void test_fdlimit_fork(void) { + for (;;) { + handle_t cur = _syscall_open("/", 1, OPEN_READ); + if (cur == -EMFILE) break; + test(cur >= 0); + } + + if (!_syscall_fork(0, NULL)) _syscall_exit(123); + + test(_syscall_fork(FORK_NEWFS, NULL) == -EMFILE); + test(_syscall_await() == 123); + test(_syscall_await() == ~0); +} + +void r_k_fdlimit(void) { + /* all these tests implicitly test if the vfs returns -EMFILE */ + run_test(test_fdlimit_pipe); + run_test(test_fdlimit_fork); +} diff --git a/src/user/app/tests/tests.c b/src/user/app/tests/tests.c index 29733aa..14225ac 100644 --- a/src/user/app/tests/tests.c +++ b/src/user/app/tests/tests.c @@ -36,6 +36,7 @@ int forkpipe(FILE **f, handle_t *h) { int main(void) { handle_t reader; if (!forkpipe(&fail_trig, &reader)) { + r_k_fdlimit(); r_k_fs(); r_k_misc(); r_k_miscsyscall(); diff --git a/src/user/app/tests/tests.h b/src/user/app/tests/tests.h index 248303d..e9b06e5 100644 --- a/src/user/app/tests/tests.h +++ b/src/user/app/tests/tests.h @@ -7,6 +7,7 @@ void run_test(void (*fn)()); +void r_k_fdlimit(void); void r_k_fs(void); void r_k_misc(void); void r_k_miscsyscall(void); |