diff options
author | Roland McGrath <roland@gnu.org> | 1996-02-10 10:00:27 +0000 |
---|---|---|
committer | Roland McGrath <roland@gnu.org> | 1996-02-10 10:00:27 +0000 |
commit | 6a032d81581978187f562e5533a32e0a6a3d352b (patch) | |
tree | 3d71a420044775c0cb50a38f7cf46ad7b6c9a0c1 /posix/execvp.c | |
parent | 56f778c958709876173156cf84f810150b2b8b1a (diff) | |
download | glibc-6a032d81581978187f562e5533a32e0a6a3d352b.tar.gz glibc-6a032d81581978187f562e5533a32e0a6a3d352b.tar.xz glibc-6a032d81581978187f562e5533a32e0a6a3d352b.zip |
Sat Feb 10 04:18:48 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu> cvs/libc-960210
* posix/execvp.c: If execv fails with ENOEXEC, run the shell on the file. Fri Feb 9 11:46:45 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu> * time/Makefile (CFLAGS-zdump.c, CFLAGS-zic.c, CFLAGS-ialloc.c, CFLAGS-scheck.c): Use -DNOID instead of -Wno-unused. * hurd/Makefile (user-interfaces): Added hurd/tioctl.
Diffstat (limited to 'posix/execvp.c')
-rw-r--r-- | posix/execvp.c | 55 |
1 files changed, 45 insertions, 10 deletions
diff --git a/posix/execvp.c b/posix/execvp.c index 17072ce844..76a9ba62a3 100644 --- a/posix/execvp.c +++ b/posix/execvp.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc. +/* Copyright (C) 1991, 1992, 1995, 1996 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 @@ -21,6 +21,7 @@ Cambridge, MA 02139, USA. */ #include <stdlib.h> #include <string.h> #include <errno.h> +#include <paths.h> /* Execute FILE, searching in the `PATH' environment variable if it contains no slashes, with arguments ARGV and environment from `environ'. */ @@ -29,9 +30,34 @@ execvp (file, argv) const char *file; char *const argv[]; { + void execute (const char *file, char *const argv[]) + { + execv (file, argv); + + if (errno == ENOEXEC) + { + /* The file is accessible but it is not an executable file. + Invoke the shell to interpret it as a script. */ + + int argc; + char **new_argv; + + /* Count the arguments. */ + for (argc = 0; argv[argc++];); + + /* Construct an argument list for the shell. */ + new_argv = __alloca ((argc + 1) * sizeof (char *)); + for (new_argv[0] = _PATH_BSHELL; argc > 0; --argc) + new_argv[argc] = argv[argc - 1]; + + /* Execute the shell. */ + execv (new_argv[0], new_argv); + } + } + if (strchr (file, '/') != NULL) /* Don't search when it contains a slash. */ - return execv (file, argv); + execute (file, argv); else { char *path, *p, *name; @@ -72,14 +98,23 @@ execvp (file, argv) } /* Try to execute this name. If it works, execv will not return. */ - execv (name, argv); - if (errno != ENOENT && errno != EACCES) - /* Those errors indicate the file is missing or not executable - by us, in which case we want to just try the next path - directory. Some other error means we found an executable - file, but something went wrong executing it; return the - error to our caller. */ - return -1; + execute (name, argv); + + switch (errno) + { + case ENOENT: + case EACCES: + /* Those errors indicate the file is missing or not executable + by us, in which case we want to just try the next path + directory. */ + break; + + default: + /* Some other error means we found an executable file, but + something went wrong executing it; return the error to our + caller. */ + return -1; + } } while (*p++ != '\0'); } |