- Fix Savannah bug #18124
authorPaul Smith <psmith@gnu.org>
Tue, 9 Jun 2009 15:35:38 +0000 (15:35 +0000)
committerPaul Smith <psmith@gnu.org>
Tue, 9 Jun 2009 15:35:38 +0000 (15:35 +0000)
- Fix Savannah bug #17521
- Fix Savannah bug #16401
- Fix Savannah bug #16469
- Fix Savannah bug #16473

ChangeLog
arscan.c
function.c
job.c
main.c
read.c
rule.c
tests/ChangeLog
tests/scripts/features/parallelism
tests/scripts/features/targetvars
vmsfunctions.c

index 7c8e87a25a824f49c684be780d7d99973ad64dc6..61b2466567236b99aac23223e383e4a7a9c56e69 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,26 @@
+2009-06-09  Paul Smith  <psmith@gnu.org>
+
+       * main.c (clean_jobserver): Clear the jobserver_fds options and
+       set job_slots to the default when we clean up.
+       (define_makeflags): Return the new MAKEFLAGS value.
+       (main): Reset MAKEFLAGS in the environment when we re-exec.
+       Fixes Savannah bug #18124.
+
+2009-06-08  Paul Smith  <psmith@gnu.org>
+
+       * read.c (eval): Collapse continuations post-semicolon on target-
+       specific variables.  Fixes Savannah bug #17521.
+
 2009-06-07  Paul Smith  <psmith@gnu.org>
 
+       * job.c (reap_children): For older systems without waitpid() (are
+       there any of these left?) run wait(2) inside EINTRLOOP to handle
+       EINTR errors.  Fixes Savannah bug #16401.
+
+       * (various): Debug message cleanup.  Fixes Savannah bug #16469.
+
+       * main.c: Fix bsd_signal() typedef.  Fixes Savannah bug #16473.
+
        * file.c (snap_deps): Set SNAPPED_DEPS at the start of snapping,
        not the end, to catch second expansion $(eval ...) defining new
        target/prereq relationships during snap_deps.
index 5e94000ac6f5413c72366295788a1ba7b9f178d7..c2af805d2396e8c447fdc1d43079ae3335ec567e 100644 (file)
--- a/arscan.c
+++ b/arscan.c
@@ -66,7 +66,7 @@ VMS_get_member_info (struct dsc$descriptor_s *module, unsigned long *rfa)
                           &bufdesc.dsc$w_length, 0);
   if (! (status & 1))
     {
-      error (NILF, _("lbr$set_module failed to extract module info, status = %d"),
+      error (NILF, _("lbr$set_module() failed to extract module info, status = %d"),
             status);
 
       lbr$close (&VMS_lib_idx);
@@ -151,7 +151,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
 
   if (! (status & 1))
     {
-      error (NILF, _("lbr$ini_control failed with status = %d"),status);
+      error (NILF, _("lbr$ini_control() failed with status = %d"), status);
       return -2;
     }
 
index 34d357a6512b021bc4977212b4d703117d09c1a6..2ea1ac4725b9353130d885693bb7974f122cf683 100644 (file)
@@ -1461,7 +1461,7 @@ windows32_openpipe (int *pipedes, int *pid_p, char **command_argv, char **envp)
                      0,
                      TRUE,
                      DUPLICATE_SAME_ACCESS) == FALSE) {
-    fatal (NILF, _("create_child_process: DuplicateHandle(In) failed (e=%ld)\n"),
+    fatal (NILF, _("windows32_openpipe(): DuplicateHandle(In) failed (e=%ld)\n"),
           GetLastError());
 
   }
@@ -1472,7 +1472,7 @@ windows32_openpipe (int *pipedes, int *pid_p, char **command_argv, char **envp)
                      0,
                      TRUE,
                      DUPLICATE_SAME_ACCESS) == FALSE) {
-    fatal (NILF, _("create_child_process: DuplicateHandle(Err) failed (e=%ld)\n"),
+    fatal (NILF, _("windows32_open_pipe(): DuplicateHandle(Err) failed (e=%ld)\n"),
           GetLastError());
   }
 
@@ -1482,7 +1482,7 @@ windows32_openpipe (int *pipedes, int *pid_p, char **command_argv, char **envp)
   hProcess = process_init_fd(hIn, hChildOutWr, hErr);
 
   if (!hProcess)
-    fatal (NILF, _("windows32_openpipe (): process_init_fd() failed\n"));
+    fatal (NILF, _("windows32_openpipe(): process_init_fd() failed\n"));
 
   /* make sure that CreateProcess() has Path it needs */
   sync_Path_environment();
diff --git a/job.c b/job.c
index 6cbfd31c6a2f038a0ac9a1872b3c6d09602cf1f2..3ed27bf45dd661e07d2bfbbb8c3c9668d80a47e7 100644 (file)
--- a/job.c
+++ b/job.c
@@ -551,7 +551,7 @@ reap_children (int block, int err)
                pid = WAIT_NOHANG (&status);
              else
 #endif
-               pid = wait (&status);
+               EINTRLOOP(pid, wait (&status));
 #endif /* !VMS */
            }
          else
