From 1d8f1a34be1c1d0850e87b54a83621824108004a Mon Sep 17 00:00:00 2001 From: min0911Y <1474635462@qq.com> Date: Tue, 28 Jan 2025 03:20:06 +0800 Subject: [PATCH] =?UTF-8?q?resman=E5=9F=BA=E6=9C=AC=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/kernel.h | 1 + include/kernel/resman.h | 23 ++++++++++++ src/kernel/hal/resman.c | 79 ++++++++++++++++++++++++++--------------- src/kernel/task/shell.c | 24 ++++++++----- 4 files changed, 90 insertions(+), 37 deletions(-) create mode 100644 include/kernel/resman.h diff --git a/include/kernel.h b/include/kernel.h index c3f24f7..2a21385 100755 --- a/include/kernel.h +++ b/include/kernel.h @@ -24,6 +24,7 @@ extern "C" { #include "kernel/pci.h" #include "kernel/ps2.h" #include "kernel/random.h" +#include "kernel/resman.h" #include "kernel/screen.h" #include "kernel/shared.h" #include "kernel/sound.h" diff --git a/include/kernel/resman.h b/include/kernel/resman.h new file mode 100644 index 0000000..120fb7a --- /dev/null +++ b/include/kernel/resman.h @@ -0,0 +1,23 @@ +#pragma once +#include "kernel.h" + +typedef struct resman { + avltree_t avltree; + i32 next_id; +} *resman_t; + +typedef struct descriptor { + vfs_node_t node; + i32 refrence_cout; +} *describtor_t; + +#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); +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/src/kernel/hal/resman.c b/src/kernel/hal/resman.c index 3352b7a..464c673 100755 --- a/src/kernel/hal/resman.c +++ b/src/kernel/hal/resman.c @@ -2,18 +2,8 @@ #include -typedef struct resman { - avltree_t avltree; - i32 next_id; -} *resman_t; - -typedef struct descriptor { - vfs_node_t node; - i32 refrence_cout; -} *describtor_t; - -st_t descriptors; -void resman_init(resman_t man); +static describtor_t descriptor_open(char *path); +st_t descriptors; static i32 alloc_next_id(resman_t man) { while (avltree_get(man->avltree, man->next_id++)) @@ -23,13 +13,14 @@ static i32 alloc_next_id(resman_t man) { void resman_descriptors_init() { descriptors = st_new(); + descriptor_open("/"); // 防止根目录被关闭 } // **NOTE**: the path is a absolute path, not a relative path static describtor_t descriptor_open(char *path) { // 首先,我们要看看能不能命中符号表 describtor_t fd = st_get(descriptors, path); - if(fd) { + if (fd) { fd->refrence_cout++; return fd; } @@ -37,19 +28,18 @@ static describtor_t descriptor_open(char *path) { vfs_node_t node = vfs_open(path); if (!node) return null; // 打开失败 // 创建文件描述符 - fd = malloc(sizeof(struct descriptor)); - fd->node = node; + fd = malloc(sizeof(struct descriptor)); + fd->node = node; fd->refrence_cout = 1; st_insert(descriptors, path, fd); return fd; } // @return: -1 works failed, 0 works successfully -static int descriptor_close(char *path) { - describtor_t fd = st_get(descriptors, path); +static int descriptor_close(describtor_t fd) { if (!fd) return -1; if (--fd->refrence_cout == 0) { vfs_close(fd->node); - st_remove(descriptors, path); + st_remove(descriptors, vfs_get_fullpath(fd->node)); free(fd); } return 0; @@ -61,8 +51,6 @@ resman_t resman_alloc() { return man; } - - void resman_init(resman_t man) { if (man == null) return; man->avltree = null; @@ -70,24 +58,57 @@ void resman_init(resman_t man) { } // @return: id ,if -1 it works failed - - int resman_open(resman_t man, i32 working_dir, cstr path) { - describtor_t fd_dir = avltree_get(man->avltree, working_dir); - if (!fd_dir) return -1; // 无效的工作目录 - vfs_node_t dir = fd_dir->node; - if (dir->type != file_dir) return -1; // 工作目录不是一个目录 - char *full_path; + describtor_t fd_dir; + vfs_node_t dir; + char *full_path = null; + if (path[0] == '/') { dir = vfs_open("/"); assert(dir, "open / failed"); full_path = strdup(path); } else { - // full_path = malloc(strlen(dir->name) + strlen(path) + 2); - // sprintf(full_path, "%s/%s", dir->name, path); + fd_dir = avltree_get(man->avltree, working_dir); + klogd("fd_dir is %p", fd_dir); + if (!fd_dir) return -1; // 无效的工作目录 + dir = fd_dir->node; + if (dir->type != file_dir) return -1; // 工作目录不是一个目录 + full_path = vfs_get_fullpath(dir); + full_path = (char *)realloc(full_path, strlen(full_path) + strlen(path) + 2); + assert(full_path); // 这如果申请失败了,那么炸了算了 + if (full_path[strlen(full_path) - 1] != '/') strcat(full_path, "/"); + strcat(full_path, path); + klogd("full path is %s", full_path); } + describtor_t fd = descriptor_open(full_path); + if (!fd) goto err; + + klogd("we get the fd %p", fd); + free(full_path); + + int id = alloc_next_id(man); + avltree_insert(man->avltree, id, fd); + return id; + +err: + free(full_path); + return -1; +} + +// @return 0: success, -1: failed +int resman_close(resman_t man, i32 id) { + describtor_t fd = avltree_get(man->avltree, id); + if (!fd) return -1; // 无效的文件描述符 + + int status = descriptor_close(fd); + if (status == -1) return -1; + + avltree_delete(man->avltree, id); + man->next_id = id; + return 0; } + void resman_deinit(resman_t man) { avltree_free(man->avltree); } diff --git a/src/kernel/task/shell.c b/src/kernel/task/shell.c index 63fa7d0..146cb14 100644 --- a/src/kernel/task/shell.c +++ b/src/kernel/task/shell.c @@ -241,14 +241,22 @@ static int shell_exec(char *path, cstr command) { printf("umount %s failed\n", dir_name); return 1; } - } else if (strneq(command, "test ", 5)) { - vfs_node_t n = vfs_open(command + 5); - if(n) { - char *path = vfs_get_fullpath(n); - printf("%s\n", path); - free(path); - } - } else { + } else if (streq(command, "test")) { + resman_descriptors_init(); + resman_t man = resman_alloc(); + resman_init(man); + printf("init a resman %p\n", man); + int root = resman_open_root_dir(man); + printf("open root dir %d\n", root); + int fatfs1 = resman_open(man, root, "fatfs1"); + printf("open fatfs1 %d\n", fatfs1); + int disk = resman_open(man, fatfs1, "disk.img"); + printf("open disk.img %d\n", disk); + resman_close(man, disk); + disk = resman_open(man, fatfs1, "testapp.bin"); + printf("open testapp.bin %d\n", disk); + + } else { char *path = exec_name_from_cmdline(command); cstr type = filetype_from_name(path); if (streq(type, "application/x-executable")) {