Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/make Fixes for PR#18573 (make -j not stopping correc...
details: https://anonhg.NetBSD.org/src/rev/cfa43e8abd90
branches: trunk
changeset: 556523:cfa43e8abd90
user: jmc <jmc%NetBSD.org@localhost>
date: Sat Dec 20 00:18:22 2003 +0000
description:
Fixes for PR#18573 (make -j not stopping correctly on error).
Using -e in sh/ksh to stop on error doesn't work with grouped commands. At
least for any SUSE compliant sh(1). Instead, extend the Shell struct and add
errOut which provides a template to use to check error status from commands.
diffstat:
usr.bin/make/job.c | 102 ++++++++++++++++++++++++++++++++++++++++------------
usr.bin/make/job.h | 15 +++++--
2 files changed, 88 insertions(+), 29 deletions(-)
diffs (254 lines):
diff -r 0ac839603d8c -r cfa43e8abd90 usr.bin/make/job.c
--- a/usr.bin/make/job.c Sat Dec 20 00:18:10 2003 +0000
+++ b/usr.bin/make/job.c Sat Dec 20 00:18:22 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: job.c,v 1.82 2003/08/07 11:14:51 agc Exp $ */
+/* $NetBSD: job.c,v 1.83 2003/12/20 00:18:22 jmc Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -70,14 +70,14 @@
*/
#ifdef MAKE_BOOTSTRAP
-static char rcsid[] = "$NetBSD: job.c,v 1.82 2003/08/07 11:14:51 agc Exp $";
+static char rcsid[] = "$NetBSD: job.c,v 1.83 2003/12/20 00:18:22 jmc 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.82 2003/08/07 11:14:51 agc Exp $");
+__RCSID("$NetBSD: job.c,v 1.83 2003/12/20 00:18:22 jmc Exp $");
#endif
#endif /* not lint */
#endif
@@ -218,7 +218,7 @@
{
"csh",
TRUE, "unset verbose", "set verbose", "unset verbose", 10,
- FALSE, "echo \"%s\"\n", "csh -c \"%s || exit 0\"",
+ FALSE, "echo \"%s\"\n", "csh -c \"%s || exit 0\"", "", '#',
"v", "e",
},
/*
@@ -227,17 +227,14 @@
*/
{
"sh",
- TRUE, "set -", "set -v", "set -", 5,
- TRUE, "set -e", "set +e",
-#ifdef OLDBOURNESHELL
- FALSE, "echo \"%s\"\n", "sh -c '%s || exit 0'\n",
-#endif
+ FALSE, "", "", "", 0,
+ FALSE, "echo \"%s\"\n", "%s\n", "{ %s \n} || exit $?\n", '#',
#ifdef __NetBSD__
- "vq",
+ "q",
#else
- "v",
+ "",
#endif
- "e",
+ "",
},
/*
* KSH description.
@@ -245,9 +242,9 @@
{
"ksh",
TRUE, "set +v", "set -v", "set +v", 6,
- TRUE, "set -e", "set +e",
+ FALSE, "echo \"%s\"\n", "%s\n", "{ %s \n} || exit $?\n", '#',
"v",
- "e",
+ "",
},
/*
* UNKNOWN.
@@ -255,7 +252,7 @@
{
(char *) 0,
FALSE, (char *) 0, (char *) 0, (char *) 0, 0,
- FALSE, (char *) 0, (char *) 0,
+ FALSE, (char *) 0, (char *) 0, (char *) 0, 0,
(char *) 0, (char *) 0,
}
};
@@ -673,10 +670,12 @@
const char *cmdTemplate; /* Template to use when printing the
* command */
char *cmdStart; /* Start of expanded command */
+ char *escCmd = NULL; /* Command with quotes/backticks escaped */
char *cmd = (char *) cmdp;
Job *job = (Job *) jobp;
- char *cp;
-
+ char *cp;
+ int i, j;
+
noSpecials = NoExecute(job->node);
if (strcmp(cmd, "...") == 0) {
@@ -717,12 +716,31 @@
while (isspace((unsigned char) *cmd))
cmd++;
+ /*
+ * If the shell doesn't have error control the alternate echo'ing will
+ * be done (to avoid showing additional error checking code)
+ * and this will need the characters '$ ` \ "' escaped
+ */
+
+ if (!commandShell->hasErrCtl) {
+ /* Worst that could happen is every char needs escaping. */
+ escCmd = (char *) emalloc((strlen(cmd) * 2) + 1);
+ for (i = 0, j= 0; cmd[i] != '\0'; i++, j++) {
+ if (cmd[i] == '$' || cmd[i] == '`' || cmd[i] == '\\' ||
+ cmd[i] == '"')
+ escCmd[j++] = '\\';
+ escCmd[j] = cmd[i];
+ }
+ escCmd[j] = 0;
+ }
+
if (shutUp) {
if (!(job->flags & JOB_SILENT) && !noSpecials &&
commandShell->hasEchoCtl) {
DBPRINTF("%s\n", commandShell->echoOff);
} else {
- shutUp = FALSE;
+ if (commandShell->hasErrCtl)
+ shutUp = FALSE;
}
}
@@ -743,7 +761,7 @@
DBPRINTF("%s\n", commandShell->ignErr);
DBPRINTF("%s\n", commandShell->echoOn);
} else {
- DBPRINTF("%s\n", commandShell->ignErr);
+ DBPRINTF("%s\n", commandShell->ignErr);
}
} else if (commandShell->ignErr &&
(*commandShell->ignErr != '\0'))
@@ -757,11 +775,16 @@
* to ignore errors. Set cmdTemplate to use the weirdness
* instead of the simple "%s\n" template.
*/
- if (!(job->flags & JOB_SILENT) && !shutUp &&
- commandShell->hasEchoCtl) {
- DBPRINTF("%s\n", commandShell->echoOff);
- DBPRINTF(commandShell->errCheck, cmd);
+ if (!(job->flags & JOB_SILENT) && !shutUp) {
+ if (commandShell->hasEchoCtl) {
+ DBPRINTF("%s\n", commandShell->echoOff);
+ }
+ DBPRINTF(commandShell->errCheck, escCmd);
shutUp = TRUE;
+ } else {
+ if (!shutUp) {
+ DBPRINTF(commandShell->errCheck, escCmd);
+ }
}
cmdTemplate = commandShell->ignErr;
/*
@@ -776,6 +799,30 @@
} else {
errOff = FALSE;
}
+ } else {
+
+ /*
+ * If errors are being checked and the shell doesn't have error control
+ * but does supply an errOut template, then setup commands to run
+ * through it.
+ */
+
+ if (!commandShell->hasErrCtl && commandShell->errOut &&
+ (*commandShell->errOut != '\0')) {
+ if (!(job->flags & JOB_SILENT) && !shutUp) {
+ if (commandShell->hasEchoCtl) {
+ DBPRINTF("%s\n", commandShell->echoOff);
+ }
+ DBPRINTF(commandShell->errCheck, escCmd);
+ shutUp = TRUE;
+ }
+ /* If it's a comment line, treat it like an ignored error */
+ if (escCmd[0] == commandShell->commentChar)
+ cmdTemplate = commandShell->ignErr;
+ else
+ cmdTemplate = commandShell->errOut;
+ errOff = FALSE;
+ }
}
if (DEBUG(SHELL) && strcmp(shellName, "sh") == 0 &&
@@ -790,7 +837,8 @@
}
DBPRINTF(cmdTemplate, cmd);
free(cmdStart);
-
+ if (escCmd)
+ free(escCmd);
if (errOff) {
/*
* If echoing is already off, there's no point in issuing the
@@ -803,7 +851,7 @@
}
DBPRINTF("%s\n", commandShell->errCheck);
}
- if (shutUp) {
+ if (shutUp && commandShell->hasEchoCtl) {
DBPRINTF("%s\n", commandShell->echoOn);
}
return 0;
@@ -2883,6 +2931,10 @@
newShell.errCheck = &argv[0][6];
} else if (strncmp(*argv, "ignore=", 7) == 0) {
newShell.ignErr = &argv[0][7];
+ } else if (strncmp(*argv, "errout=", 7) == 0) {
+ newShell.errOut = &argv[0][7];
+ } else if (strncmp(*argv, "comment=", 8) == 0) {
+ newShell.commentChar = argv[0][8];
} else {
Parse_Error(PARSE_FATAL, "Unknown keyword \"%s\"",
*argv);
diff -r 0ac839603d8c -r cfa43e8abd90 usr.bin/make/job.h
--- a/usr.bin/make/job.h Sat Dec 20 00:18:10 2003 +0000
+++ b/usr.bin/make/job.h Sat Dec 20 00:18:22 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: job.h,v 1.20 2003/08/07 11:14:52 agc Exp $ */
+/* $NetBSD: job.h,v 1.21 2003/12/20 00:18:22 jmc Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -235,9 +235,13 @@
* Some special stuff goes on if a shell doesn't have error control. In such
* a case, errCheck becomes a printf template for echoing the command,
* should echoing be on and ignErr becomes another printf template for
- * executing the command while ignoring the return status. If either of these
- * strings is empty when hasErrCtl is FALSE, the command will be executed
- * anyway as is and if it causes an error, so be it.
+ * executing the command while ignoring the return status. Finally errOut
+ * is a printf template for running the command and causing the shell to
+ * exit on error. If any of these strings are empty when hasErrCtl is FALSE,
+ * the command will be executed anyway as is and if it causes an error, so be
+ * it. Any templates setup to echo the command will escape any '$ ` \ "'i
+ * characters in the command string to avoid common problems with
+ * echo "%s\n" as a template.
*/
typedef struct Shell {
const char *name; /* the name of the shell. For Bourne and C
@@ -257,6 +261,9 @@
* individual commands */
const char *errCheck; /* string to turn error checking on */
const char *ignErr; /* string to turn off error checking */
+ const char *errOut; /* string to use for testing exit code */
+ char commentChar; /* character used by shell for comment lines */
+
/*
* command-line flags
*/
Home |
Main Index |
Thread Index |
Old Index