]> git.ipfire.org Git - thirdparty/make.git/commitdiff
[SV 27374] Fatal immediately on unrecoverable fopen() errors.
authorPaul Smith <psmith@gnu.org>
Sun, 15 Sep 2013 20:41:42 +0000 (16:41 -0400)
committerPaul Smith <psmith@gnu.org>
Sun, 15 Sep 2013 21:09:01 +0000 (17:09 -0400)
ChangeLog
read.c
tests/ChangeLog
tests/run_make_tests.pl
tests/scripts/misc/fopen-fail [new file with mode: 0644]
tests/test_driver.pl

index 899b471b7662303575f319b000b526f7155ebc71..7c88e76c669404ba182439d9bbb53c74f9570e29 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2013-09-15  Paul Smith  <psmith@gnu.org>
 
+       * read.c (eval_makefile): If the file open fails with an
+       unrecoverable error, stop now rather than trying to make it.
+       Fixes Savannah bug #27374.
+
        * main.c (main): Perform the validation of the jobserver FDs
        early, before we read makefiles, to ensure that something hasn't
        opened and used those FDs for some other reason.
diff --git a/read.c b/read.c
index 834c7f83f1c10a6f16a2820566a205df27e4bcaf..f8542b0fb960b1cba2f6b61b34d62268de88db95 100644 (file)
--- a/read.c
+++ b/read.c
@@ -353,10 +353,24 @@ eval_makefile (const char *filename, int flags)
         filename = expanded;
     }
 
-  ebuf.fp = fopen (filename, "r");
+  ENULLLOOP (ebuf.fp, fopen (filename, "r"));
+
   /* Save the error code so we print the right message later.  */
   makefile_errno = errno;
 
+  /* Check for unrecoverable errors: out of mem or FILE slots.  */
+  switch (makefile_errno)
+    {
+#ifdef EMFILE
+    case EMFILE:
+#endif
+#ifdef ENFILE
+    case ENFILE:
+#endif
+    case ENOMEM:
+      fatal (reading_file, "%s", strerror (makefile_errno));
+    }
+
   /* If the makefile wasn't found and it's either a makefile from
      the 'MAKEFILES' variable or an included makefile,
      search the included makefile search path for this makefile.  */
index d97e7e2147d377174f00f3aa3f00f08504cf0922..c6cebbf15b6260ea8dee0b321adf9bf57c86d13c 100644 (file)
@@ -1,5 +1,12 @@
 2013-09-15  Paul Smith  <psmith@gnu.org>
 
+       * scripts/misc/fopen-fail: Check for failure on infinite recursion.
+       * run_make_tests.pl (run_make_test): Allow the answer string to be
+       undef, which means that we shouldn't compare it at all.  Only the
+       exit code matters in this case.
+       * test_driver.pl (compare_output): Ditto.
+       Test for Savannah bug #27374.
+
        * scripts/features/parallelism: Test broken jobserver on recursion.
        Test for Savannah bug #39934.
 
index cb8e1bd59061fb8070c107241b1148f867254736..d8a093bc51bb462adc2d9b24fcf4a1c56ce617f1 100644 (file)
@@ -148,8 +148,10 @@ sub run_make_test
   }
 
   # Do the same processing on $answer as we did on $makestring.
-  $answer && $answer !~ /\n$/s and $answer .= "\n";
-  $answer = subst_make_string($answer);
+  if (defined $answer) {
+      $answer && $answer !~ /\n$/s and $answer .= "\n";
+      $answer = subst_make_string($answer);
+  }
 
   run_make_with_options($makefile, $options, &get_logfile(0),
                         $err_code, $timeout);
diff --git a/tests/scripts/misc/fopen-fail b/tests/scripts/misc/fopen-fail
new file mode 100644 (file)
index 0000000..6580e51
--- /dev/null
@@ -0,0 +1,15 @@
+#                                                                    -*-perl-*-
+
+$description = "Make sure make exits with an error if fopen fails.";
+
+# Recurse infinitely until we run out of open files, and ensure we
+# fail with a non-zero exit code.  Don't bother to test the output
+# since it's hard to know what it will be, exactly.
+# See Savannah bug #27374.
+
+run_make_test(q!
+include $(lastword $(MAKEFILE_LIST))
+!,
+              '', undef, 512);
+
+1;
index adc38aed24c34ef2c3129aca7444032e7514f00e..16ae8893fab4d5a7ba3ebf9f048783f3cb0f01ed 100644 (file)
@@ -653,38 +653,43 @@ sub compare_output
   local($answer,$logfile) = @_;
   local($slurp, $answer_matched) = ('', 0);
 
-  print "Comparing Output ........ " if $debug;
+  ++$tests_run;
 
-  $slurp = &read_file_into_string ($logfile);
+  if (! defined $answer) {
+      print "Ignoring output ........ " if $debug;
+      $answer_matched = 1;
+  } else {
+      print "Comparing Output ........ " if $debug;
 
-  # For make, get rid of any time skew error before comparing--too bad this
-  # has to go into the "generic" driver code :-/
-  $slurp =~ s/^.*modification time .*in the future.*\n//gm;
-  $slurp =~ s/^.*Clock skew detected.*\n//gm;
+      $slurp = &read_file_into_string ($logfile);
 
-  ++$tests_run;
+      # For make, get rid of any time skew error before comparing--too bad this
+      # has to go into the "generic" driver code :-/
+      $slurp =~ s/^.*modification time .*in the future.*\n//gm;
+      $slurp =~ s/^.*Clock skew detected.*\n//gm;
 
-  if ($slurp eq $answer) {
-    $answer_matched = 1;
-  } else {
-    # See if it is a slash or CRLF problem
-    local ($answer_mod, $slurp_mod) = ($answer, $slurp);
+      if ($slurp eq $answer) {
+          $answer_matched = 1;
+      } else {
+          # See if it is a slash or CRLF problem
+          local ($answer_mod, $slurp_mod) = ($answer, $slurp);
 
-    $answer_mod =~ tr,\\,/,;
-    $answer_mod =~ s,\r\n,\n,gs;
+          $answer_mod =~ tr,\\,/,;
+          $answer_mod =~ s,\r\n,\n,gs;
 
-    $slurp_mod =~ tr,\\,/,;
-    $slurp_mod =~ s,\r\n,\n,gs;
+          $slurp_mod =~ tr,\\,/,;
+          $slurp_mod =~ s,\r\n,\n,gs;
 
-    $answer_matched = ($slurp_mod eq $answer_mod);
+          $answer_matched = ($slurp_mod eq $answer_mod);
 
-    # If it still doesn't match, see if the answer might be a regex.
-    if (!$answer_matched && $answer =~ m,^/(.+)/$,) {
-      $answer_matched = ($slurp =~ /$1/);
-      if (!$answer_matched && $answer_mod =~ m,^/(.+)/$,) {
-          $answer_matched = ($slurp_mod =~ /$1/);
+          # If it still doesn't match, see if the answer might be a regex.
+          if (!$answer_matched && $answer =~ m,^/(.+)/$,) {
+              $answer_matched = ($slurp =~ /$1/);
+              if (!$answer_matched && $answer_mod =~ m,^/(.+)/$,) {
+                  $answer_matched = ($slurp_mod =~ /$1/);
+              }
+          }
       }
-    }
   }
 
   if ($answer_matched && $test_passed)
@@ -706,8 +711,6 @@ sub compare_output
 
     local($command) = "diff -c " . &get_basefile . " " . $logfile;
     &run_command_with_output(&get_difffile,$command);
-  } else {
-      &rmfiles ();
   }
 
   $suite_passed = 0;