1
0
Fork 0
forked from nuttx/nuttx-update

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

@ -479,14 +479,14 @@ int task_delete(pid_t pid);
<p> <p>
<b>Description:</b> <b>Description:</b>
This function causes a specified task to cease to exist. This function causes a specified task to cease to exist.
Its stack and TCB will be deallocated. Its stack and TCB will be deallocated.
This function is the companion to <code>task_create()</code>. This function is the companion to <code>task_create()</code>.
This is the version of the function exposed to the user; This is the version of the function exposed to the user;
it is simply a wrapper around the internal, <code>task_terminate()</code> function. it is simply a wrapper around the internal, <code>task_terminate()</code> function.
</p> </p>
<p> <p>
The logic in this function only deletes non-running tasks. The logic in this function only deletes non-running tasks.
If the <code>pid</code> parameter refers to to the currently runing task, then processing is redirected to <code>exit()</code>. If the <code>pid</code> parameter refers to to the currently runing task, then processing is redirected to <code>exit()</code>.
This can only happen if a task calls <code>task_delete()</code> in order to delete itself. This can only happen if a task calls <code>task_delete()</code> in order to delete itself.
</p> </p>
<p> <p>
@ -6223,7 +6223,7 @@ interface of the same name.
<b>Description:</b> <b>Description:</b>
<p>The <code>pthread_cancel()</code> function will request that thread be canceled. <p>The <code>pthread_cancel()</code> function will request that thread be canceled.
The target thread's cancelability state, enabled, or disabled, determines when the cancellation takes effect: When the cancellation is acted on, thread will be terminated. The target thread's cancelability state, enabled, or disabled, determines when the cancellation takes effect: When the cancellation is acted on, thread will be terminated.
When cancelability is disabled, all cancellations are held pending in the target thread until the thread re-enables cancelability.</p> When cancelability is disabled, all cancellations are held pending in the target thread until the thread re-enables cancelability.</p>
<p>The target thread's cancelability state determines how the cancellation is acted on: <p>The target thread's cancelability state determines how the cancellation is acted on:
@ -6592,16 +6592,16 @@ interface of the same name.
</p> </p>
<ul> <ul>
<li><code>sched_ss_low_priority</code> <li><code>sched_ss_low_priority</code>
Low scheduling priority for sporadic server. Low scheduling priority for sporadic server.
</li> </li>
<li><code>sched_ss_repl_period</code> <li><code>sched_ss_repl_period</code>
Replenishment period for sporadic server. Replenishment period for sporadic server.
</li> </li>
<li><code>sched_ss_init_budget</code> <li><code>sched_ss_init_budget</code>
Initial budget for sporadic server. Initial budget for sporadic server.
</li> </li>
<li><code>sched_ss_max_repl</code> <li><code>sched_ss_max_repl</code>
Maximum pending replenishments for sporadic server. Maximum pending replenishments for sporadic server.
</li> </li>
</ul> </ul>
<p> <p>
@ -8584,6 +8584,8 @@ int telldir(FAR DIR *dirp);
<ul><pre> <ul><pre>
#include &lt;unistd.h&gt; #include &lt;unistd.h&gt;
/* Task Control Interfaces */
pid_t vfork(void); pid_t vfork(void);
pid_t getpid(void); pid_t getpid(void);
void _exit(int status) noreturn_function; void _exit(int status) noreturn_function;
@ -8591,6 +8593,8 @@ unsigned int sleep(unsigned int seconds);
void usleep(unsigned long usec); void usleep(unsigned long usec);
int pause(void); int pause(void);
/* File descriptor operations */
int close(int fd); int close(int fd);
int dup(int fd); int dup(int fd);
int dup2(int fd1, int fd2); int dup2(int fd1, int fd2);
@ -8598,21 +8602,58 @@ int fsync(int fd);
off_t lseek(int fd, off_t offset, int whence); off_t lseek(int fd, off_t offset, int whence);
ssize_t read(int fd, FAR void *buf, size_t nbytes); 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 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]); int pipe(int fd[2]);
/* Working directory operations */
int chdir(FAR const char *path); int chdir(FAR const char *path);
FAR char *getcwd(FAR char *buf, size_t size); 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 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 #ifdef CONFIG_LIBC_EXECFUNCS
int execl(FAR const char *path, ...); int execl(FAR const char *path, ...);
int execv(FAR const char *path, FAR char *const argv[]); int execv(FAR const char *path, FAR char *const argv[]);
#endif #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); int getopt(int argc, FAR char *const argv[], FAR const char *optstring);
</pre></ul> </pre></ul>
</a> </a>

View file

@ -43,7 +43,7 @@ config DISABLE_PSEUDOFS_OPERATIONS
config PSEUDOFS_SOFTLINKS config PSEUDOFS_SOFTLINKS
bool "Pseudo-filesystem soft links" bool "Pseudo-filesystem soft links"
default n default n
depends on !DISABLE_PSEUDOFS_OPERATIONSi && EXPERIMENTAL depends on !DISABLE_PSEUDOFS_OPERATIONS
---help--- ---help---
Enable support for soft links in the pseudeo file system. Soft Enable support for soft links in the pseudeo file system. Soft
links are not supported within mounted volumes by any NuttX file 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)) if (desc->linktgt != NULL && INODE_IS_MOUNTPT(node))
{ {
FAR char *buffer;
/* There would be no problem in this case if the link was to /* There would be no problem in this case if the link was to
* either to the root directory of the MOUNTPOINT or to a * either to the root directory of the MOUNTPOINT or to a
* regular file within the the mounted volume. However, * regular file within the the mounted volume. However,
@ -530,19 +532,28 @@ int inode_search(FAR struct inode_search_s *desc)
if (desc->relpath != NULL && *desc->relpath != '\0') if (desc->relpath != NULL && *desc->relpath != '\0')
{ {
snprintf(desc->fullpath, PATH_MAX, "%s/%s", (void)asprintf(&buffer, "%s/%s",
desc->linktgt, desc->relpath); desc->linktgt, desc->relpath);
} }
else else
{ {
strncpy(desc->fullpath, desc->linktgt, PATH_MAX); buffer = strdup(desc->linktgt);
} }
/* Reset the search description and perform the search again. */ if (buffer == NULL)
{
ret = -ENOMEM;
}
else
{
/* Reset the search description and perform the search again. */
RELEASE_SEARCH(desc); RELEASE_SEARCH(desc);
SETUP_SEARCH(desc, desc->fullpath, false); SETUP_SEARCH(desc, buffer, false);
ret = _inode_search(desc); desc->buffer = buffer;
ret = _inode_search(desc);
}
} }
} }
#endif #endif

View file

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

View file

@ -115,9 +115,9 @@ FAR sem_t *sem_open (FAR const char *name, int oflags, ...)
/* Make sure that a non-NULL name is supplied */ /* Make sure that a non-NULL name is supplied */
DEBUGASSERT(name != NULL); DEBUGASSERT(name != NULL);
/* The POSIX specification requires that the "check for the existence /* The POSIX specification requires that the "check for the existence
* of a semaphore and the creation of the semaphore if it does not * of a semaphore and the creation of the semaphore if it does not
* exist shall be atomic with respect to other processes executing * exist shall be atomic with respect to other processes executing
* sem_open()..." A simple sched_lock() should be sufficient to meet * sem_open()..." A simple sched_lock() should be sufficient to meet
* this requirement. * this requirement.