diff --git a/os/vfs/drivers/overlay/drvoverlay.c b/os/vfs/drivers/overlay/drvoverlay.c index 835518176..a453f5c4c 100644 --- a/os/vfs/drivers/overlay/drvoverlay.c +++ b/os/vfs/drivers/overlay/drvoverlay.c @@ -115,13 +115,18 @@ static msg_t match_driver(vfs_overlay_driver_c *odp, return err; } -/* TODO */ static msg_t build_path(vfs_overlay_driver_c *drvp, const char *path, char *buf) { - (void) drvp; - strcpy(buf, path); + *buf++ = '\0'; + + /* Copying the prefix, if defined.*/ + if (drvp->path_prefix != NULL) { + VFS_RETURN_ON_ERROR(vfs_path_append(buf, drvp->path_prefix)); + } + + VFS_RETURN_ON_ERROR(vfs_path_append(buf, path)); return VFS_RET_SUCCESS; } diff --git a/os/vfs/include/vfs.h b/os/vfs/include/vfs.h index 0554f445b..578594035 100644 --- a/os/vfs/include/vfs.h +++ b/os/vfs/include/vfs.h @@ -86,6 +86,7 @@ /* Base VFS headers.*/ #include "vfserrors.h" #include "vfsparser.h" +#include "vfspaths.h" #include "vfsbuffers.h" #include "vfsnodes.h" #include "vfsdrivers.h" diff --git a/os/vfs/include/vfserrors.h b/os/vfs/include/vfserrors.h index 793b4b552..a8644e919 100644 --- a/os/vfs/include/vfserrors.h +++ b/os/vfs/include/vfserrors.h @@ -92,8 +92,18 @@ /* Module macros. */ /*===========================================================================*/ -#define VFS_BREAK_ON_ERROR(err) \ - if ((err) < VFS_RET_SUCCESS) break +#define VFS_BREAK_ON_ERROR(err) do { \ + if ((err) < VFS_RET_SUCCESS) { \ + break; \ + } \ +} while (false) + +#define VFS_RETURN_ON_ERROR(err) do { \ + msg_t ret = (err); \ + if (ret < VFS_RET_SUCCESS) { \ + return ret; \ + } \ +} while (false) /*===========================================================================*/ /* External declarations. */ diff --git a/os/vfs/include/vfsparser.h b/os/vfs/include/vfsparser.h index 023748bb0..8582c0ff1 100644 --- a/os/vfs/include/vfsparser.h +++ b/os/vfs/include/vfsparser.h @@ -58,7 +58,6 @@ extern "C" { msg_t vfs_parse_match_separator(const char **pathp); msg_t vfs_parse_match_end(const char **pathp); msg_t vfs_parse_get_fname(const char **pathp, char *fname); - size_t vfs_parse_copy_with_separator(char *dst, const char *src); #ifdef __cplusplus } #endif diff --git a/os/vfs/include/vfspaths.h b/os/vfs/include/vfspaths.h new file mode 100644 index 000000000..b20a902b6 --- /dev/null +++ b/os/vfs/include/vfspaths.h @@ -0,0 +1,70 @@ +/* + 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/include/vfspaths.h + * @brief VFS path utilities header file. + * + * @addtogroup VFS_PATHS + * @{ + */ + +#ifndef VFSPATHS_H +#define VFSPATHS_H + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + size_t vfs_path_copy_with_separator(char *dst, const char *src); + msg_t vfs_path_append(char *dst, const char *src); +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +#endif /* VFSPATHS_H */ + +/** @} */ diff --git a/os/vfs/src/vfsparser.c b/os/vfs/src/vfsparser.c index 01871b2f2..11a1ac82f 100644 --- a/os/vfs/src/vfsparser.c +++ b/os/vfs/src/vfsparser.c @@ -136,46 +136,4 @@ msg_t vfs_parse_get_fname(const char **pathp, char *fname) { } } -/** - * @brief Copies a path into a destination buffer. - * @details Up to @p VFS_CFG_PATHLEN_MAX characters are copied. A path - * separator is added to the end of the path if not present. - * - * @param[out] dst The destination buffer. - * @param[in] src The source path. - * @return The copied path size not including the final - * zero. - * @retval 0 If the path size exceeded @p VFS_CFG_PATHLEN_MAX. - */ -size_t vfs_parse_copy_with_separator(char *dst, const char *src) { - size_t n = 0U; - char lc = '\0'; - - /* Copying the path.*/ - while ((*dst = *src) != '\0') { - - if (n > VFS_CFG_PATHLEN_MAX) { - return 0U; - } - - lc = *src++; - dst++; - n++; - } - - /* Checking if it is terminated by a separator, if not then adding it.*/ - if (lc != '/') { - - if (n >= VFS_CFG_PATHLEN_MAX) { - return 0U; - } - - *dst++ = '/'; - *dst = '\0'; - n++; - } - - return n; -} - /** @} */ diff --git a/os/vfs/src/vfspaths.c b/os/vfs/src/vfspaths.c new file mode 100644 index 000000000..288eb7f83 --- /dev/null +++ b/os/vfs/src/vfspaths.c @@ -0,0 +1,137 @@ +/* + 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/chpaths.c + * @brief VFS path utilities code. + * + * @addtogroup VFS_PATHS + * @{ + */ + +#include "vfs.h" + +/*===========================================================================*/ +/* Module local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported functions. */ +/*===========================================================================*/ + +/** + * @brief Copies a path into a destination buffer. + * @details Up to @p VFS_CFG_PATHLEN_MAX characters are copied. A path + * separator is added to the end of the path if not present. + * + * @param[out] dst The destination buffer. + * @param[in] src The source path. + * @return The copied path size not including the final + * zero. + * @retval 0 If the path size exceeded @p VFS_CFG_PATHLEN_MAX. + */ +size_t vfs_path_copy_with_separator(char *dst, const char *src) { + size_t n = 0U; + char lc = '\0'; + + /* Copying the path.*/ + while ((*dst = *src) != '\0') { + + if (n > VFS_CFG_PATHLEN_MAX) { + return 0U; + } + + lc = *src++; + dst++; + n++; + } + + /* Checking if it is terminated by a separator, if not then adding it.*/ + if (lc != '/') { + + if (n >= VFS_CFG_PATHLEN_MAX) { + return 0U; + } + + *dst++ = '/'; + *dst = '\0'; + n++; + } + + return n; +} + +msg_t vfs_path_append(char *dst, const char *src) { + size_t n; + + /* Current path length.*/ + n = strnlen(dst, VFS_CFG_PATHLEN_MAX); + if (n >= VFS_CFG_PATHLEN_MAX) { + return ENAMETOOLONG; + } + + /* Making sure to start with a separator in place.*/ + if (n == 0U) { + *dst++ = '/'; + n++; + } + else { + dst = dst + n; + if (*(dst - 1) != '/') { + *dst++ = '/'; + n++; + } + } + + /* The appended part needs to not begin with a separator.*/ + if (*src == '/') { + src++; + } + + /* Appending.*/ + while ((*dst++ = *src++) != '\0') { + n++; + + if (n > VFS_CFG_PATHLEN_MAX) { + return ENAMETOOLONG; + } + } + + *dst = '\0'; + + return VFS_RET_SUCCESS; +} + +/** @} */ diff --git a/os/vfs/vfs.mk b/os/vfs/vfs.mk index 185d2e8b9..a67ca80e4 100644 --- a/os/vfs/vfs.mk +++ b/os/vfs/vfs.mk @@ -1,5 +1,6 @@ # List of all the ChibiOS/VFS files. VFSSRC := $(CHIBIOS)/os/vfs/src/vfsparser.c \ + $(CHIBIOS)/os/vfs/src/vfspaths.c \ $(CHIBIOS)/os/vfs/src/vfsbuffers.c \ $(CHIBIOS)/os/vfs/src/vfs.c \ $(CHIBIOS)/os/vfs/drivers/sfs/drvsfs.c \