文件系统支持完善
This commit is contained in:
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@@ -265,7 +265,9 @@
|
|||||||
"__memory": "c",
|
"__memory": "c",
|
||||||
"optional": "c",
|
"optional": "c",
|
||||||
"system_error": "c",
|
"system_error": "c",
|
||||||
"__dirent.h": "c"
|
"__dirent.h": "c",
|
||||||
|
"shell_fs.h": "c",
|
||||||
|
"shell_passthrough.h": "c"
|
||||||
},
|
},
|
||||||
"cortex-debug.showRTOS": false,
|
"cortex-debug.showRTOS": false,
|
||||||
"cortex-debug.variableUseNaturalFormat": false,
|
"cortex-debug.variableUseNaturalFormat": false,
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ add_library(LetterShell
|
|||||||
../../src/shell_companion.c
|
../../src/shell_companion.c
|
||||||
../../src/shell_ext.c
|
../../src/shell_ext.c
|
||||||
../../src/shell_cmd_list.c
|
../../src/shell_cmd_list.c
|
||||||
# ../../extensions/fs_support/shell_fs.c
|
../../extensions/fs_support/shell_fs.c
|
||||||
../../extensions/log/log.c
|
../../extensions/log/log.c
|
||||||
# ../../extensions/telnet/telnetd.c
|
# ../../extensions/telnet/telnetd.c
|
||||||
../../extensions/shell_enhance/shell_passthrough.c
|
../../extensions/shell_enhance/shell_passthrough.c
|
||||||
|
|||||||
@@ -4,20 +4,44 @@
|
|||||||
* @brief shell config
|
* @brief shell config
|
||||||
* @version 3.0.0
|
* @version 3.0.0
|
||||||
* @date 2019-12-31
|
* @date 2019-12-31
|
||||||
*
|
*
|
||||||
* @copyright (c) 2019 Letter
|
* @copyright (c) 2019 Letter
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __SHELL_CFG_USER_H__
|
#ifndef __SHELL_CFG_USER_H__
|
||||||
#define __SHELL_CFG_USER_H__
|
#define __SHELL_CFG_USER_H__
|
||||||
|
|
||||||
#include <u_sys.h>
|
#include <u_sys.h>
|
||||||
|
#include <malloc.h>
|
||||||
/**
|
/**
|
||||||
* @brief 获取系统时间(ms)
|
* @brief 获取系统时间(ms)
|
||||||
* 定义此宏为获取系统Tick,如`HAL_GetTick()`
|
* 定义此宏为获取系统Tick,如`HAL_GetTick()`
|
||||||
* @note 此宏不定义时无法使用双击tab补全命令help,无法使用shell超时锁定
|
* @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
|
#endif
|
||||||
|
|||||||
@@ -10,10 +10,25 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "shell.h"
|
#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 "cons_cli.h"
|
||||||
#include "u_sleep.h"
|
#include "u_sleep.h"
|
||||||
Shell shell;
|
static Shell shell;
|
||||||
char shellBuffer[512];
|
static ShellFs shellFs;
|
||||||
|
static char shellBuffer[256];
|
||||||
|
static char shellPathBuffer[128] = "/mnt/";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 用户shell写
|
* @brief 用户shell写
|
||||||
@@ -43,16 +58,53 @@ signed short userShellRead(char *data, unsigned short len)
|
|||||||
u_sleep_ms(5);
|
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初始化
|
* @brief 用户shell初始化
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void userShellInit(void)
|
void userShellInit(void)
|
||||||
{
|
{
|
||||||
|
shellFs.getcwd = getcwd;
|
||||||
|
shellFs.chdir = chdir;
|
||||||
|
shellFs.listdir = userShellListDir;
|
||||||
|
shellFsInit(&shellFs, shellPathBuffer, sizeof(shellPathBuffer));
|
||||||
shell.write = userShellWrite;
|
shell.write = userShellWrite;
|
||||||
shell.read = userShellRead;
|
shell.read = userShellRead;
|
||||||
shellInit(&shell, shellBuffer, 512);
|
shellSetPath(&shell, shellPathBuffer);
|
||||||
|
shellInit(&shell, shellBuffer, sizeof(shellBuffer));
|
||||||
|
shellCompanionAdd(&shell, SHELL_COMPANION_ID_FS, &shellFs);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
#define SHELL_COMPANION_ID_FS -1
|
#define SHELL_COMPANION_ID_FS -1
|
||||||
|
|
||||||
#define SHELL_FS_LIST_FILE_BUFFER_MAX 4096
|
#define SHELL_FS_LIST_FILE_BUFFER_MAX 128
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief shell文件系统支持结构体
|
* @brief shell文件系统支持结构体
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
* @brief 是否使用shell伴生对象
|
* @brief 是否使用shell伴生对象
|
||||||
* 一些扩展的组件(文件系统支持,日志工具等)需要使用伴生对象
|
* 一些扩展的组件(文件系统支持,日志工具等)需要使用伴生对象
|
||||||
*/
|
*/
|
||||||
#define SHELL_USING_COMPANION 0
|
#define SHELL_USING_COMPANION 1
|
||||||
#endif /** SHELL_USING_COMPANION */
|
#endif /** SHELL_USING_COMPANION */
|
||||||
|
|
||||||
#ifndef SHELL_SUPPORT_END_LINE
|
#ifndef SHELL_SUPPORT_END_LINE
|
||||||
|
|||||||
@@ -321,6 +321,7 @@ long be_lseek(long fd, long offset, long whence)
|
|||||||
{
|
{
|
||||||
case FD_TTY:
|
case FD_TTY:
|
||||||
{
|
{
|
||||||
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FD_FS:
|
case FD_FS:
|
||||||
@@ -332,4 +333,31 @@ long be_lseek(long fd, long offset, long whence)
|
|||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
return 0;
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,10 +2,12 @@
|
|||||||
#define _DIRENT_HAVE_D_OFF
|
#define _DIRENT_HAVE_D_OFF
|
||||||
#define _DIRENT_HAVE_D_TYPE
|
#define _DIRENT_HAVE_D_TYPE
|
||||||
|
|
||||||
|
#define DIRENT_NAME_LEN 32 // 256
|
||||||
|
|
||||||
struct dirent {
|
struct dirent {
|
||||||
ino_t d_ino;
|
ino_t d_ino;
|
||||||
off_t d_off;
|
off_t d_off;
|
||||||
unsigned short d_reclen;
|
unsigned short d_reclen;
|
||||||
unsigned char d_type;
|
unsigned char d_type;
|
||||||
char d_name[256];
|
char d_name[DIRENT_NAME_LEN];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,18 +3,22 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "__dirent.h"
|
#include "__dirent.h"
|
||||||
#include "syscall.h"
|
#include "syscall.h"
|
||||||
|
#ifndef NO_LITTLE_MODE
|
||||||
typedef char dirstream_buf_alignment_check[1-2*(int)(
|
#include "syscall_backend.h"
|
||||||
offsetof(struct __dirstream, buf) % sizeof(off_t))];
|
#endif
|
||||||
|
typedef char dirstream_buf_alignment_check[1 - 2 * (int)(offsetof(struct __dirstream, buf) % sizeof(off_t))];
|
||||||
|
|
||||||
struct dirent *readdir(DIR *dir)
|
struct dirent *readdir(DIR *dir)
|
||||||
{
|
{
|
||||||
struct dirent *de;
|
struct dirent *de;
|
||||||
|
|
||||||
if (dir->buf_pos >= dir->buf_end) {
|
if (dir->buf_pos >= dir->buf_end)
|
||||||
int len = __syscall(SYS_getdents, dir->fd, dir->buf, sizeof dir->buf);
|
{
|
||||||
if (len <= 0) {
|
int len = be_getdents(dir->fd, dir->buf, sizeof dir->buf);
|
||||||
if (len < 0 && len != -ENOENT) errno = -len;
|
if (len <= 0)
|
||||||
|
{
|
||||||
|
if (len < 0 && len != -ENOENT)
|
||||||
|
errno = -len;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
dir->buf_end = len;
|
dir->buf_end = len;
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <dirent.h>
|
||||||
int fs_open(const char *path, int flags, int mode);
|
int fs_open(const char *path, int flags, int mode);
|
||||||
int fs_read(int fd, void *buf, size_t len);
|
int fs_read(int fd, void *buf, size_t len);
|
||||||
int fs_write(int fd, void *buf, size_t len);
|
int fs_write(int fd, void *buf, size_t len);
|
||||||
int fs_close(int fd);
|
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);
|
||||||
|
|||||||
@@ -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_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, flags,
|
||||||
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, mode)
|
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)
|
sd_t fs_open(const char *path, int flags, int mode)
|
||||||
{
|
{
|
||||||
obj_handler_t hd;
|
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;
|
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)
|
int fs_read(sd_t _fd, void *buf, size_t len)
|
||||||
{
|
{
|
||||||
obj_handler_t hd = mk_sd_init_raw(_fd).hd;
|
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;
|
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)
|
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;
|
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)
|
int fs_close(sd_t _fd)
|
||||||
{
|
{
|
||||||
obj_handler_t hd = mk_sd_init_raw(_fd).hd;
|
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);
|
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)
|
int fs_lseek(sd_t _fd, int offs, int whence)
|
||||||
{
|
{
|
||||||
obj_handler_t hd = mk_sd_init_raw(_fd).hd;
|
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);
|
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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -145,7 +145,7 @@
|
|||||||
/ When LFN is not enabled, this option has no effect. */
|
/ 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
|
#define FF_SFN_BUF 12
|
||||||
/* This set of options defines size of file name members in the FILINFO structure
|
/* 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
|
/ which is used to read out directory items. These values should be suffcient for
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
#include "rpc_prot.h"
|
#include "rpc_prot.h"
|
||||||
static fs_t fs;
|
static fs_t fs;
|
||||||
void fs_svr_init(void)
|
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_OK)
|
||||||
{
|
{
|
||||||
if (ret == FR_NO_FILE)
|
if (ret == FR_NO_FILE || ret == FR_INVALID_NAME)
|
||||||
{
|
{
|
||||||
// 打开的是一个目录,则作为一个目录打开
|
// 打开的是一个目录,则作为一个目录打开
|
||||||
ret = f_opendir(&file->dir, path);
|
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);
|
return fatfs_err_conv(ret);
|
||||||
}
|
}
|
||||||
file->type = 1;
|
file->type = 1;
|
||||||
cons_write_str("open dir..\n");
|
// cons_write_str("open dir..\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -290,6 +291,26 @@ int fs_svr_readdir(int fd, dirent_t *dir)
|
|||||||
{
|
{
|
||||||
return -ENOENT;
|
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)
|
int fs_svr_mkdir(char *path)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
#define HEAP_SIZE 512
|
#define HEAP_SIZE 2048
|
||||||
#define STACK_SIZE 2048
|
#define STACK_SIZE 2048
|
||||||
|
|
||||||
#if defined(__CC_ARM)
|
#if defined(__CC_ARM)
|
||||||
|
|||||||
@@ -10,8 +10,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
void fs_test(void)
|
void fs_test(void)
|
||||||
{
|
{
|
||||||
int i = 1000;
|
|
||||||
while (i--)
|
|
||||||
{
|
{
|
||||||
char tmp[4] = "123";
|
char tmp[4] = "123";
|
||||||
int fd = open("/mnt/1.txt", O_CREAT | O_RDWR, 0777);
|
int fd = open("/mnt/1.txt", O_CREAT | O_RDWR, 0777);
|
||||||
@@ -25,5 +23,13 @@ void fs_test(void)
|
|||||||
assert(strcmp(tmp, "123") == 0);
|
assert(strcmp(tmp, "123") == 0);
|
||||||
close(fd);
|
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__);
|
printf("%s ok.\n", __func__);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user