aboutsummaryrefslogtreecommitdiff
path: root/src/kernel/user/syscall.c
diff options
context:
space:
mode:
authorAlex Auvolat <alex.auvolat@ens.fr>2015-03-08 14:48:55 +0100
committerAlex Auvolat <alex.auvolat@ens.fr>2015-03-08 14:48:55 +0100
commit0985c6237b8592652d57efee2a964c4bc91ee455 (patch)
tree1ac06e7c924f9d34d738e23694d4efbbe9725123 /src/kernel/user/syscall.c
parentad63830f0d841c41291fc01aed6e54726bd0b93f (diff)
downloadkogata-0985c6237b8592652d57efee2a964c4bc91ee455.tar.gz
kogata-0985c6237b8592652d57efee2a964c4bc91ee455.zip
Implement missing syscalls.
Diffstat (limited to 'src/kernel/user/syscall.c')
-rw-r--r--src/kernel/user/syscall.c83
1 files changed, 83 insertions, 0 deletions
diff --git a/src/kernel/user/syscall.c b/src/kernel/user/syscall.c
index 04144d4..c352ff4 100644
--- a/src/kernel/user/syscall.c
+++ b/src/kernel/user/syscall.c
@@ -1,7 +1,9 @@
#include <string.h>
+
#include <process.h>
#include <vfs.h>
#include <elf.h>
+#include <ipc.h>
#include <sct.h>
@@ -63,6 +65,15 @@ static uint32_t dbg_print_sc(sc_args_t args) {
return 0;
}
+static uint32_t new_thread_sc(sc_args_t args) {
+ return process_new_thread(current_process(), (proc_entry_t)args.a, (void*)args.b);
+}
+
+static uint32_t exit_thread_sc(sc_args_t args) {
+ exit();
+ return 0;
+}
+
// ---- Memory management related
static uint32_t mmap_sc(sc_args_t args) {
@@ -271,6 +282,72 @@ static uint32_t get_mode_sc(sc_args_t args) {
return file_get_mode(h);
}
+// ---- IPC
+
+static uint32_t make_channel_sc(sc_args_t args) {
+ // messy messy messy
+
+ bool blocking = (args.a != 0);
+
+ fd_pair_t *f = (fd_pair_t*)args.b;
+ probe_for_write(f, sizeof(fd_pair_t));
+
+ f->a = f->b = 0;
+
+ fs_handle_pair_t ch = make_channel(blocking);
+
+ if (ch.a == 0 || ch.b == 0) goto error;
+
+ f->a = proc_add_fd(current_process(), ch.a);
+ if (f->a == 0) goto error;
+
+ f->b = proc_add_fd(current_process(), ch.b);
+ if (f->b == 0) goto error;
+
+ return true;
+
+error:
+ if (f->a) {
+ proc_close_fd(current_process(), f->a);
+ f->a = 0;
+ } else {
+ if (ch.a) unref_file(ch.a);
+ }
+ if (f->b) {
+ proc_close_fd(current_process(), f->b);
+ f->b = 0;
+ } else {
+ if (ch.b) unref_file(ch.b);
+ }
+ return false;
+}
+
+static uint32_t gen_token_sc(sc_args_t args) {
+ fs_handle_t *h = proc_read_fd(current_process(), args.a);
+ if (h == 0) return false;
+
+ token_t *tok = (token_t*)args.b;
+ probe_for_write(tok, sizeof(token_t));
+
+ return gen_token_for(h, tok);
+}
+
+static uint32_t use_token_sc(sc_args_t args) {
+ token_t *tok = (token_t*)args.a;
+ probe_for_read(tok, sizeof(token_t));
+
+ fs_handle_t *h = use_token(tok);
+
+ if (h == 0) return 0;
+
+ int fd = proc_add_fd(current_process(), h);
+ if (fd == 0) unref_file(h);
+
+ return fd;
+
+ return 0; //TODO
+}
+
// ---- Managing file systems
static uint32_t make_fs_sc(sc_args_t args) {
@@ -544,6 +621,8 @@ void setup_syscall_table() {
sc_handlers[SC_YIELD] = yield_sc;
sc_handlers[SC_DBG_PRINT] = dbg_print_sc;
sc_handlers[SC_USLEEP] = usleep_sc;
+ sc_handlers[SC_NEW_THREAD] = new_thread_sc;
+ sc_handlers[SC_EXIT_THREAD] = exit_thread_sc;
sc_handlers[SC_MMAP] = mmap_sc;
sc_handlers[SC_MMAP_FILE] = mmap_file_sc;
@@ -564,6 +643,10 @@ void setup_syscall_table() {
sc_handlers[SC_IOCTL] = ioctl_sc;
sc_handlers[SC_GET_MODE] = get_mode_sc;
+ sc_handlers[SC_MK_CHANNEL] = make_channel_sc;
+ sc_handlers[SC_GEN_TOKEN] = gen_token_sc;
+ sc_handlers[SC_USE_TOKEN] = use_token_sc;
+
sc_handlers[SC_MAKE_FS] = make_fs_sc;
sc_handlers[SC_FS_ADD_SRC] = fs_add_src_sc;
sc_handlers[SC_SUBFS] = fs_subfs_sc;