Expand the scope of the .SHELL specification to also cover
the compat mode of operation and the != operator. While here, fixed a bug in the .SHELL directive processing when only the name= attribute is specified and no built-in shell matches this name, causing null pointer dereference. Obtained from: NetBSD (except for bugs)
This commit is contained in:
parent
85986ce002
commit
3ecaab1c99
@ -303,8 +303,9 @@ Compat_RunCommand (void *cmdp, void *gnp)
|
||||
* -e flag as well as -c if it's supposed to exit when it hits an
|
||||
* error.
|
||||
*/
|
||||
static char *shargv[4] = { "/bin/sh" };
|
||||
static char *shargv[4];
|
||||
|
||||
shargv[0] = shellPath;
|
||||
shargv[1] = (errCheck ? "-ec" : "-c");
|
||||
shargv[2] = cmd;
|
||||
shargv[3] = (char *)NULL;
|
||||
@ -315,13 +316,14 @@ Compat_RunCommand (void *cmdp, void *gnp)
|
||||
* This command must be passed by the shell for other reasons..
|
||||
* or.. possibly not at all.
|
||||
*/
|
||||
static char *shargv[4] = { "/bin/sh" };
|
||||
static char *shargv[4];
|
||||
|
||||
if (internal == -1) {
|
||||
/* Command does not need to be executed */
|
||||
return (0);
|
||||
}
|
||||
|
||||
shargv[0] = shellPath;
|
||||
shargv[1] = (errCheck ? "-ec" : "-c");
|
||||
shargv[2] = cmd;
|
||||
shargv[3] = (char *)NULL;
|
||||
@ -655,6 +657,7 @@ Compat_Run(Lst targs)
|
||||
int errors; /* Number of targets not remade due to errors */
|
||||
|
||||
CompatInit();
|
||||
Shell_Init(); /* Set up shell. */
|
||||
|
||||
if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
|
||||
signal(SIGINT, CompatInterrupt);
|
||||
|
@ -224,9 +224,9 @@ static Shell *commandShell = &shells[DEFSHELL];/* this is the shell to
|
||||
* commands in the Makefile.
|
||||
* It is set by the
|
||||
* Job_ParseShell function */
|
||||
static char *shellPath = NULL, /* full pathname of
|
||||
char *shellPath = NULL, /* full pathname of
|
||||
* executable image */
|
||||
*shellName; /* last component of shell */
|
||||
*shellName = NULL; /* last component of shell */
|
||||
|
||||
|
||||
static int maxJobs; /* The most children we can run at once */
|
||||
@ -2332,6 +2332,22 @@ Job_Make(GNode *gn)
|
||||
(void) JobStart(gn, 0, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
Shell_Init(void)
|
||||
{
|
||||
if (shellPath == NULL) {
|
||||
/*
|
||||
* The user didn't specify a shell to use, so we are using the
|
||||
* default one... Both the absolute path and the last component
|
||||
* must be set. The last component is taken from the 'name' field
|
||||
* of the default shell description pointed-to by commandShell.
|
||||
* All default shells are located in _PATH_DEFSHELLDIR.
|
||||
*/
|
||||
shellName = commandShell->name;
|
||||
shellPath = str_concat(_PATH_DEFSHELLDIR, shellName, STR_ADDSLASH);
|
||||
}
|
||||
}
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* Job_Init --
|
||||
@ -2377,18 +2393,7 @@ Job_Init(int maxproc, int maxlocal)
|
||||
targFmt = TARG_FMT;
|
||||
}
|
||||
|
||||
if (shellPath == NULL) {
|
||||
/*
|
||||
* The user didn't specify a shell to use, so we are using the
|
||||
* default one... Both the absolute path and the last component
|
||||
* must be set. The last component is taken from the 'name' field
|
||||
* of the default shell description pointed-to by commandShell.
|
||||
* All default shells are located in _PATH_DEFSHELLDIR.
|
||||
*/
|
||||
shellName = commandShell->name;
|
||||
shellPath = str_concat(_PATH_DEFSHELLDIR, shellName, STR_ADDSLASH);
|
||||
}
|
||||
|
||||
Shell_Init();
|
||||
if (commandShell->exit == NULL) {
|
||||
commandShell->exit = "";
|
||||
}
|
||||
@ -2547,7 +2552,7 @@ JobMatchShell(char *name)
|
||||
match = sh;
|
||||
}
|
||||
}
|
||||
return(match == NULL ? sh : match);
|
||||
return(match);
|
||||
}
|
||||
|
||||
/*-
|
||||
@ -2601,7 +2606,7 @@ Job_ParseShell(char *line)
|
||||
char **argv;
|
||||
int argc;
|
||||
char *path;
|
||||
Shell newShell;
|
||||
Shell newShell, *sh;
|
||||
Boolean fullSpec = FALSE;
|
||||
|
||||
while (isspace((unsigned char) *line)) {
|
||||
@ -2661,7 +2666,12 @@ Job_ParseShell(char *line)
|
||||
Parse_Error(PARSE_FATAL, "Neither path nor name specified");
|
||||
return(FAILURE);
|
||||
} else {
|
||||
commandShell = JobMatchShell(newShell.name);
|
||||
if ((sh = JobMatchShell(newShell.name)) == NULL) {
|
||||
Parse_Error(PARSE_FATAL, "%s: no matching shell",
|
||||
newShell.name);
|
||||
return(FAILURE);
|
||||
}
|
||||
commandShell = sh;
|
||||
shellName = newShell.name;
|
||||
}
|
||||
} else {
|
||||
@ -2685,7 +2695,12 @@ Job_ParseShell(char *line)
|
||||
shellName = path;
|
||||
}
|
||||
if (!fullSpec) {
|
||||
commandShell = JobMatchShell(shellName);
|
||||
if ((sh = JobMatchShell(shellName)) == NULL) {
|
||||
Parse_Error(PARSE_FATAL, "%s: no matching shell",
|
||||
shellName);
|
||||
return(FAILURE);
|
||||
}
|
||||
commandShell = sh;
|
||||
} else {
|
||||
commandShell = (Shell *) emalloc(sizeof(Shell));
|
||||
*commandShell = newShell;
|
||||
|
@ -205,6 +205,9 @@ typedef struct Shell {
|
||||
char *exit; /* exit on error */
|
||||
} Shell;
|
||||
|
||||
extern char *shellPath;
|
||||
extern char *shellName;
|
||||
|
||||
/*
|
||||
* If REMOTE is defined then these things need exposed, otherwise they are
|
||||
* static to job.c!
|
||||
@ -229,6 +232,7 @@ extern Boolean jobFull; /* Non-zero if no more jobs should/will start*/
|
||||
extern int maxJobs; /* Number of jobs that may run */
|
||||
|
||||
|
||||
void Shell_Init(void);
|
||||
void Job_Touch(GNode *, Boolean);
|
||||
Boolean Job_CheckCommands(GNode *, void (*abortProc)(const char *, ...));
|
||||
void Job_CatchChildren(Boolean);
|
||||
|
@ -1042,10 +1042,12 @@ Cmd_Exec(char *cmd, char **error)
|
||||
|
||||
*error = NULL;
|
||||
|
||||
if (shellPath == NULL)
|
||||
Shell_Init();
|
||||
/*
|
||||
* Set up arguments for shell
|
||||
*/
|
||||
args[0] = "sh";
|
||||
args[0] = shellName;
|
||||
args[1] = "-c";
|
||||
args[2] = cmd;
|
||||
args[3] = NULL;
|
||||
@ -1076,15 +1078,7 @@ Cmd_Exec(char *cmd, char **error)
|
||||
(void) dup2(fds[1], 1);
|
||||
(void) close(fds[1]);
|
||||
|
||||
#if defined(DEFSHELL) && DEFSHELL == 0
|
||||
(void) execv("/bin/csh", args);
|
||||
#elif DEFSHELL == 1
|
||||
(void) execv("/bin/sh", args);
|
||||
#elif DEFSHELL == 2
|
||||
(void) execv("/bin/ksh", args);
|
||||
#else
|
||||
#error "DEFSHELL must be 1 or 2."
|
||||
#endif
|
||||
(void) execv(shellPath, args);
|
||||
_exit(1);
|
||||
/*NOTREACHED*/
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user