完善路径管理功能
This commit is contained in:
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@@ -267,7 +267,9 @@
|
||||
"system_error": "c",
|
||||
"__dirent.h": "c",
|
||||
"shell_fs.h": "c",
|
||||
"shell_passthrough.h": "c"
|
||||
"shell_passthrough.h": "c",
|
||||
"u_slist.h": "c",
|
||||
"atomic": "c"
|
||||
},
|
||||
"cortex-debug.showRTOS": false,
|
||||
"cortex-debug.variableUseNaturalFormat": false,
|
||||
|
||||
@@ -10,12 +10,13 @@ set(CMAKE_ASM_FLAGS ${CMAKE_C_FLAGS})
|
||||
add_library(LetterShell
|
||||
# main.c
|
||||
shell_port.c
|
||||
shell_fs_ext.c
|
||||
# shell_cpp.cpp
|
||||
../../src/shell.c
|
||||
../../src/shell_companion.c
|
||||
../../src/shell_ext.c
|
||||
../../src/shell_cmd_list.c
|
||||
../../extensions/fs_support/shell_fs.c
|
||||
# ../../extensions/fs_support/shell_fs.c
|
||||
../../extensions/log/log.c
|
||||
# ../../extensions/telnet/telnetd.c
|
||||
../../extensions/shell_enhance/shell_passthrough.c
|
||||
|
||||
31
mkrtos_user/lib/letter-shell/demo/mkrtos/shell_fs_ext.c
Normal file
31
mkrtos_user/lib/letter-shell/demo/mkrtos/shell_fs_ext.c
Normal file
@@ -0,0 +1,31 @@
|
||||
#include "shell.h"
|
||||
#include <stdio.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <pthread.h>
|
||||
int ls(int argc, char *agrv[])
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *ptr;
|
||||
int i;
|
||||
if (argc < 2)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
dir = opendir(agrv[1]);
|
||||
if (!dir)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
while ((ptr = readdir(dir)) != NULL)
|
||||
{
|
||||
printf("%s \n", ptr->d_name);
|
||||
}
|
||||
closedir(dir);
|
||||
return 0;
|
||||
}
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), ls, ls, ls command);
|
||||
@@ -28,7 +28,7 @@
|
||||
static Shell shell;
|
||||
static ShellFs shellFs;
|
||||
static char shellBuffer[256];
|
||||
static char shellPathBuffer[128] = "/mnt/";
|
||||
// static char shellPathBuffer[128] = "/";
|
||||
|
||||
/**
|
||||
* @brief 用户shell写
|
||||
@@ -96,15 +96,15 @@ size_t userShellListDir(char *path, char *buffer, size_t maxLen)
|
||||
*/
|
||||
void userShellInit(void)
|
||||
{
|
||||
shellFs.getcwd = getcwd;
|
||||
shellFs.chdir = chdir;
|
||||
shellFs.listdir = userShellListDir;
|
||||
shellFsInit(&shellFs, shellPathBuffer, sizeof(shellPathBuffer));
|
||||
// shellFs.getcwd = getcwd;
|
||||
// shellFs.chdir = chdir;
|
||||
// shellFs.listdir = userShellListDir;
|
||||
// shellFsInit(&shellFs, shellPathBuffer, sizeof(shellPathBuffer));
|
||||
shell.write = userShellWrite;
|
||||
shell.read = userShellRead;
|
||||
shellSetPath(&shell, shellPathBuffer);
|
||||
// shellSetPath(&shell, shellPathBuffer);
|
||||
shellInit(&shell, shellBuffer, sizeof(shellBuffer));
|
||||
shellCompanionAdd(&shell, SHELL_COMPANION_ID_FS, &shellFs);
|
||||
// shellCompanionAdd(&shell, SHELL_COMPANION_ID_FS, &shellFs);
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
* @brief 是否使用shell伴生对象
|
||||
* 一些扩展的组件(文件系统支持,日志工具等)需要使用伴生对象
|
||||
*/
|
||||
#define SHELL_USING_COMPANION 1
|
||||
#define SHELL_USING_COMPANION 0
|
||||
#endif /** SHELL_USING_COMPANION */
|
||||
|
||||
#ifndef SHELL_SUPPORT_END_LINE
|
||||
|
||||
@@ -11,5 +11,8 @@
|
||||
#define ROUND_UP(a, b) ROUND(a, b) //!< a除b向上取整数
|
||||
#define ROUND_DOWN(a, b) ((a) / (b)) //!< a/b向下取整
|
||||
|
||||
#define container_of(ptr, type, member) \
|
||||
((type *)(((umword_t)(ptr)) - ((umword_t)(&(((type *)0)->member)))))
|
||||
|
||||
#define ATTR_ALIGN(a) __attribute__((aligned(a)))
|
||||
#define AUTO_CALL(prio) __attribute__((constructor(prio)))
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "u_types.h"
|
||||
#include "ns_types.h"
|
||||
|
||||
int ns_register(const char *path, obj_handler_t svr_hd);
|
||||
int ns_register(const char *path, obj_handler_t svr_hd, enum node_type type);
|
||||
int ns_query(const char *path, obj_handler_t *svr_hd);
|
||||
|
||||
@@ -6,5 +6,5 @@
|
||||
#include "ns_types.h"
|
||||
|
||||
void ns_init(ns_t *ns);
|
||||
int namespace_register(const char *path, obj_handler_t hd);
|
||||
int namespace_register(const char *path, obj_handler_t hd, int type);
|
||||
int namespace_query(const char *path, obj_handler_t *hd);
|
||||
|
||||
@@ -1,22 +1,33 @@
|
||||
#pragma once
|
||||
#include "u_types.h"
|
||||
#include "u_rpc_svr.h"
|
||||
#include "u_slist.h"
|
||||
#define NAMESPACE_PATH_LEN 32
|
||||
#define NAMESAPCE_NR 8
|
||||
|
||||
/**
|
||||
* @brief 非常简单的方式实现路径管理
|
||||
*
|
||||
*/
|
||||
typedef struct namespace_entry
|
||||
enum node_type
|
||||
{
|
||||
char path[NAMESPACE_PATH_LEN]; //!< 服务的路径名
|
||||
obj_handler_t hd; //!< 服务的fd
|
||||
} namespace_entry_t;
|
||||
MOUNT_NODE,
|
||||
FILE_NODE,
|
||||
DIR_NODE,
|
||||
};
|
||||
typedef struct ns_node
|
||||
{
|
||||
struct ns_node *parent;
|
||||
char node_name[NAMESPACE_PATH_LEN];
|
||||
enum node_type type;
|
||||
union
|
||||
{
|
||||
obj_handler_t node_hd;
|
||||
slist_head_t sub_dir;
|
||||
};
|
||||
slist_head_t node;
|
||||
int ref;
|
||||
} ns_node_t;
|
||||
|
||||
typedef struct ns
|
||||
{
|
||||
rpc_svr_obj_t svr;
|
||||
namespace_entry_t ne_list[NAMESAPCE_NR]; //!< 服务列表
|
||||
ns_node_t root_node;
|
||||
obj_handler_t hd; //!< 存储临时用于映射的hd
|
||||
} ns_t;
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
/*open*/
|
||||
RPC_GENERATION_CALL3(fs_t, FS_PROT, FS_OPEN, open,
|
||||
rpc_ref_array_uint32_t_uint8_t_32_t, rpc_array_uint32_t_uint8_t_32_t, RPC_DIR_IN, RPC_TYPE_DATA, path,
|
||||
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, flags,
|
||||
@@ -43,6 +44,7 @@ sd_t fs_open(const char *path, int flags, int mode)
|
||||
|
||||
return mk_sd_init2(hd, msg_tag_get_val(tag)).raw;
|
||||
}
|
||||
/*read*/
|
||||
RPC_GENERATION_CALL3(fs_t, FS_PROT, FS_READ, read,
|
||||
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, fd,
|
||||
rpc_ref_array_uint32_t_uint8_t_32_t, rpc_array_uint32_t_uint8_t_32_t, RPC_DIR_OUT, RPC_TYPE_DATA, buf,
|
||||
@@ -85,6 +87,7 @@ int fs_read(sd_t _fd, void *buf, size_t len)
|
||||
|
||||
return rlen;
|
||||
}
|
||||
/*write*/
|
||||
RPC_GENERATION_CALL3(fs_t, FS_PROT, FS_WRITE, write,
|
||||
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, fd,
|
||||
rpc_ref_array_uint32_t_uint8_t_32_t, rpc_array_uint32_t_uint8_t_32_t, RPC_DIR_IN, RPC_TYPE_DATA, buf,
|
||||
@@ -126,6 +129,7 @@ int fs_write(sd_t _fd, void *buf, size_t len)
|
||||
|
||||
return wlen;
|
||||
}
|
||||
/*close*/
|
||||
RPC_GENERATION_CALL1(fs_t, FS_PROT, FS_CLOSE, close,
|
||||
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, fd)
|
||||
int fs_close(sd_t _fd)
|
||||
@@ -145,6 +149,7 @@ int fs_close(sd_t _fd)
|
||||
|
||||
return msg_tag_get_val(tag);
|
||||
}
|
||||
/*lseek*/
|
||||
RPC_GENERATION_CALL3(fs_t, FS_PROT, FS_LSEEK, lseek,
|
||||
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, fd,
|
||||
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, offs,
|
||||
@@ -173,6 +178,7 @@ int fs_lseek(sd_t _fd, int offs, int whence)
|
||||
|
||||
return msg_tag_get_val(tag);
|
||||
}
|
||||
/*readdir*/
|
||||
RPC_GENERATION_CALL2(fs_t, FS_PROT, FS_READDIR, readdir,
|
||||
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, fd,
|
||||
rpc_dirent_t_t, rpc_dirent_t_t, RPC_DIR_OUT, RPC_TYPE_DATA, dir)
|
||||
|
||||
@@ -68,15 +68,16 @@ static bool_t reg_hd(const char *path, obj_handler_t hd, int split_inx)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RPC_GENERATION_CALL2(ns_t, NS_PROT, NS_REGISTER_OP, register,
|
||||
RPC_GENERATION_CALL3(ns_t, NS_PROT, NS_REGISTER_OP, register,
|
||||
rpc_ref_array_uint32_t_uint8_t_32_t, rpc_array_uint32_t_uint8_t_32_t, RPC_DIR_IN, RPC_TYPE_DATA, path,
|
||||
rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_IN, RPC_TYPE_BUF, svr_hd)
|
||||
rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_IN, RPC_TYPE_BUF, svr_hd,
|
||||
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, type)
|
||||
|
||||
RPC_GENERATION_CALL2(ns_t, NS_PROT, NS_QUERY_OP, query,
|
||||
rpc_ref_array_uint32_t_uint8_t_32_t, rpc_array_uint32_t_uint8_t_32_t, RPC_DIR_IN, RPC_TYPE_DATA, path,
|
||||
rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_INOUT, RPC_TYPE_BUF, cli_hd)
|
||||
|
||||
int ns_register(const char *path, obj_handler_t svr_hd)
|
||||
int ns_register(const char *path, obj_handler_t svr_hd, enum node_type type)
|
||||
{
|
||||
assert(path);
|
||||
|
||||
@@ -87,8 +88,11 @@ int ns_register(const char *path, obj_handler_t svr_hd)
|
||||
rpc_obj_handler_t_t rpc_svr_hd = {
|
||||
.data = svr_hd,
|
||||
};
|
||||
rpc_int_t rpc_type = {
|
||||
.data = type,
|
||||
};
|
||||
|
||||
msg_tag_t tag = ns_t_register_call(u_get_global_env()->ns_hd, &rpc_path, &rpc_svr_hd);
|
||||
msg_tag_t tag = ns_t_register_call(u_get_global_env()->ns_hd, &rpc_path, &rpc_svr_hd, &rpc_type);
|
||||
|
||||
return msg_tag_get_val(tag);
|
||||
}
|
||||
|
||||
@@ -7,13 +7,14 @@
|
||||
#include "u_hd_man.h"
|
||||
#include <stdio.h>
|
||||
|
||||
RPC_GENERATION_OP2(ns_t, NS_PROT, NS_REGISTER_OP, register,
|
||||
RPC_GENERATION_OP3(ns_t, NS_PROT, NS_REGISTER_OP, register,
|
||||
rpc_ref_array_uint32_t_uint8_t_32_t, rpc_array_uint32_t_uint8_t_32_t, RPC_DIR_IN, RPC_TYPE_DATA, path,
|
||||
rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_IN, RPC_TYPE_BUF, svr_hd)
|
||||
rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_IN, RPC_TYPE_BUF, svr_hd,
|
||||
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, type)
|
||||
{
|
||||
path->data[path->len - 1] = 0;
|
||||
|
||||
int ret = namespace_register((char *)(path->data), obj->hd);
|
||||
int ret = namespace_register((char *)(path->data), obj->hd, type->data);
|
||||
if (ret >= 0)
|
||||
{
|
||||
printf("register [%s] success.\n", (char *)(path->data));
|
||||
@@ -24,9 +25,10 @@ RPC_GENERATION_OP2(ns_t, NS_PROT, NS_REGISTER_OP, register,
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
RPC_GENERATION_DISPATCH2(ns_t, NS_PROT, NS_REGISTER_OP, register,
|
||||
RPC_GENERATION_DISPATCH3(ns_t, NS_PROT, NS_REGISTER_OP, register,
|
||||
rpc_ref_array_uint32_t_uint8_t_32_t, rpc_array_uint32_t_uint8_t_32_t, RPC_DIR_IN, RPC_TYPE_DATA, path,
|
||||
rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_IN, RPC_TYPE_BUF, svr_hd)
|
||||
rpc_obj_handler_t_t, rpc_obj_handler_t_t, RPC_DIR_IN, RPC_TYPE_BUF, svr_hd,
|
||||
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, type)
|
||||
|
||||
RPC_GENERATION_OP2(ns_t, NS_PROT, NS_QUERY_OP, query,
|
||||
rpc_ref_array_uint32_t_uint8_t_32_t, rpc_array_uint32_t_uint8_t_32_t, RPC_DIR_IN, RPC_TYPE_DATA, path,
|
||||
@@ -54,9 +56,5 @@ RPC_DISPATCH2(ns_t, NS_PROT, typeof(NS_REGISTER_OP), NS_REGISTER_OP, register, N
|
||||
void ns_init(ns_t *ns)
|
||||
{
|
||||
rpc_svr_obj_init(&ns->svr, rpc_ns_t_dispatch, NS_PROT);
|
||||
for (int i = 0; i < NAMESAPCE_NR; i++)
|
||||
{
|
||||
ns->ne_list[i].hd = HANDLER_INVALID;
|
||||
}
|
||||
ns->hd = HANDLER_INVALID;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <u_util.h>
|
||||
/**
|
||||
* @brief 循环双向链表
|
||||
*/
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <mr_api.h>
|
||||
int main(int argc, char *args[])
|
||||
{
|
||||
ns_register("/dev", drv_svr_init());
|
||||
ns_register("/dev", drv_svr_init(), MOUNT_NODE);
|
||||
mr_auto_init();
|
||||
printf("mr drv start success...\n");
|
||||
drv_svr_loop();
|
||||
|
||||
@@ -21,7 +21,7 @@ int main(int args, char *argv[])
|
||||
ret = rpc_meta_init(THREAD_MAIN, &hd);
|
||||
assert(ret >= 0);
|
||||
fs_svr_init();
|
||||
ns_register("/mnt", hd);
|
||||
ns_register("/mnt", hd, MOUNT_NODE);
|
||||
|
||||
FRESULT res = f_mount(&fs, "0:", 1);
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@ target_include_directories(
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys_svr/inc
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/cpio
|
||||
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/server/init/src
|
||||
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/arch/arm/
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/arch/generic
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/obj/src/internal
|
||||
|
||||
32
mkrtos_user/server/init/src/file_desc.c
Normal file
32
mkrtos_user/server/init/src/file_desc.c
Normal file
@@ -0,0 +1,32 @@
|
||||
#include "file_desc.h"
|
||||
|
||||
file_desc_t *fd_alloc(ns_node_t *node)
|
||||
{
|
||||
for (int i = 0; i < FILE_DESC_NR; i++)
|
||||
{
|
||||
if (fd_list[i].node == NULL)
|
||||
{
|
||||
fd_list[i].node = node;
|
||||
fd_list[i].node_iter = NULL;
|
||||
return &fd_list[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
file_desc_t *fd_get(int fd)
|
||||
{
|
||||
if (fd < 0 || fd >= FILE_DESC_NR)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return &fd_list[fd];
|
||||
}
|
||||
void fd_free(int fd)
|
||||
{
|
||||
if (fd < 0 || fd >= FILE_DESC_NR)
|
||||
{
|
||||
return;
|
||||
}
|
||||
fd_list[fd].node = NULL;
|
||||
fd_list[fd].node_iter = NULL;
|
||||
}
|
||||
15
mkrtos_user/server/init/src/file_desc.h
Normal file
15
mkrtos_user/server/init/src/file_desc.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
#include <ns_types.h>
|
||||
|
||||
#define FILE_DESC_NR 32
|
||||
|
||||
typedef struct file_desc
|
||||
{
|
||||
ns_node_t *node;
|
||||
ns_node_t *node_iter;
|
||||
} file_desc_t;
|
||||
|
||||
static file_desc_t fd_list[FILE_DESC_NR];
|
||||
file_desc_t *fd_alloc(ns_node_t *node);
|
||||
file_desc_t *fd_get(int fd);
|
||||
void fd_free(int fd);
|
||||
@@ -3,4 +3,5 @@
|
||||
# mr_drv
|
||||
# hello
|
||||
# rtthread_drv
|
||||
fatfs
|
||||
sh
|
||||
|
||||
@@ -52,6 +52,7 @@ static void test(void)
|
||||
ipc_obj_test();
|
||||
pthread_cond_lock_test();
|
||||
pthread_lock_test();
|
||||
ns_test();
|
||||
#endif
|
||||
}
|
||||
int main(int argc, char *args[])
|
||||
@@ -60,13 +61,14 @@ int main(int argc, char *args[])
|
||||
uenv_t *env;
|
||||
|
||||
ulog_write_str(LOG_PROT, "init..\n");
|
||||
test();
|
||||
env = u_get_global_env();
|
||||
rpc_meta_init(THREAD_MAIN, &env->ns_hd);
|
||||
namespace_init();
|
||||
namespace_init(env->ns_hd);
|
||||
pm_init();
|
||||
console_init();
|
||||
|
||||
test();
|
||||
|
||||
ret = parse_cfg(DEFAULT_INIT_CFG, env);
|
||||
printf("run app num is %d.\n", ret);
|
||||
namespace_pre_alloc_map_fd();
|
||||
|
||||
@@ -17,36 +17,380 @@
|
||||
#include "u_ipc.h"
|
||||
#include "ns_types.h"
|
||||
#include "ns_svr.h"
|
||||
#include "fs_svr.h"
|
||||
#include "namespace.h"
|
||||
#include "u_rpc_svr.h"
|
||||
#include "file_desc.h"
|
||||
#include <malloc.h>
|
||||
#include <fcntl.h>
|
||||
static ns_t ns;
|
||||
void namespace_init(void)
|
||||
static fs_t ns_fs;
|
||||
int ns_reg(const char *path, obj_handler_t hd, enum node_type type);
|
||||
|
||||
static ns_node_t *node_init(ns_node_t *new_node, ns_node_t *parent, const char *name, obj_handler_t hd, enum node_type type)
|
||||
{
|
||||
ns_init(&ns);
|
||||
meta_reg_svr_obj(&ns.svr, NS_PROT);
|
||||
printf("ns svr init...\n");
|
||||
strncpy(new_node->node_name, name, sizeof(new_node->node_name));
|
||||
new_node->node_name[sizeof(new_node->node_name) - 1] = 0;
|
||||
new_node->ref = 1;
|
||||
new_node->type = type;
|
||||
new_node->parent = parent;
|
||||
if (parent)
|
||||
{
|
||||
parent->ref++; //! 父目录的引用计数+1
|
||||
}
|
||||
slist_init(&new_node->node);
|
||||
if (type == DIR_NODE)
|
||||
{
|
||||
slist_init(&new_node->sub_dir);
|
||||
}
|
||||
else
|
||||
{
|
||||
new_node->node_hd = hd;
|
||||
}
|
||||
return new_node;
|
||||
}
|
||||
/**
|
||||
* @brief Create a node object
|
||||
*
|
||||
* @param dir
|
||||
* @param name
|
||||
* @param hd
|
||||
* @param typef
|
||||
* @return ns_node_t*
|
||||
*/
|
||||
static ns_node_t *create_node(ns_node_t *parent, const char *name, obj_handler_t hd, enum node_type type)
|
||||
{
|
||||
ns_node_t *new_node = malloc(sizeof(*new_node));
|
||||
|
||||
if (new_node == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
node_init(new_node, parent, name, hd, type);
|
||||
return new_node;
|
||||
}
|
||||
/**
|
||||
* @brief 路径分割
|
||||
*
|
||||
* @param name
|
||||
* @return int
|
||||
*/
|
||||
static int path_split(const char *name)
|
||||
{
|
||||
int i = -1;
|
||||
|
||||
for (i = 0; name[i]; i++)
|
||||
{
|
||||
if (name[i] == '/')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
/**
|
||||
* @brief 找到某个节点
|
||||
*
|
||||
* @param dir
|
||||
* @param name
|
||||
* @param ret_inx
|
||||
* @return ns_node_t*
|
||||
*/
|
||||
static ns_node_t *node_lookup(ns_node_t *dir, const char *name, size_t *ret_inx)
|
||||
{
|
||||
int inx = -1;
|
||||
int find_inx = 0;
|
||||
int r_inx = 0;
|
||||
ns_node_t *node = NULL;
|
||||
bool_t find = FALSE;
|
||||
|
||||
if (dir->type != DIR_NODE)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (name[0] == 0)
|
||||
{
|
||||
return dir;
|
||||
}
|
||||
if (name[0] == '/')
|
||||
{
|
||||
node = dir;
|
||||
find_inx++;
|
||||
r_inx++;
|
||||
find = TRUE;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
ns_node_t *pos;
|
||||
|
||||
inx = path_split(name + find_inx);
|
||||
if (inx <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
slist_foreach(pos, &(node->sub_dir), node)
|
||||
{
|
||||
if (strncmp(name + find_inx, pos->node_name, inx) != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
switch (pos->type)
|
||||
{
|
||||
case DIR_NODE:
|
||||
{
|
||||
// dir
|
||||
node = pos;
|
||||
r_inx += inx;
|
||||
find = TRUE;
|
||||
}
|
||||
break;
|
||||
case FILE_NODE:
|
||||
case MOUNT_NODE:
|
||||
{
|
||||
find = TRUE;
|
||||
r_inx += inx;
|
||||
node = pos;
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
find_inx += inx;
|
||||
}
|
||||
end:
|
||||
if (!find)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (ret_inx)
|
||||
{
|
||||
*ret_inx = r_inx;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
/**
|
||||
* @brief 释放一个节点
|
||||
*
|
||||
* @param node
|
||||
*/
|
||||
int ns_node_free(ns_node_t *node)
|
||||
{
|
||||
if (!node)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (node->ref == 1)
|
||||
{
|
||||
//!< 父级目录的引用计数-1
|
||||
ns_node_free(node->parent);
|
||||
}
|
||||
node->ref--;
|
||||
if (node->ref <= 0)
|
||||
{
|
||||
switch (node->type)
|
||||
{
|
||||
case DIR_NODE:
|
||||
assert(slist_is_empty(&node->sub_dir));
|
||||
break;
|
||||
case FILE_NODE:
|
||||
case MOUNT_NODE:
|
||||
handler_free_umap(node->node_hd);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (slist_in_list(&node->node))
|
||||
{
|
||||
slist_del(&node->node);
|
||||
}
|
||||
free(node);
|
||||
}
|
||||
return node->ref;
|
||||
}
|
||||
int fs_svr_open(const char *path, int flags, int mode)
|
||||
{
|
||||
ns_node_t *node;
|
||||
size_t ret_inx;
|
||||
int len;
|
||||
|
||||
again:
|
||||
node = node_lookup(&ns.root_node, path, &ret_inx);
|
||||
if (!node)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
len = strlen(path);
|
||||
if (len != ret_inx)
|
||||
{
|
||||
if (flags & O_CREAT)
|
||||
{
|
||||
int ret = ns_reg(path, 0, DIR_NODE);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
goto again;
|
||||
}
|
||||
return -ENOENT;
|
||||
}
|
||||
file_desc_t *fd_p = fd_alloc(node);
|
||||
|
||||
if (!fd_p)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
node->ref++;
|
||||
return 0;
|
||||
}
|
||||
int fs_svr_readdir(int fd, dirent_t *dir)
|
||||
{
|
||||
bool_t is_dec_ref = 0;
|
||||
file_desc_t *fdp = fd_get(fd);
|
||||
|
||||
if (!fdp)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
if (fdp->node_iter == (void *)((umword_t)(-1)))
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
if (fdp->node_iter == NULL)
|
||||
{
|
||||
// 首次迭代
|
||||
if (slist_is_empty(&fdp->node->sub_dir))
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
// 获得第一个节点
|
||||
fdp->node_iter = container_of(slist_first(&fdp->node->sub_dir), ns_node_t, node);
|
||||
fdp->node_iter->ref++;
|
||||
}
|
||||
|
||||
// 拷贝数据
|
||||
dir->d_type = fdp->node_iter->type == FILE_NODE ? DT_CHR : DT_DIR;
|
||||
dir->d_reclen = sizeof(*dir);
|
||||
strncpy(dir->d_name, fdp->node_iter->node_name, sizeof(dir->d_name));
|
||||
dir->d_name[sizeof(dir->d_name) - 1] = 0;
|
||||
dir->d_ino = 0;
|
||||
slist_head_t *next = fdp->node_iter->node.next;
|
||||
|
||||
ns_node_free(fdp->node_iter);
|
||||
if (next == &fdp->node->sub_dir)
|
||||
{
|
||||
// 到达结尾
|
||||
fdp->node_iter = (void *)((umword_t)(-1));
|
||||
return sizeof(*dir);
|
||||
}
|
||||
else
|
||||
{
|
||||
ns_node_t *next_n = container_of(next, ns_node_t, node);
|
||||
|
||||
fdp->node_iter = next_n;
|
||||
next_n->ref++;
|
||||
}
|
||||
return sizeof(*dir);
|
||||
}
|
||||
void fs_svr_close(int fd)
|
||||
{
|
||||
file_desc_t *fdp = fd_get(fd);
|
||||
|
||||
if (!fdp)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (fdp->node_iter && fdp->node_iter != (void *)(-1))
|
||||
{
|
||||
// 最后一个迭代的节点需要删除
|
||||
ns_node_free(fdp->node_iter);
|
||||
}
|
||||
ns_node_free(fdp->node);
|
||||
fd_free(fd);
|
||||
}
|
||||
int fs_svr_unlink(char *path)
|
||||
{
|
||||
ns_node_t *node;
|
||||
int ret_inx;
|
||||
|
||||
node = node_lookup(&ns.root_node, path, &ret_inx);
|
||||
if (node && ret_inx == strlen(path))
|
||||
{
|
||||
if (node->ref == 1)
|
||||
{
|
||||
ns_node_free(node);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int namespace_alloc(const char *path, obj_handler_t hd)
|
||||
static int find_path(const char *name)
|
||||
{
|
||||
for (int i = 0; i < NAMESAPCE_NR; i++)
|
||||
int len = strlen(name);
|
||||
|
||||
for (int i = len; i >= 0; i--)
|
||||
{
|
||||
if (ns.ne_list[i].hd == HANDLER_INVALID)
|
||||
if (name[i] == '/')
|
||||
{
|
||||
ns.ne_list[i].hd = hd;
|
||||
strncpy(ns.ne_list[i].path, path, NAMESPACE_PATH_LEN);
|
||||
ns.ne_list[i].path[NAMESPACE_PATH_LEN - 1] = 0;
|
||||
return i;
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
enum ns_op
|
||||
/**
|
||||
* @brief 注册一个节点
|
||||
*
|
||||
* @param path
|
||||
* @param hd
|
||||
* @return int
|
||||
*/
|
||||
int ns_reg(const char *path, obj_handler_t hd, enum node_type type)
|
||||
{
|
||||
OP_REGISTER,
|
||||
OP_QUERY,
|
||||
};
|
||||
size_t ret_inx;
|
||||
ns_node_t *new_node;
|
||||
ns_node_t *node;
|
||||
|
||||
node = node_lookup(&ns.root_node, path, &ret_inx);
|
||||
if (node && ret_inx == strlen(path))
|
||||
{
|
||||
handler_free_umap(hd);
|
||||
return -EEXIST;
|
||||
}
|
||||
int inx = find_path(path);
|
||||
|
||||
if (ret_inx != inx)
|
||||
{
|
||||
handler_free_umap(hd);
|
||||
return -ENOENT;
|
||||
}
|
||||
new_node = create_node(node, path + inx, hd, type);
|
||||
if (!new_node)
|
||||
{
|
||||
handler_free_umap(hd);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
slist_add_append(&node->sub_dir, &new_node->node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static obj_handler_t ns_hd;
|
||||
void namespace_init(obj_handler_t ipc_hd)
|
||||
{
|
||||
ns_init(&ns);
|
||||
fs_init(&ns_fs);
|
||||
meta_reg_svr_obj(&ns.svr, NS_PROT);
|
||||
meta_reg_svr_obj(&ns_fs.svr, FS_PROT);
|
||||
node_init(&ns.root_node, NULL, "", 0, DIR_NODE);
|
||||
ns_hd = ipc_hd;
|
||||
printf("ns svr init...\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 注册一个obj
|
||||
@@ -55,15 +399,18 @@ enum ns_op
|
||||
* @param hd 注册的hd
|
||||
* @return int
|
||||
*/
|
||||
int namespace_register(const char *path, obj_handler_t hd)
|
||||
int namespace_register(const char *path, obj_handler_t hd, int type)
|
||||
{
|
||||
if (namespace_alloc(path, hd) < 0)
|
||||
if (type == DIR_NODE)
|
||||
{
|
||||
return -1;
|
||||
handler_free_umap(hd);
|
||||
namespace_pre_alloc_map_fd();
|
||||
return -ECANCELED;
|
||||
}
|
||||
int ret = ns_reg(path, hd, type); // TODO:增加类型支持
|
||||
printf("register svr, name is %s, hd is %d\n", path, hd);
|
||||
namespace_pre_alloc_map_fd();
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* @brief 申请一个obj
|
||||
@@ -74,25 +421,28 @@ int namespace_register(const char *path, obj_handler_t hd)
|
||||
*/
|
||||
int namespace_query(const char *path, obj_handler_t *hd)
|
||||
{
|
||||
for (int i = 0; i < NAMESAPCE_NR; i++)
|
||||
assert(hd);
|
||||
size_t ret_inx;
|
||||
ns_node_t *new_node;
|
||||
ns_node_t *node;
|
||||
|
||||
if (path[0] == '/' && path[1] == 0)
|
||||
{
|
||||
if (ns.ne_list[i].hd != HANDLER_INVALID)
|
||||
*hd = ns_hd;
|
||||
return 0;
|
||||
}
|
||||
|
||||
node = node_lookup(&ns.root_node, path, &ret_inx);
|
||||
if (node && ret_inx == strlen(path))
|
||||
{
|
||||
char *split_str = strstr(path, ns.ne_list[i].path);
|
||||
if (split_str && (split_str == path))
|
||||
return -EEXIST;
|
||||
}
|
||||
if (node->type == DIR_NODE)
|
||||
{
|
||||
msg_tag_t tag = task_obj_valid(TASK_THIS, ns.ne_list[i].hd);
|
||||
if (msg_tag_get_val(tag) != 1)
|
||||
{
|
||||
// 对象变为无效,删除该条记录
|
||||
ns.ne_list[i].hd = HANDLER_INVALID;
|
||||
return -ENOENT;
|
||||
}
|
||||
*hd = ns.ne_list[i].hd;
|
||||
return (int)(strlen(ns.ne_list[i].path));
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
*hd = node->node_hd;
|
||||
return ret_inx;
|
||||
}
|
||||
int namespace_pre_alloc_map_fd(void)
|
||||
{
|
||||
@@ -113,3 +463,36 @@ void namespace_loop(void)
|
||||
{
|
||||
rpc_loop();
|
||||
}
|
||||
|
||||
|
||||
int fs_svr_read(int fd, void *buf, size_t len)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
int fs_svr_write(int fd, void *buf, size_t len)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
int fs_svr_lseek(int fd, int offs, int whence)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
int fs_svr_ftruncate(int fd, off_t off)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
void fs_svr_sync(int fd)
|
||||
{
|
||||
}
|
||||
int fs_svr_mkdir(char *path)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
int fs_svr_renmae(char *oldname, char *newname)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
int fs_svr_fstat(int fd, stat_t *stat)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
@@ -11,9 +11,13 @@
|
||||
#pragma once
|
||||
#include "u_types.h"
|
||||
#include "u_prot.h"
|
||||
|
||||
void namespace_init(void);
|
||||
int namespace_register(const char *path, obj_handler_t hd);
|
||||
enum ns_op
|
||||
{
|
||||
OP_REGISTER,
|
||||
OP_QUERY,
|
||||
};
|
||||
void namespace_init(obj_handler_t ipc_hd);
|
||||
int namespace_register(const char *path, obj_handler_t hd, int type);
|
||||
int namespace_query(const char *path, obj_handler_t *hd);
|
||||
int namespace_pre_alloc_map_fd(void);
|
||||
void namespace_loop(void);
|
||||
|
||||
64
mkrtos_user/server/init/src/test/ns_test.c
Normal file
64
mkrtos_user/server/init/src/test/ns_test.c
Normal file
@@ -0,0 +1,64 @@
|
||||
|
||||
#include "namespace.h"
|
||||
#include "u_rpc.h"
|
||||
#include "ns_types.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
int fs_svr_open(const char *path, int flags, int mode);
|
||||
int fs_svr_readdir(int fd, dirent_t *dir);
|
||||
void fs_svr_close(int fd);
|
||||
int fs_svr_unlink(char *path);
|
||||
int ns_reg(const char *path, obj_handler_t hd, enum node_type type);
|
||||
|
||||
void ns_test(void)
|
||||
{
|
||||
int ret;
|
||||
ret = ns_reg("/", 0, FILE_NODE);
|
||||
assert(ret < 0);
|
||||
ret = ns_reg("/test", 0, FILE_NODE);
|
||||
assert(ret >= 0);
|
||||
ret = ns_reg("/test", 0, FILE_NODE);
|
||||
assert(ret < 0);
|
||||
ret = ns_reg("/test1", 0, DIR_NODE);
|
||||
assert(ret >= 0);
|
||||
ret = ns_reg("/test2", 0, MOUNT_NODE);
|
||||
assert(ret >= 0);
|
||||
|
||||
int fd;
|
||||
|
||||
{
|
||||
fd = fs_svr_open("/c", O_CREAT, 0);
|
||||
assert(fd >= 0);
|
||||
fs_svr_close(fd);
|
||||
}
|
||||
{
|
||||
fd = fs_svr_open("/", 0, 0);
|
||||
assert(fd >= 0);
|
||||
dirent_t dir;
|
||||
while (fs_svr_readdir(fd, &dir) >= 0)
|
||||
{
|
||||
printf("%s\n", dir.d_name);
|
||||
}
|
||||
fs_svr_close(fd);
|
||||
}
|
||||
|
||||
ret = fs_svr_unlink("/test");
|
||||
assert(ret >= 0);
|
||||
ret = fs_svr_unlink("/test1");
|
||||
assert(ret >= 0);
|
||||
ret = fs_svr_unlink("/test2");
|
||||
assert(ret >= 0);
|
||||
ret = fs_svr_unlink("/c");
|
||||
assert(ret >= 0);
|
||||
{
|
||||
fd = fs_svr_open("/", 0, 0);
|
||||
assert(fd >= 0);
|
||||
dirent_t dir;
|
||||
while (fs_svr_readdir(fd, &dir) >= 0)
|
||||
{
|
||||
printf("%s\n", dir.d_name);
|
||||
}
|
||||
fs_svr_close(fd);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
// TODO:修改为init call
|
||||
void mm_test(void);
|
||||
void ulog_test(void);
|
||||
void factory_test(void);
|
||||
@@ -17,3 +16,4 @@ void kobj_create_press_test(void);
|
||||
void sleep_tick(int tick);
|
||||
void pthread_lock_test(void);
|
||||
int pthread_cond_lock_test(void);
|
||||
void ns_test(void);
|
||||
|
||||
@@ -20,7 +20,7 @@ void ns_test(void)
|
||||
assert(tmp_ipc_hd != HANDLER_INVALID);
|
||||
msg_tag_t tag = factory_create_ipc(FACTORY_PROT, vpage_create_raw3(0, 0, tmp_ipc_hd));
|
||||
|
||||
assert(ns_register("shell", tmp_ipc_hd) >= 0);
|
||||
assert(ns_register("shell", tmp_ipc_hd, FILE_NODE) >= 0);
|
||||
obj_handler_t rcv_ipc_hd;
|
||||
|
||||
assert(ns_query("shell", &rcv_ipc_hd) >= 0);
|
||||
|
||||
@@ -27,7 +27,7 @@ set(CMAKE_C_FLAGS "-mcpu=${MKRTOS_ARCH} -mthumb -O0 -g3 -lc -lrdimon -msoft-floa
|
||||
-fno-stack-protector -Wl,--gc-sections \
|
||||
" CACHE STRING "" FORCE)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "-mcpu=${MKRTOS_ARCH}-mthumb -mno-thumb-interwork -D=MKRTOS \
|
||||
set(CMAKE_CXX_FLAGS "-mcpu=${MKRTOS_ARCH} -mthumb -mno-thumb-interwork -D=MKRTOS \
|
||||
-mfix-cortex-m3-ldrd -Os -g3 -std=c++11 \
|
||||
-fmessage-length=0 -Xlinker --print-map -Wall -W -fno-stack-protector -g \
|
||||
-mfloat-abi=soft -lc -lrdimon -u _printf_float \
|
||||
|
||||
Reference in New Issue
Block a user