From 320366586cdab663df182fc0b0b25ce4bdb17e1a Mon Sep 17 00:00:00 2001 From: Matheus Date: Mon, 12 Jun 2023 21:15:21 -0300 Subject: [PATCH] syscalls: waitpid --- kernel-src/arch/x86-64/syscall.asm | 4 +- kernel-src/sys/syscalls/waitpid.c | 77 ++++++++++++++++++++++++++ patches/mlibc/jinx-working-patch.patch | 49 ++++++++-------- 3 files changed, 107 insertions(+), 23 deletions(-) create mode 100644 kernel-src/sys/syscalls/waitpid.c diff --git a/kernel-src/arch/x86-64/syscall.asm b/kernel-src/arch/x86-64/syscall.asm index 7555fb0e..6c093dd8 100644 --- a/kernel-src/arch/x86-64/syscall.asm +++ b/kernel-src/arch/x86-64/syscall.asm @@ -13,6 +13,7 @@ extern syscall_fstatat extern syscall_fork extern syscall_execve extern syscall_exit +extern syscall_waitpid syscalltab: dq syscall_print dq syscall_mmap @@ -28,7 +29,8 @@ dq syscall_fstatat dq syscall_fork dq syscall_execve dq syscall_exit -syscallcount equ 14 +dq syscall_waitpid +syscallcount equ 15 section .text global arch_syscall_entry ; on entry: diff --git a/kernel-src/sys/syscalls/waitpid.c b/kernel-src/sys/syscalls/waitpid.c new file mode 100644 index 00000000..f12938d7 --- /dev/null +++ b/kernel-src/sys/syscalls/waitpid.c @@ -0,0 +1,77 @@ +#include +#include +#include +#include +#include + +syscallret_t syscall_waitpid(context_t *context, pid_t pid, int *status, int options) { + syscallret_t ret = { + .ret = -1 + }; + + // TODO address check + // TODO implement these + __assert(options == 0); + __assert(pid == -1 || pid > 0); + + thread_t *thread = _cpu()->thread; + proc_t *proc = thread->proc; + spinlock_acquire(&proc->lock); + + proc_t *prev = NULL; + proc_t *iterator = proc->child; + proc_t *desired = NULL; + + for (;;) { + if (iterator == NULL) { + if (pid > 0 && desired == NULL) { + ret.errno = ECHILD; + spinlock_release(&proc->lock); + return ret; + } + spinlock_release(&proc->lock); + if (semaphore_wait(&proc->waitsem, true)) { + ret.errno = EINTR; + return ret; + } + spinlock_acquire(&proc->lock); + prev = NULL; + iterator = proc->child; + desired = NULL; // set as null to be certain another thread didn't get it + continue; + } + + if (pid > 0 && iterator->pid == pid) + desired = iterator; + + if (iterator->state == SCHED_PROC_STATE_ZOMBIE) + break; + + prev = iterator; + iterator = iterator->sibling; + } + + // iterator has the zombie child + + if (prev) + prev->sibling = iterator->sibling; + else + proc->child = iterator->sibling; + + spinlock_release(&proc->lock); + + // TODO memory safe operation + if (status) + *status = iterator->status; + + for (int i = 0; i < iterator->threadtablesize; ++i) { + if (iterator->threads[i] == NULL) + continue; + sched_destroythread(iterator->threads[i]); + } + + ret.ret = iterator->pid; + ret.errno = 0; + sched_destroyproc(iterator); + return ret; +} diff --git a/patches/mlibc/jinx-working-patch.patch b/patches/mlibc/jinx-working-patch.patch index ae521d02..587013a0 100644 --- a/patches/mlibc/jinx-working-patch.patch +++ b/patches/mlibc/jinx-working-patch.patch @@ -133,10 +133,10 @@ index 0000000..e5b087a + diff --git mlibc-workdir/sysdeps/astral/generic/generic.cpp mlibc-workdir/sysdeps/astral/generic/generic.cpp new file mode 100644 -index 0000000..f212b93 +index 0000000..afd1ebc --- /dev/null +++ mlibc-workdir/sysdeps/astral/generic/generic.cpp -@@ -0,0 +1,189 @@ +@@ -0,0 +1,193 @@ +#include +#include +#include @@ -151,57 +151,56 @@ index 0000000..f212b93 + +namespace mlibc { + -+ // stub -+ + int sys_setuid(uid_t id) { ++ // TODO UNSTUB + return 0; + } + -+ // stub -+ + int sys_setgid(gid_t id) { ++ // TODO UNSTUB + return 0; + } -+ -+ // stub + + uid_t sys_getuid() { ++ // TODO UNSTUB + return 0; + } + -+ // stub -+ + gid_t sys_getgid() { ++ // TODO UNSTUB + return 0; + } + -+ // stub -+ + uid_t sys_geteuid() { ++ // TODO UNSTUB + return 0; + } + -+ // stub -+ + gid_t sys_getegid() { ++ // TODO UNSTUB + return 0; + } + -+ // stub -+ + pid_t sys_getppid() { ++ // TODO UNSTUB + return 1; + } -+ -+ // stub + + int sys_getpgid(pid_t pid, pid_t *pgid) { ++ // TODO UNSTUB + *pgid = 1; + return 0; + } + ++ int sys_waitpid(pid_t pid, int *status, int flags, struct rusage *ru, pid_t *ret_pid) { ++ long ret; ++ long err = syscall(SYSCALL_WAITPID, &ret, pid, (uint64_t)status, flags); ++ *ret_pid = ret; ++ return err; ++ } ++ + int sys_execve(const char *path, char *const argv[], char *const envp[]) { -+ long ret = 0; ++ long ret; + return syscall(SYSCALL_EXECVE, &ret, (uint64_t)path, (uint64_t)argv, (uint64_t)envp); + } + @@ -240,7 +239,7 @@ index 0000000..f212b93 + + [[noreturn]] void sys_libc_panic() { + sys_libc_log("mlibc: panic"); -+ for (;;) ; ++ sys_exit(1); + } + + [[noreturn]] void sys_exit(int status) { @@ -254,9 +253,11 @@ index 0000000..f212b93 + } + + int sys_futex_wait(int *pointer, int expected, const struct timespec *time) { ++ // TODO UNSTUB + return ENOSYS; + } + int sys_futex_wake(int *pointer) { ++ // TODO UNSTUB + return ENOSYS; + } + @@ -313,14 +314,17 @@ index 0000000..f212b93 + } + + int sys_vm_unmap(void *pointer, size_t size) { ++ // TODO UNSTUB + return ENOSYS; + } + + int sys_isatty(int fd) { ++ // TODO UNSTUB + return 0; + } + + int sys_clock_get(int clock, time_t *secs, long *nanos) { ++ // TODO UNSTUB + return ENOSYS; + } + @@ -345,10 +349,10 @@ index 0000000..990eca0 +#endif diff --git mlibc-workdir/sysdeps/astral/include/astral/syscall.h mlibc-workdir/sysdeps/astral/include/astral/syscall.h new file mode 100644 -index 0000000..8a8d77d +index 0000000..43c4367 --- /dev/null +++ mlibc-workdir/sysdeps/astral/include/astral/syscall.h -@@ -0,0 +1,37 @@ +@@ -0,0 +1,38 @@ +#ifndef _SYSCALL_H_INCLUDE +#define _SYSCALL_H_INCLUDE + @@ -366,6 +370,7 @@ index 0000000..8a8d77d +#define SYSCALL_FORK 11 +#define SYSCALL_EXECVE 12 +#define SYSCALL_EXIT 13 ++#define SYSCALL_WAITPID 14 + +#include +#include