Kernel: reparent child processes to PID 1 when their parent exits
This commit is contained in:
parent
a29f7f8df2
commit
656667812a
@ -163,24 +163,30 @@ int main()
|
||||
}
|
||||
if (child == 0)
|
||||
{
|
||||
sleep(2);
|
||||
sleep(1);
|
||||
pid_t child = fork();
|
||||
printf("I am the child (PID %ld), my parent is PID %ld!!\n", getpid(), getppid());
|
||||
execv("/bin/sym", NULL);
|
||||
if (child) execv("/bin/sym", NULL);
|
||||
else
|
||||
execv("/bin/init", NULL);
|
||||
perror("execv");
|
||||
return 1;
|
||||
}
|
||||
else { printf("Success!! Got PID %ld\n", child); }
|
||||
|
||||
int status;
|
||||
pid_t result;
|
||||
while ((result = waitpid(child, &status, 0)) == 0) // Child has not yet exited
|
||||
for (;;)
|
||||
{
|
||||
msleep(100);
|
||||
pid_t result;
|
||||
while ((result = wait(&status)) == 0) // No child has exited yet
|
||||
{
|
||||
msleep(100);
|
||||
}
|
||||
if (result < 0)
|
||||
{
|
||||
perror("wait");
|
||||
return 1;
|
||||
}
|
||||
if (WIFEXITED(status)) { printf("Child process %ld exited with code %d\n", result, WEXITSTATUS(status)); }
|
||||
}
|
||||
if (result < 0)
|
||||
{
|
||||
perror("waitpid");
|
||||
return 1;
|
||||
}
|
||||
if (WIFEXITED(status)) { printf("Child process %ld exited with code %d\n", result, WEXITSTATUS(status)); }
|
||||
}
|
||||
|
@ -45,6 +45,14 @@ template <typename Callback> void sched_for_each_task(Callback callback)
|
||||
} while (task != base_task);
|
||||
}
|
||||
|
||||
template <typename Callback> void sched_for_each_child(Task* task, Callback callback)
|
||||
{
|
||||
sched_for_each_task([&](Task* child) {
|
||||
if (child->ppid == task->id) { return callback(child); }
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
Task* Scheduler::find_by_pid(uint64_t pid)
|
||||
{
|
||||
Task* result = nullptr;
|
||||
@ -265,6 +273,13 @@ void Scheduler::task_exit(Context* context, int64_t status)
|
||||
else
|
||||
sched_current_task->state = sched_current_task->Dying;
|
||||
sched_current_task->exit_status = status;
|
||||
if (sched_current_task->id != 1)
|
||||
{
|
||||
sched_for_each_child(sched_current_task, [](Task* child) {
|
||||
if (child->state != child->Exited) child->ppid = 1;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
task_yield(context);
|
||||
}
|
||||
|
||||
@ -431,8 +446,8 @@ void sys_waitpid(Context* context, long pid, int* wstatus,
|
||||
Task* child = nullptr;
|
||||
if (pid == -1)
|
||||
{
|
||||
sched_for_each_task([&](Task* task) {
|
||||
if (task->state == task->Dying && task->ppid == sched_current_task->id)
|
||||
sched_for_each_child(sched_current_task, [&](Task* task) {
|
||||
if (task->state == task->Dying)
|
||||
{
|
||||
child = task;
|
||||
return false;
|
||||
|
Loading…
Reference in New Issue
Block a user