Original patch from Dmitry Goncharov <dgoncharov@users.sf.net>.
When handling a fatal signal ensure the temporary files for
stdin and the jobserver fifo (if in use) are deleted.
* src/makeint.h (temp_stdin_unlink): Declare a new method.
* src/main.c (temp_stdin_unlink): Delete the stdin temporary file
if it exists. If the unlink fails and we're not handling a signal
then show an error.
(main): Call temp_stdin_unlink() instead of unlinking by hand.
* src/commands.c (fatal_error_signal): Invoke cleanup methods if
we're handling a fatal signal.
* tests/scripts/features/output-sync: Test signal handling during
output sync and jobserver with FIFO.
* tests/scripts/features/temp_stdin: Test signal handling when
makefiles are read from stdin.
#include "makeint.h"
#include "filedef.h"
+#include "os.h"
#include "dep.h"
#include "variable.h"
#include "job.h"
It is blocked now while we run this handler. */
signal (sig, SIG_DFL);
+ temp_stdin_unlink ();
+ osync_clear ();
+ jobserver_clear ();
+
/* A termination signal won't be sent to the entire
process group, but it means we want to kill the children. */
jobserver_auth = NULL;
}
+void
+temp_stdin_unlink ()
+{
+ /* This function is called from a signal handler. Keep async-signal-safe.
+ If there is a temp file from reading from stdin, get rid of it. */
+ if (stdin_offset >= 0)
+ {
+ const char *nm = makefiles->list[stdin_offset];
+ int r = 0;
+
+ stdin_offset = -1;
+ EINTRLOOP(r, unlink (nm));
+ if (r < 0 && errno != ENOENT && !handling_fatal_signal)
+ perror_with_name (_("unlink (temporary file): "), nm);
+ }
+}
+
#ifdef _AMIGA
int
main (int argc, char **argv)
#endif
jobserver_post_child(1);
- /* Get rid of any stdin temp file. */
- if (stdin_offset >= 0)
- unlink (makefiles->list[stdin_offset]);
+ temp_stdin_unlink ();
_exit (127);
}
}
}
- /* If there is a temp file from reading a makefile from stdin, get rid of
- it now. */
- if (stdin_offset >= 0)
- {
- const char *nm = makefiles->list[stdin_offset];
- if (unlink (nm) < 0 && errno != ENOENT)
- perror_with_name (_("unlink (temporary file): "), nm);
- stdin_offset = -1;
- }
+ temp_stdin_unlink ();
/* If there were no command-line goals, use the default. */
if (goals == 0)
print_version ();
/* Get rid of a temp file from reading a makefile from stdin. */
- if (stdin_offset >= 0)
- {
- const char *nm = makefiles->list[stdin_offset];
- if (unlink (nm) < 0 && errno != ENOENT)
- perror_with_name (_("unlink (temporary file): "), nm);
- stdin_offset = -1;
- }
+ temp_stdin_unlink ();
/* Wait for children to die. */
err = (status != 0);
(_f), (_n), (_s))
void decode_env_switches (const char*, size_t line);
+void temp_stdin_unlink (void);
void die (int) NORETURN;
void pfatal_with_name (const char *) NORETURN;
void perror_with_name (const char *, const char *);
'-O', "#MAKE#: ./foo: $ERR_no_such_file\n#MAKE#: *** [#MAKEFILE#:2: all] Error 127\n", 512);
}
+if ($port_type eq 'UNIX') {
+# POSIX doesn't require sh to set PPID so test this
+my $cmd = create_command();
+add_options($cmd, '-f', '/dev/null', '-E', q!all:;@echo $$PPID!);
+my $fout = 'ppidtest.out';
+run_command_with_output($fout, @$cmd);
+$_ = read_file_into_string($fout);
+chomp($_);
+if (/^[0-9]+$/) {
+use POSIX ();
+# SV 63157.
+# Test that make removes temporary files, even when a signal is received.
+# The general test_driver postprocessing will ensure the temporary file used
+# to synchronize output and the jobserver fifo are both removed.
+run_make_test(q!
+pid:=$(shell echo $$PPID)
+all:; @kill -TERM $(pid)
+!, '-O -j2', "", POSIX::SIGTERM);
+}
+
+unlink($fout);
+}
+
# This tells the test driver that the perl test script executed properly.
1;
'-R --debug=b -f-', "/Re-executing.+?--temp-stdin=\Q$temppath\E/");
if ($port_type eq 'UNIX') {
+# POSIX doesn't require sh to set PPID so test this
+my $cmd = create_command();
+add_options($cmd, '-f', '/dev/null', '-E', q!all:;@echo $$PPID!);
+my $fout = 'ppidtest.out';
+run_command_with_output($fout, @$cmd);
+$_ = read_file_into_string($fout);
+chomp($_);
+if (/^[0-9]+$/) {
+use POSIX ();
+
+# sv 63157.
+# Test that make removes the temporary file which holds make code from stdin,
+# even when a signal is received.
+# include bye.mk and bye.mk: rule is needed to cause make to keep the temporary
+# file for re-exec. Without re-exec make will remove the file before the signal
+# arrives.
+&utouch(-600, 'bye.mk');
+close(STDIN);
+open(STDIN, "<", 'input.mk') || die "$0: cannot open input.mk for reading: $!";
+run_make_test(q!
+include bye.mk
+pid:=$(shell echo $$PPID)
+all:;
+bye.mk: force; @kill -TERM $(pid)
+force:
+!, '-f-', "", POSIX::SIGTERM);
+}
+unlink($fout);
+
# sv 62118,62145.
# Test that a stdin temp file is removed, when execvp fails to re-exec make.
# In order to cause execvp to fail, copy the tested make binary to the temp