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 \