summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2025-05-16 09:28:44 -0400
committerIan Moffett <ian@osmora.org>2025-05-16 09:28:44 -0400
commit03f145b2fd5a01e40a3066c6cf2f649000a9fcd8 (patch)
tree62e67065b27bb91fbf865a4385edd49ffea5e6c4 /sys/kern
parent02ca8f9faf6b6ddd0b7a514503b223e9ecbe8fe9 (diff)
kernel: proc: Handle parent exit
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_exit.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 75ab0e9..24c7e74 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -81,7 +81,7 @@ int
exit1(struct proc *td)
{
struct pcb *pcbp;
- struct proc *curtd;
+ struct proc *curtd, *procp;
uintptr_t stack;
pid_t target_pid, curpid;
@@ -93,6 +93,13 @@ exit1(struct proc *td)
stack = td->stack_base;
td->flags |= PROC_EXITING;
+ /* If we have any children, kill them too */
+ if (td->nleaves > 0) {
+ TAILQ_FOREACH(procp, &td->leafq, leaf_link) {
+ exit1(procp);
+ }
+ }
+
/*
* If this is on the higher half, it is kernel
* mapped and we need to convert it to a physical
@@ -107,7 +114,17 @@ exit1(struct proc *td)
vm_free_frame(stack, PROC_STACK_PAGES);
pmap_destroy_vas(pcbp->addrsp);
- dynfree(td);
+
+ /*
+ * Only free the process structure if we aren't
+ * being waited on, otherwise let it be so the
+ * parent can examine what's left of it.
+ */
+ if (!ISSET(td->flags, PROC_WAITED)) {
+ dynfree(td);
+ } else {
+ td->flags |= PROC_ZOMB;
+ }
/*
* If we are the thread exiting, reenter the scheduler
@@ -119,9 +136,15 @@ exit1(struct proc *td)
return 0;
}
+/*
+ * arg0: Exit status.
+ */
scret_t
sys_exit(struct syscall_args *scargs)
{
- exit1(this_td());
+ struct proc *td = this_td();
+
+ td->exit_status = scargs->arg0;
+ exit1(td);
__builtin_unreachable();
}