Skip to content

Commit

Permalink
resman基本完成
Browse files Browse the repository at this point in the history
  • Loading branch information
min0911Y committed Jan 27, 2025
1 parent 33d2aa6 commit 1d8f1a3
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 37 deletions.
1 change: 1 addition & 0 deletions include/kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
23 changes: 23 additions & 0 deletions include/kernel/resman.h
Original file line number Diff line number Diff line change
@@ -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, "/")
79 changes: 50 additions & 29 deletions src/kernel/hal/resman.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,8 @@

#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;

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++))
Expand All @@ -23,33 +13,33 @@ 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;
}
// 如果没有命中,那么我们就要打开文件
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;
Expand All @@ -61,33 +51,64 @@ resman_t resman_alloc() {
return man;
}



void resman_init(resman_t man) {
if (man == null) return;
man->avltree = null;
man->next_id = 0;
}

// @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);
}
24 changes: 16 additions & 8 deletions src/kernel/task/shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -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")) {
Expand Down

0 comments on commit 1d8f1a3

Please sign in to comment.