Soft links: Eliminate in-stack allocation of path working buffer needed for traversal fo paths with soft links.
This commit is contained in:
parent
45fd98da88
commit
47ddfa346d
5 changed files with 90 additions and 24 deletions
|
@ -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 <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
/* 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>
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in a new issue