[SV 27374] Fatal immediately on unrecoverable fopen() errors.

This commit is contained in:
Paul Smith 2013-09-15 16:41:42 -04:00
parent a4d8444b59
commit 1b90248893
6 changed files with 74 additions and 29 deletions

View file

@ -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.

16
read.c
View file

@ -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. */

View 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.

View 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);

View file

@ -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;

View file

@ -653,38 +653,43 @@ sub compare_output
local($answer,$logfile) = @_;
local($slurp, $answer_matched) = ('', 0);
print "Comparing Output ........ " if $debug;
$slurp = &read_file_into_string ($logfile);
# 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;
++$tests_run;
if ($slurp eq $answer) {
$answer_matched = 1;
if (! defined $answer) {
print "Ignoring output ........ " if $debug;
$answer_matched = 1;
} else {
# See if it is a slash or CRLF problem
local ($answer_mod, $slurp_mod) = ($answer, $slurp);
print "Comparing Output ........ " if $debug;
$answer_mod =~ tr,\\,/,;
$answer_mod =~ s,\r\n,\n,gs;
$slurp = &read_file_into_string ($logfile);
$slurp_mod =~ tr,\\,/,;
$slurp_mod =~ s,\r\n,\n,gs;
# 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;
$answer_matched = ($slurp_mod eq $answer_mod);
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 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/);
$answer_mod =~ tr,\\,/,;
$answer_mod =~ s,\r\n,\n,gs;
$slurp_mod =~ tr,\\,/,;
$slurp_mod =~ s,\r\n,\n,gs;
$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 ($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;