@@ -2028,7 +2028,7 @@ exec_command (char **argv, char **envp)
     {
       int i;
       fprintf(stderr,
-              _("process_easy() failed failed to launch process (e=%ld)\n"),
+              _("process_easy() failed to launch process (e=%ld)\n"),
               process_last_err(hPID));
       for (i = 0; argv[i]; i++)
           fprintf(stderr, "%s ", argv[i]);
diff --git a/main.c b/main.c
index 67a544d86bb3f8b9e7f51d3825aaca9de9ba4675..8261fefdf3afebe784973cb2d5ec57f76a144235 100644 (file)
--- a/main.c
+++ b/main.c
@@ -80,7 +80,7 @@ static void print_data_base (void);
 static void print_version (void);
 static void decode_switches (int argc, char **argv, int env);
 static void decode_env_switches (char *envar, unsigned int len);
-static void define_makeflags (int all, int makefile);
+static const char *define_makeflags (int all, int makefile);
 static char *quote_for_env (char *out, const char *in);
 static void initialize_global_hash_tables (void);
 
@@ -516,7 +516,7 @@ int fatal_signal_mask;
 # if !defined HAVE_SIGACTION
 #  define bsd_signal signal
 # else
-typedef RETSIGTYPE (*bsd_signal_ret_t) ();
+typedef RETSIGTYPE (*bsd_signal_ret_t) (int);
 
 static bsd_signal_ret_t
 bsd_signal (int sig, bsd_signal_ret_t func)
@@ -767,8 +767,8 @@ find_and_set_default_shell (const char *token)
     unixy_shell = 0;
     sprintf (sh_path, "%s", search_token);
     default_shell = xstrdup (w32ify (sh_path, 0));
-    DB (DB_VERBOSE,
-        (_("find_and_set_shell setting default_shell = %s\n"), default_shell));
+    DB (DB_VERBOSE, (_("find_and_set_shell() setting default_shell = %s\n"),
+                     default_shell));
     sh_found = 1;
   } else if (!no_default_sh_exe &&
              (token == NULL || !strcmp (search_token, default_shell))) {
@@ -778,8 +778,8 @@ find_and_set_default_shell (const char *token)
     /* search token path was found */
     sprintf (sh_path, "%s", search_token);
     default_shell = xstrdup (w32ify (sh_path, 0));
-    DB (DB_VERBOSE,
-        (_("find_and_set_shell setting default_shell = %s\n"), default_shell));
+    DB (DB_VERBOSE, (_("find_and_set_shell() setting default_shell = %s\n"),
+                     default_shell));
     sh_found = 1;
   } else {
     char *p;
@@ -820,7 +820,7 @@ find_and_set_default_shell (const char *token)
 
       if (sh_found)
         DB (DB_VERBOSE,
-            (_("find_and_set_shell path search set default_shell = %s\n"),
+            (_("find_and_set_shell() path search set default_shell = %s\n"),
              default_shell));
     }
   }
@@ -1663,60 +1663,60 @@ main (int argc, char **argv, char **envp)
   /* If the jobserver-fds option is seen, make sure that -j is reasonable.  */
 
   if (jobserver_fds)
