summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Smith <psmith@gnu.org>2013-09-15 16:41:42 -0400
committerPaul Smith <psmith@gnu.org>2013-09-15 17:09:01 -0400
commit1b9024889384fc26d296ee4340ffca32e8c73017 (patch)
tree88312b516ca64a727dffcbe87bf9aec3674e7a92
parenta4d8444b594e53b13659a9f2c64424418f255e27 (diff)
downloadgunmake-1b9024889384fc26d296ee4340ffca32e8c73017.tar.gz
[SV 27374] Fatal immediately on unrecoverable fopen() errors.
-rw-r--r--ChangeLog4
-rw-r--r--read.c16
-rw-r--r--tests/ChangeLog7
-rw-r--r--tests/run_make_tests.pl6
-rw-r--r--tests/scripts/misc/fopen-fail15
-rw-r--r--tests/test_driver.pl53
6 files changed, 73 insertions, 28 deletions
diff --git a/ChangeLog b/ChangeLog
index 899b471..7c88e76 100644
--- 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 834c7f8..f8542b0 100644
--- 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. */
diff --git a/tests/ChangeLog b/tests/ChangeLog
index d97e7e2..c6cebbf 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -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.
diff --git a/tests/run_make_tests.pl b/tests/run_make_tests.pl
index cb8e1bd..d8a093b 100644
--- a/tests/run_make_tests.pl
+++ b/tests/run_make_tests.pl
@@ -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
index 0000000..6580e51
--- /dev/null
+++ b/tests/scripts/misc/fopen-fail
@@ -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;
diff --git a/tests/test_driver.pl b/tests/test_driver.pl
index adc38ae..16ae889 100644
--- a/tests/test_driver.pl
+++ b/tests/test_driver.pl
@@ -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;