diff options
author | ru <ru@FreeBSD.org> | 2004-10-23 21:34:41 +0000 |
---|---|---|
committer | ru <ru@FreeBSD.org> | 2004-10-23 21:34:41 +0000 |
commit | 2f410fc7e2e8560258b86e1a9d71d559453140e9 (patch) | |
tree | 6c6a4b030e6179c38af1f4774457a0f5c68fea66 | |
parent | 80dc3e1bc2d61be3d57a34c9fdb4d5c0f07d93ea (diff) | |
download | FreeBSD-src-2f410fc7e2e8560258b86e1a9d71d559453140e9.zip FreeBSD-src-2f410fc7e2e8560258b86e1a9d71d559453140e9.tar.gz |
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)
-rw-r--r-- | usr.bin/make/compat.c | 7 | ||||
-rw-r--r-- | usr.bin/make/job.c | 51 | ||||
-rw-r--r-- | usr.bin/make/job.h | 4 | ||||
-rw-r--r-- | usr.bin/make/main.c | 14 |
4 files changed, 46 insertions, 30 deletions
diff --git a/usr.bin/make/compat.c b/usr.bin/make/compat.c index 79531ef..b9ba32b 100644 --- a/usr.bin/make/compat.c +++ b/usr.bin/make/compat.c @@ -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); diff --git a/usr.bin/make/job.c b/usr.bin/make/job.c index 8f0310b..4f1f83f 100644 --- a/usr.bin/make/job.c +++ b/usr.bin/make/job.c @@ -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; diff --git a/usr.bin/make/job.h b/usr.bin/make/job.h index 284b16b..3dcad23 100644 --- a/usr.bin/make/job.h +++ b/usr.bin/make/job.h @@ -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); diff --git a/usr.bin/make/main.c b/usr.bin/make/main.c index 284cfe2..da2be48 100644 --- a/usr.bin/make/main.c +++ b/usr.bin/make/main.c @@ -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*/ |