You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by gn...@apache.org on 2021/06/14 13:12:01 UTC

[incubator-nuttx] branch master updated: sched/posix_spawn: Don't insert name at the begin of argv

This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 0320868  sched/posix_spawn: Don't insert name at the begin of argv
0320868 is described below

commit 032086870d16992dcdf820bf93a36c2a6426d6e7
Author: Xiang Xiao <xi...@xiaomi.com>
AuthorDate: Sun Jun 13 13:43:38 2021 +0800

    sched/posix_spawn: Don't insert name at the begin of argv
    
    since the standard require the caller pass the name explicitly
    https://pubs.opengroup.org/onlinepubs/009695399/functions/posix_spawn.html:
    The argument argv is an array of character pointers to null-terminated strings.
    The last member of this array shall be a null pointer and is not counted in argc.
    These strings constitute the argument list available to the new process image.
    The value in argv[0] should point to a filename that is associated with the
    process image being started by the posix_spawn() or posix_spawnp() function.
    
    Signed-off-by: Xiang Xiao <xi...@xiaomi.com>
    Change-Id: Id79ffcc501ae9552dc4e908418ff555f498be7f1
---
 binfmt/binfmt_execmodule.c |  2 +-
 include/nuttx/sched.h      | 22 ++++++------
 sched/task/task.h          |  4 +--
 sched/task/task_create.c   |  3 +-
 sched/task/task_init.c     | 24 +++++++------
 sched/task/task_setup.c    | 88 +++++++++++++++++++++++++---------------------
 sched/task/task_vfork.c    |  2 +-
 7 files changed, 78 insertions(+), 67 deletions(-)

