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 <xiaoxiang@xiaomi.com>
Change-Id: Id79ffcc501ae9552dc4e908418ff555f498be7f1
This commit is contained in:
Xiang Xiao 2021-06-13 13:43:38 +08:00 committed by patacongo
parent 9b8e81ebc1
commit 032086870d
7 changed files with 78 additions and 67 deletions

View File

@ -168,7 +168,7 @@ int exec_module(FAR const struct binary_s *binp,
/* Initialize the task */ /* Initialize the task */
ret = nxtask_init(tcb, filename, binp->priority, ret = nxtask_init(tcb, false, filename, binp->priority,
NULL, binp->stacksize, binp->entrypt, argv); NULL, binp->stacksize, binp->entrypt, argv);
binfmt_freeargv(argv); binfmt_freeargv(argv);
if (ret < 0) if (ret < 0)

View File

@ -908,15 +908,16 @@ FAR struct streamlist *nxsched_get_streams(void);
* - Task type may be set in the TCB flags to create kernel thread * - Task type may be set in the TCB flags to create kernel thread
* *
* Input Parameters: * Input Parameters:
* tcb - Address of the new task's TCB * tcb - Address of the new task's TCB
* name - Name of the new task (not used) * insert_name - Insert name to the first argv
* priority - Priority of the new task * name - Name of the new task
* stack - Start of the pre-allocated stack * priority - Priority of the new task
* stack_size - Size (in bytes) of the stack allocated * stack - Start of the pre-allocated stack
* entry - Application start point of the new task * stack_size - Size (in bytes) of the stack allocated
* argv - A pointer to an array of input parameters. The array * entry - Application start point of the new task
* should be terminated with a NULL argv[] value. If no * argv - A pointer to an array of input parameters. The array
* parameters are required, argv may be NULL. * should be terminated with a NULL argv[] value. If no
* parameters are required, argv may be NULL.
* *
* Returned Value: * Returned Value:
* OK on success; negative error value on failure appropriately. (See * 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 void *stack, uint32_t stack_size, main_t entry,
FAR char * const argv[]); FAR char * const argv[]);

View File

@ -44,8 +44,8 @@ struct tcb_s; /* Forward reference */
void nxtask_start(void); void nxtask_start(void);
int nxtask_setup_scheduler(FAR struct task_tcb_s *tcb, int priority, int nxtask_setup_scheduler(FAR struct task_tcb_s *tcb, int priority,
start_t start, main_t main, uint8_t ttype); start_t start, main_t main, uint8_t ttype);
int nxtask_setup_arguments(FAR struct task_tcb_s *tcb, FAR const char *name, int nxtask_setup_arguments(FAR struct task_tcb_s *tcb, bool insert_name,
FAR char * const argv[]); FAR const char *name, FAR char * const argv[]);
/* Task exit */ /* Task exit */

View File

