Soft links: Eliminate in-stack allocation of path working buffer needed for traversal fo paths with soft links.

This commit is contained in:
Gregory Nutt 2017-02-05 14:57:38 -06:00
parent 45fd98da88
commit 47ddfa346d
5 changed files with 90 additions and 24 deletions

View file

@ -8584,6 +8584,8 @@ int telldir(FAR DIR *dirp);
<ul><pre>
#include &lt;unistd.h&gt;
/* Task Control Interfaces */
pid_t vfork(void);
pid_t getpid(void);
void _exit(int status) noreturn_function;
@ -8591,6 +8593,8 @@ unsigned int sleep(unsigned int seconds);
void usleep(unsigned long usec);
int pause(void);
/* File descriptor operations */
int close(int fd);
int dup(int fd);
int dup2(int fd1, int fd2);
@ -8598,21 +8602,58 @@ int fsync(int fd);
off_t lseek(int fd, off_t offset, int whence);
ssize_t read(int fd, FAR void *buf, size_t nbytes);
ssize_t write(int fd, FAR const void *buf, size_t nbytes);
ssize_t pread(int fd, FAR void *buf, size_t nbytes, off_t offset);
ssize_t pwrite(int fd, FAR const void *buf, size_t nbytes, off_t offset);
/* Check if a file descriptor corresponds to a terminal I/O file */
int isatty(int fd);
/* Memory management */
#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_MM_PGALLOC) && \
defined(CONFIG_ARCH_USE_MMU)
FAR void *sbrk(intptr_t incr);
#endif
/* Special devices */
int pipe(int fd[2]);
/* Working directory operations */
int chdir(FAR const char *path);
FAR char *getcwd(FAR char *buf, size_t size);
int unlink(FAR const char *pathname);
/* File path operations */
int access(FAR const char *path, int amode);
int rmdir(FAR const char *pathname);
int unlink(FAR const char *pathname);
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
int link(FAR const char *path1, FAR const char *path2);
ssize_t readlink(FAR const char *path, FAR char *buf, size_t bufsize);
#endif
/* Execution of programs from files */
#ifdef CONFIG_LIBC_EXECFUNCS
int execl(FAR const char *path, ...);
int execv(FAR const char *path, FAR char *const argv[]);
#endif
/* Networking */
#ifdef CONFIG_NET
int gethostname(FAR char *name, size_t size);
int sethostname(FAR const char *name, size_t size);
#endif
/* Other */
int getopt(int argc, FAR char *const argv[], FAR const char *optstring);
</pre></ul>
</a>

View file

@ -43,7 +43,7 @@ config DISABLE_PSEUDOFS_OPERATIONS
config PSEUDOFS_SOFTLINKS
bool "Pseudo-filesystem soft links"
default n
depends on !DISABLE_PSEUDOFS_OPERATIONSi && EXPERIMENTAL
depends on !DISABLE_PSEUDOFS_OPERATIONS
---help---
Enable support for soft links in the pseudeo file system. Soft
links are not supported within mounted volumes by any NuttX file

View file

@ -515,6 +515,8 @@ int inode_search(FAR struct inode_search_s *desc)
if (desc->linktgt != NULL && INODE_IS_MOUNTPT(node))
{
FAR char *buffer;
/* There would be no problem in this case if the link was to
* either to the root directory of the MOUNTPOINT or to a
* regular file within the the mounted volume. However,
@ -530,21 +532,30 @@ int inode_search(FAR struct inode_search_s *desc)
if (desc->relpath != NULL && *desc->relpath != '\0')
{
snprintf(desc->fullpath, PATH_MAX, "%s/%s",
(void)asprintf(&buffer, "%s/%s",
desc->linktgt, desc->relpath);
}
else
{
strncpy(desc->fullpath, desc->linktgt, PATH_MAX);
buffer = strdup(desc->linktgt);
}
if (buffer == NULL)
{
ret = -ENOMEM;
}
else
{
/* Reset the search description and perform the search again. */
RELEASE_SEARCH(desc);
SETUP_SEARCH(desc, desc->fullpath, false);
SETUP_SEARCH(desc, buffer, false);
desc->buffer = buffer;
ret = _inode_search(desc);
}
}
}
#endif
return ret;

View file

@ -48,6 +48,7 @@
#include <stdbool.h>
#include <dirent.h>
#include <nuttx/kmalloc.h>
#include <nuttx/fs/fs.h>
/****************************************************************************
@ -55,6 +56,7 @@
****************************************************************************/
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
# define SETUP_SEARCH(d,p,n) \
do \
{ \
@ -64,10 +66,20 @@
(d)->parent = NULL; \
(d)->relpath = NULL; \
(d)->linktgt = 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 \
{ \
@ -78,9 +90,10 @@
(d)->relpath = NULL; \
} \
while (0)
#endif
#define RELEASE_SEARCH(d)
# define RELEASE_SEARCH(d)
#endif
/****************************************************************************
* Public Types
@ -109,9 +122,10 @@
* terminal is a soft link, then return the inode of
* the link target.
* - OUTPUT: (not used)
* fullpath - INPUT: Not used
* - OUTPUT: May hold an intermediate path which is probably of
* no interest to the caller.
* buffer - INPUT: Not used
* - OUTPUT: May hold an allocated intermediate path which is
* probably of no interest to the caller unless it holds
* the relpath.
*/
struct inode_search_s
@ -123,8 +137,8 @@ struct inode_search_s
FAR const char *relpath; /* Relative path into the mountpoint */
#ifdef CONFIG_PSEUDOFS_SOFTLINKS
FAR const char *linktgt; /* Target of symbolic link if linked to a directory */
FAR char *buffer; /* Path expansion buffer */
bool nofollow; /* true: Don't follow terminal soft link */
char fullpath[PATH_MAX]; /* Path expansion buffer */
#endif
};