diff options
author | Alex Auvolat <alex.auvolat@ens.fr> | 2015-03-07 17:23:44 +0100 |
---|---|---|
committer | Alex Auvolat <alex.auvolat@ens.fr> | 2015-03-07 17:23:44 +0100 |
commit | cb6cef08023bee0feeaa60a84d19bc52745bb2e4 (patch) | |
tree | d3496821926f438b1e7580234e29c57a617e270e /src/kernel/user | |
parent | 639ec6dd97a3d27fd249fa0509f0f8ebfd1f4c91 (diff) | |
download | kogata-cb6cef08023bee0feeaa60a84d19bc52745bb2e4.tar.gz kogata-cb6cef08023bee0feeaa60a84d19bc52745bb2e4.zip |
Implement some missing syscalls.
Diffstat (limited to 'src/kernel/user')
-rw-r--r-- | src/kernel/user/process.c | 33 | ||||
-rw-r--r-- | src/kernel/user/syscall.c | 193 |
2 files changed, 205 insertions, 21 deletions
diff --git a/src/kernel/user/process.c b/src/kernel/user/process.c index 0a757b4..973e9d8 100644 --- a/src/kernel/user/process.c +++ b/src/kernel/user/process.c @@ -267,6 +267,28 @@ void process_thread_deleted(thread_t *t) { process_exit(p, PS_FINISHED, 0); } +// =========================== // +// PROCESS CHILDREN MANAGEMENT // +// =========================== // + +process_t *process_find_child(process_t *p, int pid) { + process_t *ret = 0; + + mutex_lock(&p->lock); + + for (process_t *it = p->children; it != 0; it = it->next_child) { + if (it->pid == pid) { + ret = it; + break; + } + } + + mutex_unlock(&p->lock); + + return ret; + +} + // ================================== // // MANAGING FILESYSTEMS FOR PROCESSES // @@ -289,7 +311,7 @@ fs_t *proc_find_fs(process_t *p, const char* name) { return (fs_t*)hashtbl_find(p->filesystems, name); } -void proc_remove_fs(process_t *p, const char* name) { +void proc_rm_fs(process_t *p, const char* name) { fs_t *fs = proc_find_fs(p, name); if (fs) { unref_fs(fs); @@ -306,6 +328,15 @@ int proc_add_fd(process_t *p, fs_handle_t *f) { return fd; } +bool proc_add_fd_as(process_t *p, fs_handle_t *f, int fd) { + if (hashtbl_find(p->files, (void*)fd) != 0) return false; + + if (fd >= p->next_fd) p->next_fd = fd + 1; + + bool add_ok = hashtbl_add(p->files, (void*)fd, f); + return add_ok; +} + fs_handle_t *proc_read_fd(process_t *p, int fd) { return (fs_handle_t*)hashtbl_find(p->files, (void*)fd); } diff --git a/src/kernel/user/syscall.c b/src/kernel/user/syscall.c index 73b3341..fe9b4fe 100644 --- a/src/kernel/user/syscall.c +++ b/src/kernel/user/syscall.c @@ -12,8 +12,7 @@ typedef uint32_t (*syscall_handler_t)(sc_args_t); static syscall_handler_t sc_handlers[SC_MAX] = { 0 }; -static char* sc_copy_string(uint32_t s, uint32_t slen) { - const char* addr = (const char*)s; +static char* sc_copy_string(const char* addr, size_t slen) { probe_for_read(addr, slen); char* buf = malloc(slen+1); @@ -25,6 +24,10 @@ static char* sc_copy_string(uint32_t s, uint32_t slen) { return buf; } +static char* sc_copy_string_x(uint32_t s, uint32_t slen) { + return sc_copy_string((const char*)s, slen); +} + // ==================== // // THE SYSCALLS CODE !! // // ==================== // @@ -50,7 +53,7 @@ static uint32_t usleep_sc(sc_args_t args) { } static uint32_t dbg_print_sc(sc_args_t args) { - char* msg = sc_copy_string(args.a, args.b); + char* msg = sc_copy_string_x(args.a, args.b); if (msg == 0) return -1; dbg_print(msg); @@ -86,7 +89,7 @@ static uint32_t munmap_sc(sc_args_t args) { static uint32_t create_sc(sc_args_t args) { bool ret = false; - char* fn = sc_copy_string(args.a, args.b); + char* fn = sc_copy_string_x(args.a, args.b); if (fn == 0) goto end_create; char* sep = strchr(fn, ':'); @@ -108,7 +111,7 @@ end_create: static uint32_t delete_sc(sc_args_t args) { bool ret = false; - char* fn = sc_copy_string(args.a, args.b); + char* fn = sc_copy_string_x(args.a, args.b); if (fn == 0) goto end_del; char* sep = strchr(fn, ':'); @@ -130,8 +133,8 @@ end_del: static uint32_t move_sc(sc_args_t args) { bool ret = false; - char *fn_a = sc_copy_string(args.a, args.b), - *fn_b = sc_copy_string(args.c, args.d); + char *fn_a = sc_copy_string_x(args.a, args.b), + *fn_b = sc_copy_string_x(args.c, args.d); if (fn_a == 0 || fn_b == 0) goto end_move; char* sep_a = strchr(fn_a, ':'); @@ -160,7 +163,7 @@ end_move: static uint32_t stat_sc(sc_args_t args) { bool ret = false; - char* fn = sc_copy_string(args.a, args.b); + char* fn = sc_copy_string_x(args.a, args.b); if (fn == 0) goto end_stat; char* sep = strchr(fn, ':'); @@ -185,7 +188,7 @@ end_stat: static uint32_t open_sc(sc_args_t args) { int ret = 0; - char* fn = sc_copy_string(args.a, args.b); + char* fn = sc_copy_string_x(args.a, args.b); if (fn == 0) goto end_open; char* sep = strchr(fn, ':'); @@ -270,37 +273,186 @@ static uint32_t get_mode_sc(sc_args_t args) { // ---- Managing file systems static uint32_t make_fs_sc(sc_args_t args) { - return -1; // TODO + sc_make_fs_args_t *a = (sc_make_fs_args_t*)args.a; + probe_for_read(a, sizeof(sc_make_fs_args_t)); + + bool ok = false; + + char* driver = 0; + char* fs_name = 0; + char* opts = 0; + fs_t *the_fs = 0; + + process_t *p; + if (a->bind_to_pid == 0) { + p = current_process(); + } else { + p = process_find_child(current_process(), a->bind_to_pid); + if (p == 0) goto end_mk_fs; + } + + fs_handle_t *source = 0; + if (a->source_fd != 0) { + source = proc_read_fd(current_process(), a->source_fd); + if (!source) goto end_mk_fs; + } + + driver = sc_copy_string(a->driver, a->driver_strlen); + if (!driver) goto end_mk_fs; + + fs_name = sc_copy_string(a->fs_name, a->fs_name_strlen); + if (!fs_name) goto end_mk_fs; + + opts = sc_copy_string(a->opts, a->opts_strlen); + if (!opts) goto end_mk_fs; + + the_fs = make_fs(driver, source, opts); + if (!the_fs) goto end_mk_fs; + + ok = proc_add_fs(p, the_fs, fs_name); + +end_mk_fs: + if (driver) free(driver); + if (fs_name) free(fs_name); + if (opts) free(opts); + if (the_fs && !ok) unref_fs(the_fs); + return ok; } static uint32_t fs_add_src_sc(sc_args_t args) { - return -1; //TODO + bool ok = false; + + char* opts = 0; + char* fs_name = 0; + + fs_name = sc_copy_string_x(args.a, args.b); + if (fs_name == 0) goto end_add_src; + + opts = sc_copy_string_x(args.d, args.e); + if (opts == 0) goto end_add_src; + + fs_t *fs = proc_find_fs(current_process(), fs_name); + if (fs == 0) goto end_add_src; + + fs_handle_t *src = proc_read_fd(current_process(), args.c); + if (src == 0) goto end_add_src; + + ok = fs_add_source(fs, src, opts); + +end_add_src: + if (fs_name) free(fs_name); + if (opts) free(opts); + return ok; } static uint32_t fs_subfs_sc(sc_args_t args) { - return -1; //TODO + sc_subfs_args_t *a = (sc_subfs_args_t*)args.a; + probe_for_read(a, sizeof(sc_subfs_args_t)); + + bool ok = false; + + char* new_name = 0; + char* from_fs = 0; + char* root = 0; + fs_t* new_fs = 0; + + process_t *p; + if (a->bind_to_pid == 0) { + p = current_process(); + } else { + p = process_find_child(current_process(), a->bind_to_pid); + if (p == 0) goto end_subfs; + } + + new_name = sc_copy_string(a->new_name, a->new_name_strlen); + if (!new_name) goto end_subfs; + + from_fs = sc_copy_string(a->from_fs, a->from_fs_strlen); + if (!from_fs) goto end_subfs; + + root = sc_copy_string(a->root, a->root_strlen); + if (!root) goto end_subfs; + + fs_t *orig_fs = proc_find_fs(current_process(), from_fs); + if (!orig_fs) goto end_subfs; + + new_fs = fs_subfs(orig_fs, root, a->ok_modes); + if (!new_fs) goto end_subfs; + + ok = proc_add_fs(p, new_fs, new_name); + +end_subfs: + if (new_name) free(new_name); + if (from_fs) free(from_fs); + if (root) free(root); + if (new_fs && !ok) unref_fs(new_fs); + return ok; } static uint32_t rm_fs_sc(sc_args_t args) { - return -1; //TODO + char* fs_name = sc_copy_string_x(args.a, args.b); + if (fs_name == 0) return false; + + proc_rm_fs(current_process(), fs_name); + free(fs_name); + return true; } // ---- Spawning new processes & giving them ressources static uint32_t new_proc_sc(sc_args_t args) { - return -1; //TODO + process_t *new_proc = new_process(current_process()); + if (new_proc == 0) return 0; + + return new_proc->pid; } static uint32_t bind_fs_sc(sc_args_t args) { - return -1; //TODO -} + bool ok = false; -static uint32_t bind_subfs_sc(sc_args_t args) { - return -1; //TODO + char* old_name = 0; + char* new_name = 0; + fs_t* fs = 0; + + process_t *p = process_find_child(current_process(), args.a); + if (p == 0) goto end_bind_fs; + + new_name = sc_copy_string_x(args.b, args.c); + if (!new_name) goto end_bind_fs; + + old_name = sc_copy_string_x(args.d, args.e); + if (!old_name) goto end_bind_fs; + + fs = proc_find_fs(current_process(), old_name); + if (!fs) goto end_bind_fs; + + ref_fs(fs); + ok = proc_add_fs(p, fs, new_name); + +end_bind_fs: + if (old_name) free(old_name); + if (new_name) free(new_name); + if (fs && !ok) unref_fs(fs); + return ok; } static uint32_t bind_fd_sc(sc_args_t args) { - return -1; //TODO + bool ok = false; + + fs_handle_t *h = 0; + + process_t *p = process_find_child(current_process(), args.a); + if (p == 0) goto end_bind_fd; + + h = proc_read_fd(current_process(), args.c); + if (h == 0) goto end_bind_fd; + + ref_file(h); + ok = proc_add_fd_as(p, h, args.b); + +end_bind_fd: + if (h && !ok) unref_file(h); + return ok; } static uint32_t proc_exec_sc(sc_args_t args) { @@ -355,7 +507,8 @@ void setup_syscall_table() { sc_handlers[SC_NEW_PROC] = new_proc_sc; sc_handlers[SC_BIND_FS] = bind_fs_sc; - sc_handlers[SC_BIND_SUBFS] = bind_subfs_sc; + sc_handlers[SC_BIND_SUBFS] = fs_subfs_sc; // no bind_subfs_sc; + sc_handlers[SC_BIND_MAKE_FS] = make_fs_sc; // no bind_make_fs_sc; sc_handlers[SC_BIND_FD] = bind_fd_sc; sc_handlers[SC_PROC_EXEC] = proc_exec_sc; sc_handlers[SC_PROC_STATUS] = proc_status_sc; |