diff options
| author | christos <christos@NetBSD.org> | 1998-03-26 19:20:36 +0000 |
|---|---|---|
| committer | christos <christos@NetBSD.org> | 1998-03-26 19:20:36 +0000 |
| commit | f46f2d693ea899371cf704323e0db1dbff3765c7 (patch) | |
| tree | c5ccdf0415543ce8bad914b7d0c8182f8b26fa03 /usr.bin/make | |
| parent | 531db9e0d34f755c147d58f79e07983fea5e522d (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
Diffstat (limited to 'usr.bin/make')
| -rw-r--r-- | usr.bin/make/compat.c | 18 | ||||
| -rw-r--r-- | usr.bin/make/job.c | 111 | ||||
| -rw-r--r-- | usr.bin/make/job.h | 5 | ||||
| -rw-r--r-- | usr.bin/make/main.c | 22 | ||||
| -rw-r--r-- | usr.bin/make/make.c | 8 | ||||
| -rw-r--r-- | usr.bin/make/nonints.h | 6 | ||||
| -rw-r--r-- | usr.bin/make/str.c | 56 | ||||
| -rw-r--r-- | usr.bin/make/var.c | 14 |
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); |
