[SV 57778] Don't ignore included makefiles that can't be read

If we find an included makefile but it's not readable, stop
immediately with an error rather than continuing to look in other
directories.

* src/read.c (eval_makefile): Only keep searching if the fopen error
is ENOENT, else stop and fail.
* tests/scripts/features/include: Add tests to verify this behavior.
This commit is contained in:
Dmitry Goncharov 2021-09-06 20:20:28 -04:00 committed by Paul Smith
parent 0c2fc00544
commit e7eb8b5962
2 changed files with 96 additions and 8 deletions

View file

@ -370,20 +370,27 @@ eval_makefile (const char *filename, unsigned short flags)
}
}
/* 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. */
if (ebuf.fp == NULL && (flags & RM_INCLUDED) && *filename != '/'
&& include_directories)
/* 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. */
if (ebuf.fp == NULL && deps->error == ENOENT && (flags & RM_INCLUDED)
&& *filename != '/' && include_directories)
for (const char **dir = include_directories; *dir != NULL; ++dir)
{
const char *included = concat (3, *dir, "/", filename);
ebuf.fp = fopen (included, "r");
ENULLLOOP(ebuf.fp, fopen (included, "r"));
if (ebuf.fp)
{
filename = included;
break;
}
if (errno != ENOENT)
{
filename = included;
deps->error = errno;
break;
}
}
/* Enter the final name for this makefile as a goaldep. */

View file

@ -64,6 +64,22 @@ error: foo.mk ; @echo $@
512
);
# The same as above with an additional include directory.
mkdir('hellod', 0777);
run_make_test
('
-include foo.mk
error: foo.mk ; @echo $@
',
'-Ihellod',
"#MAKE#: *** No rule to make target 'foo.mk', needed by 'error'. Stop.\n",
512
);
rmdir('hellod');
# Make sure that target-specific variables don't impact things. This could
# happen because a file record is created when a target-specific variable is
# set.
@ -161,6 +177,44 @@ inc2:; echo > $@
rmfiles('inc1', 'inc2');
# Test include of make-able file doesn't show an error.
# Specify an additional include directory.
mkdir('hellod', 0777);
run_make_test(q!
.PHONY: default
default:; @echo DONE
inc1:; echo > $@
include inc1
include inc2
inc2:; echo > $@
!,
'-Ihellod', "echo > inc1\necho > inc2\nDONE\n");
rmfiles('inc1', 'inc2');
# Test include of make-able file doesn't show an error.
# inc1 and inc2 are present in the specified include directory.
touch('hellod/inc1');
touch('hellod/inc2');
run_make_test(q!
.PHONY: default
default:; @echo DONE
inc1:; echo > $@
include inc1
include inc2
inc2:; echo > $@
!,
'-Ihellod', "DONE\n");
rmfiles('inc1', 'inc2', 'hellod/inc1', 'hellod/inc2');
rmdir('hellod');
# No target gets correct error
run_make_test('', '', '#MAKE#: *** No targets. Stop.', 512);
@ -262,6 +316,7 @@ hello.mk: ; echo 'FOO=bar' > $@
if (defined $ERR_unreadable_file) {
# Including files that can't be read should show an error
unlink('inc1');
create_file('inc1', 'FOO := foo');
chmod 0000, 'inc1';
@ -271,7 +326,18 @@ all:;@echo $(FOO)
!,
'', "#MAKEFILE#:2: inc1: $ERR_unreadable_file\n#MAKE#: *** No rule to make target 'inc1'. Stop.", 512);
# Unreadable files that we know how to successfully recreate should work
# Including files that can't be read should show an error, even when there
# is a readable file in a subsequent include directory.
mkdir('hellod', 0777);
touch("hellod/inc1");
run_make_test(q!
include inc1
all:;@echo $(FOO)
!,
'-Ihellod', "#MAKEFILE#:2: inc1: $ERR_unreadable_file\n#MAKE#: *** No rule to make target 'inc1'. Stop.", 512);
# Unreadable files that we know how to successfully recreate should work
run_make_test(sprintf(q!
all:;@echo $(FOO)
@ -280,7 +346,22 @@ inc1:; @%s $@ && echo FOO := bar > $@
!, $CMD_rmfile),
'', "bar");
rmfiles('inc1');
# Unreadable files that we know how to successfully recreate should work.
# Even when there is a readable file in an additional include directory.
unlink('inc1');
create_file('inc1', 'FOO := foo');
chmod 0000, 'inc1';
run_make_test(sprintf(q!
all:;@echo $(FOO)
include inc1
inc1:; @%s $@ && echo FOO := bar > $@
!, $CMD_rmfile),
'-Ihellod', "bar");
rmfiles('inc1', 'hellod/inc1');
rmdir('hellod');
}
# Check that the order of remaking include files is correct: should remake