diff --git a/Queue-failed-fork-etc.-to-be-handled-like-any-other-.patch b/Queue-failed-fork-etc.-to-be-handled-like-any-other-.patch new file mode 100644 index 0000000..fbf54f0 --- /dev/null +++ b/Queue-failed-fork-etc.-to-be-handled-like-any-other-.patch @@ -0,0 +1,443 @@ +From 3112c8799358cb5d051e0b63d0e916357169942c Mon Sep 17 00:00:00 2001 +From: Paul Smith +Date: Sat, 4 Aug 2018 12:18:39 -0400 +Subject: [PATCH 085/104] Queue failed fork() (etc.) to be handled like any + other failed job. + +If we failed to fork() we were essentially exiting make immediately +without respect to ignore flags, etc. On one hand that makes sense +because if you can't fork you're in real trouble, but it doesn't +work so well on systems where we don't fork at all. Instead, treat +a fork error like any other error by delaying the handling until +the next call to reap_children(). Any child with a PID of -1 is +considered to have died before starting so check these first without +waiting for them. + +* src/commands.c (fatal_error_signal): Don't kill children that +never started. +* src/function.c (func_shell_base): Handle cleanup properly if the +child doesn't start. +* src/job.c (reap_children): Check for children that died before +starting and handle them without waiting for the PID. +(start_job_command): Free memory when the child doesn't start. +(start_waiting_job): Don't manage children who never started. +(child_execute_job): If the fork fails return PID -1. +* src/vmsjobs.c: Check for children that never started. +* tests/run_make_tests.pl: Parse config.status to get all options. +--- + commands.c | 6 +- + function.c | 28 +++++---- + job.c | 123 ++++++++++++++++++---------------------- + job.h | 8 ++- + vmsjobs.c | 3 +- + tests/run_make_tests.pl | 13 ++++- + 6 files changed, 93 insertions(+), 88 deletions(-) + +--- a/commands.c 2019-04-10 22:50:51.317814695 -0400 ++++ b/commands.c 2019-04-10 23:13:38.411814695 -0400 +@@ -538,7 +538,7 @@ fatal_error_signal (int sig) + { + struct child *c; + for (c = children; c != 0; c = c->next) +- if (!c->remote) ++ if (!c->remote && c->pid > 0) + (void) kill (c->pid, SIGTERM); + } + +@@ -559,7 +559,7 @@ fatal_error_signal (int sig) + /* Remote children won't automatically get signals sent + to the process group, so we must send them. */ + for (c = children; c != 0; c = c->next) +- if (c->remote) ++ if (c->remote && c->pid > 0) + (void) remote_kill (c->pid, sig); + + for (c = children; c != 0; c = c->next) +@@ -660,7 +660,7 @@ delete_child_targets (struct child *chil + { + struct dep *d; + +- if (child->deleted) ++ if (child->deleted || child->pid < 0) + return; + + /* Delete the target file if it changed. */ +--- a/function.c 2019-04-10 22:50:51.293814695 -0400 ++++ b/function.c 2019-04-10 23:19:59.282814695 -0400 +@@ -1690,7 +1690,7 @@ func_shell_base (char *o, char **argv, i + #ifdef __MSDOS__ + FILE *fpipe; + #endif +- char **command_argv; ++ char **command_argv = NULL; + const char *error_prefix; + char **envp; + int pipedes[2]; +@@ -1753,7 +1753,8 @@ func_shell_base (char *o, char **argv, i + if (pipedes[0] < 0) + { + perror_with_name (error_prefix, "pipe"); +- return o; ++ pid = -1; ++ goto done; + } + + #elif defined(WINDOWS32) +@@ -1766,14 +1767,16 @@ func_shell_base (char *o, char **argv, i + /* Open of the pipe failed, mark as failed execution. */ + shell_completed (127, 0); + perror_with_name (error_prefix, "pipe"); +- return o; ++ pid = -1; ++ goto done; + } + + #else + if (pipe (pipedes) < 0) + { + perror_with_name (error_prefix, "pipe"); +- return o; ++ pid = -1; ++ goto done; + } + + /* Close handles that are unnecessary for the child process. */ +@@ -1790,10 +1793,7 @@ func_shell_base (char *o, char **argv, i + } + + if (pid < 0) +- { +- perror_with_name (error_prefix, "fork"); +- return o; +- } ++ goto done; + #endif + + { +@@ -1806,10 +1806,6 @@ func_shell_base (char *o, char **argv, i + #ifndef __MSDOS__ + shell_function_completed = 0; + +- /* Free the storage only the child needed. */ +- free (command_argv[0]); +- free (command_argv); +- + /* Close the write side of the pipe. We test for -1, since + pipedes[1] is -1 on MS-Windows, and some versions of MS + libraries barf when 'close' is called with -1. */ +@@ -1884,6 +1880,14 @@ func_shell_base (char *o, char **argv, i + free (buffer); + } + ++ done: ++ if (command_argv) ++ { ++ /* Free the storage only the child needed. */ ++ free (command_argv[0]); ++ free (command_argv); ++ } ++ + return o; + } + + +--- a/job.c 2019-04-10 22:50:51.306814695 -0400 ++++ b/job.c 2019-04-10 23:44:37.378814695 -0400 +@@ -622,10 +622,22 @@ reap_children (int block, int err) + + any_remote = 0; + any_local = shell_function_pid != 0; +- for (c = children; c != 0; c = c->next) ++ lastc = 0; ++ for (c = children; c != 0; lastc = c, c = c->next) + { + any_remote |= c->remote; + any_local |= ! c->remote; ++ ++ /* If pid < 0, this child never even started. Handle it. */ ++ if (c->pid < 0) ++ { ++ exit_sig = 0; ++ coredump = 0; ++ /* According to POSIX, 127 is used for command not found. */ ++ exit_code = 127; ++ goto process_child; ++ } ++ + DB (DB_JOBS, (_("Live child %p (%s) PID %s %s\n"), + c, c->file->name, pid2str (c->pid), + c->remote ? _(" (remote)") : "")); +@@ -691,9 +703,6 @@ reap_children (int block, int err) + exit_sig = WIFSIGNALED (status) ? WTERMSIG (status) : 0; + coredump = WCOREDUMP (status); + +- /* If we have started jobs in this second, remove one. */ +- if (job_counter) +- --job_counter; + } + else + { +@@ -818,6 +827,16 @@ reap_children (int block, int err) + Ignore it; it was inherited from our invoker. */ + continue; + ++ DB (DB_JOBS, (exit_sig == 0 && exit_code == 0 ++ ? _("Reaping losing child %p PID %s %s\n") ++ : _("Reaping winning child %p PID %s %s\n"), ++ c, pid2str (c->pid), c->remote ? _(" (remote)") : "")); ++ ++ /* If we have started jobs in this second, remove one. */ ++ if (job_counter) ++ --job_counter; ++ ++ process_child: + /* Determine the failure status: 0 for success, 1 for updating target in + question mode, 2 for anything else. */ + if (exit_sig == 0 && exit_code == 0) +@@ -827,11 +846,6 @@ reap_children (int block, int err) + else + child_failed = MAKE_FAILURE; + +- DB (DB_JOBS, (child_failed +- ? _("Reaping losing child %p PID %s %s\n") +- : _("Reaping winning child %p PID %s %s\n"), +- c, pid2str (c->pid), c->remote ? _(" (remote)") : "")); +- + if (c->sh_batch_file) + { + int rm_status; +@@ -939,7 +953,7 @@ reap_children (int block, int err) + + /* At this point c->file->update_status is success or failed. But + c->file->command_state is still cs_running if all the commands +- ran; notice_finish_file looks for cs_running to tell it that ++ ran; notice_finished_file looks for cs_running to tell it that + it's interesting to check the file's modtime again now. */ + + if (! handling_fatal_signal) +@@ -948,9 +962,6 @@ reap_children (int block, int err) + update_status to its also_make files. */ + notice_finished_file (c->file); + +- DB (DB_JOBS, (_("Removing child %p PID %s%s from chain.\n"), +- c, pid2str (c->pid), c->remote ? _(" (remote)") : "")); +- + /* Block fatal signals while frobnicating the list, so that + children and job_slots_used are always consistent. Otherwise + a fatal signal arriving after the child is off the chain and +@@ -958,9 +969,15 @@ reap_children (int block, int err) + live and call reap_children again. */ + block_sigs (); + +- /* There is now another slot open. */ +- if (job_slots_used > 0) +- --job_slots_used; ++ if (c->pid > 0) ++ { ++ DB (DB_JOBS, (_("Removing child %p PID %s%s from chain.\n"), ++ c, pid2str (c->pid), c->remote ? _(" (remote)") : "")); ++ ++ /* There is now another slot open. */ ++ if (job_slots_used > 0) ++ --job_slots_used; ++ } + + /* Remove the child from the chain and free it. */ + if (lastc == 0) +@@ -1071,8 +1088,10 @@ start_job_command (struct child *child) + int flags; + char *p; + #ifdef VMS ++# define FREE_ARGV(_a) + char *argv; + #else ++# define FREE_ARGV(_a) do{ if (_a) { free ((_a)[0]); free (_a); } }while(0) + char **argv; + #endif + +@@ -1190,10 +1209,7 @@ start_job_command (struct child *child) + error is 2. */ + if (argv != 0 && question_flag && !(flags & COMMANDS_RECURSE)) + { +-#ifndef VMS +- free (argv[0]); +- free (argv); +-#endif ++ FREE_ARGV (argv); + #ifdef VMS + /* On VMS, argv[0] can be a null string here */ + if (argv[0] != 0) +@@ -1211,13 +1227,7 @@ start_job_command (struct child *child) + { + /* Go on to the next command. It might be the recursive one. + We construct ARGV only to find the end of the command line. */ +-#ifndef VMS +- if (argv) +- { +- free (argv[0]); +- free (argv); +- } +-#endif ++ FREE_ARGV (argv); + argv = 0; + } + +@@ -1293,8 +1303,7 @@ start_job_command (struct child *child) + && (argv[2] && argv[2][0] == ':' && argv[2][1] == '\0') + && argv[3] == NULL) + { +- free (argv[0]); +- free (argv); ++ FREE_ARGV (argv); + goto next_command; + } + #endif /* !VMS && !_AMIGA */ +@@ -1303,10 +1312,7 @@ start_job_command (struct child *child) + + if (just_print_flag && !(flags & COMMANDS_RECURSE)) + { +-#ifndef VMS +- free (argv[0]); +- free (argv); +-#endif ++ FREE_ARGV (argv); + goto next_command; + } + +@@ -1373,11 +1379,7 @@ start_job_command (struct child *child) + + #ifdef VMS + if (!child_execute_job (child, argv)) +- { +- /* Fork failed! */ +- perror_with_name ("fork", ""); +- goto error; +- } ++ child->pid = -1; + + #else + +@@ -1385,18 +1387,11 @@ start_job_command (struct child *child) + + jobserver_pre_child (flags & COMMANDS_RECURSE); + +- child->pid = child_execute_job (&child->output, child->good_stdin, argv, child->environment); ++ child->pid = child_execute_job (&child->output, child->good_stdin, ++ argv, child->environment); + + environ = parent_environ; /* Restore value child may have clobbered. */ + jobserver_post_child (flags & COMMANDS_RECURSE); +- +- if (child->pid < 0) +- { +- /* Fork failed! */ +- unblock_sigs (); +- perror_with_name ("fork", ""); +- goto error; +- } + #endif /* !VMS */ + } + +@@ -1511,33 +1506,25 @@ start_job_command (struct child *child) + for (i = 0; argv[i]; i++) + fprintf (stderr, "%s ", argv[i]); + fprintf (stderr, _("\nCounted %d args in failed launch\n"), i); +- goto error; ++ child->pid = -1; + } + } + #endif /* WINDOWS32 */ + #endif /* __MSDOS__ or Amiga or WINDOWS32 */ + + /* Bump the number of jobs started in this second. */ +- ++job_counter; +- +- /* We are the parent side. Set the state to +- say the commands are running and return. */ ++ if (child->pid >= 0) ++ ++job_counter; + ++ /* Set the state to running. */ + set_command_state (child->file, cs_running); + + /* Free the storage used by the child's argument list. */ +-#ifndef VMS +- free (argv[0]); +- free (argv); +-#endif ++ FREE_ARGV (argv); + + OUTPUT_UNSET(); +- return; + +- error: +- child->file->update_status = us_failed; +- notice_finished_file (child->file); +- OUTPUT_UNSET(); ++#undef FREE_ARGV + } + + /* Try to start a child running. +@@ -1579,12 +1566,15 @@ start_waiting_job (struct child *c) + { + case cs_running: + c->next = children; +- DB (DB_JOBS, (_("Putting child %p (%s) PID %s%s on the chain.\n"), +- c, c->file->name, pid2str (c->pid), +- c->remote ? _(" (remote)") : "")); ++ if (c->pid > 0) ++ { ++ DB (DB_JOBS, (_("Putting child %p (%s) PID %s%s on the chain.\n"), ++ c, c->file->name, pid2str (c->pid), ++ c->remote ? _(" (remote)") : "")); ++ /* One more job slot is in use. */ ++ ++job_slots_used; ++ } + children = c; +- /* One more job slot is in use. */ +- ++job_slots_used; + unblock_sigs (); + break; + +--- a/job.h 2019-04-10 22:50:51.319814695 -0400 ++++ b/job.h 2019-04-10 23:46:53.284814695 -0400 +@@ -95,6 +95,8 @@ struct child + char **command_lines; /* Array of variable-expanded cmd lines. */ + char *command_ptr; /* Ptr into command_lines[command_line]. */ + ++ struct output output; /* Output for this child. */ ++ + #ifdef VMS + char *comname; /* Temporary command file name */ + int efn; /* Completion event flag number */ +@@ -103,7 +105,7 @@ struct child + #endif + + unsigned int command_line; /* Index into command_lines. */ +- struct output output; /* Output for this child. */ ++ + pid_t pid; /* Child process's ID number. */ + unsigned int remote:1; /* Nonzero if executing remotely. */ + unsigned int noerror:1; /* Nonzero if commands contained a '-'. */ +@@ -131,7 +133,8 @@ int child_execute_job (struct child *chi + # define FD_STDIN (fileno (stdin)) + # define FD_STDOUT (fileno (stdout)) + # define FD_STDERR (fileno (stderr)) +-pid_t child_execute_job (struct output *out, int good_stdin, char **argv, char **envp); ++pid_t child_execute_job (struct output *out, int good_stdin, ++ char **argv, char **envp); + #endif + + #ifdef _AMIGA +--- a/vmsjobs.c 2019-04-10 22:50:51.318814695 -0400 ++++ b/vmsjobs.c 2019-04-10 23:47:44.179814695 -0400 +@@ -191,7 +191,8 @@ astYHandler (void) + { + struct child *c; + for (c = children; c != 0; c = c->next) +- sys$delprc (&c->pid, 0, 0); ++ if (c->pid > 0) ++ sys$delprc (&c->pid, 0, 0); + ctrlYPressed= 1; + kill (getpid(),SIGQUIT); + return SS$_NORMAL; diff --git a/SV-54233-Preserve-higher-command_state-values-on-als.patch b/SV-54233-Preserve-higher-command_state-values-on-als.patch new file mode 100644 index 0000000..4540825 --- /dev/null +++ b/SV-54233-Preserve-higher-command_state-values-on-als.patch @@ -0,0 +1,91 @@ +From 05769ca009e630c1989f29ca8cb9d0ec4cf2a8d8 Mon Sep 17 00:00:00 2001 +From: Paul Smith +Date: Sat, 4 Aug 2018 19:07:59 -0400 +Subject: [PATCH 096/104] [SV 54233] Preserve higher command_state values on + also_make targets. + +If multiple pattern rules have the same pattern as also-make targets +and we attempt to run them at the same time, we might downgrade the +command state from 'running' to 'deps_running'; this will prevent +that also_make from being considered complete causing make to wait +forever for it to finish. + +Ensure that set_command_state never downgrades the state of a target. + +* src/file.c (set_command_state): Don't downgrade command_state. +* src/filedef.h (struct file): Document the order prerequisite. +* test/scripts/features/patternrules: Test the behavior. +--- + file.c | 7 +++++-- + filedef.h | 2 +- + tests/scripts/features/patternrules | 16 ++++++++++++++++ + 3 files changed, 22 insertions(+), 3 deletions(-) + +diff --git a/file.c b/file.c +index 4835e4f..925ce8d 100644 +--- a/file.c ++++ b/file.c +@@ -788,7 +788,9 @@ snap_deps (void) + #endif + } + +-/* Set the 'command_state' member of FILE and all its 'also_make's. */ ++/* Set the 'command_state' member of FILE and all its 'also_make's. ++ Don't decrease the state of also_make's (e.g., don't downgrade a 'running' ++ also_make to a 'deps_running' also_make). */ + + void + set_command_state (struct file *file, enum cmd_state state) +@@ -798,7 +800,8 @@ set_command_state (struct file *file, enum cmd_state state) + file->command_state = state; + + for (d = file->also_make; d != 0; d = d->next) +- d->file->command_state = state; ++ if (state > d->file->command_state) ++ d->file->command_state = state; + } + + /* Convert an external file timestamp to internal form. */ +diff --git a/filedef.h b/filedef.h +index 8af562a..9d4b816 100644 +--- a/filedef.h ++++ b/filedef.h +@@ -68,7 +68,7 @@ struct file + us_question, /* Needs to be updated (-q is is set). */ + us_failed /* Update failed. */ + } update_status ENUM_BITFIELD (2); +- enum cmd_state /* State of the commands. */ ++ enum cmd_state /* State of commands. ORDER IS IMPORTANT! */ + { + cs_not_started = 0, /* Not yet started. Must be 0! */ + cs_deps_running, /* Dep commands running. */ +diff --git a/tests/scripts/features/patternrules b/tests/scripts/features/patternrules +index f76724e..177bb32 100644 +--- a/tests/scripts/features/patternrules ++++ b/tests/scripts/features/patternrules +@@ -220,6 +220,22 @@ all: foo.x foo-mt.x + + 1; + ++# Test pattern rules building the same targets ++# See SV 54233. Rely on our standard test timeout to break the loop ++ ++touch('a.c'); ++ ++run_make_test(q! ++all: a.elf a.dbg ++ ++%.elf %.lnk: %.c ; : $*.elf $*.lnk ++ ++%.elf %.dbg: %.lnk ; : $*.elf $*.dbg ++!, ++ '-j2', ": a.elf a.lnk\n: a.elf a.dbg\n"); ++ ++unlink('a.c'); ++ + # This tells the test driver that the perl test script executed properly. + 1; + +-- +2.19.1 + diff --git a/main.c-main-SV-48274-Allow-j-in-makefile-MAKEFLAGS-v.patch b/main.c-main-SV-48274-Allow-j-in-makefile-MAKEFLAGS-v.patch new file mode 100644 index 0000000..fc14d40 --- /dev/null +++ b/main.c-main-SV-48274-Allow-j-in-makefile-MAKEFLAGS-v.patch @@ -0,0 +1,83 @@ +From 0c5a9f9b92af1634dc60fa21e9ac86ed50e5d595 Mon Sep 17 00:00:00 2001 +From: Paul Smith +Date: Mon, 30 Oct 2017 12:53:49 -0400 +Subject: [PATCH 056/104] * main.c (main): [SV 48274] Allow -j in makefile + MAKEFLAGS variable. + +* tests/jhelp.pl: New file to allow testing parallelism without sleep. +--- + tests/jhelp.pl | 63 +++++++++++++++++++++ + create mode 100755 tests/jhelp.pl + +diff --git a/tests/jhelp.pl b/tests/jhelp.pl +new file mode 100755 +index 0000000..b368099 +--- /dev/null ++++ b/tests/jhelp.pl +@@ -0,0 +1,63 @@ ++#!/usr/bin/env perl ++# -*-perl-*- ++# ++# This script helps us test jobserver/parallelism without a lot of unreliable ++# (and slow) sleep calls. Written in Perl to get portable sub-second sleep. ++# ++# It can run the following steps based on arguments: ++# -t : maximum # of seconds the script can run; else we fail. ++# Default is 4 seconds. ++# -e : echo to stdout ++# -f : echo to stdout AND create an (empty) file named ++# -w : wait for a file named to exist ++ ++# Force flush ++$| = 1; ++ ++my $timeout = 4; ++ ++sub op { ++ my ($op, $nm) = @_; ++ ++ defined $nm or die "Missing value for $op\n"; ++ ++ if ($op eq '-e') { ++ print "$nm\n"; ++ return 1; ++ } ++ ++ if ($op eq '-f') { ++ print "$nm\n"; ++ open(my $fh, '>', $nm) or die "$nm: open: $!\n"; ++ close(my $fh); ++ return 1; ++ } ++ ++ if ($op eq '-w') { ++ if (-f $nm) { ++ return 1; ++ } ++ select(undef, undef, undef, 0.1); ++ return 0; ++ } ++ ++ if ($op eq '-t') { ++ $timeout = $nm; ++ return 1; ++ } ++ ++ die("Invalid command: $op $nm\n"); ++} ++ ++my $start = time(); ++while (@ARGV) { ++ if (op($ARGV[0], $ARGV[1])) { ++ shift; ++ shift; ++ } ++ if ($start + $timeout < time()) { ++ die("Timeout after ".(time()-$start-1)." seconds\n"); ++ } ++} ++ ++exit(0); +-- +2.19.1 + diff --git a/make-4.0-newlines.patch b/make-4.0-newlines.patch index 36bd8d6..add32c5 100644 --- a/make-4.0-newlines.patch +++ b/make-4.0-newlines.patch @@ -1,6 +1,6 @@ -diff -Nrup a/src/job.c b/src/job.c ---- a/src/job.c 2014-02-03 18:23:45.936436714 -0500 -+++ b/src/job.c 2014-02-04 00:17:53.232074893 -0500 +diff -Nrup a/job.c b/job.c +--- a/job.c 2014-02-03 18:23:45.936436714 -0500 ++++ b/job.c 2014-02-04 00:17:53.232074893 -0500 @@ -3269,13 +3269,14 @@ construct_command_argv_internal (char *l #endif if (PRESERVE_BSNL) diff --git a/make-4.0-weird-shell.patch b/make-4.0-weird-shell.patch index 23f3dbf..dfdaf89 100644 --- a/make-4.0-weird-shell.patch +++ b/make-4.0-weird-shell.patch @@ -1,6 +1,6 @@ -diff -up make-3.82/src/job.c\~ make-3.82/src/job.c ---- make-3.82/src/job.c~ 2010-08-11 16:13:33.000000000 +0200 -+++ make-3.82/src/job.c 2010-08-12 14:20:08.000000000 +0200 +diff -up make-3.82/job.c\~ make-3.82/job.c +--- make-3.82/job.c~ 2010-08-11 16:13:33.000000000 +0200 ++++ make-3.82/job.c 2010-08-12 14:20:08.000000000 +0200 @@ -2442,7 +2442,11 @@ construct_command_argv_internal (char *l /* See if it is safe to parse commands internally. */ diff --git a/make-4.2-getcwd.patch b/make-4.2-getcwd.patch index 7f6f18f..6c47238 100644 --- a/make-4.2-getcwd.patch +++ b/make-4.2-getcwd.patch @@ -1,6 +1,6 @@ -diff -Nrup a/src/makeint.h b/src/makeint.h ---- a/src/makeint.h 2016-05-21 16:22:32.000000000 -0400 -+++ b/src/makeint.h 2016-09-22 16:12:38.606702160 -0400 +diff -Nrup a/makeint.h b/makeint.h +--- a/makeint.h 2016-05-21 16:22:32.000000000 -0400 ++++ b/makeint.h 2016-09-22 16:12:38.606702160 -0400 @@ -596,7 +596,7 @@ long int lseek (); # endif diff --git a/make-4.2-j8k.patch b/make-4.2-j8k.patch index 60a0c7f..2b9d7fc 100644 --- a/make-4.2-j8k.patch +++ b/make-4.2-j8k.patch @@ -1,6 +1,6 @@ -diff -Nrup a/src/main.c b/src/main.c ---- a/src/main.c 2016-05-31 03:17:26.000000000 -0400 -+++ b/src/main.c 2016-09-22 16:18:52.283889265 -0400 +diff -Nrup a/main.c b/main.c +--- a/main.c 2016-05-31 03:17:26.000000000 -0400 ++++ b/main.c 2016-09-22 16:18:52.283889265 -0400 @@ -2051,6 +2051,21 @@ main (int argc, char **argv, char **envp } #endif diff --git a/make-4.2.1-glob-fix-2.patch b/make-4.2.1-glob-fix-2.patch new file mode 100644 index 0000000..911e315 --- /dev/null +++ b/make-4.2.1-glob-fix-2.patch @@ -0,0 +1,67 @@ +From 193f1e81edd6b1b56b0eb0ff8aa4b41c7b4257b4 Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Sun, 24 Sep 2017 09:12:58 -0400 +Subject: glob: Do not assume glibc glob internals. + +It has been proposed that glibc glob start using gl_lstat, +which the API allows it to do. GNU 'make' should not get in +the way of this. See: +https://sourceware.org/ml/libc-alpha/2017-09/msg00409.html + +* dir.c (local_lstat): New function, like local_stat. +(dir_setup_glob): Use it to initialize gl_lstat too, as the API +requires. +--- + dir.c | 29 +++++++++++++++++++++++++++-- + 1 file changed, 27 insertions(+), 2 deletions(-) + +diff --git a/dir.c b/dir.c +index adbb8a9..c343e4c 100644 +--- a/dir.c ++++ b/dir.c +@@ -1299,15 +1299,40 @@ local_stat (const char *path, struct stat *buf) + } + #endif + ++/* Similarly for lstat. */ ++#if !defined(lstat) && !defined(WINDOWS32) || defined(VMS) ++# ifndef VMS ++# ifndef HAVE_SYS_STAT_H ++int lstat (const char *path, struct stat *sbuf); ++# endif ++# else ++ /* We are done with the fake lstat. Go back to the real lstat */ ++# ifdef lstat ++# undef lstat ++# endif ++# endif ++# define local_lstat lstat ++#elif defined(WINDOWS32) ++/* Windows doesn't support lstat(). */ ++# define local_lstat local_stat ++#else ++static int ++local_lstat (const char *path, struct stat *buf) ++{ ++ int e; ++ EINTRLOOP (e, lstat (path, buf)); ++ return e; ++} ++#endif ++ + void + dir_setup_glob (glob_t *gl) + { + gl->gl_opendir = open_dirstream; + gl->gl_readdir = read_dirstream; + gl->gl_closedir = free; ++ gl->gl_lstat = local_lstat; + gl->gl_stat = local_stat; +- /* We don't bother setting gl_lstat, since glob never calls it. +- The slot is only there for compatibility with 4.4 BSD. */ + } + + void +-- +cgit v1.0-41-gc330 + diff --git a/make-4.2.1-glob-fix-3.patch b/make-4.2.1-glob-fix-3.patch new file mode 100644 index 0000000..879fe50 --- /dev/null +++ b/make-4.2.1-glob-fix-3.patch @@ -0,0 +1,15 @@ +diff -Nrup a/configure b/configure +--- a/configure 2018-03-18 23:53:43.991741060 -0400 ++++ b/configure 2018-03-18 23:52:52.456028175 -0400 +@@ -11481,10 +11481,9 @@ else + #include + #include + +-#define GLOB_INTERFACE_VERSION 1 + #if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1 + # include +-# if _GNU_GLOB_INTERFACE_VERSION == GLOB_INTERFACE_VERSION ++# if _GNU_GLOB_INTERFACE_VERSION == 1 || _GNU_GLOB_INTERFACE_VERSION == 2 + gnu glob + # endif + #endif diff --git a/make-4.2.1-glob-fix.patch b/make-4.2.1-glob-fix.patch new file mode 100644 index 0000000..be3abae --- /dev/null +++ b/make-4.2.1-glob-fix.patch @@ -0,0 +1,28 @@ +From 48c8a116a914a325a0497721f5d8b58d5bba34d4 Mon Sep 17 00:00:00 2001 +From: Paul Smith +Date: Sun, 19 Nov 2017 15:09:16 -0500 +Subject: * configure.ac: Support GLIBC glob interface version 2 + +--- + configure.ac | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 8c72568..4710832 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -404,10 +404,9 @@ AC_CACHE_CHECK([if system libc has GNU glob], [make_cv_sys_gnu_glob], + #include + #include + +-#define GLOB_INTERFACE_VERSION 1 + #if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1 + # include +-# if _GNU_GLOB_INTERFACE_VERSION == GLOB_INTERFACE_VERSION ++# if _GNU_GLOB_INTERFACE_VERSION == 1 || _GNU_GLOB_INTERFACE_VERSION == 2 + gnu glob + # endif + #endif], +-- +cgit v1.0-41-gc330 + diff --git a/make-4.2.1-test-driver.patch b/make-4.2.1-test-driver.patch new file mode 100644 index 0000000..e43e8ea --- /dev/null +++ b/make-4.2.1-test-driver.patch @@ -0,0 +1,19 @@ +commit d9d4e06084a4c7da480bd49a3487aadf6ba77b54 +Author: Enrique Olaizola +Date: Sat May 27 14:24:33 2017 -0400 + + * tests/run_make_tests.pl: [SV 50902] Find Perl modules + +diff -Nrup a/tests/run_make_tests.pl b/tests/run_make_tests.pl +--- a/tests/run_make_tests.pl 2016-04-04 01:38:37.000000000 -0400 ++++ b/tests/run_make_tests.pl 2018-04-25 14:19:19.692178798 -0400 +@@ -58,6 +58,9 @@ if ($^O eq 'VMS') + *CORE::GLOBAL::rmdir = \&vms_rmdir; + } + ++use FindBin; ++use lib "$FindBin::Bin"; ++ + require "test_driver.pl"; + require "config-flags.pm"; + diff --git a/make-4.2.1.tar.bz2 b/make-4.2.1.tar.bz2 new file mode 100644 index 0000000..1fa74f8 Binary files /dev/null and b/make-4.2.1.tar.bz2 differ diff --git a/make-4.2.90.tar.gz b/make-4.2.90.tar.gz deleted file mode 100644 index 2c6480c..0000000 Binary files a/make-4.2.90.tar.gz and /dev/null differ diff --git a/make.spec b/make.spec index 6c0f1fa..a406eb3 100644 --- a/make.spec +++ b/make.spec @@ -1,20 +1,31 @@ Name: make Epoch: 1 -Version: 4.2.90 -Release: 2 +Version: 4.2.1 +Release: 11 Summary: A tool which controls the generation of executables and non-source files of a program License: GPLv3+ URL: http://www.gnu.org/software/make/ -Source0: ftp://ftp.gnu.org/gnu/make/%{name}-%{version}.tar.gz +Source0: http://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.bz2 -Patch0: make-4.0-newlines.patch -Patch1: make-4.0-noclock_gettime.patch -Patch2: make-4.0-weird-shell.patch -Patch3: make-4.2-getcwd.patch -Patch4: make-4.2-j8k.patch +Patch0: make-4.0-newlines.patch +Patch1: make-4.0-noclock_gettime.patch +Patch2: make-4.0-weird-shell.patch +Patch3: make-4.2-getcwd.patch +Patch4: make-4.2-j8k.patch +Patch5: make-4.2.1-glob-fix-2.patch +Patch6: make-4.2.1-glob-fix.patch +Patch7: make-4.2.1-glob-fix-3.patch +Patch8: make-4.2.1-test-driver.patch + +Patch6000: src-makeint.h-Use-pid_t-to-store-PIDs-of-int.patch +Patch6001: Queue-failed-fork-etc.-to-be-handled-like-any-other-.patch +Patch6002: src-job.c-reap_children-Fix-inverted-win-lose-messag.patch +Patch6003: SV-54233-Preserve-higher-command_state-values-on-als.patch +Patch6004: src-main.c-main-Set-jobserver-permissions-before-re-.patch +Patch6005: main.c-main-SV-48274-Allow-j-in-makefile-MAKEFLAGS-v.patch BuildRequires: gcc git autoconf automake procps -BuildRequires: guile-devel perl-interpreter +BuildRequires: guile-devel perl-interpreter make Requires(post): /sbin/install-info Requires(preun): /sbin/install-info @@ -35,17 +46,11 @@ Requires: %{name} = %{version}-%{release} The %{name}-devel package contains libraries and header files for developing applications that use %{name}. -%package help -Summary: Doc files for %{name} -Requires: man -Buildarch: noarch - -%description help -The %{name}-help package contains doc files for %{name}. +%package_help %prep %autosetup -n %{name}-%{version} -p1 -rm -f tests/scripts/features/parallelism.orig +#rm -f tests/scripts/features/parallelism.orig %build touch configure aclocal.m4 Makefile.in @@ -69,7 +74,6 @@ if [ -f %{_infodir}/make.info.gz ]; then /sbin/install-info %{_infodir}/make.info.gz %{_infodir}/dir --entry="* Make: (make). The GNU make utility." || : fi - %preun if [ $1 = 0 ]; then if [ -f %{_infodir}/make.info.gz ]; then @@ -78,8 +82,8 @@ if [ $1 = 0 ]; then fi %files -f %{name}.lang -%doc AUTHORS -%license COPYING +%license COPYING AUTHORS +%doc README %{_bindir}/* %{_includedir}/* @@ -87,16 +91,10 @@ fi %{_includedir}/* %files help -%doc NEWS README +%doc NEWS %{_mandir}/*/* %{_infodir}/* %changelog -* Tue Sep 27 2019 luhuaxin - 1:4.2.90-2 -- Type: enhancement -- ID: NA -- SUG: NA -- DESC: move README file to main package, fix last changelog - -* Tue Sep 10 2019 luhuaxin - 1:4.2.90-1 +* Wed Oct 30 2019 openEuler Buildteam - 1:4.2.1-11 - Package init diff --git a/src-job.c-reap_children-Fix-inverted-win-lose-messag.patch b/src-job.c-reap_children-Fix-inverted-win-lose-messag.patch new file mode 100644 index 0000000..a6ef6a9 --- /dev/null +++ b/src-job.c-reap_children-Fix-inverted-win-lose-messag.patch @@ -0,0 +1,23 @@ +From e2234bc1abe13bf3e3c4eb003b19e4d3cce188f3 Mon Sep 17 00:00:00 2001 +From: Paul Smith +Date: Sat, 4 Aug 2018 19:05:29 -0400 +Subject: [PATCH 095/104] * src/job.c (reap_children): Fix inverted win/lose + message. + +--- + job.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/job.c 2019-04-10 23:53:41.293814695 -0400 ++++ b/job.c 2019-04-10 23:57:34.736814695 -0400 +@@ -828,8 +828,8 @@ reap_children (int block, int err) + continue; + + DB (DB_JOBS, (exit_sig == 0 && exit_code == 0 +- ? _("Reaping losing child %p PID %s %s\n") +- : _("Reaping winning child %p PID %s %s\n"), ++ ? _("Reaping winning child %p PID %s %s\n") ++ : _("Reaping losing child %p PID %s %s\n"), + c, pid2str (c->pid), c->remote ? _(" (remote)") : "")); + + /* If we have started jobs in this second, remove one. */ diff --git a/src-main.c-main-Set-jobserver-permissions-before-re-.patch b/src-main.c-main-Set-jobserver-permissions-before-re-.patch new file mode 100644 index 0000000..fe8ea31 --- /dev/null +++ b/src-main.c-main-Set-jobserver-permissions-before-re-.patch @@ -0,0 +1,88 @@ +From d603b2e6ac0f4c2ae69a428e5c63349c289fe1a6 Mon Sep 17 00:00:00 2001 +From: Paul Smith +Date: Sat, 15 Sep 2018 14:48:57 -0400 +Subject: [PATCH 101/104] * src/main.c (main): Set jobserver permissions before + re-execing + +Fixes an issue seen in the Linux kernel build system, reported by +Masahiro Yamada . Fix suggested +on the bug-make mailing list by Mike Shal . +* tests/scripts/features/parallelism: Add a test to verify this. +--- + main.c | 6 +++++ + tests/scripts/features/parallelism | 35 ++++++++++++++++++++++++++++++ + 2 files changed, 41 insertions(+) + +diff --git a/main.c b/main.c +index eed4e81..bcaeab7 100644 +--- a/main.c ++++ b/main.c +@@ -2461,6 +2461,9 @@ main (int argc, char **argv, char **envp) + fflush (stdout); + fflush (stderr); + ++ /* The exec'd "child" will be another make, of course. */ ++ jobserver_pre_child(1); ++ + #ifdef _AMIGA + exec_command (nargv); + exit (0); +@@ -2491,6 +2494,9 @@ main (int argc, char **argv, char **envp) + #endif + exec_command ((char **)nargv, environ); + #endif ++ ++ /* We shouldn't get here but just in case. */ ++ jobserver_post_child(1); + free (aargv); + break; + } +diff --git a/tests/scripts/features/parallelism b/tests/scripts/features/parallelism +index 4257947..07fb758 100644 +--- a/tests/scripts/features/parallelism ++++ b/tests/scripts/features/parallelism +@@ -188,6 +188,41 @@ file2: file1 ; @touch $@ + + rmfiles('file1', 'file2', 'file3', 'file4'); + ++# Ensure that the jobserver is preserved across make re-exec. ++ ++run_make_test(q! ++all: one two ++one: ;@ #PERL# jhelp.pl -w TWO -f ONE ++two: ;@ #PERL# jhelp.pl -f TWO ++include fff1.mk ++fff1.mk: ; touch $@ ++!, ++ '-j2', "touch fff1.mk\nTWO\nONE\n"); ++ ++unlink('fff1.mk', 'ONE', 'TWO'); ++ ++# Test if a sub-make needs to re-exec and the makefile is built via ++# sub-make. Reported by Masahiro Yamada ++ ++run_make_test(q! ++all: ; @$(MAKE) -f #MAKEFILE# recurse ++ ++recurse: one two ; @echo $@ ++one: ;@ #PERL# jhelp.pl -w TWO -f ONE ++two: ;@ #PERL# jhelp.pl -f TWO ++ ++mkinclude: ; touch fff1.mk ++ ++ifeq ($(MAKECMDGOALS),recurse) ++include fff1.mk ++fff1.mk: ; @$(MAKE) -f #MAKEFILE# mkinclude ++endif ++!, ++ '--no-print-directory -j2', "touch fff1.mk\nTWO\nONE\nrecurse\n"); ++ ++unlink('fff1.mk', 'ONE', 'TWO'); ++ ++ + # Make sure that all jobserver FDs are closed if we need to re-exec the + # master copy. + # +-- +2.19.1 + diff --git a/src-makeint.h-Use-pid_t-to-store-PIDs-of-int.patch b/src-makeint.h-Use-pid_t-to-store-PIDs-of-int.patch new file mode 100644 index 0000000..3d62207 --- /dev/null +++ b/src-makeint.h-Use-pid_t-to-store-PIDs-of-int.patch @@ -0,0 +1,153 @@ +From 3f194b69e37c93a3b5c3e1a5475a5514e71b43cb Mon Sep 17 00:00:00 2001 +From: Aron Barath +Date: Mon, 9 Jul 2018 07:31:25 +0200 +Subject: [PATCH 082/104] * src/makeint.h: Use pid_t to store PIDs, of int. + +* src/commands.c (getpid): Ditto. +* src/job.h (*): Ditto. +* src/job.c (*): Ditto. +* src/main.c (main): Ditto. +* src/remote-cstms.c (start_remote_job): Ditto. +* src/remote-stub.c (start_remote_job): Ditto. +--- + commands.c | 2 +- + job.c | 15 ++++++++------- + job.h | 2 +- + main.c | 2 +- + makeint.h | 2 +- + remote-cstms.c | 4 ++-- + remote-stub.c | 2 +- + 7 files changed, 15 insertions(+), 14 deletions(-) + +--- a/commands.c 2019-04-10 22:47:44.401814695 -0400 ++++ b/commands.c 2019-04-10 22:50:51.317814695 -0400 +@@ -32,7 +32,7 @@ this program. If not, see remote if we can start a remote job. */ + if (child->remote) + { +- int is_remote, id, used_stdin; ++ int is_remote, used_stdin; ++ pid_t id; + if (start_remote_job (argv, child->environment, + child->good_stdin ? 0 : get_bad_stdin (), + &is_remote, &id, &used_stdin)) +@@ -2017,10 +2018,10 @@ start_waiting_jobs (void) + + /* EMX: Start a child process. This function returns the new pid. */ + # if defined __EMX__ +-int ++pid_t + child_execute_job (struct output *out, int good_stdin, char **argv, char **envp) + { +- int pid; ++ pid_t pid; + int fdin = good_stdin ? FD_STDIN : get_bad_stdin (); + int fdout = FD_STDOUT; + int fderr = FD_STDERR; +@@ -2115,11 +2116,11 @@ child_execute_job (struct output *out, i + /* POSIX: + Create a child process executing the command in ARGV. + ENVP is the environment of the new program. Returns the PID or -1. */ +-int ++pid_t + child_execute_job (struct output *out, int good_stdin, char **argv, char **envp) + { + int r; +- int pid; ++ pid_t pid; + int fdin = good_stdin ? FD_STDIN : get_bad_stdin (); + int fdout = FD_STDOUT; + int fderr = FD_STDERR; +@@ -2167,7 +2168,7 @@ child_execute_job (struct output *out, i + + /* EMX: This function returns the pid of the child process. */ + # ifdef __EMX__ +-int ++pid_t + # else + void + # endif +@@ -2243,7 +2244,7 @@ exec_command (char **argv, char **envp) + #else /* !WINDOWS32 */ + + # ifdef __EMX__ +- int pid; ++ pid_t pid; + # endif + + /* Be the user, permanently. */ +--- a/job.h 2019-04-10 22:47:44.386814695 -0400 ++++ b/job.h 2019-04-10 22:50:51.319814695 -0400 +@@ -131,7 +131,7 @@ int child_execute_job (struct child *chi + # define FD_STDIN (fileno (stdin)) + # define FD_STDOUT (fileno (stdout)) + # define FD_STDERR (fileno (stderr)) +-int child_execute_job (struct output *out, int good_stdin, char **argv, char **envp); ++pid_t child_execute_job (struct output *out, int good_stdin, char **argv, char **envp); + #endif + + #ifdef _AMIGA +--- a/main.c 2019-04-10 22:47:44.393814695 -0400 ++++ b/main.c 2019-04-10 22:50:51.290814695 -0400 +@@ -2457,7 +2457,7 @@ main (int argc, char **argv, char **envp + Therefore it may be the best solution simply to spawn the + child process including all file handles and to wait for its + termination. */ +- int pid; ++ pid_t pid; + int r; + pid = child_execute_job (NULL, 1, nargv, environ); + +--- a/makeint.h 2019-04-10 22:47:44.413814695 -0400 ++++ b/makeint.h 2019-04-10 22:50:51.297814695 -0400 +@@ -705,7 +705,7 @@ vms_restore_symbol (const char *string); + void remote_setup (void); + void remote_cleanup (void); + int start_remote_job_p (int); +-int start_remote_job (char **, char **, int, int *, int *, int *); ++int start_remote_job (char **, char **, int, int *, pid_t *, int *); + int remote_status (int *, int *, int *, int); + void block_remote_children (void); + void unblock_remote_children (void); +--- b/remote-cstms.c 2019-04-10 22:47:44.413814695 -0400 ++++ a/remote-cstms.c 2019-04-10 22:50:51.319814695 -0400 +@@ -136,7 +136,7 @@ start_remote_job_p (int first_p) + + int + start_remote_job (char **argv, char **envp, int stdin_fd, +- int *is_remote, int *id_ptr, int *used_stdin) ++ int *is_remote, pid_t *id_ptr, int *used_stdin) + { + char waybill[MAX_DATA_SIZE], msg[128]; + struct hostent *host; +@@ -145,7 +145,7 @@ start_remote_job (char **argv, char **en + int len; + int retsock, retport, sock; + Rpc_Stat status; +- int pid; ++ pid_t pid; + + /* Create the return socket. */ + retsock = Rpc_UdpCreate (True, 0); +--- a/remote-stub.c 2019-04-10 22:47:44.401814695 -0400 ++++ b/remote-stub.c 2019-04-10 22:50:51.319814695 -0400 +@@ -53,7 +53,7 @@ start_remote_job_p (int first_p UNUSED) + + int + start_remote_job (char **argv UNUSED, char **envp UNUSED, int stdin_fd UNUSED, +- int *is_remote UNUSED, int *id_ptr UNUSED, ++ int *is_remote UNUSED, pid_t *id_ptr UNUSED, + int *used_stdin UNUSED) + { + return -1;