diff --git a/apps/src/init.c b/apps/src/init.c index 211ae3ec..f14ed480 100644 --- a/apps/src/init.c +++ b/apps/src/init.c @@ -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)); } } diff --git a/kernel/src/thread/Scheduler.cpp b/kernel/src/thread/Scheduler.cpp index a8c0df88..43a30a03 100644 --- a/kernel/src/thread/Scheduler.cpp +++ b/kernel/src/thread/Scheduler.cpp @@ -45,6 +45,14 @@ template void sched_for_each_task(Callback callback) } while (task != base_task); } +template 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;