summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/init/main.c20
-rw-r--r--src/init/syscalls.c8
-rw-r--r--src/kernel/proc.c10
-rw-r--r--src/kernel/proc.h5
-rw-r--r--src/kernel/syscalls.c22
-rw-r--r--src/shared/syscalls.h8
6 files changed, 28 insertions, 45 deletions
diff --git a/src/init/main.c b/src/init/main.c
index 5c798d2..71a2d4e 100644
--- a/src/init/main.c
+++ b/src/init/main.c
@@ -23,7 +23,7 @@ int main(void) {
tty_fd = _syscall_open("/tty", sizeof("/tty") - 1);
if (tty_fd < 0)
- _syscall_exit(argify("couldn't open tty"));
+ _syscall_exit(1);
fs_test();
test_await();
@@ -32,7 +32,7 @@ int main(void) {
while (_syscall_read(tty_fd, &c, 1, 0))
_syscall_write(tty_fd, &c, 1, 0);
- _syscall_exit(argify("my job here is done."));
+ _syscall_exit(0);
}
void read_file(const char *path, size_t len) {
@@ -83,19 +83,15 @@ void fs_test(void) {
}
void test_await(void) {
- char buf[16];
- int len;
+ int ret;
- // the child immediately dies
- if (!_syscall_fork())
- _syscall_exit(argify("i'm dead"));
- if (!_syscall_fork())
- _syscall_exit(argify("i'm also dead"));
+ if (!_syscall_fork()) _syscall_exit(69);
+ if (!_syscall_fork()) _syscall_exit(420);
- while ((len = _syscall_await(buf, 16)) >= 0) {
+ while ((ret = _syscall_await()) != ~0) {
log("await returned: ");
- _syscall_write(tty_fd, buf, len, 0);
+ //_syscall_write(tty_fd, buf, len, 0); TODO printf
log("\n");
}
- log("await: negative len\n");
+ log("await: no more children\n");
}
diff --git a/src/init/syscalls.c b/src/init/syscalls.c
index f32594e..57a7344 100644
--- a/src/init/syscalls.c
+++ b/src/init/syscalls.c
@@ -1,8 +1,8 @@
// this file could probably just get generated by a script
#include <shared/syscalls.h>
-_Noreturn void _syscall_exit(const char __user *msg, size_t len) {
- _syscall(_SYSCALL_EXIT, (int)msg, len, 0, 0);
+_Noreturn void _syscall_exit(int ret) {
+ _syscall(_SYSCALL_EXIT, ret, 0, 0, 0);
__builtin_unreachable();
}
@@ -10,8 +10,8 @@ int _syscall_fork(void) {
return _syscall(_SYSCALL_FORK, 0, 0, 0, 0);
}
-int _syscall_await(char __user *buf, int len) {
- return _syscall(_SYSCALL_AWAIT, (int)buf, (int)len, 0, 0);
+int _syscall_await(void) {
+ return _syscall(_SYSCALL_AWAIT, 0, 0, 0, 0);
}
handle_t _syscall_open(const char __user *path, int len) {
diff --git a/src/kernel/proc.c b/src/kernel/proc.c
index b9f96c8..b1dc5c1 100644
--- a/src/kernel/proc.c
+++ b/src/kernel/proc.c
@@ -115,16 +115,12 @@ int process_try2collect(struct process *dead) {
dead->state = PS_DEADER;
parent->state = PS_RUNNING;
- len = min(parent->death_msg.len, dead->death_msg.len);
- res = virt_cpy(
- parent->pages, parent->death_msg.buf,
- dead->pages, dead->death_msg.buf, len);
-
- ret = res ? len : 0;
+ ret = dead->death_msg;
regs_savereturn(&parent->regs, ret);
return ret;
default:
- return -1;
+ return -1; // this return value isn't used anywhere
+ // TODO enforce that, somehow? idk
}
}
diff --git a/src/kernel/proc.h b/src/kernel/proc.h
index 82bb59a..592451c 100644
--- a/src/kernel/proc.h
+++ b/src/kernel/proc.h
@@ -26,10 +26,7 @@ struct process {
// saved value, meaning depends on .state
union {
- struct { // PS_DEAD, PS_WAITS4CHILDDEATH
- char __user *buf;
- size_t len;
- } death_msg;
+ int death_msg; // PS_DEAD
struct vfs_request pending_req; // PS_WAITS4FS
struct {
char __user *buf;
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c
index 1b91eb7..c89efc7 100644
--- a/src/kernel/syscalls.c
+++ b/src/kernel/syscalls.c
@@ -8,28 +8,22 @@
#include <shared/syscalls.h>
#include <stdint.h>
-_Noreturn void _syscall_exit(const char __user *msg, size_t len) {
+_Noreturn void _syscall_exit(int ret) {
process_current->state = PS_DEAD;
- process_current->death_msg.buf = (userptr_t) msg; // discarding const
- process_current->death_msg.len = len;
+ process_current->death_msg = ret;
process_try2collect(process_current);
process_switch_any();
}
-int _syscall_await(char __user *buf, int len) {
+int _syscall_await(void) {
bool has_children = false;
process_current->state = PS_WAITS4CHILDDEATH;
- process_current->death_msg.buf = buf;
- process_current->death_msg.len = len;
// find any already dead children
for (struct process *iter = process_current->child;
iter; iter = iter->sibling) {
- if (iter->state == PS_DEAD) {
- int ret = process_try2collect(iter);
- assert(ret >= 0);
- return ret;
- }
+ if (iter->state == PS_DEAD)
+ return process_try2collect(iter);
if (iter->state != PS_DEADER)
has_children = true;
}
@@ -38,7 +32,7 @@ int _syscall_await(char __user *buf, int len) {
process_switch_any(); // wait until a child dies
else {
process_current->state = PS_RUNNING;
- return -1; // error
+ return ~0; // TODO errno
}
}
@@ -276,9 +270,9 @@ int _syscall_memflag(void __user *addr, size_t len, int flags) {
int _syscall(int num, int a, int b, int c, int d) {
switch (num) {
case _SYSCALL_EXIT:
- _syscall_exit((userptr_t)a, b);
+ _syscall_exit(a);
case _SYSCALL_AWAIT:
- return _syscall_await((userptr_t)a, b);
+ return _syscall_await();
case _SYSCALL_FORK:
return _syscall_fork();
case _SYSCALL_OPEN:
diff --git a/src/shared/syscalls.h b/src/shared/syscalls.h
index 44a2f5d..3a21b66 100644
--- a/src/shared/syscalls.h
+++ b/src/shared/syscalls.h
@@ -27,12 +27,12 @@ int _syscall(int, int, int, int, int);
/** Kills the current process.
* TODO: what happens to the children?
*/
-_Noreturn void _syscall_exit(const char __user *msg, size_t len);
+_Noreturn void _syscall_exit(int ret);
-/** Waits for a child to exit, putting its exit message into *buf.
- * @return the length of the message
+/** Waits for a child to exit.
+ * @return the value the child passed to exit()
*/
-int _syscall_await(char __user *buf, int len);
+int _syscall_await(void);
/** Creates a copy of the current process, and executes it.
* All user memory pages get copied too.