diff options
author | dzwdz | 2023-08-27 02:06:32 +0200 |
---|---|---|
committer | dzwdz | 2023-08-27 02:06:32 +0200 |
commit | e43939bcc6123e02314aa403eef94d5ace441f7f (patch) | |
tree | ac0cea10e8708ae1a6a7a400257c4bc59175a91f /src/kernel | |
parent | 1f938c20b4a82ca1267ab9a1ec0922878a21ca6b (diff) |
ports: qbe, cproc :^)
Diffstat (limited to 'src/kernel')
-rw-r--r-- | src/kernel/pipe.c | 3 | ||||
-rw-r--r-- | src/kernel/proc.c | 6 | ||||
-rw-r--r-- | src/kernel/proc.h | 1 | ||||
-rw-r--r-- | src/kernel/syscalls.c | 5 |
4 files changed, 11 insertions, 4 deletions
diff --git a/src/kernel/pipe.c b/src/kernel/pipe.c index 6325369..b7f5ad3 100644 --- a/src/kernel/pipe.c +++ b/src/kernel/pipe.c @@ -1,3 +1,4 @@ +#include <camellia/errno.h> #include <kernel/panic.h> #include <kernel/pipe.h> #include <kernel/util.h> @@ -8,7 +9,7 @@ void pipe_joinqueue(Handle *h, Proc *proc, void __user *pbuf, size_t pbuflen) { assert(h && h->type == HANDLE_PIPE); assert(h->readable ^ h->writeable); if (!h->pipe.sister) { - regs_savereturn(&proc->regs, -1); + regs_savereturn(&proc->regs, h->readable ? 0 : -EPIPE); return; } diff --git a/src/kernel/proc.c b/src/kernel/proc.c index 3ef35c0..cd9db9b 100644 --- a/src/kernel/proc.c +++ b/src/kernel/proc.c @@ -349,10 +349,14 @@ void proc_tryreap(Proc *dead) { if (parent->state != PS_WAITS4CHILDDEATH) { return; /* don't reap yet */ } + uint32_t pid = proc_ns_id(parent->pns, dead); + if (parent->awaited_death.pid && parent->awaited_death.pid != pid) { + return; /* we're not The One */ + } if (parent->awaited_death.legacy) { regs_savereturn(&parent->regs, dead->death_msg); } else { - regs_savereturn(&parent->regs, proc_ns_id(parent->pns, dead)); + regs_savereturn(&parent->regs, pid); if (parent->awaited_death.out) { struct sys_wait2 __user *out = parent->awaited_death.out; struct sys_wait2 data; diff --git a/src/kernel/proc.h b/src/kernel/proc.h index a1820dc..afa4439 100644 --- a/src/kernel/proc.h +++ b/src/kernel/proc.h @@ -46,6 +46,7 @@ struct Proc { int death_msg; // PS_DEAD struct { bool legacy; /* false = wait2, true = await */ + uint32_t pid; /* valid if nonzero */ struct sys_wait2 __user *out; } awaited_death; struct { diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c index ebdf64e..a8b47ae 100644 --- a/src/kernel/syscalls.c +++ b/src/kernel/syscalls.c @@ -26,6 +26,7 @@ long _sys_await(void) { bool has_children = false; proc_setstate(proc_cur, PS_WAITS4CHILDDEATH); proc_cur->awaited_death.legacy = true; + proc_cur->awaited_death.pid = 0; for (Proc *iter = proc_cur->child; iter; iter = iter->sibling) @@ -403,7 +404,7 @@ uint32_t _sys_getppid(void) { } int _sys_wait2(int pid, int flags, struct sys_wait2 __user *out) { - if (pid != -1 || flags != 0) { + if (flags != 0) { SYSCALL_RETURN(-ENOSYS); } @@ -411,13 +412,13 @@ int _sys_wait2(int pid, int flags, struct sys_wait2 __user *out) { proc_setstate(proc_cur, PS_WAITS4CHILDDEATH); proc_cur->awaited_death.legacy = false; proc_cur->awaited_death.out = out; + proc_cur->awaited_death.pid = (0 < pid) ? pid : 0; for (Proc *iter = proc_cur->child; iter; iter = iter->sibling) { if (iter->noreap) continue; has_children = true; if (iter->state == PS_TOREAP) { proc_tryreap(iter); - return 0; // dummy } } |