@ -91,7 +91,8 @@ static int nxthread_create(FAR const char *name, uint8_t ttype,
/* Initialize the task */ /* 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) if (ret < OK)
{ {
kmm_free(tcb); kmm_free(tcb);

View File

@ -62,15 +62,16 @@
* - Task type may be set in the TCB flags to create kernel thread * - Task type may be set in the TCB flags to create kernel thread
* *
* Input Parameters: * Input Parameters:
* tcb - Address of the new task's TCB * tcb - Address of the new task's TCB
* name - Name of the new task (not used) * insert_name - Insert name to the first argv
* priority - Priority of the new task * name - Name of the new task
* stack - Start of the pre-allocated stack * priority - Priority of the new task
* stack_size - Size (in bytes) of the stack allocated * stack - Start of the pre-allocated stack
* entry - Application start point of the new task * stack_size - Size (in bytes) of the stack allocated
* argv - A pointer to an array of input parameters. The array * entry - Application start point of the new task
* should be terminated with a NULL argv[] value. If no * argv - A pointer to an array of input parameters. The array
* parameters are required, argv may be NULL. * should be terminated with a NULL argv[] value. If no
* parameters are required, argv may be NULL.
* *
* Returned Value: * Returned Value:
* OK on success; negative error value on failure appropriately. (See * 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, FAR void *stack, uint32_t stack_size,
main_t entry, FAR char * const argv[]) 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 */ /* 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 */ /* Now we have enough in place that we can join the group */

View File

@ -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, static void nxtask_setup_name(FAR struct task_tcb_s *tcb,
FAR const char *name) FAR const char *name)
{ {
/* Give a name to the unnamed tasks */
if (!name)
{
name = (FAR char *)g_noname;
}
/* Copy the name into the TCB */ /* Copy the name into the TCB */
strncpy(tcb->cmn.name, name, CONFIG_TASK_NAME_SIZE); 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. * accessible no matter what privilege mode the task runs in.
* *
* Input Parameters: * Input Parameters:
* tcb - Address of the new task's TCB * tcb - Address of the new task's TCB
* argv - A pointer to an array of input parameters. The arrau should be * insert_name - Insert name to the first entry
* terminated with a NULL argv[] value. If no parameters are * name - Name of the new task
* required, argv may be NULL. * 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: * Returned Value:
* Zero (OK) on success; a negated errno on failure. * Zero (OK) on success; a negated errno on failure.
* *
****************************************************************************/ ****************************************************************************/
static inline int nxtask_setup_stackargs(FAR struct task_tcb_s *tcb, static inline int
FAR char * const argv[]) nxtask_setup_stackargs(FAR struct task_tcb_s *tcb, bool insert_name,
FAR const char *name, FAR char * const argv[])
{ {
FAR char **stackargv; FAR char **stackargv;
FAR const char *name;
FAR char *str; FAR char *str;
size_t strtablen; size_t strtablen;
size_t argvlen; size_t argvlen;
@ -501,17 +496,9 @@ static inline int nxtask_setup_stackargs(FAR struct task_tcb_s *tcb,
int argc; int argc;
int i; 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) */ /* 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 /* Count the number of arguments and get the accumulated size of the
* argument strings (including the null terminators). The argument count * 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. * 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); stackargv = (FAR char **)up_stack_frame(&tcb->cmn, argvlen + strtablen);
DEBUGASSERT(stackargv != NULL); DEBUGASSERT(stackargv != NULL);
@ -563,6 +550,8 @@ static inline int nxtask_setup_stackargs(FAR struct task_tcb_s *tcb,
return -ENOMEM; return -ENOMEM;
} }
tcb->argv = stackargv;
/* Get the address of the string table that will lie immediately after /* Get the address of the string table that will lie immediately after
* the argv[] array and mark it as a null string. * 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. * NUL terminator in the string buffer.
*/ */
stackargv[0] = str; if (insert_name)
nbytes = strlen(name) + 1; {
strcpy(str, name); *stackargv++ = str;
str += nbytes; nbytes = strlen(name) + 1;
strcpy(str, name);
str += nbytes;
}
/* Copy each argument */ /* 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. * argument and its NUL terminator in the string buffer.
*/ */
stackargv[i + 1] = str; *stackargv++ = str;
nbytes = strlen(argv[i]) + 1; nbytes = strlen(argv[i]) + 1;
strcpy(str, argv[i]); strcpy(str, argv[i]);
str += nbytes; str += nbytes;
} }
/* Put a terminator entry at the end of the argv[] array. Then save the /* 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(). * nxtask_start().
*/ */
stackargv[argc + 1] = NULL; *stackargv++ = NULL;
tcb->argv = stackargv;
return OK; return OK;
} }
@ -696,20 +687,35 @@ int pthread_setup_scheduler(FAR struct pthread_tcb_s *tcb, int priority,
* task runs in. * task runs in.
* *
* Input Parameters: * Input Parameters:
* tcb - Address of the new task's TCB * tcb - Address of the new task's TCB
* name - Name of the new task (not used) * insert_name - Insert name to the first argv
* argv - A pointer to an array of input parameters. The array should be * name - Name of the new task
* terminated with a NULL argv[] value. If no parameters are * argv - A pointer to an array of input parameters. The array
* required, argv may be NULL. * should be terminated with a NULL argv[] value. If no
* parameters are required, argv may be NULL.
* *
* Returned Value: * Returned Value:
* OK * OK
* *
****************************************************************************/ ****************************************************************************/
int nxtask_setup_arguments(FAR struct task_tcb_s *tcb, FAR const char *name, int nxtask_setup_arguments(FAR struct task_tcb_s *tcb, bool insert_name,
FAR char * const argv[]) 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 */ /* Setup the task name */
nxtask_setup_name(tcb, 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. * privilege mode the task runs in.
*/ */
return nxtask_setup_stackargs(tcb, argv); return nxtask_setup_stackargs(tcb, insert_name, name, argv);
} }

View File

@ -208,7 +208,7 @@ FAR struct task_tcb_s *nxtask_setup_vfork(start_t retaddr)
name = parent->cmn.name; name = parent->cmn.name;
#endif #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 */ /* Now we have enough in place that we can join the group */