proc文件系统支持
This commit is contained in:
@@ -18,6 +18,7 @@ typedef struct
|
||||
umword_t (*map_buf)[CONFIG_THREAD_MAP_BUF_LEN];
|
||||
} fast_ipc_info_t;
|
||||
|
||||
msg_tag_t u_task_get_obj_name(obj_handler_t dst_task, obj_handler_t obj, char name[8/*FIXME:使用宏*/]);
|
||||
msg_tag_t u_task_set_obj_name(obj_handler_t dst_task, obj_handler_t obj, const char *name);
|
||||
msg_tag_t u_task_set_pid(obj_handler_t dst_task, umword_t pid);
|
||||
msg_tag_t u_task_get_pid(obj_handler_t dst_task, umword_t *data);
|
||||
|
||||
@@ -14,6 +14,7 @@ enum task_op_code
|
||||
TASK_GET_PID,
|
||||
TASK_COPY_DATA,
|
||||
TASK_SET_OBJ_NAME,
|
||||
TASK_GET_OBJ_NAME,
|
||||
TASK_COPY_DATA_TO, //!< 从当前task拷贝数据到目的task
|
||||
TASK_SET_COM_POINT,
|
||||
TASK_COM_UNLOCK,
|
||||
@@ -41,6 +42,33 @@ msg_tag_t u_task_set_obj_name(obj_handler_t dst_task, obj_handler_t obj, const c
|
||||
return tag;
|
||||
}
|
||||
MK_SYSCALL
|
||||
msg_tag_t u_task_get_obj_name(obj_handler_t dst_task, obj_handler_t obj, char name[8/*FIXME:使用宏*/])
|
||||
{
|
||||
register volatile umword_t r0 asm(ARCH_REG_0);
|
||||
register volatile umword_t r1 asm(ARCH_REG_1);
|
||||
register volatile umword_t r2 asm(ARCH_REG_2);
|
||||
|
||||
mk_syscall(syscall_prot_create(TASK_GET_OBJ_NAME, TASK_PROT, dst_task).raw,
|
||||
obj,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
asm __volatile__(""
|
||||
:
|
||||
:
|
||||
: ARCH_REG_0, ARCH_REG_1, ARCH_REG_2);
|
||||
if (name)
|
||||
{
|
||||
uint32_t *name_word = (uint32_t *)name;
|
||||
|
||||
*name_word++ = r1;
|
||||
*name_word = r2;
|
||||
}
|
||||
return msg_tag_init(r0);
|
||||
}
|
||||
MK_SYSCALL
|
||||
msg_tag_t u_task_set_pid(obj_handler_t dst_task, umword_t pid)
|
||||
{
|
||||
register volatile umword_t r0 asm(ARCH_REG_0);
|
||||
|
||||
@@ -198,9 +198,13 @@ next:
|
||||
#endif
|
||||
int s_inx = msg_tag_get_val(tag);
|
||||
|
||||
if (s_inx == strlen(path))
|
||||
if (path[s_inx] != '/' && path[s_inx - 1] == '/')
|
||||
{
|
||||
if (reg_hd(path, newfd, msg_tag_get_val(tag)) == FALSE)
|
||||
s_inx--;
|
||||
}
|
||||
if (msg_tag_get_val(tag)== strlen(path))
|
||||
{
|
||||
if (reg_hd(path, newfd, s_inx) == FALSE)
|
||||
{
|
||||
printf("The client service cache is full.\n");
|
||||
#if 0
|
||||
@@ -210,7 +214,7 @@ next:
|
||||
}
|
||||
}
|
||||
*svr_hd = newfd;
|
||||
return msg_tag_get_val(tag);
|
||||
return s_inx;
|
||||
}
|
||||
int ns_query_svr(const char *path, obj_handler_t *svr_hd)
|
||||
{
|
||||
|
||||
@@ -22,6 +22,7 @@ target_include_directories(
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/cpio
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/util/inc
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys_svr/inc
|
||||
|
||||
)
|
||||
target_link_libraries(
|
||||
sys_util
|
||||
|
||||
@@ -123,6 +123,7 @@ void sig_init(void)
|
||||
tag = u_facotry_create_sema(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, sema_wait_hd), 0, 1);
|
||||
assert(msg_tag_get_val(tag) >= 0);
|
||||
|
||||
#if 0
|
||||
char proc_path[20];
|
||||
umword_t pid;
|
||||
|
||||
@@ -130,5 +131,6 @@ void sig_init(void)
|
||||
|
||||
snprintf(proc_path, sizeof(proc_path), "/proc/%d", pid);
|
||||
assert(ns_register(proc_path, sig_ipc, 0) >= 0 && "task proc init failed.\n");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
@@ -4,5 +4,5 @@ cmake_minimum_required(VERSION 3.13)
|
||||
# add_subdirectory(cpiofs)
|
||||
add_subdirectory(fatfs)
|
||||
add_subdirectory(appfs)
|
||||
# add_subdirectory(procfs)
|
||||
add_subdirectory(procfs)
|
||||
# add_subdirectory(lxext4)
|
||||
|
||||
@@ -1,5 +1,31 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
file(GLOB proc_src src/proc.c src/procfs.c src/procfs_rpc.c src/procfs_impl.c)
|
||||
add_library(
|
||||
proc
|
||||
STATIC
|
||||
${proc_src}
|
||||
)
|
||||
target_include_directories(
|
||||
proc
|
||||
PUBLIC
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/server/fs/procfs/inc
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys/inc
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys/inc/${ARCH_NAME}
|
||||
)
|
||||
target_link_libraries(
|
||||
proc
|
||||
PUBLIC
|
||||
-Bstatic
|
||||
${LIBC_NAME}
|
||||
${START_LIB}
|
||||
sys
|
||||
sys_util
|
||||
sys_svr
|
||||
fd
|
||||
${GCC_LIB_PATH}/libgcc.a
|
||||
)
|
||||
|
||||
file(
|
||||
GLOB deps
|
||||
src/*.c
|
||||
|
||||
124
mkrtos_user/server/fs/procfs/armv7_8m/link.lds
Normal file
124
mkrtos_user/server/fs/procfs/armv7_8m/link.lds
Normal file
@@ -0,0 +1,124 @@
|
||||
ENTRY(_start_)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text : {
|
||||
. = ALIGN(4);
|
||||
__text_start__ = .;
|
||||
KEEP(*(.first))
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
|
||||
KEEP(*(.init))
|
||||
KEEP(*(.fini))
|
||||
|
||||
/* .ctors */
|
||||
*crtbegin.o(.ctors)
|
||||
*crtbegin?.o(.ctors)
|
||||
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
|
||||
*(SORT(.ctors.*))
|
||||
*(.ctors)
|
||||
|
||||
/* .dtors */
|
||||
*crtbegin.o(.dtors)
|
||||
*crtbegin?.o(.dtors)
|
||||
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
|
||||
*(SORT(.dtors.*))
|
||||
*(.dtors)
|
||||
|
||||
*(SORT(.rodata.*))
|
||||
*(.rodata)
|
||||
|
||||
KEEP(*(.eh_frame*))
|
||||
|
||||
. = ALIGN(4);
|
||||
__rel_start__ = .;
|
||||
*(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
|
||||
__rel_end__ = .;
|
||||
}
|
||||
.ARM.exidx : {
|
||||
. = ALIGN(4);
|
||||
__exdix_start = .;
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
/* This is used by the startup in order to initialize the .data secion */
|
||||
__exdix_end = .;
|
||||
}
|
||||
|
||||
.permissions_table : {
|
||||
. = ALIGN(4);
|
||||
__permissions_table_start__ = .;
|
||||
KEEP(*(.permissions_table))
|
||||
__permissions_table_end__ = .;
|
||||
}
|
||||
|
||||
|
||||
PROVIDE(__ram_size__ = __bss_end__ - __data_start__);
|
||||
.data : {
|
||||
. = ALIGN(4);
|
||||
__data_start__ = .;
|
||||
__got_start__ = .;
|
||||
*(.got)
|
||||
__got_end__ = .;
|
||||
. = ALIGN(4);
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
|
||||
*(vtable)
|
||||
*(.data*)
|
||||
|
||||
. = ALIGN(4);
|
||||
/* preinit data */
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP(*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
|
||||
. = ALIGN(4);
|
||||
/* init data */
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP(*(SORT(.init_array.*)))
|
||||
KEEP(*(.init_array))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
|
||||
. = ALIGN(4);
|
||||
/* finit data */
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP(*(SORT(.fini_array.*)))
|
||||
KEEP(*(.fini_array))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
|
||||
. = ALIGN(4);
|
||||
_shell_command_start = .;
|
||||
KEEP(*(shellCommand))
|
||||
_shell_command_end = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
/* All data end */
|
||||
__data_end__ = .;
|
||||
}
|
||||
|
||||
PROVIDE(__heap_size__ = __heap_end__ - __heap_start__);
|
||||
PROVIDE(__stack_size__ = __stack_end__ - __stack_start__);
|
||||
.bss : {
|
||||
. = ALIGN(4);
|
||||
/* This is used by the startup in order to initialize the .bss secion */
|
||||
__bss_start__ = .;
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
|
||||
. = ALIGN(4);
|
||||
__heap_start__ = .;
|
||||
KEEP(*(.bss.heap))
|
||||
__heap_end__ = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
__stack_start__ = .;
|
||||
KEEP(*(.bss.stack))
|
||||
__stack_end__ = .;
|
||||
|
||||
*(.bss.*)
|
||||
/* This is used by the startup in order to initialize the .bss secion */
|
||||
. = ALIGN(4);
|
||||
__bss_end__ = .;
|
||||
}
|
||||
_end = .;
|
||||
}
|
||||
66
mkrtos_user/server/fs/procfs/inc/proc.h
Normal file
66
mkrtos_user/server/fs/procfs/inc/proc.h
Normal file
@@ -0,0 +1,66 @@
|
||||
#pragma once
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include "u_rpc.h"
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#define NS_NODE_NAME_LEN 32
|
||||
|
||||
typedef enum proc_node_type
|
||||
{
|
||||
NODE_TYPE_PROC_DUMMY, //!< 虚拟节点,可以有子节点
|
||||
NODE_TYPE_PROC_FILE, //!< 服务节点,不能有子节点
|
||||
NODE_TYPE_PROC_ROOT, //!< ROOT节点
|
||||
} proc_node_type_t;
|
||||
struct proc_node;
|
||||
typedef struct proc_node proc_node_t;
|
||||
typedef struct proc_file_operation
|
||||
{
|
||||
int (*proc_open)(proc_node_t *node, const char *path, int flags, int mode);
|
||||
int (*proc_read)(proc_node_t *node, void *buf, size_t len, long offset);
|
||||
int (*proc_write)(proc_node_t *node, void *buf, size_t len, long offset);
|
||||
void (*proc_close)(proc_node_t *node);
|
||||
// int (*proc_readdir)(proc_node_t *node, dirent_t *dir);
|
||||
int (*proc_lseek)(proc_node_t *node, int offs, int whence);
|
||||
// int (*proc_ftruncate)(proc_node_t *node, off_t off);
|
||||
// int (*proc_fstat)(proc_node_t *node, void *buf);
|
||||
int (*proc_ioctl)(proc_node_t *node, int req, void *arg);
|
||||
// int (*proc_fcntl)(proc_node_t *node, int cmd, void *arg);
|
||||
// int (*proc_fsync)(proc_node_t *node);
|
||||
} proc_file_operation_t;
|
||||
|
||||
typedef struct proc_node
|
||||
{
|
||||
char name[NS_NODE_NAME_LEN]; //!< 节点名字
|
||||
proc_node_type_t type; //!< 节点类型
|
||||
struct proc_node *parent; //!< 父节点
|
||||
struct proc_node *next; //!< 兄弟节点的下一个节点
|
||||
struct proc_node *sub; //!< 子树节点
|
||||
const proc_file_operation_t *op; //!< proc的操作节点
|
||||
int ref; //!< 引用计数
|
||||
} proc_node_t;
|
||||
|
||||
|
||||
void proc_root_node_init(void);
|
||||
proc_node_t *proc_node_find(proc_node_t **pnode, const char *path, int *ret, int *svr_inx, int *p_inx);
|
||||
proc_node_t *proc_node_find_full_dir(const char *path, int *ret, int *cur_inx);
|
||||
proc_node_t *proc_node_find_full_file(const char *path, int *ret, int *cur_inx);
|
||||
proc_node_t *proc_node_find_svr_file(const char *path, int *ret, int *cur_inx);
|
||||
int proc_nodes_count(proc_node_t *tree);
|
||||
proc_node_t *proc_node_get_inx(proc_node_t *tree, int inx);
|
||||
int proc_delnode(const char *path);
|
||||
int proc_mknode(const char *path, proc_node_type_t type, const proc_file_operation_t *op);
|
||||
static inline proc_node_t *proc_node_get_next(proc_node_t *tree_node, proc_node_t *cur_node)
|
||||
{
|
||||
assert(cur_node);
|
||||
return cur_node->next;
|
||||
}
|
||||
static inline proc_node_t *proc_node_get_first(proc_node_t *tree_node)
|
||||
{
|
||||
assert(tree_node);
|
||||
return tree_node->sub;
|
||||
}
|
||||
27
mkrtos_user/server/fs/procfs/inc/procfs.h
Normal file
27
mkrtos_user/server/fs/procfs/inc/procfs.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
#include "kstat.h"
|
||||
#include "proc.h"
|
||||
#include "u_rpc.h"
|
||||
#include "u_types.h"
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
void procfs_lock(void);
|
||||
void proc_unlock(void);
|
||||
|
||||
int proc_ns_open(const char *name, int flags, int mode);
|
||||
int proc_ns_write(int fd, void *data, int len);
|
||||
int proc_ns_read(int fd, void *data, int len);
|
||||
int proc_ns_ioctl(int fd, unsigned long cmd, unsigned long arg);
|
||||
int proc_ns_lseek(int fd, int offset, unsigned long whence);
|
||||
int proc_ns_truncate(int fd, off_t length);
|
||||
int proc_ns_fstat(int fd, struct kstat *st);
|
||||
int proc_ns_stat(const char *path, struct kstat *st);
|
||||
int proc_ns_close(int fd);
|
||||
int proc_ns_remove(const char *name);
|
||||
int proc_ns_readdir(int fd, struct dirent *_dir);
|
||||
int proc_ns_mkdir(char *path);
|
||||
int proc_ns_rmdir(const char *name);
|
||||
void proc_ns_del_file_by_pid(const char *path, pid_t pid);
|
||||
int proc_register_file(const char *path, const proc_file_operation_t *op);
|
||||
int proc_ns_open_init(void);
|
||||
3
mkrtos_user/server/fs/procfs/inc/procfs_impl.h
Normal file
3
mkrtos_user/server/fs/procfs/inc/procfs_impl.h
Normal file
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
int proc_default_file_register(void);
|
||||
4
mkrtos_user/server/fs/procfs/inc/procfs_rpc.h
Normal file
4
mkrtos_user/server/fs/procfs/inc/procfs_rpc.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
void procfs_svr_init(void);
|
||||
7
mkrtos_user/server/fs/procfs/src/build.sh
Executable file
7
mkrtos_user/server/fs/procfs/src/build.sh
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e -x
|
||||
|
||||
mkdir -p build
|
||||
cmake -G Ninja -B build .
|
||||
cd build && ninja
|
||||
5
mkrtos_user/server/fs/procfs/src/clean.sh
Executable file
5
mkrtos_user/server/fs/procfs/src/clean.sh
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e -x
|
||||
|
||||
rm -r build
|
||||
13
mkrtos_user/server/fs/procfs/src/heap_stack.c
Normal file
13
mkrtos_user/server/fs/procfs/src/heap_stack.c
Normal file
@@ -0,0 +1,13 @@
|
||||
#include <u_util.h>
|
||||
#include <u_types.h>
|
||||
|
||||
#define HEAP_SIZE (4096)
|
||||
#define STACK_SIZE (1024*2)
|
||||
|
||||
#define HEAP_ATTR __attribute__((__section__(".bss.heap")))
|
||||
#define STACK_ATTR __attribute__((__section__(".bss.stack")))
|
||||
|
||||
__attribute__((used)) HEAP_ATTR static char _____heap_____[HEAP_SIZE];
|
||||
__attribute__((used)) STACK_ATTR static char _____stack_____[STACK_SIZE];
|
||||
__attribute__((used)) umword_t _____mm_bitmap_____[ROUND(HEAP_SIZE, MK_PAGE_SIZE) / (sizeof(umword_t) * 8) + 1];
|
||||
|
||||
201
mkrtos_user/server/fs/procfs/src/main.c
Normal file
201
mkrtos_user/server/fs/procfs/src/main.c
Normal file
@@ -0,0 +1,201 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include "proc.h"
|
||||
#include "procfs.h"
|
||||
#include <assert.h>
|
||||
|
||||
int procfs_mkdir_test(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = proc_ns_mkdir("/bin/tst/");
|
||||
assert(ret < 0);
|
||||
ret = proc_ns_mkdir("/bin/");
|
||||
assert(ret >= 0);
|
||||
ret = proc_ns_mkdir("/bin2");
|
||||
assert(ret >= 0);
|
||||
ret = proc_ns_mkdir("/bin/tst/");
|
||||
assert(ret >= 0);
|
||||
ret = proc_ns_remove("/bin/tst");
|
||||
assert(ret < 0);
|
||||
ret = proc_ns_rmdir("/bin/tst");
|
||||
assert(ret >= 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int procfs_scan_dir_test(void)
|
||||
{
|
||||
#define TEST_CN 10
|
||||
int ret;
|
||||
ret = proc_ns_mkdir("/bin/");
|
||||
assert(ret >= 0);
|
||||
|
||||
for (int i = 0; i < TEST_CN; i++)
|
||||
{
|
||||
char dir_name[32];
|
||||
|
||||
snprintf(dir_name, sizeof(dir_name), "/bin/tst%d", i);
|
||||
ret = proc_ns_mkdir(dir_name);
|
||||
assert(ret >= 0);
|
||||
}
|
||||
int fd;
|
||||
|
||||
fd = proc_ns_open("/bin/", O_RDWR, 0777);
|
||||
assert(fd >= 0);
|
||||
struct dirent dir_info;
|
||||
for (int i = 0; i < (TEST_CN + 1); i++)
|
||||
{
|
||||
ret = proc_ns_readdir(fd, &dir_info);
|
||||
if (i < TEST_CN)
|
||||
{
|
||||
assert(ret >= 0);
|
||||
printf("readdir info :%s\n", dir_info.d_name);
|
||||
fflush(stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(ret < 0);
|
||||
}
|
||||
}
|
||||
ret = proc_ns_lseek(fd, 2, SEEK_SET);
|
||||
printf("old seek: %d\n", ret);
|
||||
assert(ret >= 0);
|
||||
for (int i = 0; i < (TEST_CN - 2 + 1); i++)
|
||||
{
|
||||
ret = proc_ns_readdir(fd, &dir_info);
|
||||
if (i < TEST_CN - 2)
|
||||
{
|
||||
assert(ret >= 0);
|
||||
printf("readdir info :%s\n", dir_info.d_name);
|
||||
fflush(stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(ret < 0);
|
||||
}
|
||||
}
|
||||
|
||||
ret = proc_ns_close(fd);
|
||||
assert(ret >= 0);
|
||||
ret = proc_ns_readdir(fd, &dir_info);
|
||||
assert(ret < 0);
|
||||
|
||||
for (int i = 0; i < TEST_CN; i++)
|
||||
{
|
||||
char dir_name[32];
|
||||
snprintf(dir_name, sizeof(dir_name), "/bin/tst%d", i);
|
||||
ret = proc_ns_rmdir(dir_name);
|
||||
assert(ret >= 0);
|
||||
}
|
||||
ret = proc_ns_rmdir("/bin");
|
||||
assert(ret >= 0);
|
||||
#undef TEST_CN
|
||||
return 0;
|
||||
}
|
||||
int procfs_mksvr_node(void)
|
||||
{
|
||||
int ret;
|
||||
struct dirent dir;
|
||||
|
||||
ret = proc_ns_mkdir("/bin/");
|
||||
assert(ret >= 0);
|
||||
ret = proc_mknode("/bin/tst1", NODE_TYPE_PROC_FILE, NULL);
|
||||
assert(ret >= 0);
|
||||
int fd;
|
||||
|
||||
fd = proc_ns_open("/bin/tst1", O_RDWR, 0777);
|
||||
assert(fd < 0);
|
||||
fd = proc_ns_open("/bin/", O_RDWR, 0777);
|
||||
assert(fd >= 0);
|
||||
ret = proc_ns_readdir(fd, &dir);
|
||||
assert(ret >= 0);
|
||||
printf("readdir info :%s\n", dir.d_name);
|
||||
ret = proc_ns_close(fd);
|
||||
assert(ret >= 0);
|
||||
|
||||
ret = proc_ns_remove("/bin/tst1/");
|
||||
assert(ret >= 0);
|
||||
ret = proc_ns_rmdir("/bin/");
|
||||
assert(ret >= 0);
|
||||
return 0;
|
||||
}
|
||||
int procfs_query_svr_node(void)
|
||||
{
|
||||
int ret;
|
||||
ret = proc_ns_mkdir("/bin/");
|
||||
assert(ret >= 0);
|
||||
proc_node_t *node;
|
||||
proc_node_t *pnode;
|
||||
int cur_inx;
|
||||
int p_inx;
|
||||
|
||||
node = proc_node_find_full_file("/bin/", &ret, &cur_inx);
|
||||
assert(node == NULL && ret < 0);
|
||||
|
||||
#define SVR_NODE "/svr_tst"
|
||||
ret = proc_mknode(SVR_NODE, NODE_TYPE_PROC_FILE, NULL);
|
||||
assert(ret >= 0);
|
||||
|
||||
node = proc_node_find_full_file(SVR_NODE, &ret, &cur_inx);
|
||||
assert(node != NULL && ret >= 0);
|
||||
assert(cur_inx == strlen(SVR_NODE));
|
||||
|
||||
node = proc_node_find(&pnode, SVR_NODE "/1/2/3", &ret, &cur_inx, &p_inx);
|
||||
assert(node != NULL && ret >= 0);
|
||||
assert(cur_inx == strlen(SVR_NODE) + 1);
|
||||
|
||||
ret = proc_ns_mkdir(SVR_NODE "/1");
|
||||
assert(ret < 0);
|
||||
#undef SVR_NODE
|
||||
ret = proc_ns_remove("/svr_tst");
|
||||
assert(ret >= 0);
|
||||
#define SVR_NODE "/bin/svr_tst"
|
||||
ret = proc_mknode(SVR_NODE, NODE_TYPE_PROC_FILE, NULL);
|
||||
assert(ret >= 0);
|
||||
node = proc_node_find_full_file(SVR_NODE, &ret, &cur_inx);
|
||||
assert(node != NULL && ret >= 0);
|
||||
assert(cur_inx == strlen(SVR_NODE));
|
||||
node = proc_node_find_svr_file(SVR_NODE "/1/2/3", &ret, &cur_inx);
|
||||
assert(node != NULL && ret >= 0);
|
||||
assert(cur_inx == strlen(SVR_NODE) + 1);
|
||||
|
||||
ret = proc_ns_rmdir("/bin/");
|
||||
assert(ret < 0);
|
||||
|
||||
ret = proc_ns_remove(SVR_NODE);
|
||||
assert(ret >= 0);
|
||||
ret = proc_ns_rmdir("/bin/");
|
||||
assert(ret >= 0);
|
||||
return 0;
|
||||
}
|
||||
int procfs_stat_test(void)
|
||||
{
|
||||
int ret;
|
||||
struct kstat fst;
|
||||
int fd;
|
||||
|
||||
ret = proc_ns_mkdir("/tstdir/");
|
||||
assert(ret >= 0);
|
||||
fd = proc_ns_open("/tstdir/", O_RDWR, 0777);
|
||||
assert(fd >= 0);
|
||||
ret = proc_ns_fstat(fd, &fst);
|
||||
assert(ret >= 0);
|
||||
ret = proc_ns_close(fd);
|
||||
assert(ret >= 0);
|
||||
return 0;
|
||||
}
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
procfs_mkdir_test();
|
||||
procfs_scan_dir_test();
|
||||
procfs_stat_test();
|
||||
procfs_mksvr_node();
|
||||
procfs_query_svr_node();
|
||||
return 0;
|
||||
}
|
||||
406
mkrtos_user/server/fs/procfs/src/proc.c
Normal file
406
mkrtos_user/server/fs/procfs/src/proc.c
Normal file
@@ -0,0 +1,406 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "proc.h"
|
||||
#ifdef MKRTOS
|
||||
#include <u_hd_man.h>
|
||||
#include <malloc.h>
|
||||
#include <u_task.h>
|
||||
#endif
|
||||
// 其他进程可以注册节点进来,并且可以注册子节点进来,子节点可以注册更多的子节点进来。
|
||||
// 可以注册两种节点DUMMY和SVR节点
|
||||
// 只有DUMMY节点里面可以注册SVR节点
|
||||
// 查找节点时采取最大服务匹配的原则,即匹配到最后一个SVR节点时,返回最后一个SVR节点的HD,以及截断的位置。
|
||||
|
||||
static proc_node_t root_node = {
|
||||
.type = NODE_TYPE_PROC_DUMMY,
|
||||
};
|
||||
|
||||
void proc_root_node_init(void)
|
||||
{
|
||||
root_node.op = NULL;
|
||||
}
|
||||
/**
|
||||
* 从路径中copy名字
|
||||
*/
|
||||
static int proc_node_strcpy(char *dst, const char *src, int n)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; src[j] && src[j] != '/' && j < n; j++)
|
||||
{
|
||||
dst[j] = src[j];
|
||||
}
|
||||
if (j < n)
|
||||
{
|
||||
dst[j] = 0;
|
||||
}
|
||||
return j;
|
||||
}
|
||||
/**
|
||||
* 找到节点中的子节点
|
||||
*/
|
||||
static proc_node_t *proc_node_find_sub(proc_node_t *tree, const char *name)
|
||||
{
|
||||
assert(name);
|
||||
if (tree == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
proc_node_t *cur = tree->sub;
|
||||
|
||||
while (cur)
|
||||
{
|
||||
if (strncmp(cur->name, name, NS_NODE_NAME_LEN) == 0)
|
||||
{
|
||||
return cur;
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
int proc_nodes_count(proc_node_t *tree)
|
||||
{
|
||||
int nr = 0;
|
||||
assert(tree);
|
||||
assert(tree->type == NODE_TYPE_PROC_DUMMY);
|
||||
|
||||
proc_node_t *cur = tree->next;
|
||||
|
||||
while (cur)
|
||||
{
|
||||
nr++;
|
||||
cur = cur->next;
|
||||
}
|
||||
return nr;
|
||||
}
|
||||
static int proc_node_del(proc_node_t *tree, proc_node_t *del_node)
|
||||
{
|
||||
proc_node_t *tmp = tree->sub;
|
||||
proc_node_t *pre = NULL;
|
||||
|
||||
while (tmp)
|
||||
{
|
||||
if (tmp == del_node)
|
||||
{
|
||||
if (pre == NULL)
|
||||
{
|
||||
// 删除第一个节点
|
||||
tree->sub = tmp->next;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pre->next = tmp->next;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
pre = tmp;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
static proc_node_t *node_create(const char *name, proc_node_type_t type)
|
||||
{
|
||||
proc_node_t *tmp;
|
||||
|
||||
#ifdef MKRTOS
|
||||
tmp = calloc(sizeof(proc_node_t), 1);
|
||||
#else
|
||||
tmp = calloc(sizeof(proc_node_t), 1);
|
||||
#endif
|
||||
if (!tmp)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
strncpy(tmp->name, name, NS_NODE_NAME_LEN);
|
||||
tmp->name[NS_NODE_NAME_LEN - 1] = 0;
|
||||
tmp->type = type;
|
||||
return tmp;
|
||||
}
|
||||
proc_node_t *proc_node_get_inx(proc_node_t *tree, int inx)
|
||||
{
|
||||
assert(tree);
|
||||
assert(tree->type == NODE_TYPE_PROC_DUMMY);
|
||||
int nr = 0;
|
||||
proc_node_t *cur = tree->sub;
|
||||
|
||||
while (cur)
|
||||
{
|
||||
if (nr == inx)
|
||||
{
|
||||
return cur;
|
||||
}
|
||||
nr++;
|
||||
cur = cur->next;
|
||||
}
|
||||
return cur;
|
||||
}
|
||||
/**
|
||||
* 查找节点,如果是dummy节点,则一直循环查找。
|
||||
* 如果是svr节点,则立刻终止查找,然后返回当前节点,以及截断的位置
|
||||
*/
|
||||
proc_node_t *proc_node_find(proc_node_t **pnode, const char *path, int *ret, int *svr_inx, int *p_inx)
|
||||
{
|
||||
assert(ret);
|
||||
assert(path);
|
||||
|
||||
proc_node_t *cur_node = NULL;
|
||||
char name[NS_NODE_NAME_LEN];
|
||||
int find_node_cut_inx = 0;
|
||||
|
||||
if (pnode)
|
||||
{
|
||||
*pnode = NULL;
|
||||
}
|
||||
if (path[0] != '/')
|
||||
{
|
||||
printf("[%s] path is error.\n", path);
|
||||
*ret = -EINVAL;
|
||||
return cur_node;
|
||||
}
|
||||
cur_node = &root_node;
|
||||
int i = 0;
|
||||
|
||||
while (path[i])
|
||||
{
|
||||
proc_node_t *t_node;
|
||||
int len;
|
||||
|
||||
// 获得节点的名字
|
||||
len = proc_node_strcpy(name, path + i + 1, NS_NODE_NAME_LEN);
|
||||
name[MIN(NS_NODE_NAME_LEN - 1, len)] = 0;
|
||||
if (len == 0)
|
||||
{
|
||||
// find_node_cut_inx++;
|
||||
goto end;
|
||||
}
|
||||
// 查找子节点
|
||||
t_node = proc_node_find_sub(cur_node, name);
|
||||
if (pnode)
|
||||
{
|
||||
*pnode = cur_node;
|
||||
}
|
||||
|
||||
if (t_node)
|
||||
{
|
||||
if (t_node->type == NODE_TYPE_PROC_DUMMY)
|
||||
{
|
||||
cur_node = t_node;
|
||||
}
|
||||
else if (t_node->type == NODE_TYPE_PROC_FILE)
|
||||
{
|
||||
find_node_cut_inx = i + len + 1;
|
||||
if (path[find_node_cut_inx] == '/')
|
||||
{
|
||||
find_node_cut_inx++;
|
||||
}
|
||||
// 找到服务节点,那直接返回,服务节点不会有子节点。
|
||||
cur_node = t_node;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cur_node == NULL)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
cur_node = NULL;
|
||||
}
|
||||
if (p_inx)
|
||||
{
|
||||
*p_inx = i;
|
||||
}
|
||||
if (path[i] == '/')
|
||||
{
|
||||
i++;
|
||||
}
|
||||
i += len;
|
||||
}
|
||||
end:
|
||||
*svr_inx = find_node_cut_inx;
|
||||
*ret = 0;
|
||||
return cur_node;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除节点时,必须保证全路径匹配
|
||||
*/
|
||||
int proc_delnode(const char *path)
|
||||
{
|
||||
proc_node_t *cur_node;
|
||||
int ret;
|
||||
int cur_inx;
|
||||
|
||||
cur_node = proc_node_find(NULL, path, &ret, &cur_inx, NULL);
|
||||
if (cur_node == NULL)
|
||||
{
|
||||
printf("ns node not find.\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
if (cur_node->type == NODE_TYPE_PROC_DUMMY && cur_node->ref != 0)
|
||||
{
|
||||
printf("ns dir is not empty.\n");
|
||||
return -ENOTEMPTY;
|
||||
}
|
||||
ret = proc_node_del(cur_node->parent, cur_node);
|
||||
if (cur_node->type == NODE_TYPE_PROC_FILE)
|
||||
{
|
||||
printf("ns del [%s].\n", path);
|
||||
}
|
||||
cur_node->parent->ref--;
|
||||
#ifdef MKRTOS
|
||||
free(cur_node);
|
||||
#else
|
||||
free(cur_node);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* 查找到完整的路径目录
|
||||
*/
|
||||
proc_node_t *proc_node_find_full_dir(const char *path, int *ret, int *cur_inx)
|
||||
{
|
||||
assert(path);
|
||||
assert(ret);
|
||||
assert(cur_inx);
|
||||
proc_node_t *dir_node;
|
||||
|
||||
dir_node = proc_node_find(NULL, path, ret, cur_inx, NULL);
|
||||
if (dir_node == NULL || dir_node->type != NODE_TYPE_PROC_DUMMY || *cur_inx != 0)
|
||||
{
|
||||
#if 0
|
||||
printf("ns node not find or path error.\n");
|
||||
#endif
|
||||
// 未找到,节点不是dummy节点,路径不是结尾处 则直接退出
|
||||
*ret = -ENOENT;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dir_node;
|
||||
}
|
||||
/**
|
||||
* 查找到完整的路径文件
|
||||
*/
|
||||
proc_node_t *proc_node_find_full_file(const char *path, int *ret, int *cur_inx)
|
||||
{
|
||||
assert(path);
|
||||
assert(ret);
|
||||
assert(cur_inx);
|
||||
proc_node_t *dir_node;
|
||||
|
||||
dir_node = proc_node_find(NULL, path, ret, cur_inx, NULL);
|
||||
if (dir_node == NULL || dir_node->type != NODE_TYPE_PROC_FILE || path[*cur_inx] != '\0')
|
||||
{
|
||||
#if 0
|
||||
printf("ns node not find or path error.\n");
|
||||
#endif
|
||||
// 未找到,节点不是 svr 节点,路径不是结尾处 则直接退出
|
||||
*ret = -ENOENT;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dir_node;
|
||||
}
|
||||
static inline int is_root_node(proc_node_t *node)
|
||||
{
|
||||
return node == &root_node;
|
||||
}
|
||||
proc_node_t *proc_node_find_svr_file(const char *path, int *ret, int *cur_inx)
|
||||
{
|
||||
assert(path);
|
||||
assert(ret);
|
||||
assert(cur_inx);
|
||||
proc_node_t *dir_node;
|
||||
proc_node_t *parent_node;
|
||||
|
||||
dir_node = proc_node_find(&parent_node, path, ret, cur_inx, NULL);
|
||||
if (is_root_node(dir_node))
|
||||
{
|
||||
(*cur_inx)++;
|
||||
return dir_node;
|
||||
}
|
||||
if (dir_node == NULL || dir_node->type != NODE_TYPE_PROC_FILE)
|
||||
{
|
||||
#if 0
|
||||
printf("ns node not find or path error.\n");
|
||||
#endif
|
||||
if (is_root_node(parent_node))
|
||||
{
|
||||
return parent_node;
|
||||
}
|
||||
if (!parent_node)
|
||||
{
|
||||
*ret = -ENOENT;
|
||||
return NULL;
|
||||
}
|
||||
if ((parent_node->type == NODE_TYPE_PROC_DUMMY && (dir_node == NULL || dir_node->type == NODE_TYPE_PROC_DUMMY)))
|
||||
{
|
||||
return &root_node;
|
||||
}
|
||||
// 未找到,节点不是 svr 节点,路径不是结尾处 则直接退出
|
||||
*ret = -ENOENT;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dir_node;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个节点
|
||||
* 只能在前置节点全部为dummy的节点里面创建节点
|
||||
*/
|
||||
int proc_mknode(const char *path, proc_node_type_t type, const proc_file_operation_t *op)
|
||||
{
|
||||
proc_node_t *dir_node;
|
||||
proc_node_t *new_node;
|
||||
proc_node_t *cur_node;
|
||||
int ret;
|
||||
int cur_inx;
|
||||
int p_inx;
|
||||
char name[NS_NODE_NAME_LEN];
|
||||
|
||||
cur_node = proc_node_find(&dir_node, path, &ret, &cur_inx, &p_inx);
|
||||
if (dir_node == NULL || dir_node->type != NODE_TYPE_PROC_DUMMY || (cur_node != NULL))
|
||||
{
|
||||
if (cur_node != NULL && cur_node->type == NODE_TYPE_PROC_FILE)
|
||||
{
|
||||
return -EEXIST;
|
||||
}
|
||||
if (cur_node != NULL && cur_node->type == NODE_TYPE_PROC_DUMMY)
|
||||
{
|
||||
return -EISDIR;
|
||||
}
|
||||
return -ENOENT;
|
||||
}
|
||||
// 获得节点的名字
|
||||
// int name_len = 0;
|
||||
|
||||
proc_node_strcpy(name, path + p_inx + 1, NS_NODE_NAME_LEN);
|
||||
|
||||
new_node = node_create(name, NODE_TYPE_PROC_DUMMY);
|
||||
if (new_node == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
// 加到目录的链表中
|
||||
new_node->next = dir_node->sub;
|
||||
dir_node->sub = new_node;
|
||||
new_node->type = type;
|
||||
new_node->parent = dir_node;
|
||||
if (type == NODE_TYPE_PROC_FILE)
|
||||
{
|
||||
new_node->op = op;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_node->sub = NULL;
|
||||
}
|
||||
// 增加引用计数
|
||||
dir_node->ref++;
|
||||
return 0;
|
||||
}
|
||||
689
mkrtos_user/server/fs/procfs/src/procfs.c
Normal file
689
mkrtos_user/server/fs/procfs/src/procfs.c
Normal file
@@ -0,0 +1,689 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <malloc.h>
|
||||
#include <u_mutex.h>
|
||||
#include <u_hd_man.h>
|
||||
#include "proc.h"
|
||||
#include "kstat.h"
|
||||
#define DIR_INFO_CACHE_NR 32
|
||||
|
||||
typedef struct dir_info_cache
|
||||
{
|
||||
proc_node_t *info;
|
||||
int ref;
|
||||
} dir_info_cache_t;
|
||||
|
||||
static dir_info_cache_t dir_info_cache_list[DIR_INFO_CACHE_NR];
|
||||
static u_mutex_t procfs_mutex_lock;
|
||||
|
||||
void procfs_lock(void)
|
||||
{
|
||||
u_mutex_lock(&procfs_mutex_lock, 0, NULL);
|
||||
}
|
||||
void proc_unlock(void)
|
||||
{
|
||||
u_mutex_unlock(&procfs_mutex_lock);
|
||||
}
|
||||
static int dir_info_cache_get(proc_node_t *info)
|
||||
{
|
||||
if (info == NULL)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
for (int i = 0; i < DIR_INFO_CACHE_NR; i++)
|
||||
{
|
||||
if (dir_info_cache_list[i].info == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (dir_info_cache_list[i].info == info)
|
||||
{
|
||||
dir_info_cache_list[i].ref++;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < DIR_INFO_CACHE_NR; i++)
|
||||
{
|
||||
if (dir_info_cache_list[i].info == NULL)
|
||||
{
|
||||
dir_info_cache_list[i].info = info;
|
||||
dir_info_cache_list[i].ref++;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
static void dir_info_cache_put(proc_node_t *info)
|
||||
{
|
||||
assert(info);
|
||||
for (int i = 0; i < DIR_INFO_CACHE_NR; i++)
|
||||
{
|
||||
if (dir_info_cache_list[i].info == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (dir_info_cache_list[i].info == info)
|
||||
{
|
||||
dir_info_cache_list[i].ref--;
|
||||
if (dir_info_cache_list[i].ref == 0)
|
||||
{
|
||||
dir_info_cache_list[i].info = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
enum proc_ns_type
|
||||
{
|
||||
FS_NS_FILE_TYPE,
|
||||
FS_NS_DIR_TYPE,
|
||||
};
|
||||
#define DIR_INFO_NR 32
|
||||
typedef struct proc_ns_file
|
||||
{
|
||||
int dir_info_fd; //!< dirinfo cache fd.
|
||||
int tmp_fd; //!< current info fd.
|
||||
uint8_t flags; //!< 文件操作的flags
|
||||
int offset; //!< 文件操作的偏移
|
||||
enum proc_ns_type type; //!< 类型
|
||||
uint8_t used;
|
||||
} proc_ns_file_t;
|
||||
|
||||
static proc_ns_file_t proc_ns_files[DIR_INFO_NR];
|
||||
|
||||
static proc_ns_file_t *proc_ns_get_file(int fd);
|
||||
|
||||
static int proc_ns_file_alloc(proc_node_t *file, int flags, enum proc_ns_type type)
|
||||
{
|
||||
int dir_info_fd = -1;
|
||||
|
||||
if (file != NULL)
|
||||
{
|
||||
dir_info_fd = dir_info_cache_get(file);
|
||||
if (dir_info_fd < 0)
|
||||
{
|
||||
printf("dir_info cache is full.\n");
|
||||
return dir_info_fd;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < DIR_INFO_NR; i++)
|
||||
{
|
||||
if (proc_ns_files[i].used == 0)
|
||||
{
|
||||
// 不存在则增加一个新的
|
||||
proc_ns_files[i].dir_info_fd = dir_info_fd;
|
||||
proc_ns_files[i].tmp_fd = -1;
|
||||
proc_ns_files[i].flags = flags;
|
||||
proc_ns_files[i].offset = 0;
|
||||
proc_ns_files[i].type = type;
|
||||
proc_ns_files[i].used = 1;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static proc_ns_file_t *proc_ns_get_file(int fd)
|
||||
{
|
||||
if (fd < 0 || fd >= DIR_INFO_NR)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (proc_ns_files[fd].used == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return proc_ns_files + fd;
|
||||
}
|
||||
|
||||
int proc_ns_open(const char *name, int flags, int mode)
|
||||
{
|
||||
int ret;
|
||||
proc_node_t *file;
|
||||
int fd;
|
||||
int cur_inx;
|
||||
enum proc_ns_type type;
|
||||
|
||||
if (name[0] == '\0')
|
||||
{
|
||||
name = "/";
|
||||
}
|
||||
// 路径必须'/'卡头
|
||||
if (name[0] != '/')
|
||||
{
|
||||
printf("nsfs path is error.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (flags & O_CREAT)
|
||||
{
|
||||
// not support to create file.
|
||||
return -ENOSYS;
|
||||
}
|
||||
procfs_lock();
|
||||
// path must is dir.
|
||||
file = proc_node_find_full_dir(name, &ret, &cur_inx);
|
||||
if (file == NULL)
|
||||
{
|
||||
file = proc_node_find_full_file(name, &ret, &cur_inx);
|
||||
if (file == NULL)
|
||||
{
|
||||
proc_unlock();
|
||||
return -EINVAL;
|
||||
}
|
||||
type = FS_NS_FILE_TYPE;
|
||||
if (file->op && file->op->proc_open)
|
||||
{
|
||||
ret = file->op->proc_open(file, name, flags, mode);
|
||||
if (ret < 0)
|
||||
{
|
||||
proc_unlock();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
type = FS_NS_DIR_TYPE;
|
||||
}
|
||||
fd = proc_ns_file_alloc(file, flags, type);
|
||||
if (fd < 0)
|
||||
{
|
||||
proc_unlock();
|
||||
return fd;
|
||||
}
|
||||
proc_unlock();
|
||||
return fd;
|
||||
}
|
||||
int proc_ns_write(int fd, void *data, int len)
|
||||
{
|
||||
proc_ns_file_t *file;
|
||||
int ret = 0;
|
||||
|
||||
procfs_lock();
|
||||
file = proc_ns_get_file(fd);
|
||||
if (!file || file->used == 0)
|
||||
{
|
||||
ret = -ENOENT;
|
||||
goto end;
|
||||
}
|
||||
if (file->type != FS_NS_FILE_TYPE)
|
||||
{
|
||||
ret = -EBADF;
|
||||
goto end;
|
||||
}
|
||||
proc_node_t *info;
|
||||
|
||||
info = dir_info_cache_list[file->dir_info_fd].info;
|
||||
if (!info->op || !info->op->proc_write)
|
||||
{
|
||||
ret = -EROFS;
|
||||
goto end;
|
||||
}
|
||||
ret = info->op->proc_write(info, data, len, file->offset);
|
||||
if (ret >= 0)
|
||||
{
|
||||
file->offset += ret;
|
||||
}
|
||||
end:
|
||||
proc_unlock();
|
||||
return ret;
|
||||
}
|
||||
int proc_ns_read(int fd, void *data, int len)
|
||||
{
|
||||
proc_ns_file_t *file;
|
||||
int ret = 0;
|
||||
|
||||
procfs_lock();
|
||||
file = proc_ns_get_file(fd);
|
||||
if (!file || file->used == 0)
|
||||
{
|
||||
ret = -ENOENT;
|
||||
goto end;
|
||||
}
|
||||
if (file->type != FS_NS_FILE_TYPE)
|
||||
{
|
||||
ret = -EBADF;
|
||||
goto end;
|
||||
}
|
||||
proc_node_t *info;
|
||||
|
||||
info = dir_info_cache_list[file->dir_info_fd].info;
|
||||
if (!info->op || !info->op->proc_read)
|
||||
{
|
||||
ret = -EIO;
|
||||
goto end;
|
||||
}
|
||||
ret = info->op->proc_read(info, data, len, file->offset);
|
||||
if (ret >= 0)
|
||||
{
|
||||
file->offset += ret;
|
||||
}
|
||||
end:
|
||||
proc_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int proc_ns_ioctl(int fd, unsigned long cmd, unsigned long arg)
|
||||
{
|
||||
proc_ns_file_t *file;
|
||||
int ret = 0;
|
||||
|
||||
procfs_lock();
|
||||
file = proc_ns_get_file(fd);
|
||||
if (!file || file->used == 0)
|
||||
{
|
||||
ret = -ENOENT;
|
||||
goto end;
|
||||
}
|
||||
if (file->type != FS_NS_FILE_TYPE)
|
||||
{
|
||||
ret = -EBADF;
|
||||
goto end;
|
||||
}
|
||||
proc_node_t *info;
|
||||
|
||||
info = dir_info_cache_list[file->dir_info_fd].info;
|
||||
if (!info->op || !info->op->proc_ioctl)
|
||||
{
|
||||
ret = -EIO;
|
||||
goto end;
|
||||
}
|
||||
ret = info->op->proc_ioctl(info, cmd, (void *)arg);
|
||||
if (ret >= 0)
|
||||
{
|
||||
file->offset += ret;
|
||||
}
|
||||
end:
|
||||
proc_unlock();
|
||||
return ret;
|
||||
}
|
||||
static int proc_ns_get_dir_size(proc_ns_file_t *file)
|
||||
{
|
||||
return proc_nodes_count(dir_info_cache_list[file->dir_info_fd].info);
|
||||
}
|
||||
int proc_ns_lseek(int fd, int offset, unsigned long whence)
|
||||
{
|
||||
proc_ns_file_t *file;
|
||||
int new_offs = 0;
|
||||
int old_offs = 0;
|
||||
|
||||
procfs_lock();
|
||||
file = proc_ns_get_file(fd);
|
||||
if (!file || file->used == 0)
|
||||
{
|
||||
proc_unlock();
|
||||
return -ENOENT;
|
||||
}
|
||||
old_offs = file->offset;
|
||||
switch (whence)
|
||||
{
|
||||
case SEEK_SET:
|
||||
new_offs = offset;
|
||||
break;
|
||||
case SEEK_END:
|
||||
{
|
||||
new_offs = proc_ns_get_dir_size(file) + offset;
|
||||
}
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
{
|
||||
new_offs = offset + file->offset;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
proc_unlock();
|
||||
return -EINVAL;
|
||||
}
|
||||
if (new_offs > proc_ns_get_dir_size(file))
|
||||
{
|
||||
new_offs = proc_ns_get_dir_size(file);
|
||||
}
|
||||
if (new_offs < 0)
|
||||
{
|
||||
new_offs = 0;
|
||||
}
|
||||
if (file->type == FS_NS_DIR_TYPE)
|
||||
{
|
||||
proc_node_t *new_dir_info;
|
||||
|
||||
new_dir_info = proc_node_get_inx(dir_info_cache_list[file->dir_info_fd].info, new_offs);
|
||||
if (new_dir_info == NULL)
|
||||
{
|
||||
proc_unlock();
|
||||
return -ENOENT;
|
||||
}
|
||||
if (file->tmp_fd >= 0)
|
||||
{
|
||||
dir_info_cache_put(dir_info_cache_list[file->tmp_fd].info);
|
||||
}
|
||||
file->tmp_fd = dir_info_cache_get(new_dir_info);
|
||||
}
|
||||
file->offset = new_offs;
|
||||
proc_unlock();
|
||||
return old_offs;
|
||||
}
|
||||
int proc_ns_truncate(int fd, off_t length)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
int proc_ns_fstat(int fd, struct kstat *st)
|
||||
{
|
||||
proc_ns_file_t *file;
|
||||
|
||||
procfs_lock();
|
||||
file = proc_ns_get_file(fd);
|
||||
if (!file || file->used == 0)
|
||||
{
|
||||
proc_unlock();
|
||||
return -ENOENT;
|
||||
}
|
||||
memset(st, 0, sizeof(*st));
|
||||
st->st_size = 0;
|
||||
st->st_mode = file->type == FS_NS_FILE_TYPE ? S_IFREG : S_IFDIR;
|
||||
st->st_nlink = dir_info_cache_list[file->dir_info_fd].info->ref;
|
||||
proc_unlock();
|
||||
return 0;
|
||||
}
|
||||
int proc_ns_stat(const char *path, struct kstat *st)
|
||||
{
|
||||
if (path[0] == '\0')
|
||||
{
|
||||
path = "/";
|
||||
}
|
||||
memset(st, 0, sizeof(*st));
|
||||
|
||||
proc_node_t *file;
|
||||
int ret;
|
||||
int cur_inx;
|
||||
|
||||
procfs_lock();
|
||||
file = proc_node_find_full_dir(path, &ret, &cur_inx);
|
||||
if (file == NULL)
|
||||
{
|
||||
file = proc_node_find_full_file(path, &ret, &cur_inx);
|
||||
if (file == NULL)
|
||||
{
|
||||
proc_unlock();
|
||||
return -ENOENT;
|
||||
}
|
||||
}
|
||||
|
||||
st->st_size = 0;
|
||||
st->st_mode = file->type != NODE_TYPE_PROC_DUMMY ? S_IFREG : S_IFDIR;
|
||||
st->st_nlink = file->ref;
|
||||
proc_unlock();
|
||||
return 0;
|
||||
}
|
||||
int proc_ns_close(int fd)
|
||||
{
|
||||
proc_ns_file_t *file;
|
||||
|
||||
procfs_lock();
|
||||
file = proc_ns_get_file(fd);
|
||||
if (!file || file->used == 0)
|
||||
{
|
||||
proc_unlock();
|
||||
return -ENOENT;
|
||||
}
|
||||
proc_node_t *info = dir_info_cache_list[file->dir_info_fd].info;
|
||||
if (file->type == FS_NS_FILE_TYPE)
|
||||
{
|
||||
if (info->op && info->op->proc_close)
|
||||
{
|
||||
// 不关心close的返回值
|
||||
info->op->proc_close(info);
|
||||
}
|
||||
}
|
||||
if (file->tmp_fd >= 0)
|
||||
{
|
||||
dir_info_cache_put(dir_info_cache_list[file->tmp_fd].info);
|
||||
}
|
||||
dir_info_cache_put(dir_info_cache_list[file->dir_info_fd].info);
|
||||
file->dir_info_fd = -1;
|
||||
file->tmp_fd = -1;
|
||||
file->flags = 0;
|
||||
file->offset = 0;
|
||||
file->used = 0;
|
||||
file->type = FS_NS_FILE_TYPE;
|
||||
proc_unlock();
|
||||
return 0;
|
||||
}
|
||||
int proc_ns_rmdir(const char *name)
|
||||
{
|
||||
proc_node_t *file;
|
||||
int ret;
|
||||
int dir_info_fd;
|
||||
int cur_inx;
|
||||
|
||||
if (name[0] == '\0')
|
||||
{
|
||||
name = "/";
|
||||
}
|
||||
procfs_lock();
|
||||
file = proc_node_find_full_dir(name, &ret, &cur_inx);
|
||||
if (file == NULL)
|
||||
{
|
||||
proc_unlock();
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
dir_info_fd = dir_info_cache_get(file);
|
||||
if (dir_info_cache_list[dir_info_fd].ref == 1)
|
||||
{
|
||||
ret = proc_delnode(name);
|
||||
if (ret < 0)
|
||||
{
|
||||
dir_info_cache_put(file);
|
||||
proc_unlock();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
dir_info_cache_put(file);
|
||||
proc_unlock();
|
||||
return 0;
|
||||
}
|
||||
int proc_ns_remove(const char *name)
|
||||
{
|
||||
proc_node_t *file;
|
||||
int ret;
|
||||
int dir_info_fd;
|
||||
int cur_inx;
|
||||
|
||||
if (name[0] == '\0')
|
||||
{
|
||||
name = "/";
|
||||
}
|
||||
procfs_lock();
|
||||
file = proc_node_find_full_file(name, &ret, &cur_inx);
|
||||
if (file == NULL)
|
||||
{
|
||||
proc_unlock();
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
dir_info_fd = dir_info_cache_get(file);
|
||||
if (dir_info_cache_list[dir_info_fd].ref == 1)
|
||||
{
|
||||
ret = proc_delnode(name);
|
||||
if (ret < 0)
|
||||
{
|
||||
proc_unlock();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
dir_info_cache_put(file);
|
||||
proc_unlock();
|
||||
return 0;
|
||||
}
|
||||
int proc_ns_readdir(int fd, struct dirent *_dir)
|
||||
{
|
||||
int ret = -1;
|
||||
proc_ns_file_t *file;
|
||||
|
||||
procfs_lock();
|
||||
file = proc_ns_get_file(fd);
|
||||
if (!file || file->used == 0)
|
||||
{
|
||||
proc_unlock();
|
||||
return -ENOENT;
|
||||
}
|
||||
if (file->type != FS_NS_DIR_TYPE)
|
||||
{
|
||||
proc_unlock();
|
||||
return -EACCES;
|
||||
}
|
||||
if (file->tmp_fd == -1)
|
||||
{
|
||||
proc_node_t *dir_info;
|
||||
|
||||
dir_info = proc_node_get_first(dir_info_cache_list[file->dir_info_fd].info);
|
||||
if (dir_info == NULL)
|
||||
{
|
||||
proc_unlock();
|
||||
return -ENOENT;
|
||||
}
|
||||
ret = dir_info_cache_get(dir_info);
|
||||
if (ret < 0)
|
||||
{
|
||||
proc_unlock();
|
||||
return ret;
|
||||
}
|
||||
file->tmp_fd = ret;
|
||||
}
|
||||
else if (file->tmp_fd == -2)
|
||||
{
|
||||
proc_unlock();
|
||||
return -ENOENT;
|
||||
}
|
||||
proc_node_t *node_info;
|
||||
|
||||
node_info = dir_info_cache_list[file->tmp_fd].info;
|
||||
_dir->d_reclen = sizeof(*_dir);
|
||||
_dir->d_type = node_info->type == NODE_TYPE_PROC_DUMMY ? DT_DIR : DT_CHR; // DT_REG;
|
||||
strncpy(_dir->d_name, node_info->name, sizeof(_dir->d_name));
|
||||
_dir->d_name[sizeof(_dir->d_name) - 1] = 0;
|
||||
|
||||
proc_node_t *next_dir_info = proc_node_get_next(dir_info_cache_list[file->dir_info_fd].info, node_info);
|
||||
dir_info_cache_put(node_info);
|
||||
ret = dir_info_cache_get(next_dir_info);
|
||||
if (ret >= 0)
|
||||
{
|
||||
file->tmp_fd = ret;
|
||||
file->offset++;
|
||||
}
|
||||
else
|
||||
{
|
||||
file->tmp_fd = -2; // -2代表结束遍历
|
||||
}
|
||||
proc_unlock();
|
||||
return sizeof(*_dir);
|
||||
}
|
||||
int proc_ns_mkdir(char *path)
|
||||
{
|
||||
int ret;
|
||||
|
||||
procfs_lock();
|
||||
ret = proc_mknode(path, NODE_TYPE_PROC_DUMMY, NULL);
|
||||
proc_unlock();
|
||||
return ret;
|
||||
}
|
||||
int proc_ns_open_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
for (int i = 0; i < DIR_INFO_NR; i++)
|
||||
{
|
||||
proc_ns_files[i].dir_info_fd = -1;
|
||||
proc_ns_files[i].tmp_fd = -1;
|
||||
}
|
||||
ret = u_mutex_init(&procfs_mutex_lock, handler_alloc());
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过pid删除nsfs中的文件
|
||||
*/
|
||||
void proc_ns_del_file_by_pid(const char *path, pid_t pid)
|
||||
{
|
||||
if (path == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int fd;
|
||||
char *new_path;
|
||||
struct dirent dir;
|
||||
int path_len;
|
||||
|
||||
path_len = strlen(path) + 64;
|
||||
new_path = malloc(path_len);
|
||||
if (new_path == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
fd = proc_ns_open(path, O_RDONLY, 0);
|
||||
if (fd < 0)
|
||||
{
|
||||
free(new_path);
|
||||
return;
|
||||
}
|
||||
while (1)
|
||||
{
|
||||
if (proc_ns_readdir(fd, &dir) < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (path[0] == '/' && path[1] == '\0')
|
||||
{
|
||||
snprintf(new_path, path_len, "/%s", dir.d_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(new_path, path_len, "%s/%s", path, dir.d_name);
|
||||
}
|
||||
// 递归删除
|
||||
if (dir.d_type == DT_DIR)
|
||||
{
|
||||
proc_ns_del_file_by_pid(new_path, pid);
|
||||
continue;
|
||||
}
|
||||
struct kstat st;
|
||||
if (proc_ns_stat(new_path, &st) < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (st.pid == pid)
|
||||
{
|
||||
proc_ns_remove(new_path);
|
||||
}
|
||||
}
|
||||
free(new_path);
|
||||
proc_ns_close(fd);
|
||||
}
|
||||
|
||||
int proc_register_file(const char *path, const proc_file_operation_t *op)
|
||||
{
|
||||
assert(op);
|
||||
assert(path);
|
||||
int ret;
|
||||
|
||||
procfs_lock();
|
||||
ret = proc_mknode(path, NODE_TYPE_PROC_FILE, op);
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("register [%s] failed.\n", (char *)(path));
|
||||
}
|
||||
proc_unlock();
|
||||
return ret;
|
||||
}
|
||||
53
mkrtos_user/server/fs/procfs/src/procfs_impl.c
Normal file
53
mkrtos_user/server/fs/procfs/src/procfs_impl.c
Normal file
@@ -0,0 +1,53 @@
|
||||
#include "proc.h"
|
||||
#include "procfs.h"
|
||||
#include "procfs_rpc.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
static int proc_open(proc_node_t *node, const char *path, int flags, int mode)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static int proc_read(proc_node_t *node, void *buf, size_t len, long offset)
|
||||
{
|
||||
msg_tag_t tag;
|
||||
char name[8];
|
||||
|
||||
if (offset >= sizeof(name))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
tag = u_task_get_obj_name(TASK_THIS, TASK_THIS, name);
|
||||
memcpy(buf, name + offset, MIN(len, sizeof(name) - offset));
|
||||
return MIN(len, sizeof(name));
|
||||
}
|
||||
static int proc_write(proc_node_t *node, void *buf, size_t len, long offset)
|
||||
{
|
||||
msg_tag_t tag;
|
||||
char name[8];
|
||||
|
||||
if (len < sizeof(name) || offset >= sizeof(name))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
memcpy(name, buf, MIN(len, sizeof(name)));
|
||||
tag = u_task_set_obj_name(TASK_THIS, TASK_THIS, name);
|
||||
return MIN(len, sizeof(name));
|
||||
}
|
||||
static const proc_file_operation_t name_op =
|
||||
{
|
||||
.proc_open = proc_open,
|
||||
.proc_read = proc_read,
|
||||
.proc_write = proc_write,
|
||||
};
|
||||
int proc_default_file_register(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = proc_register_file("/comm", &name_op);
|
||||
if (ret < 0) {
|
||||
printf("task reg [name] node failed.\n");
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
147
mkrtos_user/server/fs/procfs/src/procfs_rpc.c
Normal file
147
mkrtos_user/server/fs/procfs/src/procfs_rpc.c
Normal file
@@ -0,0 +1,147 @@
|
||||
#include "cons_cli.h"
|
||||
#include "fs_svr.h"
|
||||
#include "kstat.h"
|
||||
#include "rpc_prot.h"
|
||||
#include "u_env.h"
|
||||
#include "u_log.h"
|
||||
#include "u_rpc.h"
|
||||
#include "u_rpc_svr.h"
|
||||
#include "u_sig.h"
|
||||
#include "u_task.h"
|
||||
#include "pm_cli.h"
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <u_malloc.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ns_cli.h>
|
||||
#include "fd.h"
|
||||
#include "u_path.h"
|
||||
#include "procfs.h"
|
||||
#include "procfs_impl.h"
|
||||
|
||||
static fs_t fs;
|
||||
static meta_t procfs_meta;
|
||||
static obj_handler_t procfs_ipc_hd;
|
||||
static int fs_sig_call_back(pid_t pid, umword_t sig_val);
|
||||
|
||||
static int fs_svr_open(const char *path, int flags, int mode)
|
||||
{
|
||||
return proc_ns_open(path, flags, mode);
|
||||
}
|
||||
|
||||
static int fs_svr_read(int fd, void *buf, size_t len)
|
||||
{
|
||||
return proc_ns_read(fd, buf, len);
|
||||
}
|
||||
static int fs_svr_write(int fd, void *buf, size_t len)
|
||||
{
|
||||
return proc_ns_write(fd, buf, len);
|
||||
}
|
||||
static void fs_svr_close(int fd)
|
||||
{
|
||||
proc_ns_close(fd);
|
||||
}
|
||||
static int fs_svr_readdir(int fd, dirent_t *dir)
|
||||
{
|
||||
return proc_ns_readdir(fd, dir);
|
||||
}
|
||||
static int fs_svr_lseek(int fd, int offs, int whence)
|
||||
{
|
||||
return proc_ns_lseek(fd, offs, whence);
|
||||
}
|
||||
static int fs_svr_ftruncate(int fd, off_t off)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
static int fs_svr_fstat(int fd, void *_stat)
|
||||
{
|
||||
return proc_ns_fstat(fd, _stat);
|
||||
}
|
||||
static int fs_svr_ioctl(int fd, int req, void *arg)
|
||||
{
|
||||
return proc_ns_ioctl(fd, req, (unsigned long)arg);
|
||||
}
|
||||
static int fs_svr_fsync(int fd)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
static int fs_svr_unlink(const char *path)
|
||||
{
|
||||
return proc_ns_remove(path);
|
||||
}
|
||||
static int fs_svr_symlink(const char *existing, const char *new)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
static int fs_svr_mkdir(char *path)
|
||||
{
|
||||
return proc_ns_mkdir(path);
|
||||
}
|
||||
static int fs_svr_rmdir(char *path)
|
||||
{
|
||||
return proc_ns_rmdir(path);
|
||||
}
|
||||
static int fs_svr_rename(char *oldname, char *newname)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
static int fs_svr_stat(const char *path, void *_buf)
|
||||
{
|
||||
return proc_ns_stat(path, _buf);
|
||||
}
|
||||
static ssize_t fs_svr_readlink(const char *path, char *buf, size_t bufsize)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
static int fs_svr_statfs(const char *path, struct statfs *buf)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
static const fs_operations_t ops =
|
||||
{
|
||||
.fs_svr_open = fs_svr_open,
|
||||
.fs_svr_read = fs_svr_read,
|
||||
.fs_svr_write = fs_svr_write,
|
||||
.fs_svr_close = fs_svr_close,
|
||||
.fs_svr_readdir = fs_svr_readdir,
|
||||
.fs_svr_lseek = fs_svr_lseek,
|
||||
.fs_svr_ftruncate = fs_svr_ftruncate,
|
||||
.fs_svr_fstat = fs_svr_fstat,
|
||||
.fs_svr_ioctl = fs_svr_ioctl,
|
||||
// .fs_svr_fcntl = fs_svr_fcntl,
|
||||
.fs_svr_fsync = fs_svr_fsync,
|
||||
.fs_svr_unlink = fs_svr_unlink,
|
||||
.fs_svr_symlink = fs_svr_symlink,
|
||||
.fs_svr_mkdir = fs_svr_mkdir,
|
||||
.fs_svr_rmdir = fs_svr_rmdir,
|
||||
.fs_svr_rename = fs_svr_rename,
|
||||
.fs_svr_stat = fs_svr_stat,
|
||||
.fs_svr_readlink = fs_svr_readlink,
|
||||
};
|
||||
AUTO_CALL(101) __USED
|
||||
void procfs_svr_init(void)
|
||||
{
|
||||
int ret;
|
||||
char proc_path[20];
|
||||
umword_t pid;
|
||||
|
||||
fs_init(&fs, &ops);
|
||||
meta_obj_init(&procfs_meta);
|
||||
rpc_meta_init(&procfs_meta, TASK_THIS, &procfs_ipc_hd);
|
||||
meta_reg_svr_obj_raw(&procfs_meta, &fs.svr, FS_PROT);
|
||||
|
||||
u_task_get_pid(TASK_THIS, &pid);
|
||||
snprintf(proc_path, sizeof(proc_path), "/proc/%d", pid);
|
||||
|
||||
ret = ns_register(proc_path, procfs_ipc_hd, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("task proc reg failed [%d].\n", ret);
|
||||
}
|
||||
proc_default_file_register();
|
||||
}
|
||||
@@ -16,7 +16,7 @@ target_link_libraries(sh.elf
|
||||
sys
|
||||
sys_util
|
||||
sys_svr
|
||||
# mr
|
||||
proc
|
||||
LetterShell
|
||||
--no-whole-archive
|
||||
${GCC_LIB_PATH}/libgcc.a
|
||||
@@ -29,6 +29,7 @@ target_include_directories(
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys_svr/inc
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/letter-shell/demo/mkrtos
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/letter-shell/src
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_user/server/fs/procfs/inc
|
||||
)
|
||||
set_target_properties(sh.elf PROPERTIES LINK_FLAGS
|
||||
"-T ${CMAKE_CURRENT_LIST_DIR}/${ARCH_NAME}/link.lds ${CORTEX_M_LINK_FLAGS} --gc-section -no-dynamic-linker "
|
||||
@@ -64,5 +65,5 @@ add_dependencies(shell_dump sys_util)
|
||||
add_dependencies(shell_dump sys_svr)
|
||||
# add_dependencies(shell_dump start)
|
||||
# add_dependencies(shell_dump muslc)
|
||||
add_dependencies(shell_dump LetterShell)
|
||||
add_dependencies(shell_dump LetterShell proc)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user