]> git.ipfire.org Git - thirdparty/make.git/commitdiff
[SV 57778] Don't ignore included makefiles that can't be read
authorDmitry Goncharov <dgoncharov@users.sf.net>
Tue, 7 Sep 2021 00:20:28 +0000 (20:20 -0400)
committerPaul Smith <psmith@gnu.org>
Tue, 7 Sep 2021 00:20:28 +0000 (20:20 -0400)
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
tests/scripts/features/include

index 58c69a25e60d88e53eaf0f4fe6a3d9f6f70fc016..1db51cfa91228846f3d34b05c2647e6bf0b9a7c8 100644 (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.  */
index 54ad12c1cd7bf028f5c4624d1159426c601349bc..00c128aa34235f9bce67cd25b14d36c9b0d4a723 100644 (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