From dd88643cced91b05516283160ff79ac429c1566c Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Fri, 31 Dec 2021 12:51:42 +0000 Subject: [PATCH] Unified open() and close(). git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15296 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- .../cfg/ffconf.h | 1 + .../cfg/stm32l4r9ai_discovery/ffconf.h | 1 + os/various/shell/shell_cmd.c | 4 +- os/vfs/include/vfs.h | 11 +-- os/vfs/include/vfsdrivers.h | 5 +- os/vfs/src/vfs.c | 91 +++++++++---------- os/vfs/src/vfsdrivers.c | 86 ++++++++++++++++++ os/vfs/various/syscalls.c | 24 +++-- os/vfs/vfs.mk | 1 + 9 files changed, 160 insertions(+), 64 deletions(-) create mode 100644 os/vfs/src/vfsdrivers.c diff --git a/demos/STM32/RT-STM32L4R9-DISCOVERY-SB_HOST_STATIC/cfg/ffconf.h b/demos/STM32/RT-STM32L4R9-DISCOVERY-SB_HOST_STATIC/cfg/ffconf.h index ffa61d7bf..b76edc527 100644 --- a/demos/STM32/RT-STM32L4R9-DISCOVERY-SB_HOST_STATIC/cfg/ffconf.h +++ b/demos/STM32/RT-STM32L4R9-DISCOVERY-SB_HOST_STATIC/cfg/ffconf.h @@ -1,5 +1,6 @@ /* CHIBIOS FIX */ #include "ch.h" +#define FATFS_CHIBIOS_EXTENSIONS /*---------------------------------------------------------------------------/ / FatFs Functional Configurations diff --git a/demos/STM32/RT-VFS-FATFS/cfg/stm32l4r9ai_discovery/ffconf.h b/demos/STM32/RT-VFS-FATFS/cfg/stm32l4r9ai_discovery/ffconf.h index ffa61d7bf..b76edc527 100644 --- a/demos/STM32/RT-VFS-FATFS/cfg/stm32l4r9ai_discovery/ffconf.h +++ b/demos/STM32/RT-VFS-FATFS/cfg/stm32l4r9ai_discovery/ffconf.h @@ -1,5 +1,6 @@ /* CHIBIOS FIX */ #include "ch.h" +#define FATFS_CHIBIOS_EXTENSIONS /*---------------------------------------------------------------------------/ / FatFs Functional Configurations diff --git a/os/various/shell/shell_cmd.c b/os/various/shell/shell_cmd.c index 64bb17ff4..35bbb861d 100644 --- a/os/various/shell/shell_cmd.c +++ b/os/various/shell/shell_cmd.c @@ -263,7 +263,7 @@ static void scan_nodes(BaseSequentialStream *chp, } } - vfsCloseDirectory(dirp); + vfsClose((vfs_node_c *)dirp); } } @@ -381,7 +381,7 @@ static void cmd_ls(BaseSequentialStream *chp, int argc, char *argv[]) { chprintf(chp, "%s" SHELL_NEWLINE_STR, dip->name); } - vfsCloseDirectory(dirp); + vfsClose((vfs_node_c *)dirp); } else { chprintf(chp, "Failed (%d)" SHELL_NEWLINE_STR, res); diff --git a/os/vfs/include/vfs.h b/os/vfs/include/vfs.h index f5e90608d..4a66102b2 100644 --- a/os/vfs/include/vfs.h +++ b/os/vfs/include/vfs.h @@ -132,17 +132,14 @@ extern "C" { msg_t vfsGetStat(vfs_node_c *np, vfs_stat_t *sp); msg_t vfsChangeCurrentDirectory(const char *path); msg_t vfsGetCurrentDirectory(char *buf, size_t size); - msg_t vfsOpenDirectory(const char *name, - vfs_directory_node_c **vdnpp); - void vfsCloseDirectory(vfs_directory_node_c *vdnp); + msg_t vfsOpen(const char *path, int flags, vfs_node_c **vnpp); + msg_t vfsOpenDirectory(const char *name, vfs_directory_node_c **vdnpp); + msg_t vfsOpenFile(const char *name, int flags, vfs_file_node_c **vfnpp); + void vfsClose(vfs_node_c *vnp); msg_t vfsReadDirectoryFirst(vfs_directory_node_c *vdnp, vfs_direntry_info_t *dip); msg_t vfsReadDirectoryNext(vfs_directory_node_c *vdnp, vfs_direntry_info_t *dip); - msg_t vfsOpenFile(const char *name, - int flags, - vfs_file_node_c **vfnpp); - void vfsCloseFile(vfs_file_node_c *vfnp); ssize_t vfsReadFile(vfs_file_node_c *vfnp, uint8_t *buf, size_t n); ssize_t vfsWriteFile(vfs_file_node_c *vfnp, const uint8_t *buf, size_t n); msg_t vfsSetFilePosition(vfs_file_node_c *vfnp, diff --git a/os/vfs/include/vfsdrivers.h b/os/vfs/include/vfsdrivers.h index 9e1499964..111fd4df1 100644 --- a/os/vfs/include/vfsdrivers.h +++ b/os/vfs/include/vfsdrivers.h @@ -112,7 +112,10 @@ typedef struct vfs_driver { #ifdef __cplusplus extern "C" { #endif - + msg_t vfsDrvOpen(vfs_driver_c *drvp, + const char *path, + int flags, + vfs_node_c **vnpp); #ifdef __cplusplus } #endif diff --git a/os/vfs/src/vfs.c b/os/vfs/src/vfs.c index 7c43ff6b5..33df14a3c 100644 --- a/os/vfs/src/vfs.c +++ b/os/vfs/src/vfs.c @@ -118,32 +118,64 @@ msg_t vfsGetCurrentDirectory(char *buf, size_t size) { } /** - * @brief Opens a VFS directory. + * @brief Opens a VFS file or directory. * - * @param[in] path Absolute path of the directory to be opened. - * @param[out] vdnpp Pointer to the pointer to the instantiated. - * @p vfs_directory_node_c object + * @param[in] path Absolute path of the node to be opened. + * @param[in] flags Open flags. + * @param[out] vnpp Pointer to the pointer to the instantiated + * @p vfs_node_c object. * @return The operation result. * * @api */ -msg_t vfsOpenDirectory(const char *path, - vfs_directory_node_c **vdnpp) { +msg_t vfsOpen(const char *path, int flags, vfs_node_c **vnpp) { + + return vfsDrvOpen(vfs_root, path, flags, vnpp); +} + +/** + * @brief Opens a VFS directory. + * + * @param[in] path Absolute path of the directory to be opened. + * @param[out] vdnpp Pointer to the pointer to the instantiated + * @p vfs_directory_node_c object. + * @return The operation result. + * + * @api + */ +msg_t vfsOpenDirectory(const char *path, vfs_directory_node_c **vdnpp) { return vfsDrvOpenDirectory(vfs_root, path, vdnpp); } /** - * @brief Releases a @p vfs_directory_node_c object. + * @brief Opens a VFS file. * - * @param[in] vdnp Pointer to the @p vfs_directory_node_c object - * to be released. + * @param[in] path Path of the file to be opened. + * @param[in] flags File open flags. + * @param[out] vdnpp Pointer to the pointer to the instantiated + * @p vfs_file_node_c object. + * @return The operation result. * * @api */ -void vfsCloseDirectory(vfs_directory_node_c *vdnp) { +msg_t vfsOpenFile(const char *path, int flags, vfs_file_node_c **vfnpp) { - vdnp->vmt->release((void *)vdnp); + return vfsDrvOpenFile(vfs_root, path, flags, vfnpp); +} + +/** + * @brief Releases a @p vfs_node_c or descendant object. + * + * @param[in] vnp Pointer to the @p vfs_node_c object to be released. + * + * @api + */ +void vfsClose(vfs_node_c *vnp) { + + chDbgAssert(vnp->references > 0U, "zero count"); + + vnp->vmt->release((void *)vnp); } /** @@ -168,8 +200,8 @@ msg_t vfsReadDirectoryFirst(vfs_directory_node_c *vdnp, /** * @brief Next directory entry. * - * @param[in] vdnp Pointer to the @p vfs_directory_node_c object.. - * @param[out] dip Pointer to a @p vfs_direntry_info_t structure + * @param[in] vdnp Pointer to the @p vfs_directory_node_c object. + * @param[out] dip Pointer to a @p vfs_direntry_info_t structure. * @return The operation result. * @retval 0 Zero entries read, end-of-directory condition. * @retval 1 One directory entry read. @@ -184,39 +216,6 @@ msg_t vfsReadDirectoryNext(vfs_directory_node_c *vdnp, return vdnp->vmt->dir_next((void *)vdnp, dip); } -/** - * @brief Opens a VFS file. - * - * @param[in] path Path of the file to be opened. - * @param[in] flags File open flags. - * @param[out] vdnpp Pointer to the pointer to the instantiated - * @p vfs_file_node_c object. - * @return The operation result. - * - * @api - */ -msg_t vfsOpenFile(const char *path, - int flags, - vfs_file_node_c **vfnpp) { - - return vfsDrvOpenFile(vfs_root, path, flags, vfnpp); -} - -/** - * @brief Releases a @p vfs_file_node_c object. - * - * @param[in] vfnp Pointer to the @p vfs_file_node_c object. - * to be released - * - * @api - */ -void vfsCloseFile(vfs_file_node_c *vfnp) { - - chDbgAssert(vfnp->references > 0U, "zero count"); - - vfnp->vmt->release((void *)vfnp); -} - /** * @brief File node read. * @details The function reads data from a file node into a buffer. diff --git a/os/vfs/src/vfsdrivers.c b/os/vfs/src/vfsdrivers.c new file mode 100644 index 000000000..6724c42b9 --- /dev/null +++ b/os/vfs/src/vfsdrivers.c @@ -0,0 +1,86 @@ +/* + ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014, + 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation version 3 of the License. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file vfs/src/vfsdrivers.c + * @brief VFS drivers code. + * + * @addtogroup VFS_DRIVERS + * @{ + */ + +#include "vfs.h" + +/*===========================================================================*/ +/* Module local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported functions. */ +/*===========================================================================*/ + +/** + * @brief Opens a VFS file or directory. + * + * @param[in] drvp Pointer to the @p vfs_driver_c object. + * @param[in] path Absolute path of the node to be opened. + * @param[in] flags Open flags. + * @param[out] vnpp Pointer to the pointer to the instantiated + * @p vfs_node_c object. + * @return The operation result. + * + * @api + */ +msg_t vfsDrvOpen(vfs_driver_c *drvp, + const char *path, + int flags, + vfs_node_c **vnpp) { + msg_t ret; + + /* Attempting to open as file.*/ + ret = vfsDrvOpenFile(drvp, path, flags, (vfs_file_node_c **)vnpp); + if (ret == CH_RET_EISDIR) { + if ((flags & VO_ACCMODE) != VO_RDONLY) { + ret = CH_RET_EISDIR; + } + else { + ret = vfsDrvOpenDirectory(drvp, path, (vfs_directory_node_c **)vnpp); + } + } + + return ret; +} + +/** @} */ diff --git a/os/vfs/various/syscalls.c b/os/vfs/various/syscalls.c index a13cad86b..9ca74f0eb 100644 --- a/os/vfs/various/syscalls.c +++ b/os/vfs/various/syscalls.c @@ -26,19 +26,19 @@ #define SYSCALL_MAX_FDS 10 #endif -static vfs_file_node_c *fds[SYSCALL_MAX_FDS]; +static vfs_node_c *fds[SYSCALL_MAX_FDS]; /***************************************************************************/ __attribute__((used)) int _open_r(struct _reent *r, const char *p, int oflag, int mode) { msg_t err; - vfs_file_node_c *vfnp; + vfs_node_c *vnp; int file; (void)mode; - err = vfsOpenFile(p, oflag, &vfnp); + err = vfsOpen(p, oflag, &vnp); if (err < CH_RET_SUCCESS) { __errno_r(r) = CH_DECODE_ERROR(err); return -1; @@ -47,12 +47,12 @@ int _open_r(struct _reent *r, const char *p, int oflag, int mode) { /* Searching for a free file handle.*/ for (file = 0; file < SYSCALL_MAX_FDS; file++) { if (fds[file] == NULL) { - fds[file] = vfnp; + fds[file] = vnp; return file; } } - vfsCloseFile(vfnp); + vfsClose(vnp); __errno_r(r) = EMFILE; return -1; @@ -68,7 +68,7 @@ int _close_r(struct _reent *r, int file) { return -1; } - vfsCloseFile(fds[file]); + vfsClose((vfs_node_c *)fds[file]); fds[file] = NULL; return 0; @@ -85,7 +85,11 @@ int _read_r(struct _reent *r, int file, char *ptr, int len) { return -1; } - nr = vfsReadFile(fds[file], (uint8_t *)ptr, (size_t)len); + if (!VFS_MODE_S_ISREG(fds[file]->mode)) { + return EISDIR; + } + + nr = vfsReadFile((vfs_file_node_c *)fds[file], (uint8_t *)ptr, (size_t)len); if (CH_RET_IS_ERROR(nr)) { __errno_r(r) = CH_DECODE_ERROR(nr); return -1; @@ -105,7 +109,11 @@ int _write_r(struct _reent *r, int file, const char *ptr, int len) { return -1; } - nw = vfsWriteFile(fds[file], (const uint8_t *)ptr, (size_t)len); + if (!VFS_MODE_S_ISREG(fds[file]->mode)) { + return EISDIR; + } + + nw = vfsWriteFile((vfs_file_node_c *)fds[file], (const uint8_t *)ptr, (size_t)len); if (CH_RET_IS_ERROR(nw)) { __errno_r(r) = CH_DECODE_ERROR(nw); return -1; diff --git a/os/vfs/vfs.mk b/os/vfs/vfs.mk index e560199b7..e5814a3b8 100644 --- a/os/vfs/vfs.mk +++ b/os/vfs/vfs.mk @@ -2,6 +2,7 @@ VFSSRC := $(CHIBIOS)/os/vfs/src/vfsparser.c \ $(CHIBIOS)/os/vfs/src/vfspaths.c \ $(CHIBIOS)/os/vfs/src/vfsbuffers.c \ + $(CHIBIOS)/os/vfs/src/vfsdrivers.c \ $(CHIBIOS)/os/vfs/src/vfs.c \ $(CHIBIOS)/os/vfs/drivers/template/drvtemplate.c \ $(CHIBIOS)/os/vfs/drivers/sfs/drvsfs.c \