diff --git a/include/kernel/mtask.h b/include/kernel/mtask.h index 8341e59..f602e8f 100755 --- a/include/kernel/mtask.h +++ b/include/kernel/mtask.h @@ -1,10 +1,10 @@ #pragma once #include "00-include.h" #include "cpu.h" +#include "resman.h" #include #include #include - #define SIGINT 0 #define SIGKIL 1 diff --git a/include/kernel/resman.h b/include/kernel/resman.h index 120fb7a..d11a871 100644 --- a/include/kernel/resman.h +++ b/include/kernel/resman.h @@ -11,13 +11,14 @@ typedef struct descriptor { i32 refrence_cout; } *describtor_t; -#define resman_free(man) free(((void *)(man)) +#define resman_free(man) free(((void *)(man))) resman_t resman_alloc(); void resman_init(resman_t man); void resman_descriptors_init(); int resman_open(resman_t man, i32 working_dir, cstr path); int resman_close(resman_t man, i32 id); +resman_t resman_clone(resman_t man); void resman_deinit(resman_t man); #define resman_open_root_dir(man) resman_open((man), 0, "/") \ No newline at end of file diff --git a/include/kernel/task/kernel-part b/include/kernel/task/kernel-part index 1233996..3a85ca0 100644 --- a/include/kernel/task/kernel-part +++ b/include/kernel/task/kernel-part @@ -38,6 +38,8 @@ struct _NAME { avltree_t children; // 子线程 bool is_switched; // 是否是因其它进程请求切换过来的 bool fpu_enabled; // 是否开启了 fpu/sse/avx + resman_t resman; // 资源管理器 + i32 working_dir; // 工作目录 }; #undef _NAME diff --git a/src/kernel/hal/resman.c b/src/kernel/hal/resman.c index 464c673..354405f 100755 --- a/src/kernel/hal/resman.c +++ b/src/kernel/hal/resman.c @@ -109,6 +109,24 @@ int resman_close(resman_t man, i32 id) { return 0; } +static void clone_avltree(avltree_t src, avltree_t dst) { + if (src == null) return; + if (src->left) clone_avltree(src->left, dst); + avltree_insert(dst, src->key, src->value); + describtor_t fd = src->value; + fd->refrence_cout++; + if (src->right) clone_avltree(src->right, dst); +} + +resman_t resman_clone(resman_t man) { + resman_t new_resman = resman_alloc(); + resman_init(new_resman); + clone_avltree(man->avltree, new_resman->avltree); + return new_resman; +} +static void close_file(void *p) { + descriptor_close(p); +} void resman_deinit(resman_t man) { - avltree_free(man->avltree); + avltree_free_with(man->avltree, close_file); } diff --git a/src/kernel/init/init.c b/src/kernel/init/init.c index 0cc4e51..d8738fc 100755 --- a/src/kernel/init/init.c +++ b/src/kernel/init/init.c @@ -85,6 +85,8 @@ void sysinit() { tmpfs_regist(); iso9660_regist(); + resman_descriptors_init(); // 初始化文件描述符表 + if (total_mem_size < 256 * 1024 * 1024) { fatal("You should have at least 256MiB memory in your pc to start Plant-OS."); } else { diff --git a/src/kernel/syscall/read-write.c b/src/kernel/syscall/read-write.c index 0ebdb66..bf47f4c 100755 --- a/src/kernel/syscall/read-write.c +++ b/src/kernel/syscall/read-write.c @@ -7,11 +7,17 @@ // open, // close, // }; +int syscall_open(const char *path, int flags, int mode) { + if (!check_string_permission(path)) task_abort(); + return resman_open(current_task->resman, current_task->working_dir, path); +} isize syscall_read(int fd, void *addr, usize size) { if (fd < 0) return -1; if (addr == null) return -1; - return 0; + describtor_t file = avltree_get(current_task->resman->avltree, fd); + if (file == null) return -1; + return vfs_read(file->node, addr, 0, size); } isize syscall_write(int fd, const void *addr, usize size) { diff --git a/src/kernel/task/mtask.c b/src/kernel/task/mtask.c index 03d7a5e..ecf53a3 100755 --- a/src/kernel/task/mtask.c +++ b/src/kernel/task/mtask.c @@ -274,6 +274,10 @@ task_t create_task(void *entry, u32 ticks, u32 floor) { t->running = 0; t->timeout = ticks; t->jiffies = 0; + t->resman = resman_alloc(); + resman_init(t->resman); + t->working_dir = resman_open_root_dir(t->resman); + page_link_addr_pde(TASK_USER_PART_ADDR, t->cr3, (usize)t->_user_part); with_no_interrupts(avltree_insert(tasks, t->tid, t)); @@ -356,6 +360,8 @@ void task_kill(task_t task) { if (mouse_use_task == task) mouse_sleep(&mdec); task->state = THREAD_DEAD; + resman_deinit(task->resman); + resman_free(task->resman); avltree_free_with(task->children, (free_t)task_kill); @@ -468,13 +474,15 @@ int task_fork() { m->mousefifo->buf = page_malloc_one(); memcpy(m->mousefifo->buf, current_task->mousefifo->buf, 4096); } - m->cr3 = pd_clone(current_task->cr3); - m->user_mode = true; - m->running = 0; - m->jiffies = 0; - m->timeout = 1; - m->ptid = current_task->tid; - m->parent = current_task; + m->cr3 = pd_clone(current_task->cr3); + m->user_mode = true; + m->running = 0; + m->jiffies = 0; + m->timeout = 1; + m->ptid = current_task->tid; + m->parent = current_task; + m->resman = resman_clone(current_task->resman); + m->working_dir = current_task->working_dir; build_fork_stack(m); }); task_run(m); diff --git a/src/kernel/task/shell.c b/src/kernel/task/shell.c index 146cb14..3543490 100644 --- a/src/kernel/task/shell.c +++ b/src/kernel/task/shell.c @@ -242,7 +242,6 @@ static int shell_exec(char *path, cstr command) { return 1; } } else if (streq(command, "test")) { - resman_descriptors_init(); resman_t man = resman_alloc(); resman_init(man); printf("init a resman %p\n", man);