From 6a032d81581978187f562e5533a32e0a6a3d352b Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sat, 10 Feb 1996 10:00:27 +0000 Subject: Sat Feb 10 04:18:48 1996 Roland McGrath * posix/execvp.c: If execv fails with ENOEXEC, run the shell on the file. Fri Feb 9 11:46:45 1996 Roland McGrath * 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. --- posix/execvp.c | 55 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 10 deletions(-) (limited to 'posix/execvp.c') 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 #include #include +#include /* 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'); } -- cgit v1.2.3