On a normal day , when a process is killed , all its child processes must be attached to 'init' process (Great Grand-Daddy of all processes). Strangely , the XV6 doesn't seem to do so. Below is the code of 'kill' function in proc.c file in XV6
int kill(int pid)
{
struct proc * p;
acquire(&ptable.lock);
for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
if(p->pid == pid){
p->killed = 1;
if(p->state == SLEEPING)
p->state = RUNNABLE;
release(&ptable.lock);
return 0;
}
}//end of for loop
release(&ptable.lock);
return -1;
}
Why isn't the killed process removed from the process table?
Why aren't its children adopted by 'init'?
And for God's sake, why is the killed process made RUNNABLE again ?
In POSIX, to receive and handle a signal (terminating the process is handling a signal) a process must be scheduled. Before that time the signal is considered pending and the process still exists.
The child processes are probably orphaned when the process is actually terminated and removed from the kernel data structures.