You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2023/04/27 09:36:05 UTC
[nuttx] 01/02: sched/spawn: remove spawn proxy thread to simplify task/posix_spawn()
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 507c8145a9ecb2a575700dc3f1580e2a1f7895f7
Author: chao an <an...@xiaomi.com>
AuthorDate: Wed Apr 26 11:44:08 2023 +0800
sched/spawn: remove spawn proxy thread to simplify task/posix_spawn()
The spawn proxy thread is a special existence in NuttX, usually some developers
spend a lot of time on stack overflow of spawn proxy thread:
https://github.com/apache/nuttx/issues/9046
https://github.com/apache/nuttx/pull/9081
In order to avoid similar issues, this PR will remove spawn proxy thread to simplify
the process of task/posix_spawn().
1. Postpone the related processing of spawn file actions until after task_init()
2. Delete the temporary thread of spawn proxy and related global variables
Signed-off-by: chao an <an...@xiaomi.com>
---
binfmt/binfmt_exec.c | 8 +-
binfmt/binfmt_execmodule.c | 17 ++-
drivers/serial/serial.c | 3 +-
fs/inode/fs_files.c | 123 ++++++++++++----
fs/vfs/fs_open.c | 50 ++++++-
include/nuttx/binfmt/binfmt.h | 7 +-
include/nuttx/fs/fs.h | 91 +++++++++++-
include/nuttx/sched.h | 34 +++++
include/nuttx/spawn.h | 3 +
sched/init/nx_bringup.c | 2 +-
sched/sched/sched_getfiles.c | 32 ++++-
sched/task/spawn.h | 57 +-------
sched/task/task_posixspawn.c | 200 ++------------------------
sched/task/task_spawn.c | 317 ++++++++++++++----------------------------
sched/task/task_spawnparms.c | 145 ++++++++-----------
15 files changed, 491 insertions(+), 598 deletions(-)
diff --git a/binfmt/binfmt_exec.c b/binfmt/binfmt_exec.c
index ab361d5887..2d281b6dce 100644
--- a/binfmt/binfmt_exec.c
+++ b/binfmt/binfmt_exec.c
@@ -62,6 +62,7 @@
* exported by the caller and made available for linking the
* module into the system.
* nexports - The number of symbols in the exports table.
+ * actions - The spawn file actions
* attr - The spawn attributes.
*
* Returned Value:
@@ -72,7 +73,8 @@
int exec_spawn(FAR const char *filename, FAR char * const *argv,
FAR char * const *envp, FAR const struct symtab_s *exports,
- int nexports, FAR const posix_spawnattr_t *attr)
+ int nexports, FAR const posix_spawn_file_actions_t *actions,
+ FAR const posix_spawnattr_t *attr)
{
FAR struct binary_s *bin;
int pid;
@@ -128,7 +130,7 @@ int exec_spawn(FAR const char *filename, FAR char * const *argv,
/* Then start the module */
- pid = exec_module(bin, filename, argv, envp);
+ pid = exec_module(bin, filename, argv, envp, actions);
if (pid < 0)
{
ret = pid;
@@ -239,7 +241,7 @@ int exec(FAR const char *filename, FAR char * const *argv,
{
int ret;
- ret = exec_spawn(filename, argv, envp, exports, nexports, NULL);
+ ret = exec_spawn(filename, argv, envp, exports, nexports, NULL, NULL);
if (ret < 0)
{
set_errno(-ret);
diff --git a/binfmt/binfmt_execmodule.c b/binfmt/binfmt_execmodule.c
index 8beea49cdd..6e6b26649d 100644
--- a/binfmt/binfmt_execmodule.c
+++ b/binfmt/binfmt_execmodule.c
@@ -35,6 +35,7 @@
#include <nuttx/arch.h>
#include <nuttx/kmalloc.h>
#include <nuttx/sched.h>
+#include <nuttx/spawn.h>
#include <nuttx/binfmt/binfmt.h>
#include "binfmt.h"
@@ -113,7 +114,8 @@ static void exec_ctors(FAR void *arg)
int exec_module(FAR struct binary_s *binp,
FAR const char *filename, FAR char * const *argv,
- FAR char * const *envp)
+ FAR char * const *envp,
+ FAR const posix_spawn_file_actions_t *actions)
{
FAR struct task_tcb_s *tcb;
#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_BUILD_KERNEL)
@@ -216,6 +218,17 @@ int exec_module(FAR struct binary_s *binp,
binfmt_freeargv(argv);
binfmt_freeenv(envp);
+ /* Perform file actions */
+
+ if (actions != NULL)
+ {
+ ret = spawn_file_actions(&tcb->cmn, actions);
+ if (ret < 0)
+ {
+ goto errout_with_tcbinit;
+ }
+ }
+
#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_ARCH_KERNEL_STACK)
/* Allocate the kernel stack */
@@ -283,7 +296,6 @@ int exec_module(FAR struct binary_s *binp,
return (int)pid;
-#if defined(CONFIG_ARCH_ADDRENV) || defined(CONFIG_ARCH_VMA_MAPPING)
errout_with_tcbinit:
#ifndef CONFIG_BUILD_KERNEL
if (binp->stackaddr != NULL)
@@ -294,7 +306,6 @@ errout_with_tcbinit:
nxtask_uninit(tcb);
return ret;
-#endif
errout_with_addrenv:
#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_BUILD_KERNEL)
diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c
index dea33b0a79..f97ea696c9 100644
--- a/drivers/serial/serial.c
+++ b/drivers/serial/serial.c
@@ -1750,7 +1750,8 @@ static void uart_launch_worker(void *arg)
CONFIG_TTY_LAUNCH_ENTRYPOINT,
NULL, &attr, argv, NULL);
#else
- exec_spawn(CONFIG_TTY_LAUNCH_FILEPATH, argv, NULL, NULL, 0, &attr);
+ exec_spawn(CONFIG_TTY_LAUNCH_FILEPATH,
+ argv, NULL, NULL, 0, NULL, &attr);
#endif
posix_spawnattr_destroy(&attr);
}
diff --git a/fs/inode/fs_files.c b/fs/inode/fs_files.c
index e38662b777..1f91b5e51e 100644
--- a/fs/inode/fs_files.c
+++ b/fs/inode/fs_files.c
@@ -185,7 +185,7 @@ void files_releaselist(FAR struct filelist *list)
}
/****************************************************************************
- * Name: file_allocate
+ * Name: file_allocate_from_tcb
*
* Description:
* Allocate a struct files instance and associate it with an inode
@@ -197,8 +197,9 @@ void files_releaselist(FAR struct filelist *list)
*
****************************************************************************/
-int file_allocate(FAR struct inode *inode, int oflags, off_t pos,
- FAR void *priv, int minfd, bool addref)
+int file_allocate_from_tcb(FAR struct tcb_s *tcb, FAR struct inode *inode,
+ int oflags, off_t pos, FAR void *priv, int minfd,
+ bool addref)
{
FAR struct filelist *list;
int ret;
@@ -207,7 +208,7 @@ int file_allocate(FAR struct inode *inode, int oflags, off_t pos,
/* Get the file descriptor list. It should not be NULL in this context. */
- list = nxsched_get_files();
+ list = nxsched_get_files_from_tcb(tcb);
DEBUGASSERT(list != NULL);
ret = nxmutex_lock(&list->fl_lock);
@@ -285,6 +286,26 @@ int file_allocate(FAR struct inode *inode, int oflags, off_t pos,
return i * CONFIG_NFILE_DESCRIPTORS_PER_BLOCK;
}
+/****************************************************************************
+ * Name: file_allocate
+ *
+ * Description:
+ * Allocate a struct files instance and associate it with an inode
+ * instance.
+ *
+ * Returned Value:
+ * Returns the file descriptor == index into the files array on success;
+ * a negated errno value is returned on any failure.
+ *
+ ****************************************************************************/
+
+int file_allocate(FAR struct inode *inode, int oflags, off_t pos,
+ FAR void *priv, int minfd, bool addref)
+{
+ return file_allocate_from_tcb(nxsched_self(), inode, oflags,
+ pos, priv, minfd, addref);
+}
+
/****************************************************************************
* Name: files_duplist
*
@@ -432,14 +453,15 @@ int fs_getfilep(int fd, FAR struct file **filep)
}
/****************************************************************************
- * Name: nx_dup2
+ * Name: nx_dup2_from_tcb
*
* Description:
- * nx_dup2() is similar to the standard 'dup2' interface except that is
- * not a cancellation point and it does not modify the errno variable.
+ * nx_dup2_from_tcb() is similar to the standard 'dup2' interface
+ * except that is not a cancellation point and it does not modify the
+ * errno variable.
*
- * nx_dup2() is an internal NuttX interface and should not be called from
- * applications.
+ * nx_dup2_from_tcb() is an internal NuttX interface and should not be
+ * called from applications.
*
* Clone a file descriptor to a specific descriptor number.
*
@@ -449,11 +471,11 @@ int fs_getfilep(int fd, FAR struct file **filep)
*
****************************************************************************/
-int nx_dup2(int fd1, int fd2)
+int nx_dup2_from_tcb(FAR struct tcb_s *tcb, int fd1, int fd2)
{
FAR struct filelist *list;
- FAR struct file *filep;
- FAR struct file file;
+ FAR struct file *filep;
+ FAR struct file file;
int ret;
if (fd1 == fd2)
@@ -461,10 +483,9 @@ int nx_dup2(int fd1, int fd2)
return fd1;
}
- /* Get the file descriptor list. It should not be NULL in this context. */
+ list = nxsched_get_files_from_tcb(tcb);
- list = nxsched_get_files();
- DEBUGASSERT(list != NULL);
+ /* Get the file descriptor list. It should not be NULL in this context. */
if (fd1 < 0 || fd1 >= CONFIG_NFILE_DESCRIPTORS_PER_BLOCK * list->fl_rows ||
fd2 < 0)
@@ -506,6 +527,29 @@ int nx_dup2(int fd1, int fd2)
return ret < 0 ? ret : fd2;
}
+/****************************************************************************
+ * Name: nx_dup2
+ *
+ * Description:
+ * nx_dup2() is similar to the standard 'dup2' interface except that is
+ * not a cancellation point and it does not modify the errno variable.
+ *
+ * nx_dup2() is an internal NuttX interface and should not be called from
+ * applications.
+ *
+ * Clone a file descriptor to a specific descriptor number.
+ *
+ * Returned Value:
+ * fd2 is returned on success; a negated errno value is return on
+ * any failure.
+ *
+ ****************************************************************************/
+
+int nx_dup2(int fd1, int fd2)
+{
+ return nx_dup2_from_tcb(nxsched_self(), fd1, fd2);
+}
+
/****************************************************************************
* Name: dup2
*
@@ -530,14 +574,15 @@ int dup2(int fd1, int fd2)
}
/****************************************************************************
- * Name: nx_close
+ * Name: nx_close_from_tcb
*
* Description:
- * nx_close() is similar to the standard 'close' interface except that is
- * not a cancellation point and it does not modify the errno variable.
+ * nx_close_from_tcb() is similar to the standard 'close' interface
+ * except that is not a cancellation point and it does not modify the
+ * errno variable.
*
- * nx_close() is an internal NuttX interface and should not be called from
- * applications.
+ * nx_close_from_tcb() is an internal NuttX interface and should not
+ * be called from applications.
*
* Close an inode (if open)
*
@@ -551,19 +596,14 @@ int dup2(int fd1, int fd2)
*
****************************************************************************/
-int nx_close(int fd)
+int nx_close_from_tcb(FAR struct tcb_s *tcb, int fd)
{
- FAR struct filelist *list;
FAR struct file *filep;
FAR struct file file;
+ FAR struct filelist *list;
int ret;
- /* Get the thread-specific file list. It should never be NULL in this
- * context.
- */
-
- list = nxsched_get_files();
- DEBUGASSERT(list != NULL);
+ list = nxsched_get_files_from_tcb(tcb);
/* Perform the protected close operation */
@@ -592,6 +632,33 @@ int nx_close(int fd)
return file_close(&file);
}
+/****************************************************************************
+ * Name: nx_close
+ *
+ * Description:
+ * nx_close() is similar to the standard 'close' interface except that is
+ * not a cancellation point and it does not modify the errno variable.
+ *
+ * nx_close() is an internal NuttX interface and should not be called from
+ * applications.
+ *
+ * Close an inode (if open)
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success; A negated errno value is returned on
+ * on any failure.
+ *
+ * Assumptions:
+ * Caller holds the list mutex because the file descriptor will be
+ * freed.
+ *
+ ****************************************************************************/
+
+int nx_close(int fd)
+{
+ return nx_close_from_tcb(nxsched_self(), fd);
+}
+
/****************************************************************************
* Name: close
*
diff --git a/fs/vfs/fs_open.c b/fs/vfs/fs_open.c
index 014eed9b75..44e344adf4 100644
--- a/fs/vfs/fs_open.c
+++ b/fs/vfs/fs_open.c
@@ -224,6 +224,7 @@ errout_with_search:
* applications.
*
* Input Parameters:
+ * tcb - Address of the task's TCB
* path - The full path to the file to be opened.
* oflags - open flags.
* ap - Variable argument list, may include 'mode_t mode'
@@ -234,7 +235,8 @@ errout_with_search:
*
****************************************************************************/
-static int nx_vopen(FAR const char *path, int oflags, va_list ap)
+static int nx_vopen(FAR struct tcb_s *tcb,
+ FAR const char *path, int oflags, va_list ap)
{
struct file filep;
int ret;
@@ -250,8 +252,8 @@ static int nx_vopen(FAR const char *path, int oflags, va_list ap)
/* Allocate a new file descriptor for the inode */
- fd = file_allocate(filep.f_inode, filep.f_oflags,
- filep.f_pos, filep.f_priv, 0, false);
+ fd = file_allocate_from_tcb(tcb, filep.f_inode, filep.f_oflags,
+ filep.f_pos, filep.f_priv, 0, false);
if (fd < 0)
{
file_close(&filep);
@@ -341,6 +343,44 @@ int file_open(FAR struct file *filep, FAR const char *path, int oflags, ...)
return ret;
}
+/****************************************************************************
+ * Name: nx_open_from_tcb
+ *
+ * Description:
+ * nx_open_from_tcb() is similar to the standard 'open' interface except
+ * that it is not a cancellation point and it does not modify the errno
+ * variable.
+ *
+ * nx_open_from_tcb() is an internal NuttX interface and should not be
+ * called from applications.
+ *
+ * Input Parameters:
+ * tcb - Address of the task's TCB
+ * path - The full path to the file to be opened.
+ * oflags - open flags.
+ * ... - Variable number of arguments, may include 'mode_t mode'
+ *
+ * Returned Value:
+ * The new file descriptor is returned on success; a negated errno value is
+ * returned on any failure.
+ *
+ ****************************************************************************/
+
+int nx_open_from_tcb(FAR struct tcb_s *tcb,
+ FAR const char *path, int oflags, ...)
+{
+ va_list ap;
+ int fd;
+
+ /* Let nx_vopen() do all of the work */
+
+ va_start(ap, oflags);
+ fd = nx_vopen(tcb, path, oflags, ap);
+ va_end(ap);
+
+ return fd;
+}
+
/****************************************************************************
* Name: nx_open
*
@@ -370,7 +410,7 @@ int nx_open(FAR const char *path, int oflags, ...)
/* Let nx_vopen() do all of the work */
va_start(ap, oflags);
- fd = nx_vopen(path, oflags, ap);
+ fd = nx_vopen(nxsched_self(), path, oflags, ap);
va_end(ap);
return fd;
@@ -400,7 +440,7 @@ int open(FAR const char *path, int oflags, ...)
/* Let nx_vopen() do most of the work */
va_start(ap, oflags);
- fd = nx_vopen(path, oflags, ap);
+ fd = nx_vopen(nxsched_self(), path, oflags, ap);
va_end(ap);
/* Set the errno value if any errors were reported by nx_open() */
diff --git a/include/nuttx/binfmt/binfmt.h b/include/nuttx/binfmt/binfmt.h
index e1b8e18157..1da05b65c9 100644
--- a/include/nuttx/binfmt/binfmt.h
+++ b/include/nuttx/binfmt/binfmt.h
@@ -264,7 +264,8 @@ int unload_module(FAR struct binary_s *bin);
int exec_module(FAR struct binary_s *binp,
FAR const char *filename, FAR char * const *argv,
- FAR char * const *envp);
+ FAR char * const *envp,
+ FAR const posix_spawn_file_actions_t *actions);
/****************************************************************************
* Name: exec
@@ -355,6 +356,7 @@ int exec(FAR const char *filename, FAR char * const *argv,
* exported by the caller and made available for linking the
* module into the system.
* nexports - The number of symbols in the exports table.
+ * actions - The spawn file actions
* attr - The spawn attributes.
*
* Returned Value:
@@ -366,7 +368,8 @@ int exec(FAR const char *filename, FAR char * const *argv,
int exec_spawn(FAR const char *filename, FAR char * const *argv,
FAR char * const *envp, FAR const struct symtab_s *exports,
- int nexports, FAR const posix_spawnattr_t *attr);
+ int nexports, FAR const posix_spawn_file_actions_t *actions,
+ FAR const posix_spawnattr_t *attr);
/****************************************************************************
* Name: binfmt_exit
diff --git a/include/nuttx/fs/fs.h b/include/nuttx/fs/fs.h
index 5d36568066..d2db19e987 100644
--- a/include/nuttx/fs/fs.h
+++ b/include/nuttx/fs/fs.h
@@ -170,6 +170,7 @@ struct stat;
struct statfs;
struct pollfd;
struct mtd_dev_s;
+struct tcb_s;
/* The internal representation of type DIR is just a container for an inode
* reference, and the path of directory.
@@ -785,6 +786,23 @@ void files_releaselist(FAR struct filelist *list);
int files_duplist(FAR struct filelist *plist, FAR struct filelist *clist);
+/****************************************************************************
+ * Name: file_allocate_from_tcb
+ *
+ * Description:
+ * Allocate a struct files instance and associate it with an inode
+ * instance.
+ *
+ * Returned Value:
+ * Returns the file descriptor == index into the files array on success;
+ * a negated errno value is returned on any failure.
+ *
+ ****************************************************************************/
+
+int file_allocate_from_tcb(FAR struct tcb_s *tcb, FAR struct inode *inode,
+ int oflags, off_t pos, FAR void *priv, int minfd,
+ bool addref);
+
/****************************************************************************
* Name: file_allocate
*
@@ -834,6 +852,27 @@ int file_dup(FAR struct file *filep, int minfd, bool cloexec);
int file_dup2(FAR struct file *filep1, FAR struct file *filep2);
+/****************************************************************************
+ * Name: nx_dup2_from_tcb
+ *
+ * Description:
+ * nx_dup2_from_tcb() is similar to the standard 'dup2' interface
+ * except that is not a cancellation point and it does not modify the
+ * errno variable.
+ *
+ * nx_dup2_from_tcb() is an internal NuttX interface and should not be
+ * called from applications.
+ *
+ * Clone a file descriptor to a specific descriptor number.
+ *
+ * Returned Value:
+ * fd2 is returned on success; a negated errno value is return on
+ * any failure.
+ *
+ ****************************************************************************/
+
+int nx_dup2_from_tcb(FAR struct tcb_s *tcb, int fd1, int fd2);
+
/****************************************************************************
* Name: nx_dup2
*
@@ -875,6 +914,32 @@ int nx_dup2(int fd1, int fd2);
int file_open(FAR struct file *filep, FAR const char *path, int oflags, ...);
+/****************************************************************************
+ * Name: nx_open_from_tcb
+ *
+ * Description:
+ * nx_open_from_tcb() is similar to the standard 'open' interface except
+ * that it is not a cancellation point and it does not modify the errno
+ * variable.
+ *
+ * nx_open_from_tcb() is an internal NuttX interface and should not be
+ * called from applications.
+ *
+ * Input Parameters:
+ * tcb - Address of the task's TCB
+ * path - The full path to the file to be opened.
+ * oflags - open flags.
+ * ... - Variable number of arguments, may include 'mode_t mode'
+ *
+ * Returned Value:
+ * The new file descriptor is returned on success; a negated errno value is
+ * returned on any failure.
+ *
+ ****************************************************************************/
+
+int nx_open_from_tcb(FAR struct tcb_s *tcb,
+ FAR const char *path, int oflags, ...);
+
/****************************************************************************
* Name: nx_open
*
@@ -931,6 +996,31 @@ int fs_getfilep(int fd, FAR struct file **filep);
int file_close(FAR struct file *filep);
+/****************************************************************************
+ * Name: nx_close_from_tcb
+ *
+ * Description:
+ * nx_close_from_tcb() is similar to the standard 'close' interface
+ * except that is not a cancellation point and it does not modify the
+ * errno variable.
+ *
+ * nx_close_from_tcb() is an internal NuttX interface and should not
+ * be called from applications.
+ *
+ * Close an inode (if open)
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success; A negated errno value is returned on
+ * on any failure.
+ *
+ * Assumptions:
+ * Caller holds the list mutex because the file descriptor will be
+ * freed.
+ *
+ ****************************************************************************/
+
+int nx_close_from_tcb(FAR struct tcb_s *tcb, int fd);
+
/****************************************************************************
* Name: nx_close
*
@@ -1043,7 +1133,6 @@ int close_mtddriver(FAR struct inode *pinode);
****************************************************************************/
#ifdef CONFIG_FILE_STREAM
-struct tcb_s; /* Forward reference */
int fs_fdopen(int fd, int oflags, FAR struct tcb_s *tcb,
FAR struct file_struct **filep);
#endif
diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h
index 1a163f6ac5..82df2b831f 100644
--- a/include/nuttx/sched.h
+++ b/include/nuttx/sched.h
@@ -847,6 +847,40 @@ int nxsched_release_tcb(FAR struct tcb_s *tcb, uint8_t ttype);
* the currently executing task.
*/
+/****************************************************************************
+ * Name: nxsched_get_files_from_tcb
+ *
+ * Description:
+ * Return a pointer to the file list from task context
+ *
+ * Input Parameters:
+ * tcb - Address of the new task's TCB
+ *
+ * Returned Value:
+ * A pointer to the errno.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+FAR struct filelist *nxsched_get_files_from_tcb(FAR struct tcb_s *tcb);
+
+/****************************************************************************
+ * Name: nxsched_get_files
+ *
+ * Description:
+ * Return a pointer to the file list for this thread
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * A pointer to the errno.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
FAR struct filelist *nxsched_get_files(void);
/****************************************************************************
diff --git a/include/nuttx/spawn.h b/include/nuttx/spawn.h
index 09535c0371..c552e15f9a 100644
--- a/include/nuttx/spawn.h
+++ b/include/nuttx/spawn.h
@@ -100,6 +100,9 @@ extern "C"
void add_file_action(FAR posix_spawn_file_actions_t *file_action,
FAR struct spawn_general_file_action_s *entry);
+int spawn_file_actions(FAR struct tcb_s *tcb,
+ FAR const posix_spawn_file_actions_t *actions);
+
#ifdef __cplusplus
}
#endif
diff --git a/sched/init/nx_bringup.c b/sched/init/nx_bringup.c
index 14a88d7eec..24c3c5fbfe 100644
--- a/sched/init/nx_bringup.c
+++ b/sched/init/nx_bringup.c
@@ -295,7 +295,7 @@ static inline void nx_start_application(void)
attr.stacksize = CONFIG_INIT_STACKSIZE;
ret = exec_spawn(CONFIG_INIT_FILEPATH, argv, NULL,
- CONFIG_INIT_SYMTAB, CONFIG_INIT_NEXPORTS, &attr);
+ CONFIG_INIT_SYMTAB, CONFIG_INIT_NEXPORTS, NULL, &attr);
#endif
posix_spawnattr_destroy(&attr);
DEBUGASSERT(ret > 0);
diff --git a/sched/sched/sched_getfiles.c b/sched/sched/sched_getfiles.c
index cdbb49a5fb..baa21b2393 100644
--- a/sched/sched/sched_getfiles.c
+++ b/sched/sched/sched_getfiles.c
@@ -31,13 +31,13 @@
****************************************************************************/
/****************************************************************************
- * Name: nxsched_get_files
+ * Name: nxsched_get_files_from_tcb
*
* Description:
- * Return a pointer to the file list for this thread
+ * Return a pointer to the file list from task context
*
* Input Parameters:
- * None
+ * tcb - Address of the new task's TCB
*
* Returned Value:
* A pointer to the errno.
@@ -46,10 +46,9 @@
*
****************************************************************************/
-FAR struct filelist *nxsched_get_files(void)
+FAR struct filelist *nxsched_get_files_from_tcb(FAR struct tcb_s *tcb)
{
- FAR struct tcb_s *rtcb = this_task();
- FAR struct task_group_s *group = rtcb->group;
+ FAR struct task_group_s *group = tcb->group;
/* The group may be NULL under certain conditions. For example, if
* debug output is attempted from the IDLE thead before the group has
@@ -66,3 +65,24 @@ FAR struct filelist *nxsched_get_files(void)
return NULL;
}
+
+/****************************************************************************
+ * Name: nxsched_get_files
+ *
+ * Description:
+ * Return a pointer to the file list for this thread
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * A pointer to the errno.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+FAR struct filelist *nxsched_get_files(void)
+{
+ return nxsched_get_files_from_tcb(this_task());
+}
diff --git a/sched/task/spawn.h b/sched/task/spawn.h
index 9b75c5a8cc..e55d6d0b4e 100644
--- a/sched/task/spawn.h
+++ b/sched/task/spawn.h
@@ -29,55 +29,6 @@
#include <nuttx/mutex.h>
#include <spawn.h>
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-#ifndef CONFIG_POSIX_SPAWN_PROXY_STACKSIZE
-# define CONFIG_POSIX_SPAWN_PROXY_STACKSIZE 1024
-#endif
-
-/****************************************************************************
- * Public Type Definitions
- ****************************************************************************/
-
-struct spawn_parms_s
-{
- /* Common parameters */
-
- int result;
- FAR pid_t *pid;
- FAR const posix_spawn_file_actions_t *file_actions;
- FAR const posix_spawnattr_t *attr;
- FAR char * const *argv;
- FAR char * const *envp;
-
- /* Parameters that differ for posix_spawn[p] and task_spawn */
-
- union
- {
- struct
- {
- FAR const char *path;
- } posix;
- struct
- {
- FAR const char *name;
- main_t entry;
- } task;
- } u;
-};
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-extern mutex_t g_spawn_parmlock;
-#ifndef CONFIG_SCHED_WAITPID
-extern sem_t g_spawn_execsem;
-#endif
-extern struct spawn_parms_s g_spawn_parms;
-
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
@@ -116,16 +67,10 @@ int spawn_execattrs(pid_t pid, FAR const posix_spawnattr_t *attr);
*
* Input Parameters:
*
- * pid - The pid of the new task.
* attr - The attributes to use
- * file_actions - The attributes to use
- *
- * Returned Value:
- * 0 (OK) on success; A negated errno value is returned on failure.
*
****************************************************************************/
-int spawn_proxyattrs(FAR const posix_spawnattr_t *attr,
- FAR const posix_spawn_file_actions_t *file_actions);
+void spawn_proxyattrs(FAR const posix_spawnattr_t *attr);
#endif /* __SCHED_TASK_SPAWN_H */
diff --git a/sched/task/task_posixspawn.c b/sched/task/task_posixspawn.c
index a4d9e4a780..0fb56c97b9 100644
--- a/sched/task/task_posixspawn.c
+++ b/sched/task/task_posixspawn.c
@@ -59,6 +59,8 @@
* CONFIG_LIBC_ENVPATH is defined, this may be either a relative or
* or an absolute path. Otherwise, it must be an absolute path.
*
+ * actions - The spawn file actions
+ *
* attr - If the value of the 'attr' parameter is NULL, the all default
* values for the POSIX spawn attributes will be used. Otherwise, the
* attributes will be set according to the spawn flags. The
@@ -84,6 +86,7 @@
****************************************************************************/
static int nxposix_spawn_exec(FAR pid_t *pidp, FAR const char *path,
+ FAR const posix_spawn_file_actions_t *actions,
FAR const posix_spawnattr_t *attr,
FAR char * const argv[],
FAR char * const envp[])
@@ -108,7 +111,7 @@ static int nxposix_spawn_exec(FAR pid_t *pidp, FAR const char *path,
/* Start the task */
- pid = exec_spawn(path, argv, envp, symtab, nsymbols, attr);
+ pid = exec_spawn(path, argv, envp, symtab, nsymbols, actions, attr);
if (pid < 0)
{
ret = -pid;
@@ -140,81 +143,6 @@ errout:
return ret;
}
-/****************************************************************************
- * Name: nxposix_spawn_proxy
- *
- * Description:
- * Perform file_actions, then execute the task from the file system.
- *
- * Do we really need this proxy task? Isn't that wasteful?
- *
- * Q: Why not use a starthook so that there is callout from nxtask_start()
- * to perform these operations after the file is loaded from
- * the file system?
- * A: That existing nxtask_starthook() implementation cannot be used in
- * this context; any of nxtask_starthook() will also conflict with
- * binfmt's use of the start hook to call C++ static initializers.
- * task_restart() would also be an issue.
- *
- * Input Parameters:
- * Standard task start-up parameters
- *
- * Returned Value:
- * Standard task return value.
- *
- ****************************************************************************/
-
-static int nxposix_spawn_proxy(int argc, FAR char *argv[])
-{
- int ret;
-
- /* Perform file actions and/or set a custom signal mask. We get here only
- * if the file_actions parameter to posix_spawn[p] was non-NULL and/or the
- * option to change the signal mask was selected.
- */
-
- DEBUGASSERT(g_spawn_parms.file_actions ||
- (g_spawn_parms.attr &&
- (g_spawn_parms.attr->flags & POSIX_SPAWN_SETSIGMASK) != 0));
-
- /* Set the attributes and perform the file actions as appropriate */
-
- ret = spawn_proxyattrs(g_spawn_parms.attr, g_spawn_parms.file_actions);
- if (ret == OK)
- {
- /* Start the task */
-
- ret = nxposix_spawn_exec(g_spawn_parms.pid, g_spawn_parms.u.posix.path,
- g_spawn_parms.attr, g_spawn_parms.argv,
- g_spawn_parms.envp);
-
-#ifdef CONFIG_SCHED_HAVE_PARENT
- if (ret == OK)
- {
- /* Change of the parent of the task we just spawned to our parent.
- * What should we do in the event of a failure?
- */
-
- int tmp = task_reparent(0, *g_spawn_parms.pid);
- if (tmp < 0)
- {
- serr("ERROR: task_reparent() failed: %d\n", tmp);
- }
- }
-#endif
- }
-
- /* Post the semaphore to inform the parent task that we have completed
- * what we need to do.
- */
-
- g_spawn_parms.result = ret;
-#ifndef CONFIG_SCHED_WAITPID
- nxsem_post(&g_spawn_execsem);
-#endif
- return OK;
-}
-
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -311,125 +239,15 @@ int posix_spawn(FAR pid_t *pid, FAR const char *path,
FAR const posix_spawnattr_t *attr,
FAR char * const argv[], FAR char * const envp[])
{
- struct sched_param param;
- int proxy;
-#ifdef CONFIG_SCHED_WAITPID
- int status;
-#endif
- int ret;
-
- DEBUGASSERT(path);
-
sinfo("pid=%p path=%s file_actions=%p attr=%p argv=%p\n",
pid, path, file_actions, attr, argv);
- /* If there are no file actions to be performed and there is no change to
- * the signal mask, then start the new child task directly from the parent
- * task.
- */
-
- if ((file_actions == NULL || *file_actions == NULL) &&
- (attr == NULL || (attr->flags & POSIX_SPAWN_SETSIGMASK) == 0))
+ if (attr != NULL)
{
- return nxposix_spawn_exec(pid, path, attr, argv, envp);
+ spawn_proxyattrs(attr);
}
- /* Otherwise, we will have to go through an intermediary/proxy task in
- * order to perform the I/O redirection. This would be a natural place
- * to fork(). However, true fork() behavior requires an MMU and most
- * implementations of vfork() are not capable of these operations.
- *
- * Even without fork(), we can still do the job, but parameter passing is
- * messier. Unfortunately, there is no (clean) way to pass binary values
- * as a task parameter, so we will use a semaphore-protected global
- * structure.
- */
-
- /* Get exclusive access to the global parameter structure */
-
- ret = nxmutex_lock(&g_spawn_parmlock);
- if (ret < 0)
- {
- serr("ERROR: nxmutex_lock failed: %d\n", ret);
- return -ret;
- }
-
- /* Populate the parameter structure */
-
- g_spawn_parms.result = ENOSYS;
- g_spawn_parms.pid = pid;
- g_spawn_parms.file_actions = file_actions ? *file_actions : NULL;
- g_spawn_parms.attr = attr;
- g_spawn_parms.argv = argv;
- g_spawn_parms.envp = envp;
- g_spawn_parms.u.posix.path = path;
-
- /* Get the priority of this (parent) task */
-
- ret = nxsched_get_param(0, ¶m);
- if (ret < 0)
- {
- serr("ERROR: nxsched_get_param failed: %d\n", ret);
- nxmutex_unlock(&g_spawn_parmlock);
- return -ret;
- }
-
- /* Disable pre-emption so that the proxy does not run until waitpid
- * is called. This is probably unnecessary since the nxposix_spawn_proxy
- * has the same priority as this thread; it should be schedule behind
- * this task in the ready-to-run list.
- */
-
-#ifdef CONFIG_SCHED_WAITPID
- sched_lock();
-#endif
-
- /* Start the intermediary/proxy task at the same priority as the parent
- * task.
- */
-
- proxy = nxthread_create("nxposix_spawn_proxy", TCB_FLAG_TTYPE_KERNEL,
- param.sched_priority, NULL,
- CONFIG_POSIX_SPAWN_PROXY_STACKSIZE,
- nxposix_spawn_proxy, NULL, environ);
- if (proxy < 0)
- {
- ret = -proxy;
- serr("ERROR: Failed to start nxposix_spawn_proxy: %d\n", ret);
- goto errout_with_lock;
- }
-
- /* Wait for the proxy to complete its job */
-
-#ifdef CONFIG_SCHED_WAITPID
- /* REVISIT: This should not call waitpid() directly. waitpid is a
- * cancellation point and modifies the errno value. It is inappropriate
- * for use within the OS.
- */
-
- ret = nxsched_waitpid((pid_t)proxy, &status, 0);
- if (ret < 0)
- {
- serr("ERROR: waitpid() failed: %d\n", ret);
- goto errout_with_lock;
- }
-#else
- ret = nxsem_wait_uninterruptible(&g_spawn_execsem);
- if (ret < 0)
- {
- serr("ERROR: nxsem_wait_uninterruptible() failed: %d\n", ret);
- goto errout_with_lock;
- }
-#endif
-
- /* Get the result and relinquish our access to the parameter structure */
-
- ret = g_spawn_parms.result;
-
-errout_with_lock:
-#ifdef CONFIG_SCHED_WAITPID
- sched_unlock();
-#endif
- nxmutex_unlock(&g_spawn_parmlock);
- return ret;
+ return nxposix_spawn_exec(pid, path,
+ file_actions != NULL ?
+ *file_actions : NULL, attr, argv, envp);
}
diff --git a/sched/task/task_spawn.c b/sched/task/task_spawn.c
index b680508b04..bb011a3853 100644
--- a/sched/task/task_spawn.c
+++ b/sched/task/task_spawn.c
@@ -46,6 +46,92 @@
* Private Functions
****************************************************************************/
+/****************************************************************************
+ * Name: nxtask_spawn_create
+ *
+ * Description:
+ * This function creates and activates a new thread of the specified type
+ * with a specified priority and returns its system-assigned ID. It is the
+ * internal, common implementation of task_create() and kthread_create().
+ * See comments with task_create() for further information.
+ *
+ * Input Parameters:
+ * name - Name of the new task
+ * ttype - Type of the new task
+ * priority - Priority of the new task
+ * stack_addr - Address of the stack needed
+ * stack_size - Size (in bytes) of the stack needed
+ * entry - Entry point of a new task
+ * arg - A pointer to an array of input parameters. The array
+ * should be terminated with a NULL argv[] value. If no
+ * parameters are required, argv may be NULL.
+ * envp - A pointer to an array of environment strings. Terminated
+ * with a NULL entry.
+ * actions - The spawn file actions
+ *
+ * Returned Value:
+ * Returns the positive, non-zero process ID of the new task or a negated
+ * errno value to indicate the nature of any failure. If memory is
+ * insufficient or the task cannot be created -ENOMEM will be returned.
+ *
+ ****************************************************************************/
+
+static int nxtask_spawn_create(FAR const char *name, int priority,
+ FAR void *stack_addr, int stack_size,
+ main_t entry, FAR char * const argv[],
+ FAR char * const envp[],
+ FAR const posix_spawn_file_actions_t *actions)
+{
+ FAR struct task_tcb_s *tcb;
+ pid_t pid;
+ int ret;
+
+ /* Allocate a TCB for the new task. */
+
+ tcb = (FAR struct task_tcb_s *)kmm_zalloc(sizeof(struct task_tcb_s));
+ if (tcb == NULL)
+ {
+ serr("ERROR: Failed to allocate TCB\n");
+ return -ENOMEM;
+ }
+
+ /* Setup the task type */
+
+ tcb->cmn.flags = TCB_FLAG_TTYPE_TASK;
+
+ /* Initialize the task */
+
+ ret = nxtask_init(tcb, name, priority, stack_addr, stack_size,
+ entry, argv, envp);
+ if (ret < OK)
+ {
+ kmm_free(tcb);
+ return ret;
+ }
+
+ /* Perform file actions */
+
+ if (actions != NULL)
+ {
+ ret = spawn_file_actions(&tcb->cmn, actions);
+ if (ret < 0)
+ {
+ nxtask_uninit(tcb);
+ return ret;
+ }
+ }
+
+ /* Get the assigned pid before we start the task */
+
+ pid = tcb->cmn.pid;
+
+ /* Activate the task */
+
+ nxtask_activate(&tcb->cmn);
+
+ return (int)pid;
+}
+
/****************************************************************************
* Name: nxtask_spawn_exec
*
@@ -61,6 +147,8 @@
*
* entry - The child task's entry point (an address in memory)
*
+ * actions - The spawn file actions
+ *
* attr - If the value of the 'attr' parameter is NULL, the all default
* values for the POSIX spawn attributes will be used. Otherwise, the
* attributes will be set according to the spawn flags. The
@@ -89,7 +177,9 @@
****************************************************************************/
static int nxtask_spawn_exec(FAR pid_t *pidp, FAR const char *name,
- main_t entry, FAR const posix_spawnattr_t *attr,
+ main_t entry,
+ FAR const posix_spawn_file_actions_t *actions,
+ FAR const posix_spawnattr_t *attr,
FAR char * const *argv, FAR char * const envp[])
{
FAR void *stackaddr = NULL;
@@ -131,12 +221,13 @@ static int nxtask_spawn_exec(FAR pid_t *pidp, FAR const char *name,
/* Start the task */
- pid = nxtask_create(name, priority, stackaddr,
- stacksize, entry, argv, envp);
+ pid = nxtask_spawn_create(name, priority, stackaddr,
+ stacksize, entry, argv,
+ envp ? envp : environ, actions);
if (pid < 0)
{
ret = pid;
- serr("ERROR: nxtask_create failed: %d\n", ret);
+ serr("ERROR: nxtask_spawn_create failed: %d\n", ret);
goto errout;
}
@@ -164,92 +255,6 @@ errout:
return ret;
}
-/****************************************************************************
- * Name: nxtask_spawn_proxy
- *
- * Description:
- * Perform file_actions, then execute the task from the file system.
- *
- * Do we really need a proxy task in this case? Isn't that wasteful?
- *
- * Q: Why can we do what we need to do here and the just call the
- * new task's entry point.
- * A: This would require setting up the name, priority, and stacksize from
- * the task_spawn, but it do-able. The only issue I can think of is
- * that NuttX supports task_restart(), and you would never be able to
- * restart a task from this point.
- *
- * Q: Why not use a starthook so that there is callout from nxtask_start()
- * to perform these operations?
- * A: Good idea, except that existing nxtask_starthook() implementation
- * cannot be used here unless we get rid of task_create and, instead,
- * use nxtask_init() and nxtask_activate(). start_taskhook() could then
- * be called between nxtask_init() and nxtask_activate().
- * task_restart() would still be an issue.
- *
- * Input Parameters:
- * argc, argv - Ignored. The task's start-up parameters are passed via the
- * semaphore-protected global structure g_spawn_parms.
- *
- * Returned Value:
- * Standard task return value.
- *
- ****************************************************************************/
-
-static int nxtask_spawn_proxy(int argc, FAR char *argv[])
-{
- int ret;
-
- /* Perform file actions and/or set a custom signal mask. We get here only
- * if the file_actions parameter to task_spawn[p] was non-NULL and/or the
- * option to change the signal mask was selected.
- */
-
- UNUSED(argc);
- UNUSED(argv);
-
- DEBUGASSERT(g_spawn_parms.file_actions ||
- (g_spawn_parms.attr &&
- (g_spawn_parms.attr->flags & POSIX_SPAWN_SETSIGMASK) != 0));
-
- /* Set the attributes and perform the file actions as appropriate */
-
- ret = spawn_proxyattrs(g_spawn_parms.attr, g_spawn_parms.file_actions);
- if (ret == OK)
- {
- /* Start the task */
-
- ret = nxtask_spawn_exec(g_spawn_parms.pid, g_spawn_parms.u.task.name,
- g_spawn_parms.u.task.entry, g_spawn_parms.attr,
- g_spawn_parms.argv, g_spawn_parms.envp);
-
-#ifdef CONFIG_SCHED_HAVE_PARENT
- if (ret == OK)
- {
- /* Change of the parent of the task we just spawned to our parent.
- * What should we do in the event of a failure?
- */
-
- int tmp = task_reparent(0, *g_spawn_parms.pid);
- if (tmp < 0)
- {
- serr("ERROR: task_reparent() failed: %d\n", tmp);
- }
- }
-#endif
- }
-
- /* Post the semaphore to inform the parent task that we have completed
- * what we need to do.
- */
-
- g_spawn_parms.result = ret;
-#ifndef CONFIG_SCHED_WAITPID
- nxsem_post(&g_spawn_execsem);
-#endif
- return OK;
-}
-
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -321,142 +326,22 @@ int task_spawn(FAR const char *name, main_t entry,
FAR const posix_spawnattr_t *attr,
FAR char * const argv[], FAR char * const envp[])
{
- struct sched_param param;
- pid_t proxy;
pid_t pid = INVALID_PROCESS_ID;
-#ifdef CONFIG_SCHED_WAITPID
- int status;
-#endif
int ret;
sinfo("name=%s entry=%p file_actions=%p attr=%p argv=%p\n",
name, entry, file_actions, attr, argv);
- /* If there are no file actions to be performed and there is no change to
- * the signal mask, then start the new child task directly from the parent
- * task.
- */
-
- if ((file_actions == NULL || *file_actions == NULL) &&
- (attr == NULL || (attr->flags & POSIX_SPAWN_SETSIGMASK) == 0))
+ if (attr != NULL)
{
- ret = nxtask_spawn_exec(&pid, name, entry, attr, argv, envp);
- if (ret < 0)
- {
- return ret;
- }
-
- return pid;
- }
-
- /* Otherwise, we will have to go through an intermediary/proxy task in
- * order to perform the I/O redirection. This would be a natural place to
- * fork(). However, true fork() behavior requires an MMU and most
- * implementations of vfork() are not capable of these operations.
- *
- * Even without fork(), we can still do the job, but parameter passing is
- * messier. Unfortunately, there is no (clean) way to pass binary values
- * as a task parameter, so we will use a semaphore-protected global
- * structure.
- */
-
- /* Get exclusive access to the global parameter structure */
-
- ret = nxmutex_lock(&g_spawn_parmlock);
- if (ret < 0)
- {
- serr("ERROR: nxmutex_lock failed: %d\n", ret);
- return ret;
+ spawn_proxyattrs(attr);
}
- /* Populate the parameter structure */
-
- g_spawn_parms.result = ENOSYS;
- g_spawn_parms.pid = &pid;
- g_spawn_parms.file_actions = file_actions ? *file_actions : NULL;
- g_spawn_parms.attr = attr;
- g_spawn_parms.argv = argv;
- g_spawn_parms.envp = envp;
- g_spawn_parms.u.task.name = name;
- g_spawn_parms.u.task.entry = entry;
-
- /* Get the priority of this (parent) task */
+ ret = nxtask_spawn_exec(&pid, name, entry,
+ file_actions != NULL ? *file_actions : NULL,
+ attr, argv, envp);
- ret = nxsched_get_param(0, ¶m);
- if (ret < 0)
- {
- serr("ERROR: nxsched_get_param failed: %d\n", ret);
- g_spawn_parms.pid = NULL;
- nxmutex_unlock(&g_spawn_parmlock);
- return ret;
- }
-
-#ifdef CONFIG_SCHED_WAITPID
- /* Disable pre-emption so that the proxy does not run until waitpid
- * is called. This is probably unnecessary since the nxtask_spawn_proxy
- * has the same priority as this thread; it should be schedule behind
- * this task in the ready-to-run list.
- *
- * REVISIT: This will may not have the desired effect in SMP mode.
- */
-
- sched_lock();
-#endif
-
- /* Start the intermediary/proxy task at the same priority as the parent
- * task.
- */
-
- proxy = nxtask_create("nxtask_spawn_proxy", param.sched_priority,
- NULL, CONFIG_POSIX_SPAWN_PROXY_STACKSIZE,
- nxtask_spawn_proxy, NULL, NULL);
- if (proxy < 0)
- {
- ret = proxy;
- serr("ERROR: Failed to start nxtask_spawn_proxy: %d\n", ret);
- goto errout_with_lock;
- }
-
- /* Wait for the proxy to complete its job */
-
-#ifdef CONFIG_SCHED_WAITPID
- /* REVISIT: This should not call waitpid() directly. waitpid is a
- * cancellation point and modifies the errno value. It is inappropriate
- * for use within the OS.
- */
-
- ret = nxsched_waitpid(proxy, &status, 0);
- if (ret < 0)
- {
- serr("ERROR: waitpid() failed: %d\n", ret);
- goto errout_with_lock;
- }
-#else
- ret = nxsem_wait_uninterruptible(&g_spawn_execsem);
- if (ret < 0)
- {
- serr("ERROR: g_spawn_execsem() failed: %d\n", ret);
- goto errout_with_lock;
- }
-#endif
-
- /* Get the result and relinquish our access to the parameter structure */
-
- ret = -g_spawn_parms.result;
- if (ret < 0)
- {
- goto errout_with_lock;
- }
-
- ret = (int)pid;
-
-errout_with_lock:
-#ifdef CONFIG_SCHED_WAITPID
- sched_unlock();
-#endif
- g_spawn_parms.pid = NULL;
- nxmutex_unlock(&g_spawn_parmlock);
- return ret;
+ return ret >= 0 ? (int)pid : ret;
}
#endif /* CONFIG_BUILD_KERNEL */
diff --git a/sched/task/task_spawnparms.c b/sched/task/task_spawnparms.c
index 3a62f1006c..2813713534 100644
--- a/sched/task/task_spawnparms.c
+++ b/sched/task/task_spawnparms.c
@@ -38,16 +38,6 @@
#include "task/spawn.h"
#include "task/task.h"
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-mutex_t g_spawn_parmlock = NXMUTEX_INITIALIZER;
-#ifndef CONFIG_SCHED_WAITPID
-sem_t g_spawn_execsem = SEM_INITIALIZER(0);
-#endif
-struct spawn_parms_s g_spawn_parms;
-
/****************************************************************************
* Private Functions
****************************************************************************/
@@ -68,73 +58,53 @@ struct spawn_parms_s g_spawn_parms;
*
****************************************************************************/
-static inline int nxspawn_close(FAR struct spawn_close_file_action_s *action)
+static inline int nxspawn_close(FAR struct tcb_s *tcb,
+ FAR struct spawn_close_file_action_s *action)
{
/* The return value from nx_close() is ignored */
sinfo("Closing fd=%d\n", action->fd);
- nx_close(action->fd);
- return OK;
+ return nx_close_from_tcb(tcb, action->fd);
}
-static inline int nxspawn_dup2(FAR struct spawn_dup2_file_action_s *action)
+static inline int nxspawn_dup2(FAR struct tcb_s *tcb,
+ FAR struct spawn_dup2_file_action_s *action)
{
- int ret;
-
/* Perform the dup */
sinfo("Dup'ing %d->%d\n", action->fd1, action->fd2);
- ret = nx_dup2(action->fd1, action->fd2);
- if (ret < 0)
- {
- serr("ERROR: dup2 failed: %d\n", ret);
- return ret;
- }
-
- return OK;
+ return nx_dup2_from_tcb(tcb, action->fd1, action->fd2);
}
-static inline int nxspawn_open(FAR struct spawn_open_file_action_s *action)
+static inline int nxspawn_open(FAR struct tcb_s *tcb,
+ FAR struct spawn_open_file_action_s *action)
{
- int fd;
int ret = OK;
+ int fd;
/* Open the file */
sinfo("Open'ing path=%s oflags=%04x mode=%04x\n",
action->path, action->oflags, action->mode);
- fd = nx_open(action->path, action->oflags, action->mode);
+ nx_close_from_tcb(tcb, action->fd);
+
+ fd = nx_open_from_tcb(tcb, action->path, action->oflags, action->mode);
if (fd < 0)
{
ret = fd;
- serr("ERROR: open failed: %d\n", ret);
}
-
- /* Does the return file descriptor happen to match the required file
- * descriptor number?
- */
-
else if (fd != action->fd)
{
- /* No.. dup2 to get the correct file number */
-
- sinfo("Dup'ing %d->%d\n", fd, action->fd);
-
- ret = nx_dup2(fd, action->fd);
- if (ret < 0)
- {
- serr("ERROR: dup2 failed: %d\n", ret);
- }
- else
+ ret = nx_dup2_from_tcb(tcb, fd, action->fd);
+ if (ret >= 0)
{
ret = OK;
}
- sinfo("Closing fd=%d\n", fd);
- nx_close(fd);
+ nx_close_from_tcb(tcb, fd);
}
return ret;
@@ -266,61 +236,66 @@ int spawn_execattrs(pid_t pid, FAR const posix_spawnattr_t *attr)
*
* Input Parameters:
*
- * pid - The pid of the new task.
* attr - The attributes to use
- * file_actions - The attributes to use
- *
- * Returned Value:
- * 0 (OK) on success; A negated errno value is returned on failure.
*
****************************************************************************/
-int spawn_proxyattrs(FAR const posix_spawnattr_t *attr,
- FAR const posix_spawn_file_actions_t *file_actions)
+void spawn_proxyattrs(FAR const posix_spawnattr_t *attr)
{
- FAR struct spawn_general_file_action_s *entry;
- int ret = OK;
-
/* Check if we need to change the signal mask */
if (attr != NULL && (attr->flags & POSIX_SPAWN_SETSIGMASK) != 0)
{
nxsig_procmask(SIG_SETMASK, &attr->sigmask, NULL);
}
+}
- /* Were we also requested to perform file actions? */
+/****************************************************************************
+ * Name: spawn_file_actions
+ *
+ * Description:
+ * Perform Spawn file object that specifies file-related actions
+ *
+ * Input Parameters:
+ *
+ * attr - The spawn file actions
+ *
+ * Returned Value:
+ * 0 (OK) on success; A negated errno value is returned on failure.
+ *
+ ****************************************************************************/
- if (file_actions != NULL)
- {
- /* Yes.. Execute each file action */
+int spawn_file_actions(FAR struct tcb_s *tcb,
+ FAR const posix_spawn_file_actions_t *actions)
+{
+ FAR struct spawn_general_file_action_s *entry;
+ int ret = OK;
+
+ /* Execute each file action */
- for (entry = (FAR struct spawn_general_file_action_s *)file_actions;
- entry && ret == OK;
- entry = entry->flink)
+ for (entry = (FAR struct spawn_general_file_action_s *)actions;
+ entry && ret == OK;
+ entry = entry->flink)
+ {
+ switch (entry->action)
{
- switch (entry->action)
- {
- case SPAWN_FILE_ACTION_CLOSE:
- ret = nxspawn_close((FAR struct spawn_close_file_action_s *)
- entry);
- break;
-
- case SPAWN_FILE_ACTION_DUP2:
- ret = nxspawn_dup2((FAR struct spawn_dup2_file_action_s *)
- entry);
- break;
-
- case SPAWN_FILE_ACTION_OPEN:
- ret = nxspawn_open((FAR struct spawn_open_file_action_s *)
- entry);
- break;
-
- case SPAWN_FILE_ACTION_NONE:
- default:
- serr("ERROR: Unknown action: %d\n", entry->action);
- ret = EINVAL;
- break;
- }
+ case SPAWN_FILE_ACTION_CLOSE:
+ ret = nxspawn_close(tcb, (FAR void *)entry);
+ break;
+
+ case SPAWN_FILE_ACTION_DUP2:
+ ret = nxspawn_dup2(tcb, (FAR void *)entry);
+ break;
+
+ case SPAWN_FILE_ACTION_OPEN:
+ ret = nxspawn_open(tcb, (FAR void *)entry);
+ break;
+
+ case SPAWN_FILE_ACTION_NONE:
+ default:
+ serr("ERROR: Unknown action: %d\n", entry->action);
+ ret = -EINVAL;
+ break;
}
}