mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-02-28 20:15:24 +08:00
add --enable-newlib-use-malloc-in-execl option The previous version of these functions allocated a 256 entry array and copied arguments in that array with no bound checking. That implementation always occupied 1024 bytes of stack for the array even in the common case in which the number of passed arguments is far less than 256, risking stack overflows in environments with small stacks, and caused a stack buffer overflow if called with more than 256 arguments. The improved implementation counts the actual number of passed arguments and allocates a suitable buffer. The default implementation uses alloca to allocate the buffer to satisfy the POSIX.1-2008 requirement that execl and execle should be callable from signal handlers, but it is possible to override this behavior and use malloc for targets where the risk of stack overflow due to unbounded stack allocations is a more pressing requirement than the corner case of allowing execl calls from signal handlers.
63 lines
1003 B
C
63 lines
1003 B
C
#ifndef _NO_EXECVE
|
|
|
|
/* execlp.c */
|
|
|
|
/* This and the other exec*.c files in this directory require
|
|
the target to provide the _execve syscall. */
|
|
|
|
#include <_ansi.h>
|
|
#include <unistd.h>
|
|
#ifdef _EXECL_USE_MALLOC
|
|
#include <errno.h>
|
|
#include <stdlib.h>
|
|
#else
|
|
#include <alloca.h>
|
|
#endif
|
|
|
|
|
|
#include <stdarg.h>
|
|
|
|
int
|
|
execlp (const char *path,
|
|
const char *arg0, ...)
|
|
|
|
|
|
{
|
|
int i;
|
|
va_list args;
|
|
const char **argv;
|
|
|
|
i = 1;
|
|
va_start (args, arg0);
|
|
do
|
|
i++;
|
|
while (va_arg (args, const char *) != NULL);
|
|
va_end (args);
|
|
#ifndef _EXECL_USE_MALLOC
|
|
argv = alloca (i * sizeof(const char *));
|
|
#else
|
|
argv = malloc (i * sizeof(const char *));
|
|
if (argv == NULL)
|
|
{
|
|
errno = ENOMEM;
|
|
return -1;
|
|
}
|
|
#endif
|
|
|
|
va_start (args, arg0);
|
|
argv[0] = arg0;
|
|
i = 1;
|
|
do
|
|
argv[i] = va_arg (args, const char *);
|
|
while (argv[i++] != NULL);
|
|
va_end (args);
|
|
|
|
i = execvp (path, (char * const *) argv);
|
|
#ifdef _EXECL_USE_MALLOC
|
|
free (argv);
|
|
#endif
|
|
return i;
|
|
}
|
|
|
|
#endif /* !_NO_EXECVE */
|