文件系统支持完善

This commit is contained in:
zhangzheng
2023-12-02 23:15:33 +08:00
parent 2d68c1b480
commit 50e54e7662
15 changed files with 212 additions and 45 deletions

View File

@@ -15,7 +15,7 @@ add_library(LetterShell
../../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

View File

@@ -4,20 +4,44 @@
* @brief shell config
* @version 3.0.0
* @date 2019-12-31
*
*
* @copyright (c) 2019 Letter
*
*
*/
#ifndef __SHELL_CFG_USER_H__
#define __SHELL_CFG_USER_H__
#include <u_sys.h>
#include <malloc.h>
/**
* @brief 获取系统时间(ms)
* 定义此宏为获取系统Tick如`HAL_GetTick()`
* @note 此宏不定义时无法使用双击tab补全命令help无法使用shell超时锁定
*/
#define SHELL_GET_TICK() sys_read_tick()
#define SHELL_GET_TICK() sys_read_tick()
/**
* @brief shell内存分配
* shell本身不需要此接口若使用shell伴生对象需要进行定义
*/
#define SHELL_MALLOC(size) malloc(size)
/**
* @brief shell内存释放
* shell本身不需要此接口若使用shell伴生对象需要进行定义
*/
#define SHELL_FREE(obj) free(obj)
/**
* @brief 使用函数签名
* 使能后可以在声明命令时指定函数的签名shell 会根据函数签名进行参数转换,
* 而不是自动判断参数的类型,如果参数和函数签名不匹配,会停止执行命令
*/
#define SHELL_USING_FUNC_SIGNATURE 1
/**
* @brief 支持数组参数
* 使能后,可以在命令中使用数组参数,如`cmd [1,2,3]`
* 需要使能 `SHELL_USING_FUNC_SIGNATURE` 宏,并且配置 `SHELL_MALLOC`, `SHELL_FREE`
*/
#define SHELL_SUPPORT_ARRAY_PARAM 1
#endif

View File

@@ -10,10 +10,25 @@
*/
#include "shell.h"
#include "shell_ext.h"
#include "shell_fs.h"
#include "shell_passthrough.h"
#include "shell_secure_user.h"
#include "log.h"
// #include "telnetd.h"
#include <stdio.h>
#include <dirent.h>
#include <unistd.h>
#include <stddef.h>
#include <string.h>
#include <sys/time.h>
#include <pthread.h>
#include "cons_cli.h"
#include "u_sleep.h"
Shell shell;
char shellBuffer[512];
static Shell shell;
static ShellFs shellFs;
static char shellBuffer[256];
static char shellPathBuffer[128] = "/mnt/";
/**
* @brief 用户shell写
@@ -43,16 +58,53 @@ signed short userShellRead(char *data, unsigned short len)
u_sleep_ms(5);
}
}
/**
* @brief 列出文件
*
* @param path 路径
* @param buffer 结果缓冲
* @param maxLen 最大缓冲长度
* @return size_t 0
*/
size_t userShellListDir(char *path, char *buffer, size_t maxLen)
{
DIR *dir;
struct dirent *ptr;
int i;
if (!path)
{
return 0;
}
dir = opendir(path);
if (!dir)
{
return 0;
}
memset(buffer, 0, maxLen);
while ((ptr = readdir(dir)) != NULL)
{
strcat(buffer, ptr->d_name);
strcat(buffer, "\t");
}
closedir(dir);
return 0;
}
/**
* @brief 用户shell初始化
*
*/
void userShellInit(void)
{
shellFs.getcwd = getcwd;
shellFs.chdir = chdir;
shellFs.listdir = userShellListDir;
shellFsInit(&shellFs, shellPathBuffer, sizeof(shellPathBuffer));
shell.write = userShellWrite;
shell.read = userShellRead;
shellInit(&shell, shellBuffer, 512);
shellSetPath(&shell, shellPathBuffer);
shellInit(&shell, shellBuffer, sizeof(shellBuffer));
shellCompanionAdd(&shell, SHELL_COMPANION_ID_FS, &shellFs);
while (1)
{

View File

@@ -18,7 +18,7 @@
#define SHELL_COMPANION_ID_FS -1
#define SHELL_FS_LIST_FILE_BUFFER_MAX 4096
#define SHELL_FS_LIST_FILE_BUFFER_MAX 128
/**
* @brief shell文件系统支持结构体

View File

@@ -39,7 +39,7 @@
* @brief 是否使用shell伴生对象
* 一些扩展的组件(文件系统支持,日志工具等)需要使用伴生对象
*/
#define SHELL_USING_COMPANION 0
#define SHELL_USING_COMPANION 1
#endif /** SHELL_USING_COMPANION */
#ifndef SHELL_SUPPORT_END_LINE

View File

@@ -321,6 +321,7 @@ long be_lseek(long fd, long offset, long whence)
{
case FD_TTY:
{
return -ENOSYS;
}
break;
case FD_FS:
@@ -332,4 +333,31 @@ long be_lseek(long fd, long offset, long whence)
return -ENOSYS;
}
return 0;
}
}
long be_getdents(long fd, char *buf, size_t size)
{
fd_map_entry_t u_fd;
int ret = fd_map_get(fd, &u_fd);
if (ret < 0)
{
return -EBADF;
}
switch (u_fd.type)
{
case FD_TTY:
{
return -ENOSYS;
}
break;
case FD_FS:
{
ret = fs_readdir(u_fd.priv_fd, (struct dirent *)buf);
}
break;
default:
return -ENOSYS;
}
return ret;
}

View File

@@ -2,10 +2,12 @@
#define _DIRENT_HAVE_D_OFF
#define _DIRENT_HAVE_D_TYPE
#define DIRENT_NAME_LEN 32 // 256
struct dirent {
ino_t d_ino;
off_t d_off;
unsigned short d_reclen;
unsigned char d_type;
char d_name[256];
char d_name[DIRENT_NAME_LEN];
};

View File

@@ -3,18 +3,22 @@
#include <stddef.h>
#include "__dirent.h"
#include "syscall.h"
typedef char dirstream_buf_alignment_check[1-2*(int)(
offsetof(struct __dirstream, buf) % sizeof(off_t))];
#ifndef NO_LITTLE_MODE
#include "syscall_backend.h"
#endif
typedef char dirstream_buf_alignment_check[1 - 2 * (int)(offsetof(struct __dirstream, buf) % sizeof(off_t))];
struct dirent *readdir(DIR *dir)
{
struct dirent *de;
if (dir->buf_pos >= dir->buf_end) {
int len = __syscall(SYS_getdents, dir->fd, dir->buf, sizeof dir->buf);
if (len <= 0) {
if (len < 0 && len != -ENOENT) errno = -len;
if (dir->buf_pos >= dir->buf_end)
{
int len = be_getdents(dir->fd, dir->buf, sizeof dir->buf);
if (len <= 0)
{
if (len < 0 && len != -ENOENT)
errno = -len;
return 0;
}
dir->buf_end = len;

View File

@@ -1,8 +1,10 @@
#pragma once
#include <stddef.h>
#include <dirent.h>
int fs_open(const char *path, int flags, int mode);
int fs_read(int fd, void *buf, size_t len);
int fs_write(int fd, void *buf, size_t len);
int fs_close(int fd);
int fs_lseek(int fd, int offs, int whence);
int fs_lseek(int fd, int offs, int whence);
int fs_readdir(int _fd, struct dirent *dirent);

View File

@@ -14,23 +14,6 @@ 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,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, mode)
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,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, len)
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,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, len)
RPC_GENERATION_CALL1(fs_t, FS_PROT, FS_CLOSE, close,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, fd)
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,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, whence)
sd_t fs_open(const char *path, int flags, int mode)
{
obj_handler_t hd;
@@ -60,6 +43,11 @@ sd_t fs_open(const char *path, int flags, int mode)
return mk_sd_init2(hd, msg_tag_get_val(tag)).raw;
}
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,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, len)
int fs_read(sd_t _fd, void *buf, size_t len)
{
obj_handler_t hd = mk_sd_init_raw(_fd).hd;
@@ -97,6 +85,10 @@ int fs_read(sd_t _fd, void *buf, size_t len)
return rlen;
}
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,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, len)
int fs_write(sd_t _fd, void *buf, size_t len)
{
@@ -134,6 +126,8 @@ int fs_write(sd_t _fd, void *buf, size_t len)
return wlen;
}
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)
{
obj_handler_t hd = mk_sd_init_raw(_fd).hd;
@@ -151,6 +145,11 @@ int fs_close(sd_t _fd)
return msg_tag_get_val(tag);
}
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,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, whence)
int fs_lseek(sd_t _fd, int offs, int whence)
{
obj_handler_t hd = mk_sd_init_raw(_fd).hd;
@@ -173,4 +172,31 @@ int fs_lseek(sd_t _fd, int offs, int whence)
}
return msg_tag_get_val(tag);
}
}
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)
int fs_readdir(sd_t _fd, dirent_t *dirent)
{
obj_handler_t hd = mk_sd_init_raw(_fd).hd;
int fd = mk_sd_init_raw(_fd).fd;
rpc_int_t rpc_fd = {
.data = fd,
};
rpc_dirent_t_t rpc_dient = {
.data.d_ino = 0,
};
msg_tag_t tag = fs_t_readdir_call(hd, &rpc_fd, &rpc_dient);
if (msg_tag_get_val(tag) >= 0)
{
if (dirent)
{
*dirent = rpc_dient.data;
}
}
return msg_tag_get_val(tag);
}

