Skip to content

Commit

Permalink
execl() no longer depends on CONFIG_MAX_TASK_ARGS
Browse files Browse the repository at this point in the history
  • Loading branch information
gregory-nutt committed Nov 13, 2014
1 parent bb65701 commit 5979994
Showing 1 changed file with 45 additions and 8 deletions.
53 changes: 45 additions & 8 deletions libc/unistd/lib_execl.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* This is an artificial limit to detect error conditions where an argv[]
* list is not properly terminated.
*/

#define MAX_EXECL_ARGS 256

/****************************************************************************
* Global Variables
Expand Down Expand Up @@ -119,28 +124,60 @@

int execl(FAR const char *path, ...)
{
FAR char *argv[CONFIG_MAX_TASK_ARGS+1];
FAR char **argv;
size_t nargs;
va_list ap;
int argc;
int ret;

/* Collect the arguments into the argv[] array */
/* Count the number of arguments */

va_start(ap, path);
for (argc = 0; argc < CONFIG_MAX_TASK_ARGS; argc++)
for (nargs = 0, argc = 0; argv[argc]; argc++)
{
argv[argc] = va_arg(ap, FAR char *);
if (argv[argc] == NULL)
/* Increment the number of args. Here is a sanity check to prevent
* running away with an unterminated argv[] list. MAX_EXECL_ARGS
* should be sufficiently large that this never happens in normal
* usage.
*/

if (++nargs > MAX_EXECL_ARGS)
{
break;
set_errno(E2BIG);
return ERROR;
}
}

argv[CONFIG_MAX_TASK_ARGS] = NULL;
va_end(ap);

/* Allocate a temporary argv[] array */

argv = (FAR char **)malloc((nargs + 1) * sizeof(FAR char *));
if (argv = (FAR char **)NULL)
{
set_errno(ENOMEM);
return ERROR;
}

/* Collect the arguments into the argv[] array */

va_start(ap, path);
for (argc = 0; argc < nargs; argc++)
{
argv[argc] = va_arg(ap, FAR char *);
}

argv[nargs] = NULL;
va_end(ap);

/* Then let execv() do the real work */

return execv(path, (char * const *)&argv);
ret = execv(path, (char * const *)&argv);

/* Free the allocated argv[] list */

free(argv);
return ret;
}

#endif /* CONFIG_LIBC_EXECFUNCS */

0 comments on commit 5979994

Please sign in to comment.