diff --git a/binfmt/binfmt_execmodule.c b/binfmt/binfmt_execmodule.c
index 6206559..834176f 100644
--- a/binfmt/binfmt_execmodule.c
+++ b/binfmt/binfmt_execmodule.c
@@ -168,7 +168,7 @@ int exec_module(FAR const struct binary_s *binp,
 
   /* Initialize the task */
 
-  ret = nxtask_init(tcb, filename, binp->priority,
+  ret = nxtask_init(tcb, false, filename, binp->priority,
                     NULL, binp->stacksize, binp->entrypt, argv);
   binfmt_freeargv(argv);
   if (ret < 0)
diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h
index 8f32440..0be56bc 100644
--- a/include/nuttx/sched.h
+++ b/include/nuttx/sched.h
@@ -908,15 +908,16 @@ FAR struct streamlist *nxsched_get_streams(void);
  *     - Task type may be set in the TCB flags to create kernel thread
  *
  * Input Parameters:
- *   tcb        - Address of the new task's TCB
- *   name       - Name of the new task (not used)
- *   priority   - Priority of the new task
- *   stack      - Start of the pre-allocated stack
- *   stack_size - Size (in bytes) of the stack allocated
- *   entry      - Application start point of the new task
- *   argv       - 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.
+ *   tcb         - Address of the new task's TCB
+ *   insert_name - Insert name to the first argv
+ *   name        - Name of the new task
+ *   priority    - Priority of the new task
+ *   stack       - Start of the pre-allocated stack
+ *   stack_size  - Size (in bytes) of the stack allocated
+ *   entry       - Application start point of the new task
+ *   argv        - 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.
  *
  * Returned Value:
  *   OK on success; negative error value on failure appropriately.  (See
@@ -927,7 +928,8 @@ FAR struct streamlist *nxsched_get_streams(void);
  *
  ****************************************************************************/
 
-int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority,
+int nxtask_init(FAR struct task_tcb_s *tcb, bool insert_name,
+                const char *name, int priority,
                 FAR void *stack, uint32_t stack_size, main_t entry,
                 FAR char * const argv[]);
 
diff --git a/sched/task/task.h b/sched/task/task.h
index daea1bd..ab06689 100644
--- a/sched/task/task.h
+++ b/sched/task/task.h
@@ -44,8 +44,8 @@ struct tcb_s; /* Forward reference */
 void nxtask_start(void);
 int  nxtask_setup_scheduler(FAR struct task_tcb_s *tcb, int priority,
        start_t start, main_t main, uint8_t ttype);
-int  nxtask_setup_arguments(FAR struct task_tcb_s *tcb, FAR const char *name,
-       FAR char * const argv[]);
+int  nxtask_setup_arguments(FAR struct task_tcb_s *tcb, bool insert_name,
+       FAR const char *name, FAR char * const argv[]);
 
 /* Task exit */
 
diff --git a/sched/task/task_create.c b/sched/task/task_create.c
index 9915c5d..078d8d2 100644
--- a/sched/task/task_create.c
+++ b/sched/task/task_create.c
@@ -91,7 +91,8 @@ static int nxthread_create(FAR const char *name, uint8_t ttype,
 
   /* Initialize the task */
 
-  ret = nxtask_init(tcb, name, priority, NULL, stack_size, entry, argv);
+  ret = nxtask_init(tcb, true, name, priority,
+                    NULL, stack_size, entry, argv);
   if (ret < OK)
     {
       kmm_free(tcb);
diff --git a/sched/task/task_init.c b/sched/task/task_init.c
index dfd7c7f..35facff 100644
--- a/sched/task/task_init.c
+++ b/sched/task/task_init.c
@@ -62,15 +62,16 @@
  *     - Task type may be set in the TCB flags to create kernel thread
  *
  * Input Parameters:
- *   tcb        - Address of the new task's TCB
- *   name       - Name of the new task (not used)
- *   priority   - Priority of the new task
- *   stack      - Start of the pre-allocated stack
- *   stack_size - Size (in bytes) of the stack allocated
- *   entry      - Application start point of the new task
- *   argv       - 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.
+ *   tcb         - Address of the new task's TCB
+ *   insert_name - Insert name to the first argv
+ *   name        - Name of the new task
+ *   priority    - Priority of the new task
+ *   stack       - Start of the pre-allocated stack
+ *   stack_size  - Size (in bytes) of the stack allocated
+ *   entry       - Application start point of the new task
+ *   argv        - 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.
  *
  * Returned Value:
  *   OK on success; negative error value on failure appropriately.  (See
@@ -81,7 +82,8 @@
  *
  ****************************************************************************/
 
-int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority,
+int nxtask_init(FAR struct task_tcb_s *tcb, bool insert_name,
+                const char *name, int priority,
                 FAR void *stack, uint32_t stack_size,
                 main_t entry, FAR char * const argv[])
 {
@@ -153,7 +155,7 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority,
 
   /* Setup to pass parameters to the new task */
 
-  nxtask_setup_arguments(tcb, name, argv);
+  nxtask_setup_arguments(tcb, insert_name, name, argv);
 
   /* Now we have enough in place that we can join the group */
 
diff --git a/sched/task/task_setup.c b/sched/task/task_setup.c
index 73f6815..5bac051 100644
--- a/sched/task/task_setup.c
+++ b/sched/task/task_setup.c
@@ -452,13 +452,6 @@ static int nxthread_setup_scheduler(FAR struct tcb_s *tcb, int priority,
 static void nxtask_setup_name(FAR struct task_tcb_s *tcb,
                               FAR const char *name)
 {
-  /* Give a name to the unnamed tasks */
-
-  if (!name)
-    {
-      name = (FAR char *)g_noname;
-    }
-
   /* Copy the name into the TCB */
 
   strncpy(tcb->cmn.name, name, CONFIG_TASK_NAME_SIZE);
@@ -479,21 +472,23 @@ static void nxtask_setup_name(FAR struct task_tcb_s *tcb,
  *   accessible no matter what privilege mode the task runs in.
  *
  * Input Parameters:
- *   tcb  - Address of the new task's TCB
- *   argv - A pointer to an array of input parameters. The arrau should be
- *          terminated with a NULL argv[] value. If no parameters are
- *          required, argv may be NULL.
+ *   tcb         - Address of the new task's TCB
+ *   insert_name - Insert name to the first entry
+ *   name        - Name of the new task
+ *   argv        - 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.
  *
  * Returned Value:
  *  Zero (OK) on success; a negated errno on failure.
  *
  ****************************************************************************/
 
-static inline int nxtask_setup_stackargs(FAR struct task_tcb_s *tcb,
-                                         FAR char * const argv[])
+static inline int
+nxtask_setup_stackargs(FAR struct task_tcb_s *tcb, bool insert_name,
+                       FAR const char *name, FAR char * const argv[])
 {
   FAR char **stackargv;
-  FAR const char *name;
   FAR char *str;
   size_t strtablen;
   size_t argvlen;
@@ -501,17 +496,9 @@ static inline int nxtask_setup_stackargs(FAR struct task_tcb_s *tcb,
   int argc;
   int i;
 
-  /* Get the name string that we will use as the first argument */
-
-#if CONFIG_TASK_NAME_SIZE > 0
-  name = tcb->cmn.name;
-#else
-  name = (FAR const char *)g_noname;
-#endif /* CONFIG_TASK_NAME_SIZE */
-
   /* Get the size of the task name (including the NUL terminator) */
 
-  strtablen = (strlen(name) + 1);
+  strtablen = insert_name ? (strlen(name) + 1) : 0;
 
   /* Count the number of arguments and get the accumulated size of the
    * argument strings (including the null terminators).  The argument count
@@ -554,7 +541,7 @@ static inline int nxtask_setup_stackargs(FAR struct task_tcb_s *tcb,
    * task name plus a NULL argv[] entry to terminate the list.
    */
 
-  argvlen   = (argc + 2) * sizeof(FAR char *);
+  argvlen   = (insert_name + argc + 1) * sizeof(FAR char *);
   stackargv = (FAR char **)up_stack_frame(&tcb->cmn, argvlen + strtablen);
 
   DEBUGASSERT(stackargv != NULL);
@@ -563,6 +550,8 @@ static inline int nxtask_setup_stackargs(FAR struct task_tcb_s *tcb,
       return -ENOMEM;
     }
 
+  tcb->argv = stackargv;
+
   /* Get the address of the string table that will lie immediately after
    * the argv[] array and mark it as a null string.
    */
@@ -573,10 +562,13 @@ static inline int nxtask_setup_stackargs(FAR struct task_tcb_s *tcb,
    * NUL terminator in the string buffer.
    */
 
-  stackargv[0] = str;
-  nbytes       = strlen(name) + 1;
-  strcpy(str, name);
-  str         += nbytes;
+  if (insert_name)
+    {
+      *stackargv++ = str;
+      nbytes       = strlen(name) + 1;
+      strcpy(str, name);
+      str         += nbytes;
+    }
 
   /* Copy each argument */
 
@@ -587,10 +579,10 @@ static inline int nxtask_setup_stackargs(FAR struct task_tcb_s *tcb,
        * argument and its NUL terminator in the string buffer.
        */
 
-      stackargv[i + 1] = str;
-      nbytes           = strlen(argv[i]) + 1;
+      *stackargv++ = str;
+      nbytes       = strlen(argv[i]) + 1;
       strcpy(str, argv[i]);
-      str             += nbytes;
+      str         += nbytes;
     }
 
   /* Put a terminator entry at the end of the argv[] array.  Then save the
@@ -598,8 +590,7 @@ static inline int nxtask_setup_stackargs(FAR struct task_tcb_s *tcb,
    * nxtask_start().
    */
 
-  stackargv[argc + 1] = NULL;
-  tcb->argv = stackargv;
+  *stackargv++ = NULL;
 
   return OK;
 }
@@ -696,20 +687,35 @@ int pthread_setup_scheduler(FAR struct pthread_tcb_s *tcb, int priority,
  *   task runs in.
  *
  * Input Parameters:
- *   tcb  - Address of the new task's TCB
- *   name - Name of the new task (not used)
- *   argv - 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.
+ *   tcb         - Address of the new task's TCB
+ *   insert_name - Insert name to the first argv
+ *   name        - Name of the new task
+ *   argv        - 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.
  *
  * Returned Value:
  *  OK
  *
  ****************************************************************************/
 
-int nxtask_setup_arguments(FAR struct task_tcb_s *tcb, FAR const char *name,
-                           FAR char * const argv[])
+int nxtask_setup_arguments(FAR struct task_tcb_s *tcb, bool insert_name,
+                           FAR const char *name, FAR char * const argv[])
 {
+  /* Give a name to the unnamed tasks */
+
+  if (!name)
+    {
+      name = (FAR char *)g_noname;
+    }
+
+  /* Always insert name if argv equals NULL */
+
+  if (!argv)
+    {
+      insert_name = true;
+    }
+
   /* Setup the task name */
 
   nxtask_setup_name(tcb, name);
@@ -719,5 +725,5 @@ int nxtask_setup_arguments(FAR struct task_tcb_s *tcb, FAR const char *name,
    * privilege mode the task runs in.
    */
 
-  return nxtask_setup_stackargs(tcb, argv);
+  return nxtask_setup_stackargs(tcb, insert_name, name, argv);
 }
diff --git a/sched/task/task_vfork.c b/sched/task/task_vfork.c
index b31b732..9ff5471 100644
--- a/sched/task/task_vfork.c
+++ b/sched/task/task_vfork.c
@@ -208,7 +208,7 @@ FAR struct task_tcb_s *nxtask_setup_vfork(start_t retaddr)
   name = parent->cmn.name;
 #endif
 
-  nxtask_setup_arguments(child, name, parent->argv);
+  nxtask_setup_arguments(child, false, name, parent->argv);
 
   /* Now we have enough in place that we can join the group */