diff options
author | Ulrich Drepper <drepper@redhat.com> | 2004-12-22 20:10:10 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2004-12-22 20:10:10 +0000 |
commit | a334319f6530564d22e775935d9c91663623a1b4 (patch) | |
tree | b5877475619e4c938e98757d518bb1e9cbead751 /posix/execvp.c | |
parent | 0ecb606cb6cf65de1d9fc8a919bceb4be476c602 (diff) | |
download | glibc-a334319f6530564d22e775935d9c91663623a1b4.tar.gz |
(CFLAGS-tst-align.c): Add -mpreferred-stack-boundary=4.
Diffstat (limited to 'posix/execvp.c')
-rw-r--r-- | posix/execvp.c | 128 |
1 files changed, 36 insertions, 92 deletions
diff --git a/posix/execvp.c b/posix/execvp.c index 887379e3a2..d6f60c02e7 100644 --- a/posix/execvp.c +++ b/posix/execvp.c @@ -1,5 +1,4 @@ -/* Copyright (C) 1991,92, 1995-99, 2002, 2004, 2005, 2007 - Free Software Foundation, Inc. +/* Copyright (C) 1991,92,1995-99,2002,2004 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,10 +16,8 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include <alloca.h> #include <unistd.h> #include <stdarg.h> -#include <stdbool.h> #include <stdlib.h> #include <string.h> #include <errno.h> @@ -31,16 +28,27 @@ the shell to interpret it as a script. */ static void internal_function -scripts_argv (const char *file, char *const argv[], int argc, char **new_argv) +script_execute (const char *file, char *const argv[]) { + /* Count the arguments. */ + int argc = 0; + while (argv[argc++]) + ; + /* Construct an argument list for the shell. */ - new_argv[0] = (char *) _PATH_BSHELL; - new_argv[1] = (char *) file; - while (argc > 1) - { - new_argv[argc] = argv[argc - 1]; - --argc; - } + { + char *new_argv[argc + 1]; + new_argv[0] = (char *) _PATH_BSHELL; + new_argv[1] = (char *) file; + while (argc > 1) + { + new_argv[argc] = argv[argc - 1]; + --argc; + } + + /* Execute the shell. */ + __execve (new_argv[0], new_argv, __environ); + } } @@ -64,74 +72,36 @@ execvp (file, argv) __execve (file, argv, __environ); if (errno == ENOEXEC) - { - /* Count the arguments. */ - int argc = 0; - while (argv[argc++]) - ; - size_t len = (argc + 1) * sizeof (char *); - char **script_argv; - void *ptr = NULL; - if (__libc_use_alloca (len)) - script_argv = alloca (len); - else - script_argv = ptr = malloc (len); - - if (script_argv != NULL) - { - scripts_argv (file, argv, argc, script_argv); - __execve (script_argv[0], script_argv, __environ); - - free (ptr); - } - } + script_execute (file, argv); } else { + int got_eacces = 0; + char *path, *p, *name; + size_t len; size_t pathlen; - size_t alloclen = 0; - char *path = getenv ("PATH"); - if (path == NULL) - { - pathlen = confstr (_CS_PATH, (char *) NULL, 0); - alloclen = pathlen + 1; - } - else - pathlen = strlen (path); - - size_t len = strlen (file) + 1; - alloclen += pathlen + len + 1; - - char *name; - char *path_malloc = NULL; - if (__libc_use_alloca (alloclen)) - name = alloca (alloclen); - else - { - path_malloc = name = malloc (alloclen); - if (name == NULL) - return -1; - } + path = getenv ("PATH"); if (path == NULL) { /* There is no `PATH' in the environment. The default search path is the current directory followed by the path `confstr' returns for `_CS_PATH'. */ - path = name + pathlen + len + 1; + len = confstr (_CS_PATH, (char *) NULL, 0); + path = (char *) __alloca (1 + len); path[0] = ':'; - (void) confstr (_CS_PATH, path + 1, pathlen); + (void) confstr (_CS_PATH, path + 1, len); } + len = strlen (file) + 1; + pathlen = strlen (path); + name = __alloca (pathlen + len + 1); /* Copy the file name at the top. */ name = (char *) memcpy (name + pathlen + 1, file, len); /* And add the slash. */ *--name = '/'; - char **script_argv = NULL; - void *script_argv_malloc = NULL; - bool got_eacces = false; - char *p = path; + p = path; do { char *startp; @@ -146,34 +116,11 @@ execvp (file, argv) else startp = (char *) memcpy (name - (p - path), path, p - path); - /* Try to execute this name. If it works, execve will not return. */ + /* Try to execute this name. If it works, execv will not return. */ __execve (startp, argv, __environ); if (errno == ENOEXEC) - { - if (script_argv == NULL) - { - /* Count the arguments. */ - int argc = 0; - while (argv[argc++]) - ; - size_t arglen = (argc + 1) * sizeof (char *); - if (__libc_use_alloca (alloclen + arglen)) - script_argv = alloca (arglen); - else - script_argv = script_argv_malloc = malloc (arglen); - if (script_argv == NULL) - { - /* A possible EACCES error is not as important as - the ENOMEM. */ - got_eacces = false; - break; - } - scripts_argv (startp, argv, argc, script_argv); - } - - __execve (script_argv[0], script_argv, __environ); - } + script_execute (startp, argv); switch (errno) { @@ -181,7 +128,7 @@ execvp (file, argv) /* Record the we got a `Permission denied' error. If we end up finding no executable we can use, we want to diagnose that we did find one but were denied access. */ - got_eacces = true; + got_eacces = 1; case ENOENT: case ESTALE: case ENOTDIR: @@ -207,11 +154,8 @@ execvp (file, argv) /* We tried every element and none of them worked. */ if (got_eacces) /* At least one failure was due to permissions, so report that - error. */ + error. */ __set_errno (EACCES); - - free (script_argv_malloc); - free (path_malloc); } /* Return the error from the last attempt (probably ENOENT). */ |