]> git.ipfire.org Git - thirdparty/make.git/commitdiff
[SV 64085] Handle .POSIX plus .IGNORE correctly
authorPaul Smith <psmith@gnu.org>
Mon, 5 Feb 2024 00:41:50 +0000 (19:41 -0500)
committerPaul Smith <psmith@gnu.org>
Mon, 5 Feb 2024 00:41:50 +0000 (19:41 -0500)
POSIX requires that a conforming makefile should not use -e if
 1) make is invoked with -i
 2) A .IGNORE target exists with no prerequisites
 3) The current target is a prerequisite of .IGNORE

* src/job.c (start_job_command): Add the target's flags when
constructing argv so it can check (3) above.
(construct_command_argv_internal): Don't set shellflags if it's not
set: this only happens if we're parsing for the slow path and we
don't need them.
(construct_command_argv): Don't allocate buffers if not needed.
When detecting "-ec", check the global ignore_errors_flag and the
current command line flags.
* tests/scripts/targets/IGNORE: Add tests for .IGNORE.
* tests/scripts/targets/POSIX: Add tests for the three cases above.

src/job.c
tests/scripts/targets/IGNORE [new file with mode: 0644]
tests/scripts/targets/POSIX

index 45e45c5c88c490677a0de3c29817292f0d8fa543..09fe9d162be563c5eee3c2ed2e6e4b4ca1b22dd0 100644 (file)
--- a/src/job.c
+++ b/src/job.c
@@ -1257,7 +1257,7 @@ start_job_command (struct child *child)
       }
 #else
     argv = construct_command_argv (p, &end, child->file,
-                                   child->file->cmds->lines_flags[child->command_line - 1],
+                                   child->file->cmds->lines_flags[child->command_line - 1] | child->file->command_flags,
                                    &child->sh_batch_file);
 #endif
     if (end == NULL)
@@ -2836,9 +2836,6 @@ construct_command_argv_internal (char *line, char **restp, const char *shell,
   if (*line == '\0')
     return 0;
 
-  if (shellflags == 0)
-    shellflags = posix_pedantic && NONE_SET (flags, COMMANDS_NOERROR) ? "-ec" : "-c";
-
   /* See if it is safe to parse commands internally.  */
   if (shell == 0)
     shell = default_shell;
@@ -3628,7 +3625,9 @@ char **
 construct_command_argv (char *line, char **restp, struct file *file,
                         int cmd_flags, char **batch_filename)
 {
-  char *shell, *ifs, *shellflags;
+  char *shell, *ifs;
+  char *allocflags = NULL;
+  const char *shellflags;
   char **argv;
 
   {
@@ -3695,12 +3694,14 @@ construct_command_argv (char *line, char **restp, struct file *file,
 
     var = lookup_variable_for_file (STRING_SIZE_TUPLE (".SHELLFLAGS"), file);
     if (!var)
-      shellflags = xstrdup ("");
-    else if (posix_pedantic && var->origin == o_default)
+      shellflags = "";
+    else if (var->origin != o_default)
+      shellflags = allocflags = allocated_expand_string_for_file (var->value, file);
+    else if (posix_pedantic && !ignore_errors_flag && NONE_SET (cmd_flags, COMMANDS_NOERROR))
       /* In POSIX mode we default to -ec, unless we're ignoring errors.  */
-      shellflags = xstrdup (ANY_SET (cmd_flags, COMMANDS_NOERROR) ? "-c" : "-ec");
+      shellflags = "-ec";
     else
-      shellflags = allocated_expand_string_for_file (var->value, file);
+      shellflags = "-c";
 
     ifs = allocated_expand_variable_for_file (STRING_SIZE_TUPLE ("IFS"), file);
 
@@ -3711,7 +3712,7 @@ construct_command_argv (char *line, char **restp, struct file *file,
                                           cmd_flags, batch_filename);
 
   free (shell);
-  free (shellflags);
+  free (allocflags);
   free (ifs);
 
   return argv;
diff --git a/tests/scripts/targets/IGNORE b/tests/scripts/targets/IGNORE
new file mode 100644 (file)
index 0000000..04afc5d
--- /dev/null
@@ -0,0 +1,28 @@
+#                                                                    -*-perl-*-
+
+$description = "Test the behaviour of the .IGNORE target.";
+
+$details = "";
+
+# Without any ignore
+run_make_test(q!
+all: ; @#HELPER# -q fail 1
+!,
+              '', "#MAKE#: *** [#MAKEFILE#:2: all] Error 1", 512);
+
+# Global .IGNORE
+run_make_test(q!
+.IGNORE:
+all: ; @#HELPER# -q fail 1
+!,
+              '', "#MAKE#: [#MAKEFILE#:3: all] Error 1 (ignored)");
+
+# Specific .IGNORE
+
+run_make_test(q!
+.IGNORE: all
+all: ; @#HELPER# -q fail 1
+!,
+              '', "#MAKE#: [#MAKEFILE#:3: all] Error 1 (ignored)");
+
+1;
index 325d58cb9290c858880563a3e61dc40998373487..43e1cf91d255a96b1548a648c4709b9e3543c0ea 100644 (file)
@@ -37,6 +37,28 @@ all: ; @-#HELPER# -q fail 1; #HELPER# out hello
 !,
               '', "hello\n");
 
+# SV 64085: Also don't add -e if -i or .IGNORE is used
+
+run_make_test(q!
+.POSIX:
+all: ; @#HELPER# -q fail 1; #HELPER# out hello
+!,
+              '-i', "hello\n");
+
+run_make_test(q!
+.POSIX:
+.IGNORE:
+all: ; @#HELPER# -q fail 1; #HELPER# out hello
+!,
+              '', "hello\n");
+
+run_make_test(q!
+.POSIX:
+.IGNORE: all
+all: ; @#HELPER# -q fail 1; #HELPER# out hello
+!,
+              '', "hello\n");
+
 # But explicit settings must still take precedence
 
 run_make_test(q!