mirror of
https://github.com/ish-app/ish.git
synced 2026-01-25 14:06:40 +00:00
67 lines
1.7 KiB
C
67 lines
1.7 KiB
C
#include <pthread.h>
|
|
#include "sys/calls.h"
|
|
|
|
noreturn void do_exit(int status) {
|
|
if (current->pid == 1) {
|
|
exit(status >> 8);
|
|
}
|
|
pthread_mutex_lock(¤t->parent->lock);
|
|
current->exit_code = status;
|
|
current->zombie = true;
|
|
pthread_cond_broadcast(¤t->parent->child_exit);
|
|
pthread_mutex_unlock(¤t->parent->lock);
|
|
pthread_exit(NULL);
|
|
}
|
|
|
|
noreturn dword_t sys_exit(dword_t status) {
|
|
do_exit(status << 8);
|
|
}
|
|
|
|
dword_t sys_exit_group(dword_t status) {
|
|
sys_exit(status);
|
|
}
|
|
|
|
static int reap_if_zombie(struct process *proc, addr_t status_addr) {
|
|
if (proc->zombie) {
|
|
if (status_addr != 0)
|
|
user_put(status_addr, proc->exit_code);
|
|
process_destroy(proc);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
dword_t sys_waitpid(dword_t pid, addr_t status_addr, dword_t options) {
|
|
if (pid == (dword_t) -1) {
|
|
if (list_empty(¤t->children))
|
|
return _ESRCH;
|
|
} else if (process_for_pid(pid) == NULL) {
|
|
return _ESRCH;
|
|
}
|
|
|
|
pthread_mutex_lock(¤t->lock);
|
|
|
|
retry:
|
|
if (pid == (dword_t) -1) {
|
|
// look for a zombie child
|
|
struct process *proc;
|
|
list_for_each_entry(¤t->children, proc, siblings) {
|
|
pid = proc->pid;
|
|
if (reap_if_zombie(proc, status_addr))
|
|
goto found_zombie;
|
|
}
|
|
} else {
|
|
// check if this child is a zombie
|
|
if (reap_if_zombie(process_for_pid(pid), status_addr))
|
|
goto found_zombie;
|
|
}
|
|
|
|
// no matching zombie found, wait for one
|
|
pthread_cond_wait(¤t->child_exit, ¤t->lock);
|
|
goto retry;
|
|
|
|
found_zombie:
|
|
pthread_mutex_unlock(¤t->lock);
|
|
return pid;
|
|
}
|