diff --git a/os/vfs/drivers/overlay/drvoverlay.c b/os/vfs/drivers/overlay/drvoverlay.c index ac1545693..2a1dfc9bf 100644 --- a/os/vfs/drivers/overlay/drvoverlay.c +++ b/os/vfs/drivers/overlay/drvoverlay.c @@ -45,6 +45,8 @@ /* Module local variables. */ /*===========================================================================*/ +static msg_t drv_set_cwd(void *instance, const char *path); +static msg_t drv_get_cwd(void *instance, char *buf, size_t size); static msg_t drv_open_dir(void *instance, const char *path, vfs_directory_node_c **vdnpp); @@ -54,6 +56,8 @@ static msg_t drv_open_file(void *instance, vfs_file_node_c **vfnpp); static const struct vfs_overlay_driver_vmt driver_vmt = { + .set_cwd = drv_set_cwd, + .get_cwd = drv_get_cwd, .open_dir = drv_open_dir, .open_file = drv_open_file }; @@ -115,6 +119,17 @@ static msg_t match_driver(vfs_overlay_driver_c *odp, return err; } +static const char *get_current_directory(vfs_overlay_driver_c *drvp) { + const char *cwd = drvp->path_cwd; + + /* In case it has not yet been defined using root.*/ + if (cwd == NULL) { + return "/"; + } + + return cwd; +} + static msg_t build_path(vfs_overlay_driver_c *drvp, const char *path, char *buf) { @@ -126,11 +141,38 @@ static msg_t build_path(vfs_overlay_driver_c *drvp, VFS_RETURN_ON_ERROR(vfs_path_append(buf, drvp->path_prefix)); } + /* If it is a relative path then we need to consider the current directory.*/ + if (!vfs_parse_is_separator(*path)) { + + /* Adding the current directory, note, it is already a normalized + path, no need to re-normalize.*/ + VFS_RETURN_ON_ERROR(vfs_path_append(buf, get_current_directory(drvp))); + } + + /* Finally adding the path requested by the user.*/ VFS_RETURN_ON_ERROR(vfs_path_append(buf, path)); return VFS_RET_SUCCESS; } +static msg_t drv_set_cwd(void *instance, const char *path) { + + (void) instance; + (void) path; + + return VFS_RET_NOT_IMPLEMENTED; +} + +static msg_t drv_get_cwd(void *instance, char *buf, size_t size) { + + (void) instance; + (void) size; + + strcpy(buf, "/"); + + return VFS_RET_SUCCESS; +} + static msg_t drv_open_dir(void *instance, const char *path, vfs_directory_node_c **vdnpp) { @@ -363,6 +405,7 @@ vfs_driver_c *drvOverlayObjectInit(vfs_overlay_driver_c *vodp, vodp->rootname = rootname; vodp->overlaid_drv = overlaid_drv; vodp->path_prefix = path_prefix; + vodp->path_cwd = NULL; vodp->next_driver = 0U; return (vfs_driver_c *)vodp; diff --git a/os/vfs/drivers/overlay/drvoverlay.h b/os/vfs/drivers/overlay/drvoverlay.h index 6ae95fbdc..0eb0cf1ce 100644 --- a/os/vfs/drivers/overlay/drvoverlay.h +++ b/os/vfs/drivers/overlay/drvoverlay.h @@ -111,6 +111,8 @@ typedef struct vfs_overlay_dir_node { vfs_driver_c *overlaid_drv; \ /* Path prefix for the overlaid driver or NULL.*/ \ const char *path_prefix ; \ + /* Current directory or NULL.*/ \ + const char *path_cwd; \ /* Next registration slot.*/ \ unsigned next_driver; \ /* Registration slots.*/ \ diff --git a/os/vfs/include/vfsdrivers.h b/os/vfs/include/vfsdrivers.h index 542f8da74..580cd6cc5 100644 --- a/os/vfs/include/vfsdrivers.h +++ b/os/vfs/include/vfsdrivers.h @@ -67,6 +67,8 @@ */ #define __vfs_driver_methods \ __base_object_methods \ + msg_t (*set_cwd)(void *instance, const char *path); \ + msg_t (*get_cwd)(void *instance, char *buf, size_t size); \ msg_t (*open_dir)(void *instance, \ const char *path, \ vfs_directory_node_c **vdnpp); \ diff --git a/os/vfs/include/vfserrors.h b/os/vfs/include/vfserrors.h index a8644e919..e4efc7344 100644 --- a/os/vfs/include/vfserrors.h +++ b/os/vfs/include/vfserrors.h @@ -38,21 +38,6 @@ * @name Error codes compatible with HAL and Posix * @{ */ -#if 0 -#define VFS_RET_SUCCESS 0 -#define VFS_RET_TIMEOUT -1 -#define VFS_RET_EOF -2 -#define VFS_RET_NOT_IMPLEMENTED -3 -#define VFS_RET_NO_RESOURCE -4 -#define VFS_RET_NO_DRIVER -5 -#define VFS_RET_INVALID_PATH -6 -#define VFS_RET_NOT_FOUND -7 -#define VFS_RET_EXIST -8 -#define VFS_RET_ACCESS_DENIED -9 -#define VFS_RET_MEDIA_ERROR -10 -#define VFS_RET_INNER_ERROR -11 -#define VFS_RET_INVALID_MODE -12 -#endif #define VFS_RET_SUCCESS 0 /* Success */ #define VFS_RET_TIMEOUT -1 /* Timeout */ #define VFS_RET_EOF -2 /* End-of-file */