From e7eb8b5962efe316b08a4a6209d2a63130d1f22f Mon Sep 17 00:00:00 2001 From: Dmitry Goncharov Date: Mon, 6 Sep 2021 20:20:28 -0400 Subject: [PATCH] [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. --- src/read.c | 19 +++++--- tests/scripts/features/include | 85 +++++++++++++++++++++++++++++++++- 2 files changed, 96 insertions(+), 8 deletions(-) diff --git a/src/read.c b/src/read.c index 58c69a25..1db51cfa 100644 --- a/src/read.c +++ b/src/read.c @@ -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. */ diff --git a/tests/scripts/features/include b/tests/scripts/features/include index 54ad12c1..00c128aa 100644 --- a/tests/scripts/features/include +++ b/tests/scripts/features/include @@ -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