summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchristos <christos@NetBSD.org>1998-03-26 19:20:36 +0000
committerchristos <christos@NetBSD.org>1998-03-26 19:20:36 +0000
commitf46f2d693ea899371cf704323e0db1dbff3765c7 (patch)
treec5ccdf0415543ce8bad914b7d0c8182f8b26fa03
parent531db9e0d34f755c147d58f79e07983fea5e522d (diff)
PR/5210: Hauke Fath: make core dumps with .SHELL
Unfortunately this revealed a deeper problem with the brk_string code. To fix it: - remove sharing of the buffer between brk_string invocations - change the semantics of brk_string so that the argument array starts with 0, and return the buffer where the strings are stored
-rw-r--r--usr.bin/make/compat.c18
-rw-r--r--usr.bin/make/job.c111
-rw-r--r--usr.bin/make/job.h5
-rw-r--r--usr.bin/make/main.c22
-rw-r--r--usr.bin/make/make.c8
-rw-r--r--usr.bin/make/nonints.h6
-rw-r--r--usr.bin/make/str.c56
-rw-r--r--usr.bin/make/var.c14
8 files changed, 123 insertions, 117 deletions
diff --git a/usr.bin/make/compat.c b/usr.bin/make/compat.c
index f874d5d02d8..903ba04a63a 100644
--- a/usr.bin/make/compat.c
+++ b/usr.bin/make/compat.c
@@ -1,4 +1,4 @@
-/* $NetBSD: compat.c,v 1.23 1997/12/31 06:06:12 thorpej Exp $ */
+/* $NetBSD: compat.c,v 1.24 1998/03/26 19:20:36 christos Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -39,14 +39,14 @@
*/
#ifdef MAKE_BOOTSTRAP
-static char rcsid[] = "$NetBSD: compat.c,v 1.23 1997/12/31 06:06:12 thorpej Exp $";
+static char rcsid[] = "$NetBSD: compat.c,v 1.24 1998/03/26 19:20:36 christos Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)compat.c 8.2 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: compat.c,v 1.23 1997/12/31 06:06:12 thorpej Exp $");
+__RCSID("$NetBSD: compat.c,v 1.24 1998/03/26 19:20:36 christos Exp $");
#endif
#endif /* not lint */
#endif
@@ -157,7 +157,7 @@ CompatRunCommand (cmdp, gnp)
ClientData gnp; /* Node from which the command came */
{
char *cmdStart; /* Start of expanded command */
- register char *cp;
+ char *cp, *bp;
Boolean silent, /* Don't print command */
errCheck; /* Check errors */
int reason; /* Reason for child's death */
@@ -188,7 +188,7 @@ CompatRunCommand (cmdp, gnp)
cmdStart = Var_Subst (NULL, cmd, gn, FALSE);
/*
- * brk_string will return an argv with a NULL in av[1], thus causing
+ * brk_string will return an argv with a NULL in av[0], thus causing
* execvp to choke and die horribly. Besides, how can we execute a null
* command? In any case, we warn the user that the command expanded to
* nothing (is this the right thing to do?).
@@ -263,15 +263,13 @@ CompatRunCommand (cmdp, gnp)
shargv[3] = (char *)NULL;
av = shargv;
argc = 0;
+ bp = NULL;
} else {
/*
* No meta-characters, so no need to exec a shell. Break the command
* into words to form an argument vector we can execute.
- * brk_string sticks our name in av[0], so we have to
- * skip over it...
*/
- av = brk_string(cmd, &argc, TRUE);
- av += 1;
+ av = brk_string(cmd, &argc, TRUE, &bp);
}
local = TRUE;
@@ -293,6 +291,8 @@ CompatRunCommand (cmdp, gnp)
}
_exit(1);
}
+ if (bp)
+ free(bp);
free(cmdStart);
Lst_Replace (cmdNode, (ClientData) NULL);
diff --git a/usr.bin/make/job.c b/usr.bin/make/job.c
index f1c7aa1c7e7..f3ef4d1b4c5 100644
--- a/usr.bin/make/job.c
+++ b/usr.bin/make/job.c
@@ -1,4 +1,4 @@
-/* $NetBSD: job.c,v 1.21 1997/09/28 03:31:05 lukem Exp $ */
+/* $NetBSD: job.c,v 1.22 1998/03/26 19:20:36 christos Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -39,14 +39,14 @@
*/
#ifdef MAKE_BOOTSTRAP
-static char rcsid[] = "$NetBSD: job.c,v 1.21 1997/09/28 03:31:05 lukem Exp $";
+static char rcsid[] = "$NetBSD: job.c,v 1.22 1998/03/26 19:20:36 christos Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)job.c 8.2 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: job.c,v 1.21 1997/09/28 03:31:05 lukem Exp $");
+__RCSID("$NetBSD: job.c,v 1.22 1998/03/26 19:20:36 christos Exp $");
#endif
#endif /* not lint */
#endif
@@ -79,6 +79,8 @@ __RCSID("$NetBSD: job.c,v 1.21 1997/09/28 03:31:05 lukem Exp $");
* Hence, the makefile must have been parsed
* before this function is called.
*
+ * Job_End Cleanup any memory used.
+ *
* Job_Full Return TRUE if the job table is filled.
*
* Job_Empty Return TRUE if the job table is completely
@@ -88,7 +90,7 @@ __RCSID("$NetBSD: job.c,v 1.21 1997/09/28 03:31:05 lukem Exp $");
* the line as a shell specification. Returns
* FAILURE if the spec was incorrect.
*
- * Job_End Perform any final processing which needs doing.
+ * Job_Finish Perform any final processing which needs doing.
* This includes the execution of any commands
* which have been/were attached to the .END
* target. It should only be called when the
@@ -220,7 +222,8 @@ static Shell *commandShell = &shells[DEFSHELL];/* this is the shell to
* Job_ParseShell function */
static char *shellPath = NULL, /* full pathname of
* executable image */
- *shellName; /* last component of shell */
+ *shellName = NULL, /* last component of shell */
+ *shellArgv = NULL; /* Custom shell args */
static int maxJobs; /* The most children we can run at once */
@@ -2662,47 +2665,52 @@ Job_ParseShell(line)
while (isspace(*line)) {
line++;
}
- words = brk_string(line, &wordCount, TRUE);
+
+ if (shellArgv)
+ free(shellArgv);
+
+ words = brk_string(line, &wordCount, TRUE, &shellArgv);
memset((Address)&newShell, 0, sizeof(newShell));
/*
* Parse the specification by keyword
*/
- for (path = NULL, argc = wordCount - 1, argv = words + 1;
- argc != 0;
- argc--, argv++) {
- if (strncmp(*argv, "path=", 5) == 0) {
- path = &argv[0][5];
- } else if (strncmp(*argv, "name=", 5) == 0) {
- newShell.name = &argv[0][5];
- } else {
- if (strncmp(*argv, "quiet=", 6) == 0) {
- newShell.echoOff = &argv[0][6];
- } else if (strncmp(*argv, "echo=", 5) == 0) {
- newShell.echoOn = &argv[0][5];
- } else if (strncmp(*argv, "filter=", 7) == 0) {
- newShell.noPrint = &argv[0][7];
- newShell.noPLen = strlen(newShell.noPrint);
- } else if (strncmp(*argv, "echoFlag=", 9) == 0) {
- newShell.echo = &argv[0][9];
- } else if (strncmp(*argv, "errFlag=", 8) == 0) {
- newShell.exit = &argv[0][8];
- } else if (strncmp(*argv, "hasErrCtl=", 10) == 0) {
- char c = argv[0][10];
- newShell.hasErrCtl = !((c != 'Y') && (c != 'y') &&
+ for (path = NULL, argc = wordCount - 1, argv = words;
+ argc != 0;
+ argc--, argv++) {
+ if (strncmp(*argv, "path=", 5) == 0) {
+ path = &argv[0][5];
+ } else if (strncmp(*argv, "name=", 5) == 0) {
+ newShell.name = &argv[0][5];
+ } else {
+ if (strncmp(*argv, "quiet=", 6) == 0) {
+ newShell.echoOff = &argv[0][6];
+ } else if (strncmp(*argv, "echo=", 5) == 0) {
+ newShell.echoOn = &argv[0][5];
+ } else if (strncmp(*argv, "filter=", 7) == 0) {
+ newShell.noPrint = &argv[0][7];
+ newShell.noPLen = strlen(newShell.noPrint);
+ } else if (strncmp(*argv, "echoFlag=", 9) == 0) {
+ newShell.echo = &argv[0][9];
+ } else if (strncmp(*argv, "errFlag=", 8) == 0) {
+ newShell.exit = &argv[0][8];
+ } else if (strncmp(*argv, "hasErrCtl=", 10) == 0) {
+ char c = argv[0][10];
+ newShell.hasErrCtl = !((c != 'Y') && (c != 'y') &&
(c != 'T') && (c != 't'));
- } else if (strncmp(*argv, "check=", 6) == 0) {
- newShell.errCheck = &argv[0][6];
- } else if (strncmp(*argv, "ignore=", 7) == 0) {
- newShell.ignErr = &argv[0][7];
- } else {
- Parse_Error(PARSE_FATAL, "Unknown keyword \"%s\"",
- *argv);
- return(FAILURE);
- }
- fullSpec = TRUE;
- }
+ } else if (strncmp(*argv, "check=", 6) == 0) {
+ newShell.errCheck = &argv[0][6];
+ } else if (strncmp(*argv, "ignore=", 7) == 0) {
+ newShell.ignErr = &argv[0][7];
+ } else {
+ Parse_Error(PARSE_FATAL, "Unknown keyword \"%s\"",
+ *argv);
+ free(words);
+ return(FAILURE);
+ }
+ fullSpec = TRUE;
+ }
}
if (path == NULL) {
@@ -2762,7 +2770,7 @@ Job_ParseShell(line)
/*
* Do not free up the words themselves, since they might be in use by the
- * shell specification...
+ * shell specification.
*/
free(words);
return SUCCESS;
@@ -2918,7 +2926,7 @@ JobInterrupt(runINTERRUPT, signo)
/*
*-----------------------------------------------------------------------
- * Job_End --
+ * Job_Finish --
* Do final processing such as the running of the commands
* attached to the .END target.
*
@@ -2931,7 +2939,7 @@ JobInterrupt(runINTERRUPT, signo)
*-----------------------------------------------------------------------
*/
int
-Job_End()
+Job_Finish()
{
if (postCommands != NILGNODE && !Lst_IsEmpty(postCommands->commands)) {
if (errors) {
@@ -2953,6 +2961,25 @@ Job_End()
/*-
*-----------------------------------------------------------------------
+ * Job_End --
+ * Cleanup any memory used by the jobs module
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Memory is freed
+ *-----------------------------------------------------------------------
+ */
+void
+Job_End()
+{
+ if (shellArgv)
+ free(shellArgv);
+}
+
+/*-
+ *-----------------------------------------------------------------------
* Job_Wait --
* Waits for all running jobs to finish and returns. Sets 'aborting'
* to ABORT_WAIT to prevent other jobs from starting.
diff --git a/usr.bin/make/job.h b/usr.bin/make/job.h
index 22510575cf4..30093f1baa0 100644
--- a/usr.bin/make/job.h
+++ b/usr.bin/make/job.h
@@ -1,4 +1,4 @@
-/* $NetBSD: job.h,v 1.5 1996/11/06 17:59:10 christos Exp $ */
+/* $NetBSD: job.h,v 1.6 1998/03/26 19:20:37 christos Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -227,7 +227,8 @@ void Job_Init __P((int, int));
Boolean Job_Full __P((void));
Boolean Job_Empty __P((void));
ReturnStatus Job_ParseShell __P((char *));
-int Job_End __P((void));
+int Job_Finish __P((void));
+void Job_End __P((void));
void Job_Wait __P((void));
void Job_AbortAll __P((void));
void JobFlagForMigration __P((int));
diff --git a/usr.bin/make/main.c b/usr.bin/make/main.c
index 636356a2a2b..5a188b2a437 100644
--- a/usr.bin/make/main.c
+++ b/usr.bin/make/main.c
@@ -1,4 +1,4 @@
-/* $NetBSD: main.c,v 1.39 1997/11/08 09:33:16 lukem Exp $ */
+/* $NetBSD: main.c,v 1.40 1998/03/26 19:20:37 christos Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -39,7 +39,7 @@
*/
#ifdef MAKE_BOOTSTRAP
-static char rcsid[] = "$NetBSD: main.c,v 1.39 1997/11/08 09:33:16 lukem Exp $";
+static char rcsid[] = "$NetBSD: main.c,v 1.40 1998/03/26 19:20:37 christos Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
@@ -51,7 +51,7 @@ __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993\n\
#if 0
static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: main.c,v 1.39 1997/11/08 09:33:16 lukem Exp $");
+__RCSID("$NetBSD: main.c,v 1.40 1998/03/26 19:20:37 christos Exp $");
#endif
#endif /* not lint */
#endif
@@ -377,6 +377,9 @@ Main_ParseArgLine(line)
{
char **argv; /* Manufactured argument vector */
int argc; /* Number of arguments in argv */
+ char *args; /* Space used by the args */
+ char *buf, *p1;
+ char *argv0 = Var_Value(".MAKE", VAR_GLOBAL, &p1);
if (line == NULL)
return;
@@ -385,8 +388,16 @@ Main_ParseArgLine(line)
if (!*line)
return;
- argv = brk_string(line, &argc, TRUE);
+ buf = emalloc(strlen(line) + strlen(argv0) + 2);
+ (void)sprintf(buf, "%s %s", argv0, line);
+ if (p1)
+ free(p1);
+
+ argv = brk_string(line, &argc, TRUE, &args);
MainParseArgs(argc, argv);
+
+ free(args);
+ free(argv);
}
char *
@@ -599,7 +610,6 @@ main(argc, argv)
* directories */
Var_Init(); /* As well as the lists of variables for
* parsing arguments */
- str_init();
Var_Set(".CURDIR", curdir, VAR_GLOBAL);
Var_Set(".OBJDIR", objdir, VAR_GLOBAL);
@@ -820,10 +830,10 @@ main(argc, argv)
Suff_End();
Targ_End();
Arch_End();
- str_end();
Var_End();
Parse_End();
Dir_End();
+ Job_End();
if (queryFlag && outOfDate)
return(1);
diff --git a/usr.bin/make/make.c b/usr.bin/make/make.c
index 881aa86fad3..76a8cbe60a9 100644
--- a/usr.bin/make/make.c
+++ b/usr.bin/make/make.c
@@ -1,4 +1,4 @@
-/* $NetBSD: make.c,v 1.19 1997/09/28 03:31:07 lukem Exp $ */
+/* $NetBSD: make.c,v 1.20 1998/03/26 19:20:37 christos Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -39,14 +39,14 @@
*/
#ifdef MAKE_BOOTSTRAP
-static char rcsid[] = "$NetBSD: make.c,v 1.19 1997/09/28 03:31:07 lukem Exp $";
+static char rcsid[] = "$NetBSD: make.c,v 1.20 1998/03/26 19:20:37 christos Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)make.c 8.1 (Berkeley) 6/6/93";
#else
-__RCSID("$NetBSD: make.c,v 1.19 1997/09/28 03:31:07 lukem Exp $");
+__RCSID("$NetBSD: make.c,v 1.20 1998/03/26 19:20:37 christos Exp $");
#endif
#endif /* not lint */
#endif
@@ -1003,7 +1003,7 @@ Make_Run (targs)
(void)MakeStartJobs();
}
- errors = Job_End();
+ errors = Job_Finish();
/*
* Print the final status of each target. E.g. if it wasn't made
diff --git a/usr.bin/make/nonints.h b/usr.bin/make/nonints.h
index bb7f5920d85..50c69a3da66 100644
--- a/usr.bin/make/nonints.h
+++ b/usr.bin/make/nonints.h
@@ -1,4 +1,4 @@
-/* $NetBSD: nonints.h,v 1.14 1997/09/23 21:15:09 fair Exp $ */
+/* $NetBSD: nonints.h,v 1.15 1998/03/26 19:20:37 christos Exp $ */
/*-
* Copyright (c) 1988, 1989, 1990, 1993
@@ -92,10 +92,8 @@ void Parse_FromString __P((char *));
Lst Parse_MainName __P((void));
/* str.c */
-void str_init __P((void));
-void str_end __P((void));
char *str_concat __P((char *, char *, int));
-char **brk_string __P((char *, int *, Boolean));
+char **brk_string __P((char *, int *, Boolean, char **));
char *Str_FindSubstring __P((char *, char *));
int Str_Match __P((char *, char *));
char *Str_SYSVMatch __P((char *, char *, int *len));
diff --git a/usr.bin/make/str.c b/usr.bin/make/str.c
index 492bc6be435..dcee265b3ec 100644
--- a/usr.bin/make/str.c
+++ b/usr.bin/make/str.c
@@ -1,4 +1,4 @@
-/* $NetBSD: str.c,v 1.15 1997/09/28 03:31:10 lukem Exp $ */
+/* $NetBSD: str.c,v 1.16 1998/03/26 19:20:37 christos Exp $ */
/*-
* Copyright (c) 1988, 1989, 1990, 1993
@@ -39,54 +39,20 @@
*/
#ifdef MAKE_BOOTSTRAP
-static char rcsid[] = "$NetBSD: str.c,v 1.15 1997/09/28 03:31:10 lukem Exp $";
+static char rcsid[] = "$NetBSD: str.c,v 1.16 1998/03/26 19:20:37 christos Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)str.c 5.8 (Berkeley) 6/1/90";
#else
-__RCSID("$NetBSD: str.c,v 1.15 1997/09/28 03:31:10 lukem Exp $");
+__RCSID("$NetBSD: str.c,v 1.16 1998/03/26 19:20:37 christos Exp $");
#endif
#endif /* not lint */
#endif
#include "make.h"
-static char **argv, *buffer;
-static int argmax, curlen;
-
-/*
- * str_init --
- * Initialize the strings package
- *
- */
-void
-str_init()
-{
- char *p1;
- argv = (char **)emalloc(((argmax = 50) + 1) * sizeof(char *));
- argv[0] = Var_Value(".MAKE", VAR_GLOBAL, &p1);
-}
-
-
-/*
- * str_end --
- * Cleanup the strings package
- *
- */
-void
-str_end()
-{
- if (argv) {
- if (argv[0])
- free(argv[0]);
- free((Address) argv);
- }
- if (buffer)
- free(buffer);
-}
-
/*-
* str_concat --
* concatenate the two strings, inserting a space or slash between them,
@@ -144,33 +110,33 @@ str_concat(s1, s2, flags)
* the first word is always the value of the .MAKE variable.
*/
char **
-brk_string(str, store_argc, expand)
+brk_string(str, store_argc, expand, buffer)
register char *str;
int *store_argc;
Boolean expand;
+ char **buffer;
{
register int argc, ch;
register char inquote, *p, *start, *t;
int len;
+ int argmax = 50, curlen = 0;
+ char **argv = (char **)emalloc((argmax + 1) * sizeof(char *));
/* skip leading space chars. */
for (; *str == ' ' || *str == '\t'; ++str)
continue;
/* allocate room for a copy of the string */
- if ((len = strlen(str) + 1) > curlen) {
- if (buffer)
- free(buffer);
- buffer = emalloc(curlen = len);
- }
+ if ((len = strlen(str) + 1) > curlen)
+ *buffer = emalloc(curlen = len);
/*
* copy the string; at the same time, parse backslashes,
* quotes and build the argument list.
*/
- argc = 1;
+ argc = 0;
inquote = '\0';
- for (p = str, start = t = buffer;; ++p) {
+ for (p = str, start = t = *buffer;; ++p) {
switch(ch = *p) {
case '"':
case '\'':
diff --git a/usr.bin/make/var.c b/usr.bin/make/var.c
index 5c4aef3def8..a00ef996ee5 100644
--- a/usr.bin/make/var.c
+++ b/usr.bin/make/var.c
@@ -1,4 +1,4 @@
-/* $NetBSD: var.c,v 1.23 1997/09/28 03:31:14 lukem Exp $ */
+/* $NetBSD: var.c,v 1.24 1998/03/26 19:20:37 christos Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -39,14 +39,14 @@
*/
#ifdef MAKE_BOOTSTRAP
-static char rcsid[] = "$NetBSD: var.c,v 1.23 1997/09/28 03:31:14 lukem Exp $";
+static char rcsid[] = "$NetBSD: var.c,v 1.24 1998/03/26 19:20:37 christos Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: var.c,v 1.23 1997/09/28 03:31:14 lukem Exp $");
+__RCSID("$NetBSD: var.c,v 1.24 1998/03/26 19:20:37 christos Exp $");
#endif
#endif /* not lint */
#endif
@@ -1255,16 +1255,20 @@ VarModify (str, modProc, datum)
* buffer before adding the trimmed
* word */
char **av; /* word list [first word does not count] */
+ char *as; /* word list memory */
int ac, i;
buf = Buf_Init (0);
addSpace = FALSE;
- av = brk_string(str, &ac, FALSE);
+ av = brk_string(str, &ac, FALSE, &as);
- for (i = 1; i < ac; i++)
+ for (i = 0; i < ac; i++)
addSpace = (*modProc)(av[i], addSpace, buf, datum);
+ free(as);
+ free(av);
+
Buf_AddByte (buf, '\0');
str = (char *)Buf_GetAll (buf, (int *)NULL);
Buf_Destroy (buf, FALSE);