From 3a486d207fc948bf1d146b6071480a6ecdae41b7 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Thu, 17 Jul 2025 00:25:52 -0400 Subject: kernel: spawn: Add waitpid() Add waitpid() in preparation of deprecating SPAWN_WAIT. Signed-off-by: Ian Moffett --- sys/include/sys/proc.h | 1 + sys/include/sys/syscall.h | 1 + sys/kern/kern_spawn.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++ sys/kern/kern_syscall.c | 1 + 4 files changed, 54 insertions(+) (limited to 'sys') diff --git a/sys/include/sys/proc.h b/sys/include/sys/proc.h index decc615..972d3c4 100644 --- a/sys/include/sys/proc.h +++ b/sys/include/sys/proc.h @@ -119,6 +119,7 @@ pid_t getppid(void); scret_t sys_getpid(struct syscall_args *scargs); scret_t sys_getppid(struct syscall_args *scargs); +scret_t sys_waitpid(struct syscall_args *scargs); int md_spawn(struct proc *p, struct proc *parent, uintptr_t ip); diff --git a/sys/include/sys/syscall.h b/sys/include/sys/syscall.h index 51c2579..02629a9 100644 --- a/sys/include/sys/syscall.h +++ b/sys/include/sys/syscall.h @@ -58,6 +58,7 @@ #define SYS_getppid 17 #define SYS_setuid 18 #define SYS_getuid 19 +#define SYS_waitpid 20 #if defined(_KERNEL) /* Syscall return value and arg type */ diff --git a/sys/kern/kern_spawn.c b/sys/kern/kern_spawn.c index 930c3d2..c1c0029 100644 --- a/sys/kern/kern_spawn.c +++ b/sys/kern/kern_spawn.c @@ -28,6 +28,7 @@ */ #include +#include #include #include #include @@ -96,6 +97,35 @@ spawn_thunk(void) __builtin_unreachable(); } +pid_t +waitpid(pid_t pid, int *wstatus, int options) +{ + struct proc *child, *td; + pid_t ret; + + td = this_td(); + child = get_child(td, pid); + + if (child == NULL) { + return -1; + } + + /* Wait for it to be done */ + while (!ISSET(child->flags, PROC_ZOMB)) { + sched_yield(); + } + + + /* Give back the status */ + if (wstatus != NULL) { + copyout(&child->exit_status, wstatus, sizeof(*wstatus)); + } + + ret = child->pid; + proc_reap(child); + return ret; +} + /* * Spawn a new process * @@ -219,6 +249,27 @@ get_child(struct proc *cur, pid_t pid) return NULL; } +/* + * arg0: PID + * arg1: wstatus + * arg2: options + * + * Returns PID of terminated child, returns + * -1 on failure. + */ +scret_t +sys_waitpid(struct syscall_args *scargs) +{ + pid_t pid; + int *u_wstatus; + int options; + + pid = scargs->arg0; + u_wstatus = (void *)scargs->arg1; + options = scargs->arg2; + return waitpid(pid, u_wstatus, options); +} + /* * arg0: The file /path/to/executable * arg1: Argv diff --git a/sys/kern/kern_syscall.c b/sys/kern/kern_syscall.c index a28d2dd..cb7e1d2 100644 --- a/sys/kern/kern_syscall.c +++ b/sys/kern/kern_syscall.c @@ -59,6 +59,7 @@ scret_t(*g_sctab[])(struct syscall_args *) = { sys_getppid, /* SYS_getppid */ sys_setuid, /* SYS_setuid */ sys_getuid, /* SYS_getuid */ + sys_waitpid, /* SYS_waitpid */ }; const size_t MAX_SYSCALLS = NELEM(g_sctab); -- cgit v1.2.3