mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-15 10:17:20 +00:00
Fix a very long-standing error in handling .SHELL targets: this target
uses the brk_string function to parse the line. That function uses static storage for both the expanded string and the returned argv[] vector. The JobParseShell function simply stored away pointers into this static storage. On the next use of something like ${FOO:O} this storage would get overwritten with fatal results. This also allows us to make the shells[] array const bringing us one step further in making make WARNS=4 ready.
This commit is contained in:
parent
de4cbbf593
commit
21d15001f9
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=138079
@ -206,14 +206,11 @@ static Shell shells[] = {
|
|||||||
"v", "e",
|
"v", "e",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
static Shell *commandShell = &shells[DEFSHELL];/* this is the shell to
|
static Shell *commandShell = NULL; /* this is the shell to which we pass
|
||||||
* which we pass all
|
* all commands in the Makefile. It is
|
||||||
* commands in the Makefile.
|
* set by the Job_ParseShell function */
|
||||||
* It is set by the
|
char *shellPath = NULL, /* full pathname of executable image */
|
||||||
* Job_ParseShell function */
|
*shellName = NULL; /* last component of shell */
|
||||||
char *shellPath = NULL, /* full pathname of
|
|
||||||
* executable image */
|
|
||||||
*shellName = NULL; /* last component of shell */
|
|
||||||
|
|
||||||
|
|
||||||
static int maxJobs; /* The most children we can run at once */
|
static int maxJobs; /* The most children we can run at once */
|
||||||
@ -2071,9 +2068,90 @@ Job_Make(GNode *gn)
|
|||||||
(void) JobStart(gn, 0, NULL);
|
(void) JobStart(gn, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* JobCopyShell:
|
||||||
|
*
|
||||||
|
* Make a new copy of the shell structure including a copy of the strings
|
||||||
|
* in it. This also defaults some fields in case they are NULL.
|
||||||
|
*
|
||||||
|
* The function returns a pointer to the new shell structure otherwise.
|
||||||
|
*/
|
||||||
|
static Shell *
|
||||||
|
JobCopyShell(const Shell *osh)
|
||||||
|
{
|
||||||
|
Shell *nsh;
|
||||||
|
|
||||||
|
nsh = emalloc(sizeof(*nsh));
|
||||||
|
nsh->name = estrdup(osh->name);
|
||||||
|
|
||||||
|
if (osh->echoOff != NULL)
|
||||||
|
nsh->echoOff = estrdup(osh->echoOff);
|
||||||
|
else
|
||||||
|
nsh->echoOff = NULL;
|
||||||
|
if (osh->echoOn != NULL)
|
||||||
|
nsh->echoOn = estrdup(osh->echoOn);
|
||||||
|
else
|
||||||
|
nsh->echoOn = NULL;
|
||||||
|
nsh->hasEchoCtl = osh->hasEchoCtl;
|
||||||
|
|
||||||
|
if (osh->noPrint != NULL)
|
||||||
|
nsh->noPrint = estrdup(osh->noPrint);
|
||||||
|
else
|
||||||
|
nsh->noPrint = NULL;
|
||||||
|
nsh->noPLen = osh->noPLen;
|
||||||
|
|
||||||
|
nsh->hasErrCtl = osh->hasErrCtl;
|
||||||
|
if (osh->errCheck == NULL)
|
||||||
|
nsh->errCheck = estrdup("");
|
||||||
|
else
|
||||||
|
nsh->errCheck = estrdup(osh->errCheck);
|
||||||
|
if (osh->ignErr == NULL)
|
||||||
|
nsh->ignErr = estrdup("%s");
|
||||||
|
else
|
||||||
|
nsh->ignErr = estrdup(osh->ignErr);
|
||||||
|
|
||||||
|
if (osh->echo == NULL)
|
||||||
|
nsh->echo = estrdup("");
|
||||||
|
else
|
||||||
|
nsh->echo = estrdup(osh->echo);
|
||||||
|
|
||||||
|
if (osh->exit == NULL)
|
||||||
|
nsh->exit = estrdup("");
|
||||||
|
else
|
||||||
|
nsh->exit = estrdup(osh->exit);
|
||||||
|
|
||||||
|
return (nsh);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* JobFreeShell:
|
||||||
|
*
|
||||||
|
* Free a shell structure and all associated strings.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
JobFreeShell(Shell *sh)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (sh != NULL) {
|
||||||
|
free(sh->name);
|
||||||
|
free(sh->echoOff);
|
||||||
|
free(sh->echoOn);
|
||||||
|
free(sh->noPrint);
|
||||||
|
free(sh->errCheck);
|
||||||
|
free(sh->ignErr);
|
||||||
|
free(sh->echo);
|
||||||
|
free(sh->exit);
|
||||||
|
free(sh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Shell_Init(void)
|
Shell_Init(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (commandShell == NULL)
|
||||||
|
commandShell = JobCopyShell(&shells[DEFSHELL]);
|
||||||
|
|
||||||
if (shellPath == NULL) {
|
if (shellPath == NULL) {
|
||||||
/*
|
/*
|
||||||
* The user didn't specify a shell to use, so we are using the
|
* The user didn't specify a shell to use, so we are using the
|
||||||
@ -2451,6 +2529,18 @@ Job_ParseShell(char *line)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some checks (could be more)
|
||||||
|
*/
|
||||||
|
if (fullSpec) {
|
||||||
|
if ((newShell.echoOn != NULL) ^ (newShell.echoOff != NULL))
|
||||||
|
Parse_Error(PARSE_FATAL, "Shell must have either both echoOff and "
|
||||||
|
"echoOn or none of them");
|
||||||
|
|
||||||
|
if (newShell.echoOn != NULL && newShell.echoOff)
|
||||||
|
newShell.hasEchoCtl = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (path == NULL) {
|
if (path == NULL) {
|
||||||
/*
|
/*
|
||||||
* If no path was given, the user wants one of the pre-defined shells,
|
* If no path was given, the user wants one of the pre-defined shells,
|
||||||
@ -2460,16 +2550,13 @@ Job_ParseShell(char *line)
|
|||||||
*/
|
*/
|
||||||
if (newShell.name == NULL) {
|
if (newShell.name == NULL) {
|
||||||
Parse_Error(PARSE_FATAL, "Neither path nor name specified");
|
Parse_Error(PARSE_FATAL, "Neither path nor name specified");
|
||||||
return(FAILURE);
|
return (FAILURE);
|
||||||
} else {
|
|
||||||
if ((sh = JobMatchShell(newShell.name)) == NULL) {
|
|
||||||
Parse_Error(PARSE_FATAL, "%s: no matching shell",
|
|
||||||
newShell.name);
|
|
||||||
return(FAILURE);
|
|
||||||
}
|
|
||||||
commandShell = sh;
|
|
||||||
shellName = newShell.name;
|
|
||||||
}
|
}
|
||||||
|
if ((sh = JobMatchShell(newShell.name)) == NULL) {
|
||||||
|
Parse_Error(PARSE_FATAL, "%s: no matching shell", newShell.name);
|
||||||
|
return (FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* The user provided a path. If s/he gave nothing else (fullSpec is
|
* The user provided a path. If s/he gave nothing else (fullSpec is
|
||||||
@ -2478,45 +2565,37 @@ Job_ParseShell(char *line)
|
|||||||
* to a new location. In either case, we need to record the
|
* to a new location. In either case, we need to record the
|
||||||
* path the user gave for the shell.
|
* path the user gave for the shell.
|
||||||
*/
|
*/
|
||||||
shellPath = path;
|
free(shellPath);
|
||||||
path = strrchr(path, '/');
|
shellPath = estrdup(path);
|
||||||
if (path == NULL) {
|
if (newShell.name == NULL) {
|
||||||
path = shellPath;
|
/* get the base name as the name */
|
||||||
} else {
|
path = strrchr(path, '/');
|
||||||
path += 1;
|
if (path == NULL) {
|
||||||
}
|
path = shellPath;
|
||||||
if (newShell.name != NULL) {
|
} else {
|
||||||
shellName = newShell.name;
|
path += 1;
|
||||||
} else {
|
}
|
||||||
shellName = path;
|
newShell.name = path;
|
||||||
}
|
}
|
||||||
if (!fullSpec) {
|
|
||||||
if ((sh = JobMatchShell(shellName)) == NULL) {
|
if (!fullSpec) {
|
||||||
Parse_Error(PARSE_FATAL, "%s: no matching shell",
|
if ((sh = JobMatchShell(newShell.name)) == NULL) {
|
||||||
shellName);
|
Parse_Error(PARSE_FATAL, "%s: no matching shell",
|
||||||
return(FAILURE);
|
newShell.name);
|
||||||
|
return (FAILURE);
|
||||||
}
|
}
|
||||||
commandShell = sh;
|
|
||||||
} else {
|
} else {
|
||||||
commandShell = (Shell *) emalloc(sizeof(Shell));
|
sh = &newShell;
|
||||||
*commandShell = newShell;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (commandShell->echoOn && commandShell->echoOff) {
|
/* set the new shell */
|
||||||
commandShell->hasEchoCtl = TRUE;
|
JobFreeShell(commandShell);
|
||||||
}
|
commandShell = JobCopyShell(sh);
|
||||||
|
|
||||||
if (!commandShell->hasErrCtl) {
|
shellName = commandShell->name;
|
||||||
if (commandShell->errCheck == NULL) {
|
|
||||||
commandShell->errCheck = "";
|
|
||||||
}
|
|
||||||
if (commandShell->ignErr == NULL) {
|
|
||||||
commandShell->ignErr = "%s\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return SUCCESS;
|
return (SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
|
Loading…
Reference in New Issue
Block a user