summaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/pipe.c3
-rw-r--r--src/kernel/proc.c6
-rw-r--r--src/kernel/proc.h1
-rw-r--r--src/kernel/syscalls.c5
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
}
}