-  {
-    const char *cp;
-    unsigned int ui;
+    {
+      const char *cp;
+      unsigned int ui;
 
-    for (ui=1; ui < jobserver_fds->idx; ++ui)
-      if (!streq (jobserver_fds->list[0], jobserver_fds->list[ui]))
-        fatal (NILF, _("internal error: multiple --jobserver-fds options"));
+      for (ui=1; ui < jobserver_fds->idx; ++ui)
+        if (!streq (jobserver_fds->list[0], jobserver_fds->list[ui]))
+          fatal (NILF, _("internal error: multiple --jobserver-fds options"));
 
-    /* Now parse the fds string and make sure it has the proper format.  */
+      /* Now parse the fds string and make sure it has the proper format.  */
 
-    cp = jobserver_fds->list[0];
+      cp = jobserver_fds->list[0];
 
-    if (sscanf (cp, "%d,%d", &job_fds[0], &job_fds[1]) != 2)
-      fatal (NILF,
-             _("internal error: invalid --jobserver-fds string `%s'"), cp);
+      if (sscanf (cp, "%d,%d", &job_fds[0], &job_fds[1]) != 2)
+        fatal (NILF,
+               _("internal error: invalid --jobserver-fds string `%s'"), cp);
 
-    DB (DB_JOBS,
-       (_("Jobserver client (fds %d,%d)\n"), job_fds[0], job_fds[1]));
+      DB (DB_JOBS,
+          (_("Jobserver client (fds %d,%d)\n"), job_fds[0], job_fds[1]));
 
-    /* The combination of a pipe + !job_slots means we're using the
-       jobserver.  If !job_slots and we don't have a pipe, we can start
-       infinite jobs.  If we see both a pipe and job_slots >0 that means the
-       user set -j explicitly.  This is broken; in this case obey the user
-       (ignore the jobserver pipe for this make) but print a message.  */
+      /* The combination of a pipe + !job_slots means we're using the
+         jobserver.  If !job_slots and we don't have a pipe, we can start
+         infinite jobs.  If we see both a pipe and job_slots >0 that means the
+         user set -j explicitly.  This is broken; in this case obey the user
+         (ignore the jobserver pipe for this make) but print a message.  */
 
-    if (job_slots > 0)
-      error (NILF,
-             _("warning: -jN forced in submake: disabling jobserver mode."));
+      if (job_slots > 0)
+        error (NILF,
+               _("warning: -jN forced in submake: disabling jobserver mode."));
 
-    /* Create a duplicate pipe, that will be closed in the SIGCHLD
-       handler.  If this fails with EBADF, the parent has closed the pipe
-       on us because it didn't think we were a submake.  If so, print a
-       warning then default to -j1.  */
+      /* Create a duplicate pipe, that will be closed in the SIGCHLD
+         handler.  If this fails with EBADF, the parent has closed the pipe
+         on us because it didn't think we were a submake.  If so, print a
+         warning then default to -j1.  */
 
-    else if ((job_rfd = dup (job_fds[0])) < 0)
-      {
-        if (errno != EBADF)
-          pfatal_with_name (_("dup jobserver"));
+      else if ((job_rfd = dup (job_fds[0])) < 0)
+        {
+          if (errno != EBADF)
+            pfatal_with_name (_("dup jobserver"));
 
-        error (NILF,
-               _("warning: jobserver unavailable: using -j1.  Add `+' to parent make rule."));
-        job_slots = 1;
-      }
+          error (NILF,
+                 _("warning: jobserver unavailable: using -j1.  Add `+' to parent make rule."));
+          job_slots = 1;
+        }
 
-    if (job_slots > 0)
-      {
-        close (job_fds[0]);
-        close (job_fds[1]);
-        job_fds[0] = job_fds[1] = -1;
-        free (jobserver_fds->list);
-        free (jobserver_fds);
-        jobserver_fds = 0;
-      }
-  }
+      if (job_slots > 0)
+        {
+          close (job_fds[0]);
+          close (job_fds[1]);
+          job_fds[0] = job_fds[1] = -1;
+          free (jobserver_fds->list);
+          free (jobserver_fds);
+          jobserver_fds = 0;
+        }
+    }
 
   /* If we have >1 slot but no jobserver-fds, then we're a top-level make.
      Set up the pipe and install the fds option for our children.  */
@@ -1834,8 +1834,8 @@ main (int argc, char **argv, char **envp)
 
       FILE_TIMESTAMP *makefile_mtimes = 0;
       unsigned int mm_idx = 0;
-      char **nargv = argv;
-      int nargc = argc;
+      char **nargv;
+      int nargc;
       int orig_db_level = db_level;
       int status;
 
