diff --git a/kernel/process.cpp b/kernel/process.cpp index 0a101bf6..4f67f462 100644 --- a/kernel/process.cpp +++ b/kernel/process.cpp @@ -223,11 +223,20 @@ void Process::OnLastThreadExit() // Forbid any more processes and threads from being created, so this // loop will always terminate. is_init_exiting = true; - for ( Process* process = initfirst; process; - process = process->initnext ) + Process* process = firstchild; + while ( process ) { - if ( process->pid != 0 && process != this ) + if ( process->pid != 0 ) process->DeliverSignal(SIGKILL); + if ( process->init == process ) + process->is_init_exiting = true; + if ( process->firstchild ) + process = process->firstchild; + while ( process && process != this && !process->nextsibling ) + process = process->parent; + if ( process == this ) + break; + process = process->nextsibling; } // NotifyChildExit always signals zombiecond for init when // is_init_exiting is true. diff --git a/libc/unistd/setinit.2 b/libc/unistd/setinit.2 index 77e3e378..2e9afa8f 100644 --- a/libc/unistd/setinit.2 +++ b/libc/unistd/setinit.2 @@ -27,7 +27,7 @@ or the current process if .Fa pid is zero. .Pp -Orphaned descendant processes are reparanted to their init process. +Orphaned descendant processes are reparented to their init process. If an init process exits, all descendant processes atomically receive the .Dv SIGKILL signal and become unable to create new processes and threads.