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 <xiaoxiang@xiaomi.com>
This commit is contained in:
Xiang Xiao 2020-09-14 01:15:05 +08:00 committed by David Sidrane
parent d0e0af7826
commit 66057a4612
8 changed files with 70 additions and 64 deletions

View File

@ -231,14 +231,6 @@ FAR DIR *opendir(FAR const char *path)
goto errout; 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. */ /* Find the node matching the path. */
ret = inode_search(&desc); ret = inode_search(&desc);

View File

@ -74,9 +74,9 @@ FAR struct inode *inode_unlink(FAR const char *path)
FAR struct inode *node = NULL; FAR struct inode *node = NULL;
int ret; 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; return NULL;
} }

View File

@ -182,9 +182,7 @@ int inode_reserve(FAR const char *path, FAR struct inode **inode)
DEBUGASSERT(path != NULL && inode != NULL); DEBUGASSERT(path != NULL && inode != NULL);
*inode = NULL; *inode = NULL;
/* Handle paths that are interpreted as the root directory */ if (path[0] == '\0')
if (path[0] == '\0' || path[0] != '/')
{ {
return -EINVAL; return -EINVAL;
} }

View File

@ -42,6 +42,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h>
#include <limits.h> #include <limits.h>
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
@ -60,6 +61,7 @@ static int _inode_linktarget(FAR struct inode *node,
FAR struct inode_search_s *desc); FAR struct inode_search_s *desc);
#endif #endif
static int _inode_search(FAR struct inode_search_s *desc); static int _inode_search(FAR struct inode_search_s *desc);
static FAR const char *_inode_getcwd(void);
/**************************************************************************** /****************************************************************************
* Public Data * 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 /* The node may or may not be null as per one of the following four cases:
* cases:
* *
* With node = NULL * With node = NULL
* *
@ -430,6 +431,29 @@ static int _inode_search(FAR struct inode_search_s *desc)
return ret; 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 * Public Functions
****************************************************************************/ ****************************************************************************/
@ -467,7 +491,20 @@ int inode_search(FAR struct inode_search_s *desc)
* node if node is a symbolic link. * 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); ret = _inode_search(desc);

View File

@ -40,9 +40,7 @@
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_PSEUDOFS_SOFTLINKS #define SETUP_SEARCH(d,p,n) \
# define SETUP_SEARCH(d,p,n) \
do \ do \
{ \ { \
(d)->path = (p); \ (d)->path = (p); \
@ -55,30 +53,17 @@
} \ } \
while (0) while (0)
# define RELEASE_SEARCH(d) \ #define RELEASE_SEARCH(d) \
do \
{ \
if ((d)->buffer != NULL) \ if ((d)->buffer != NULL) \
{ \ { \
kmm_free((d)->buffer); \ kmm_free((d)->buffer); \
(d)->buffer = NULL; \ (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) while (0)
# define RELEASE_SEARCH(d)
#endif
/**************************************************************************** /****************************************************************************
* Public Types * 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 *peer; /* Node to the "left" for the found inode */
FAR struct inode *parent; /* Node "above" the found inode */ FAR struct inode *parent; /* Node "above" the found inode */
FAR const char *relpath; /* Relative path into the mountpoint */ FAR const char *relpath; /* Relative path into the mountpoint */
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
FAR char *buffer; /* Path expansion buffer */ FAR char *buffer; /* Path expansion buffer */
bool nofollow; /* true: Don't follow terminal soft link */ bool nofollow; /* true: Don't follow terminal soft link */
#endif
}; };
/* Callback used by foreach_inode to traverse all inodes in the pseudo- /* Callback used by foreach_inode to traverse all inodes in the pseudo-

View File

@ -114,9 +114,9 @@ static int automount_findinode(FAR const char *path)
struct inode_search_s desc; struct inode_search_s desc;
int ret; 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. */ /* Get exclusive access to the in-memory inode tree. */

View File

@ -457,8 +457,8 @@ int rename(FAR const char *oldpath, FAR const char *newpath)
* name and cannot be moved * name and cannot be moved
*/ */
if (!oldpath || *oldpath == '\0' || oldpath[0] != '/' || if (!oldpath || *oldpath == '\0' ||
!newpath || *newpath == '\0' || newpath[0] != '/') !newpath || *newpath == '\0')
{ {
ret = -EINVAL; ret = -EINVAL;
goto errout; goto errout;

View File

@ -79,11 +79,7 @@ int symlink(FAR const char *path1, FAR const char *path2)
int errcode; int errcode;
int ret; int ret;
/* Both paths must be absolute. We need only check path1 here. path2 will if (path1 == NULL)
* be checked by inode find.
*/
if (path1 == NULL || *path1 != '/')
{ {
errcode = EINVAL; errcode = EINVAL;
goto errout; goto errout;