View File

@@ -145,7 +145,7 @@
/ When LFN is not enabled, this option has no effect. */
#define FF_LFN_BUF 255
#define FF_LFN_BUF 64
#define FF_SFN_BUF 12
/* This set of options defines size of file name members in the FILINFO structure
/ which is used to read out directory items. These values should be suffcient for

View File

@@ -9,6 +9,7 @@
#include <fcntl.h>
#include <errno.h>
#include <assert.h>
#include <string.h>
#include "rpc_prot.h"
static fs_t fs;
void fs_svr_init(void)
@@ -125,7 +126,7 @@ int fs_svr_open(const char *path, int flags, int mode)
if (ret != FR_OK)
{
if (ret == FR_NO_FILE)
if (ret == FR_NO_FILE || ret == FR_INVALID_NAME)
{
// 打开的是一个目录,则作为一个目录打开
ret = f_opendir(&file->dir, path);
@@ -136,7 +137,7 @@ int fs_svr_open(const char *path, int flags, int mode)
return fatfs_err_conv(ret);
}
file->type = 1;
cons_write_str("open dir..\n");
// cons_write_str("open dir..\n");
}
}
else
@@ -290,6 +291,26 @@ int fs_svr_readdir(int fd, dirent_t *dir)
{
return -ENOENT;
}
FILINFO info;
FRESULT ret = f_readdir(&file->dir, &info);
if (ret != FR_OK || info.fname[0] == 0)
{
return -ENOENT;
}
strncpy(dir->d_name, info.fname, sizeof(dir->d_name));
dir->d_name[sizeof(dir->d_name) - 1] = 0;
dir->d_reclen = sizeof(*dir);
dir->d_off = 0;
if (info.fattrib & AM_DIR)
{ /* Directory */
dir->d_type = DT_DIR;
}
else
{ /* File */
dir->d_type = DT_CHR;
}
return sizeof(*dir);
}
int fs_svr_mkdir(char *path)
{

View File

@@ -1,5 +1,5 @@
#define HEAP_SIZE 512
#define HEAP_SIZE 2048
#define STACK_SIZE 2048
#if defined(__CC_ARM)

View File

@@ -10,8 +10,6 @@
#include <stdio.h>
void fs_test(void)
{
int i = 1000;
while (i--)
{
char tmp[4] = "123";
int fd = open("/mnt/1.txt", O_CREAT | O_RDWR, 0777);
@@ -25,5 +23,13 @@ void fs_test(void)
assert(strcmp(tmp, "123") == 0);
close(fd);
}
{
DIR *dir = opendir("/mnt/");
assert(dir);
struct dirent *d = readdir(dir);
assert(d);
printf("%s\n", d->d_name);
closedir(dir);
}
printf("%s ok.\n", __func__);
}