(start_job_command): Save and restore environ around vfork call.

(search_path): Function #if 0'd out.
(exec_command): Use execvp instead of search_path.
This commit is contained in:
Roland McGrath 1995-01-15 15:57:48 +00:00
parent e167e0a3c2
commit 37358a9a82

100
job.c
View file

@ -689,6 +689,8 @@ start_job_command (child)
{ {
/* Fork the child process. */ /* Fork the child process. */
char *parent_environ;
#ifdef POSIX #ifdef POSIX
(void) sigprocmask (SIG_BLOCK, &fatal_signal_set, (sigset_t *) 0); (void) sigprocmask (SIG_BLOCK, &fatal_signal_set, (sigset_t *) 0);
#else #else
@ -698,7 +700,9 @@ start_job_command (child)
#endif #endif
child->remote = 0; child->remote = 0;
parent_environ = environ;
child->pid = vfork (); child->pid = vfork ();
environ = parent_environ; /* Restore value child may have clobbered. */
if (child->pid == 0) if (child->pid == 0)
{ {
/* We are the child side. */ /* We are the child side. */
@ -1073,6 +1077,8 @@ child_execute_job (stdin_fd, stdout_fd, argv, envp)
exec_command (argv, envp); exec_command (argv, envp);
} }
#if 0
/* Search PATH for FILE. /* Search PATH for FILE.
If successful, store the full pathname in PROGRAM and return 1. If successful, store the full pathname in PROGRAM and return 1.
If not sucessful, return zero. */ If not sucessful, return zero. */
@ -1171,6 +1177,7 @@ search_path (file, path, program)
return 0; return 0;
} }
#endif /* search_path commented out */
/* Replace the current process with one running the command in ARGV, /* Replace the current process with one running the command in ARGV,
with environment ENVP. This function does not return. */ with environment ENVP. This function does not return. */
@ -1180,71 +1187,54 @@ exec_command (argv, envp)
char **argv, **envp; char **argv, **envp;
{ {
char *shell, *path; char *shell, *path;
PATH_VAR (program);
register char **ep;
shell = path = 0;
for (ep = envp; *ep != 0; ++ep)
{
if (shell == 0 && !strncmp(*ep, "SHELL=", 6))
shell = &(*ep)[6];
else if (path == 0 && !strncmp(*ep, "PATH=", 5))
path = &(*ep)[5];
else if (path != 0 && shell != 0)
break;
}
/* Be the user, permanently. */ /* Be the user, permanently. */
child_access (); child_access ();
if (!search_path (argv[0], path, program)) /* Run the program. */
error ("%s: Command not found", argv[0]); environ = envp;
else execvp (argv[0], argv);
switch (errno)
{ {
/* Run the program. */ case ENOENT:
execve (program, argv, envp); error ("%s: Command not found", argv[0]);
break;
case ENOEXEC:
{
/* The file is not executable. Try it as a shell script. */
char *shell;
char **new_argv;
int argc;
if (errno == ENOEXEC) shell = getenv ("SHELL");
{ if (shell == 0)
PATH_VAR (shell_program); shell = default_shell;
char *shell_path;
if (shell == 0)
shell_path = default_shell;
else
{
if (search_path (shell, path, shell_program))
shell_path = shell_program;
else
{
shell_path = 0;
error ("%s: Shell program not found", shell);
}
}
if (shell_path != 0) argc = 1;
{ while (argv[argc] != 0)
char **new_argv; ++argc;
int argc;
argc = 1; new_argv = (char **) alloca ((1 + argc + 1) * sizeof (char *));
while (argv[argc] != 0) new_argv[0] = shell;
++argc; new_argv[1] = program;
while (argc > 0)
{
new_argv[1 + argc] = argv[argc];
--argc;
}
new_argv = (char **) alloca ((1 + argc + 1) * sizeof (char *)); execvp (shell, new_argv);
new_argv[0] = shell_path; if (errno == ENOENT)
new_argv[1] = program; error ("%s: Shell program not found", shell);
while (argc > 0) else
{ perror_with_name ("execvp: ", shell);
new_argv[1 + argc] = argv[argc]; break;
--argc; }
}
execve (shell_path, new_argv, envp); default:
perror_with_name ("execve: ", shell_path); perror_with_name ("execvp: ", argv[0]);
} break;
}
else
perror_with_name ("execve: ", program);
} }
_exit (127); _exit (127);