diff options
author | Ian Moffett <ian@osmora.org> | 2025-05-16 09:28:44 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2025-05-16 09:28:44 -0400 |
commit | 03f145b2fd5a01e40a3066c6cf2f649000a9fcd8 (patch) | |
tree | 62e67065b27bb91fbf865a4385edd49ffea5e6c4 /sys | |
parent | 02ca8f9faf6b6ddd0b7a514503b223e9ecbe8fe9 (diff) |
kernel: proc: Handle parent exit
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'sys')
-rw-r--r-- | sys/include/sys/proc.h | 12 | ||||
-rw-r--r-- | sys/kern/kern_exit.c | 29 |
2 files changed, 37 insertions, 4 deletions
diff --git a/sys/include/sys/proc.h b/sys/include/sys/proc.h index d252ab7..4024879 100644 --- a/sys/include/sys/proc.h +++ b/sys/include/sys/proc.h @@ -63,21 +63,31 @@ struct proc { struct spinlock vcache_lock; struct trapframe tf; struct pcb pcb; + struct proc *parent; size_t priority; + int exit_status; bool rested; uint32_t flags; + uint32_t nleaves; uintptr_t stack_base; struct spinlock ksigq_lock; + TAILQ_HEAD(, proc) leafq; + TAILQ_ENTRY(proc) leaf_link; TAILQ_HEAD(, ksiginfo) ksigq; TAILQ_ENTRY(proc) link; }; #define PROC_EXITING BIT(0) /* Exiting */ #define PROC_EXEC BIT(1) /* Exec called (cleared by sched) */ +#define PROC_ZOMB BIT(2) /* Zombie (dead but not deallocated) */ +#define PROC_LEAFQ BIT(3) /* Leaf queue is active */ +#define PROC_WAITED BIT(4) /* Being waited on by parent */ struct proc *this_td(void); int md_spawn(struct proc *p, struct proc *parent, uintptr_t ip); -int spawn(struct proc *cur, int flags, void(*ip)(void), struct proc **newprocp); + +scret_t sys_spawn(struct syscall_args *scargs); +pid_t spawn(struct proc *cur, void(*func)(void), void *p, int flags, struct proc **newprocp); void md_td_stackinit(struct proc *td, void *stack_top, struct exec_prog *prog); __dead void md_td_kick(struct proc *td); 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(); } |