summaryrefslogtreecommitdiff
path: root/src/init
diff options
context:
space:
mode:
authordzwdz2022-07-10 23:17:27 +0200
committerdzwdz2022-07-10 23:17:27 +0200
commitd3be139a93c578d1e055bfd5f6f79eda312091f9 (patch)
tree0d2bf35333017e41c88fea49969d12fdad0a08c2 /src/init
parent45c5bf044a063a289fad6a53b8d27ce675d9c272 (diff)
syscalls: implement dup
Diffstat (limited to 'src/init')
-rw-r--r--src/init/syscalls.c4
-rw-r--r--src/init/tests/main.c54
2 files changed, 58 insertions, 0 deletions
diff --git a/src/init/syscalls.c b/src/init/syscalls.c
index 25fa134..7c2bb68 100644
--- a/src/init/syscalls.c
+++ b/src/init/syscalls.c
@@ -26,6 +26,10 @@ int _syscall_mount(handle_t h, const char __user *path, int len) {
return _syscall(_SYSCALL_MOUNT, (int)h, (int)path, len, 0);
}
+handle_t _syscall_dup(handle_t from, handle_t to, int flags) {
+ return (handle_t)_syscall(_SYSCALL_DUP, (int)from, (int)to, flags, 0);
+}
+
int _syscall_read(handle_t h, void __user *buf, size_t len, int offset) {
return _syscall(_SYSCALL_READ, (int)h, (int)buf, (int)len, offset);
}
diff --git a/src/init/tests/main.c b/src/init/tests/main.c
index 9adb50c..97ed798 100644
--- a/src/init/tests/main.c
+++ b/src/init/tests/main.c
@@ -113,6 +113,59 @@ static void test_memflag(void) {
// TODO check if reclaims
}
+static void test_dup(void) {
+ handle_t pipe[2];
+ handle_t h1, h2;
+ assert(_syscall_pipe(pipe, 0) >= 0);
+
+ if (!_syscall_fork(0, NULL)) {
+ _syscall_close(pipe[0]);
+
+ h1 = _syscall_dup(pipe[1], -1, 0);
+ assert(h1 >= 0);
+ assert(h1 != pipe[1]);
+ h2 = _syscall_dup(h1, -1, 0);
+ assert(h2 >= 0);
+ assert(h2 != pipe[1] && h2 != h1);
+
+ _syscall_write(pipe[1], "og", 2, 0);
+ _syscall_write(h1, "h1", 2, 0);
+ _syscall_write(h2, "h2", 2, 0);
+
+ _syscall_close(pipe[1]);
+ _syscall_write(h1, "h1", 2, 0);
+ _syscall_write(h2, "h2", 2, 0);
+
+ assert(_syscall_dup(h1, pipe[1], 0) == pipe[1]);
+ assert(_syscall_dup(h2, pipe[1], 0) == pipe[1]);
+ assert(_syscall_dup(h1, pipe[1], 0) == pipe[1]);
+ assert(_syscall_dup(h2, pipe[1], 0) == pipe[1]);
+ _syscall_close(h1);
+ _syscall_close(h2);
+
+ assert(_syscall_dup(pipe[1], h2, 0) == h2);
+ _syscall_write(h2, "h2", 2, 0);
+ _syscall_close(h2);
+
+ assert(_syscall_dup(pipe[1], h1, 0) == h1);
+ _syscall_write(h1, "h1", 2, 0);
+ _syscall_close(h1);
+
+ _syscall_exit(0);
+ } else {
+ char buf[16];
+ size_t count = 0;
+ _syscall_close(pipe[1]);
+ while (_syscall_read(pipe[0], buf, sizeof buf, 0) >= 0)
+ count++;
+ assert(count == 7);
+ _syscall_await();
+ }
+
+
+ _syscall_close(pipe[0]);
+}
+
static void test_malloc(void) {
// not really a test
void *p1, *p2;
@@ -144,6 +197,7 @@ void test_all(void) {
run_forked(test_interrupted_fs);
run_forked(test_orphaned_fs);
run_forked(test_memflag);
+ run_forked(test_dup);
run_forked(test_malloc);
run_forked(test_pipe);
run_forked(test_semaphore);