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