diff options
Diffstat (limited to 'posix/execvp.c')
-rw-r--r-- | posix/execvp.c | 98 |
1 files changed, 31 insertions, 67 deletions
diff --git a/posix/execvp.c b/posix/execvp.c index 9ccfd7fc22..d6f60c02e7 100644 --- a/posix/execvp.c +++ b/posix/execvp.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991,92,1995-99,2002,2004,2005 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 @@ -18,7 +18,6 @@ #include <unistd.h> #include <stdarg.h> -#include <stdbool.h> #include <stdlib.h> #include <string.h> #include <errno.h> @@ -27,9 +26,9 @@ /* The file is accessible but it is not an executable file. Invoke the shell to interpret it as a script. */ -static char ** +static void internal_function -allocate_scripts_argv (const char *file, char *const argv[]) +script_execute (const char *file, char *const argv[]) { /* Count the arguments. */ int argc = 0; @@ -37,19 +36,19 @@ allocate_scripts_argv (const char *file, char *const argv[]) ; /* Construct an argument list for the shell. */ - char **new_argv = (char **) malloc ((argc + 1) * sizeof (char *)); - if (new_argv != NULL) - { - new_argv[0] = (char *) _PATH_BSHELL; - new_argv[1] = (char *) file; - while (argc > 1) - { - new_argv[argc] = argv[argc - 1]; - --argc; - } - } - - return new_argv; + { + 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); + } } @@ -67,58 +66,42 @@ execvp (file, argv) return -1; } - char **script_argv = NULL; - if (strchr (file, '/') != NULL) { /* Don't search when it contains a slash. */ __execve (file, argv, __environ); if (errno == ENOEXEC) - { - script_argv = allocate_scripts_argv (file, argv); - if (script_argv != NULL) - { - __execve (script_argv[0], script_argv, __environ); - - free (script_argv); - } - } + script_execute (file, argv); } else { - char *path = getenv ("PATH"); - bool path_malloc = false; + int got_eacces = 0; + char *path, *p, *name; + size_t len; + size_t pathlen; + + 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'. */ - size_t len = confstr (_CS_PATH, (char *) NULL, 0); - path = (char *) malloc (1 + len); - if (path == NULL) - return -1; + len = confstr (_CS_PATH, (char *) NULL, 0); + path = (char *) __alloca (1 + len); path[0] = ':'; (void) confstr (_CS_PATH, path + 1, len); - path_malloc = true; } - size_t len = strlen (file) + 1; - size_t pathlen = strlen (path); - char *name = malloc (pathlen + len + 1); - if (name == NULL) - { - if (path_malloc) - free (path); - return -1; - } + 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 = '/'; - bool got_eacces = false; - char *p = path; + p = path; do { char *startp; @@ -137,21 +120,7 @@ execvp (file, argv) __execve (startp, argv, __environ); if (errno == ENOEXEC) - { - if (script_argv == NULL) - { - script_argv = allocate_scripts_argv (file, argv); - if (script_argv == NULL) - { - /* A possible EACCES error is not as important as - the ENOMEM. */ - got_eacces = false; - break; - } - } - - __execve (script_argv[0], script_argv, __environ); - } + script_execute (startp, argv); switch (errno) { @@ -159,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: @@ -187,11 +156,6 @@ execvp (file, argv) /* At least one failure was due to permissions, so report that error. */ __set_errno (EACCES); - - free (script_argv); - free (name); - if (path_malloc) - free (path); } /* Return the error from the last attempt (probably ENOENT). */ |