@@ -2004,8 +2004,7 @@ main (int argc, char **argv, char **envp)
              for (i = 1; i < argc; ++i)
                if (strneq (argv[i], "-f", 2)) /* XXX */
                  {
-                   char *p = &argv[i][2];
-                   if (*p == '\0')
+                   if (argv[i][2] == '\0')
                       /* This cast is OK since we never modify argv.  */
                      argv[++i] = (char *) makefiles->list[j];
                    else
@@ -2015,6 +2014,7 @@ main (int argc, char **argv, char **envp)
            }
 
           /* Add -o option for the stdin temporary file, if necessary.  */
+          nargc = argc;
           if (stdin_nm)
             {
               nargv = xmalloc ((nargc + 2) * sizeof (char *));
@@ -2022,6 +2022,8 @@ main (int argc, char **argv, char **envp)
               nargv[nargc++] = xstrdup (concat ("-o", stdin_nm, ""));
               nargv[nargc] = 0;
             }
+          else
+            nargv = argv;
 
          if (directories != 0 && directories->idx > 0)
            {
@@ -2039,6 +2041,14 @@ main (int argc, char **argv, char **envp)
 
           ++restarts;
 
+          /* Reset makeflags in case they were changed.  */
+          {
+            const char *pv = define_makeflags (1, 1);
+            char *p = alloca (sizeof ("MAKEFLAGS=") + strlen (pv) + 1);
+            sprintf (p, "MAKEFLAGS=%s", pv);
+            putenv (p);
+          }
+
          if (ISDB (DB_BASIC))
            {
              char **p;
@@ -2691,7 +2701,7 @@ quote_for_env (char *out, const char *in)
    command switches.  Include options with args if ALL is nonzero.
    Don't include options with the `no_makefile' flag set if MAKEFILE.  */
 
-static void
+static const char *
 define_makeflags (int all, int makefile)
 {
   static const char ref[] = "$(MAKEOVERRIDES)";
@@ -2931,13 +2941,12 @@ define_makeflags (int all, int makefile)
   /* Terminate the string.  */
   *p = '\0';
 
-  v = define_variable ("MAKEFLAGS", 9,
-                      /* If there are switches, omit the leading dash
-                         unless it is a single long option with two
-                         leading dashes.  */
-                      &flagstring[(flagstring[0] == '-'
-                                   && flagstring[1] != '-')
-                                  ? 1 : 0],
+  /* If there are switches, omit the leading dash unless it is a single long
+     option with two leading dashes.  */
+  if (flagstring[0] == '-' && flagstring[1] != '-')
+    ++flagstring;
+
+  v = define_variable ("MAKEFLAGS", 9, flagstring,
                       /* This used to use o_env, but that lost when a
                          makefile defined MAKEFLAGS.  Makefiles set
                          MAKEFLAGS to add switches, but we still want
@@ -2945,11 +2954,14 @@ define_makeflags (int all, int makefile)
                          switches.  Of course, an override or command
                          definition will still take precedence.  */
                       o_file, 1);
+
   if (! all)
     /* The first time we are called, set MAKEFLAGS to always be exported.
        We should not do this again on the second call, because that is
        after reading makefiles which might have done `unexport MAKEFLAGS'. */
     v->export = v_export;
+
+  return v->value;
 }
 \f
 /* Print version information.  */
@@ -2978,7 +2990,7 @@ print_version (void)
      year, and none of the rest of it should be translated (including the
      word "Copyright", so it hardly seems worth it.  */
 
-  printf ("%sCopyright (C) 2007  Free Software Foundation, Inc.\n", precede);
+  printf ("%sCopyright (C) 2009  Free Software Foundation, Inc.\n", precede);
 
   printf (_("%sLicense GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n\
 %sThis is free software: you are free to change and redistribute it.\n\
@@ -3060,6 +3072,17 @@ clean_jobserver (int status)
                tcnt, master_job_slots);
 
       close (job_fds[0]);
+
+      /* Clean out jobserver_fds so we don't pass this information to any
+         sub-makes.  Also reset job_slots since it will be put on the command
+         line, not in MAKEFLAGS.  */
+      job_slots = default_job_slots;
+      if (jobserver_fds)
+        {
+          free (jobserver_fds->list);
+          free (jobserver_fds);
+          jobserver_fds = 0;
+        }
     }
 }
 \f
diff --git a/read.c b/read.c
index 8796dfcad4707c82bc5693df7912d83d58ba4f13..d77ed333258a9f8a31df62a1ecef45914c5d3989 100644 (file)
--- a/read.c
+++ b/read.c
@@ -1061,6 +1061,7 @@ eval (struct ebuffer *ebuf, int set_default)
               {
                 unsigned int l = p - variable_buffer;
                 *(--semip) = ';';
+                collapse_continuations (semip);
                 variable_buffer_output (p2 + strlen (p2),
                                         semip, strlen (semip)+1);
                 p = variable_buffer + l;
diff --git a/rule.c b/rule.c
index 26fc4fcaca8b1ab671314469d9a95eb10de6491d..ef0bf9b3c7b61f3da47c0302b58f3620b811cc39 100644 (file)
--- a/rule.c
+++ b/rule.c
@@ -541,7 +541,7 @@ print_rule_data_base (void)
       /* This can happen if a fatal error was detected while reading the
          makefiles and thus count_implicit_rule_limits wasn't called yet.  */
       if (num_pattern_rules != 0)
-        fatal (NILF, _("BUG: num_pattern_rules wrong!  %u != %u"),
+        fatal (NILF, _("BUG: num_pattern_rules is wrong!  %u != %u"),
                num_pattern_rules, rules);
     }
 }
index 244af416a573a7ee74e5509b0442a2e3647ba5ef..a0e83e0990149924c36f152fd677ff74229a5968 100644 (file)
@@ -1,3 +1,13 @@
+2009-06-09  Paul Smith  <psmith@gnu.org>
+
+       * scripts/features/parallelism: Add a test for re-exec with
+       jobserver master override.  Savannah bug #18124.
+
+2009-06-08  Paul Smith  <psmith@gnu.org>
+
+       * scripts/features/targetvars: Add a test for continued target
+       vars after a semicolon.  Savannah bug #17521.
+
 2009-06-07  Paul Smith  <psmith@gnu.org>
 
        * scripts/features/se_explicit: Make sure we catch defining
index 11102f2413941a3ba2a2b83d12cdde1d70c0306e..bce743c4bdc8a3e314ae69c3b93f28b163216349 100644 (file)
@@ -140,6 +140,29 @@ intermed: | phony ; touch $@
 phony: ; : phony', '-rR -j', ': phony');
 unlink('target');
 
+# TEST #10: Don't put --jobserver-fds into a re-exec'd MAKEFLAGS.
+# We can't test this directly because there's no way a makefile can
+# show the value of MAKEFLAGS we were re-exec'd with.  We can intuit it
+# by looking for "disabling jobserver mode" warnings; we should only
+# get one from the original invocation and none from the re-exec.
+# See Savannah bug #18124
+
+run_make_test(q!
+-include inc.mk
+recur:
+#      @echo 'MAKEFLAGS = $(MAKEFLAGS)'
+       @rm -f inc.mk
+       @$(MAKE) -j2 -f #MAKEFILE# all
+all:
+#      @echo 'MAKEFLAGS = $(MAKEFLAGS)'
+       @echo $@
+inc.mk:
+#      @echo 'MAKEFLAGS = $(MAKEFLAGS)'
+       @echo 'FOO = bar' > $@
+!,
+              '--no-print-directory -j2', "#MAKE#[1]: warning: -jN forced in submake: disabling jobserver mode.\nall\n");
+
+unlink('inc.mk');
 
 # Make sure that all jobserver FDs are closed if we need to re-exec the
 # master copy.
index 3864bf8c5e8d3dffaadb4cc6e29d0cfe4354470e..ddd6c1f5379f235e290820d1338a1879bff62f1f 100644 (file)
@@ -237,6 +237,15 @@ a: ; @echo "$(FOO)"
 
 run_make_test(undef, 'FOO=C', "C f1\n");
 
+# TEST #20: Check for continuation after semicolons
+
+run_make_test(q!
+a: A = 'hello; \
+world'
+a: ; @echo $(A)
+!,
+              '', "hello; world\n");
+
 # TEST #19: Test define/endef variables as target-specific vars
 
 # run_make_test('
index f3f70e3d7362d9e0a2d91b63286d1b72c2791ad8..51a270e1037ee88978b536582e0acc3d30ca3d2c 100644 (file)
@@ -91,7 +91,7 @@ readdir (DIR *dir)
 
   if (!((i = sys$search (dfab)) & 1))
     {
-      DB (DB_VERBOSE, (_("sys$search failed with %d\n"), i));
+      DB (DB_VERBOSE, (_("sys$search() failed with %d\n"), i));
       return (NULL);
     }