execl() no longer depends on CONFIG_MAX_TASK_ARGS

This commit is contained in:
Gregory Nutt 2014-11-12 18:44:11 -06:00
parent bb65701ccd
commit 597999400e

View File

@ -47,6 +47,11 @@
/**************************************************************************** /****************************************************************************
* Pre-processor Definitions * 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 * Global Variables
@ -119,28 +124,60 @@
int execl(FAR const char *path, ...) int execl(FAR const char *path, ...)
{ {
FAR char *argv[CONFIG_MAX_TASK_ARGS+1]; FAR char **argv;
size_t nargs;
va_list ap; va_list ap;
int argc; int argc;
int ret;
/* Count the number of arguments */
va_start(ap, path);
for (nargs = 0, argc = 0; argv[argc]; argc++)
{
/* 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)
{
set_errno(E2BIG);
return ERROR;
}
}
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 */ /* Collect the arguments into the argv[] array */
va_start(ap, path); va_start(ap, path);
for (argc = 0; argc < CONFIG_MAX_TASK_ARGS; argc++) for (argc = 0; argc < nargs; argc++)
{ {
argv[argc] = va_arg(ap, FAR char *); argv[argc] = va_arg(ap, FAR char *);
if (argv[argc] == NULL)
{
break;
}
} }
argv[CONFIG_MAX_TASK_ARGS] = NULL; argv[nargs] = NULL;
va_end(ap); va_end(ap);
/* Then let execv() do the real work */ /* 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 */ #endif /* CONFIG_LIBC_EXECFUNCS */