summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2025-05-31 01:58:53 -0400
committerIan Moffett <ian@osmora.org>2025-05-31 01:58:53 -0400
commit5907c6f4b449d90aa9173955374e24408d5c9c8c (patch)
tree52bfa78fd893f1cefed376295d175a87363b8c1d
parenta1383ceb824076be78b23913b1a750c3a70a4f80 (diff)
kernel: spawn: Add support for SPAWN_WAIT flag
Add SPAWN_WAIT flag that causes spawn() to wait until the child process completes. Signed-off-by: Ian Moffett <ian@osmora.org>
-rw-r--r--sys/include/sys/spawn.h3
-rw-r--r--sys/kern/kern_exit.c10
-rw-r--r--sys/kern/kern_spawn.c21
3 files changed, 33 insertions, 1 deletions
diff --git a/sys/include/sys/spawn.h b/sys/include/sys/spawn.h
index 3828d5c..9d823db 100644
--- a/sys/include/sys/spawn.h
+++ b/sys/include/sys/spawn.h
@@ -31,6 +31,9 @@
#define _SYS_SPAWN_H_
#include <sys/types.h>
+#include <sys/param.h>
+
+#define SPAWN_WAIT BIT(0)
#if !defined(_KERNEL)
pid_t spawn(const char *pathname, int flags);
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index a421e52..b6cbc4e 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -111,6 +111,7 @@ int
exit1(struct proc *td, int flags)
{
struct proc *curtd, *procp;
+ struct proc *parent;
struct cpu_info *ci;
pid_t target_pid, curpid;
@@ -120,6 +121,7 @@ exit1(struct proc *td, int flags)
curpid = curtd->pid;
td->flags |= PROC_EXITING;
+ parent = td->parent;
/* If we have any children, kill them too */
if (td->nleaves > 0) {
@@ -149,6 +151,13 @@ exit1(struct proc *td, int flags)
*/
if (target_pid == curpid) {
ci->curtd = NULL;
+ if (parent->pid == 0)
+ sched_enter();
+ if (td->data == NULL)
+ sched_enter();
+
+ sched_enqueue_td(parent);
+ parent->flags &= ~PROC_SLEEP;
sched_enter();
}
@@ -163,6 +172,7 @@ sys_exit(struct syscall_args *scargs)
{
struct proc *td = this_td();
+ td->data = scargs->tf;
td->exit_status = scargs->arg0;
exit1(td, 0);
__builtin_unreachable();
diff --git a/sys/kern/kern_spawn.c b/sys/kern/kern_spawn.c
index 3360443..d72eeae 100644
--- a/sys/kern/kern_spawn.c
+++ b/sys/kern/kern_spawn.c
@@ -111,6 +111,7 @@ spawn(struct proc *cur, void(*func)(void), void *p, int flags, struct proc **new
struct proc *newproc;
struct mmap_lgdr *mlgdr;
int error;
+ pid_t pid;
newproc = dynalloc(sizeof(*newproc));
if (newproc == NULL) {
@@ -161,7 +162,25 @@ spawn(struct proc *cur, void(*func)(void), void *p, int flags, struct proc **new
newproc->pid = ++nthreads;
signals_init(newproc);
sched_enqueue_td(newproc);
- return newproc->pid;
+ pid = newproc->pid;
+
+ if (ISSET(flags, SPAWN_WAIT)) {
+ newproc->flags |= PROC_WAITED;
+ cur->flags |= PROC_SLEEP;
+
+ while (ISSET(cur->flags, PROC_SLEEP)) {
+ sched_yield();
+ }
+
+ if (!ISSET(newproc->flags, PROC_ZOMB)) {
+ pr_error("spawn: fatal: %d not zombie\n");
+ panic("possibly memory corruption\n");
+ }
+
+ proc_reap(newproc);
+ }
+
+ return pid;
}
/*