Kernel: reparent child processes to PID 1 when their parent exits

This commit is contained in:
apio 2022-10-19 17:16:01 +02:00
parent a29f7f8df2
commit 656667812a
2 changed files with 34 additions and 13 deletions

View File

@ -163,24 +163,30 @@ int main()
} }
if (child == 0) 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()); 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"); perror("execv");
return 1; return 1;
} }
else { printf("Success!! Got PID %ld\n", child); } else { printf("Success!! Got PID %ld\n", child); }
int status; int status;
for (;;)
{
pid_t result; pid_t result;
while ((result = waitpid(child, &status, 0)) == 0) // Child has not yet exited while ((result = wait(&status)) == 0) // No child has exited yet
{ {
msleep(100); msleep(100);
} }
if (result < 0) if (result < 0)
{ {
perror("waitpid"); perror("wait");
return 1; return 1;
} }
if (WIFEXITED(status)) { printf("Child process %ld exited with code %d\n", result, WEXITSTATUS(status)); } if (WIFEXITED(status)) { printf("Child process %ld exited with code %d\n", result, WEXITSTATUS(status)); }
}
} }

View File

@ -45,6 +45,14 @@ template <typename Callback> void sched_for_each_task(Callback callback)
} while (task != base_task); } 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* Scheduler::find_by_pid(uint64_t pid)
{ {
Task* result = nullptr; Task* result = nullptr;
@ -265,6 +273,13 @@ void Scheduler::task_exit(Context* context, int64_t status)
else else
sched_current_task->state = sched_current_task->Dying; sched_current_task->state = sched_current_task->Dying;
sched_current_task->exit_status = status; 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); task_yield(context);
} }
@ -431,8 +446,8 @@ void sys_waitpid(Context* context, long pid, int* wstatus,
Task* child = nullptr; Task* child = nullptr;
if (pid == -1) if (pid == -1)
{ {
sched_for_each_task([&](Task* task) { sched_for_each_child(sched_current_task, [&](Task* task) {
if (task->state == task->Dying && task->ppid == sched_current_task->id) if (task->state == task->Dying)
{ {
child = task; child = task;
return false; return false;