From 66057a461261f685ad64bf3094446999c9c94e61 Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Mon, 14 Sep 2020 01:15:05 +0800 Subject: [PATCH] fs: Add the relative path support all functions which accept the path argument should support the relative path: https://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html Signed-off-by: Xiang Xiao --- fs/dirent/fs_opendir.c | 8 ----- fs/inode/fs_inoderemove.c | 4 +-- fs/inode/fs_inodereserve.c | 4 +-- fs/inode/fs_inodesearch.c | 43 +++++++++++++++++++++++++-- fs/inode/inode.h | 61 ++++++++++++++------------------------ fs/mount/fs_automount.c | 4 +-- fs/vfs/fs_rename.c | 4 +-- fs/vfs/fs_symlink.c | 6 +--- 8 files changed, 70 insertions(+), 64 deletions(-) diff --git a/fs/dirent/fs_opendir.c b/fs/dirent/fs_opendir.c index 687cc12b7e..8e28e25d79 100644 --- a/fs/dirent/fs_opendir.c +++ b/fs/dirent/fs_opendir.c @@ -231,14 +231,6 @@ FAR DIR *opendir(FAR const char *path) goto errout; } - /* We don't know what to do with relative paths */ - - if (*path != '/') - { - ret = ENOTDIR; - goto errout_with_semaphore; - } - /* Find the node matching the path. */ ret = inode_search(&desc); diff --git a/fs/inode/fs_inoderemove.c b/fs/inode/fs_inoderemove.c index e11f7f8c75..8fa30a3a87 100644 --- a/fs/inode/fs_inoderemove.c +++ b/fs/inode/fs_inoderemove.c @@ -74,9 +74,9 @@ FAR struct inode *inode_unlink(FAR const char *path) FAR struct inode *node = NULL; int ret; - /* Verify parameters. Ignore null paths and relative paths */ + /* Verify parameters. Ignore null paths */ - if (path == NULL || path[0] != '/') + if (path == NULL) { return NULL; } diff --git a/fs/inode/fs_inodereserve.c b/fs/inode/fs_inodereserve.c index 3f2c789d42..e649297d51 100644 --- a/fs/inode/fs_inodereserve.c +++ b/fs/inode/fs_inodereserve.c @@ -182,9 +182,7 @@ int inode_reserve(FAR const char *path, FAR struct inode **inode) DEBUGASSERT(path != NULL && inode != NULL); *inode = NULL; - /* Handle paths that are interpreted as the root directory */ - - if (path[0] == '\0' || path[0] != '/') + if (path[0] == '\0') { return -EINVAL; } diff --git a/fs/inode/fs_inodesearch.c b/fs/inode/fs_inodesearch.c index cc2d167376..0eae73c0a4 100644 --- a/fs/inode/fs_inodesearch.c +++ b/fs/inode/fs_inodesearch.c @@ -42,6 +42,7 @@ #include #include +#include #include #include #include @@ -60,6 +61,7 @@ static int _inode_linktarget(FAR struct inode *node, FAR struct inode_search_s *desc); #endif static int _inode_search(FAR struct inode_search_s *desc); +static FAR const char *_inode_getcwd(void); /**************************************************************************** * Public Data @@ -405,8 +407,7 @@ static int _inode_search(FAR struct inode_search_s *desc) } } - /* The node may or may not be null as per one of the following four cases - * cases: + /* The node may or may not be null as per one of the following four cases: * * With node = NULL * @@ -430,6 +431,29 @@ static int _inode_search(FAR struct inode_search_s *desc) return ret; } +/**************************************************************************** + * Name: _inode_getcwd + * + * Description: + * Return the current working directory + * + ****************************************************************************/ + +static FAR const char *_inode_getcwd(void) +{ + FAR const char *pwd = ""; + +#ifndef CONFIG_DISABLE_ENVIRON + pwd = getenv("PWD"); + if (pwd == NULL) + { + pwd = CONFIG_LIB_HOMEDIR; + } +#endif + + return pwd; +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -467,7 +491,20 @@ int inode_search(FAR struct inode_search_s *desc) * node if node is a symbolic link. */ - DEBUGASSERT(desc != NULL); + DEBUGASSERT(desc != NULL && desc->path != NULL); + + /* Convert the relative path to the absolute path */ + + if (*desc->path != '/') + { + asprintf(&desc->buffer, "%s/%s", _inode_getcwd(), desc->path); + if (desc->buffer == NULL) + { + return -ENOMEM; + } + + desc->path = desc->buffer; + } ret = _inode_search(desc); diff --git a/fs/inode/inode.h b/fs/inode/inode.h index 75a74004e9..62a739f59b 100644 --- a/fs/inode/inode.h +++ b/fs/inode/inode.h @@ -40,44 +40,29 @@ * Pre-processor Definitions ****************************************************************************/ -#ifdef CONFIG_PSEUDOFS_SOFTLINKS +#define SETUP_SEARCH(d,p,n) \ + do \ + { \ + (d)->path = (p); \ + (d)->node = NULL; \ + (d)->peer = NULL; \ + (d)->parent = NULL; \ + (d)->relpath = NULL; \ + (d)->buffer = NULL; \ + (d)->nofollow = (n); \ + } \ + while (0) -# define SETUP_SEARCH(d,p,n) \ - do \ - { \ - (d)->path = (p); \ - (d)->node = NULL; \ - (d)->peer = NULL; \ - (d)->parent = NULL; \ - (d)->relpath = NULL; \ - (d)->buffer = NULL; \ - (d)->nofollow = (n); \ - } \ - while (0) - -# define RELEASE_SEARCH(d) \ - if ((d)->buffer != NULL) \ - { \ - kmm_free((d)->buffer); \ - (d)->buffer = NULL; \ - } - -#else - -# define SETUP_SEARCH(d,p,n) \ - do \ - { \ - (d)->path = (p); \ - (d)->node = NULL; \ - (d)->peer = NULL; \ - (d)->parent = NULL; \ - (d)->relpath = NULL; \ - } \ - while (0) - -# define RELEASE_SEARCH(d) - -#endif +#define RELEASE_SEARCH(d) \ + do \ + { \ + if ((d)->buffer != NULL) \ + { \ + kmm_free((d)->buffer); \ + (d)->buffer = NULL; \ + } \ + } \ + while (0) /**************************************************************************** * Public Types @@ -119,10 +104,8 @@ struct inode_search_s FAR struct inode *peer; /* Node to the "left" for the found inode */ FAR struct inode *parent; /* Node "above" the found inode */ FAR const char *relpath; /* Relative path into the mountpoint */ -#ifdef CONFIG_PSEUDOFS_SOFTLINKS FAR char *buffer; /* Path expansion buffer */ bool nofollow; /* true: Don't follow terminal soft link */ -#endif }; /* Callback used by foreach_inode to traverse all inodes in the pseudo- diff --git a/fs/mount/fs_automount.c b/fs/mount/fs_automount.c index 8a4c55913d..8da1f42c03 100644 --- a/fs/mount/fs_automount.c +++ b/fs/mount/fs_automount.c @@ -114,9 +114,9 @@ static int automount_findinode(FAR const char *path) struct inode_search_s desc; int ret; - /* Make sure that we were given an absolute path */ + /* Make sure that we were given a path */ - DEBUGASSERT(path != NULL && path[0] == '/'); + DEBUGASSERT(path != NULL); /* Get exclusive access to the in-memory inode tree. */ diff --git a/fs/vfs/fs_rename.c b/fs/vfs/fs_rename.c index 0007ada6e1..b95c4342cc 100644 --- a/fs/vfs/fs_rename.c +++ b/fs/vfs/fs_rename.c @@ -457,8 +457,8 @@ int rename(FAR const char *oldpath, FAR const char *newpath) * name and cannot be moved */ - if (!oldpath || *oldpath == '\0' || oldpath[0] != '/' || - !newpath || *newpath == '\0' || newpath[0] != '/') + if (!oldpath || *oldpath == '\0' || + !newpath || *newpath == '\0') { ret = -EINVAL; goto errout; diff --git a/fs/vfs/fs_symlink.c b/fs/vfs/fs_symlink.c index 558e86e30f..5897954631 100644 --- a/fs/vfs/fs_symlink.c +++ b/fs/vfs/fs_symlink.c @@ -79,11 +79,7 @@ int symlink(FAR const char *path1, FAR const char *path2) int errcode; int ret; - /* Both paths must be absolute. We need only check path1 here. path2 will - * be checked by inode find. - */ - - if (path1 == NULL || *path1 != '/') + if (path1 == NULL) { errcode = EINVAL; goto errout;