mirror of
https://https.git.savannah.gnu.org/git/patch.git
synced 2026-01-27 01:44:34 +00:00
Simplify by using Gnulib sigaction
* bootstrap.conf (gnulib_modules): Add raise, sigaction, signal-h, sigprocmask. Remove signal. * configure.ac: Do not check for raise, sigaction, sigprocmask, sigsetmask. * src/patch.c (main): Do not block signals during dry runs; there's no need. * src/util.c (SIGCHLD, raise, sigset_t, sigemptyset, sigmask) (sigaddset, sigismember, sigprocmask, sigblock, sigsetmask): Remove substitutes; not needed now that we have Gnulib. (sigs): Don’t worry about whether SIGHUP and SIGPIPE are present. (NUM_SIGS): Now a constant, not a macro. (signals_to_block): Remove. All uses changed to fatal_act.sa_mask. (fatal_exit_handler) [!HAVE_SIGACTION]: Remove. All uses removed. (init_signals): Rename from set_signals. All uses changed. Only do the true part; the false part is now done by unblock_signals. (block_signals): Rename from ignore_signals, since it now blocks instead of ignoring on all platforms. All uses changed. (init_signals, block_signals): Simplify by assuming HAVE_SIGACTION, HAVE_SIGPROCMASK, HAVE_SIGSETMASK. (setup_handler): Remove macro. (unblock_signals): New function.
This commit is contained in:
parent
d3816ac315
commit
abf6fb176b
@ -56,11 +56,14 @@ openat
|
||||
parse-datetime
|
||||
progname
|
||||
quotearg
|
||||
raise
|
||||
readlinkat
|
||||
realloc-gnu
|
||||
renameat
|
||||
setenv
|
||||
signal
|
||||
sigaction
|
||||
signal-h
|
||||
sigprocmask
|
||||
size_max
|
||||
ssize_t
|
||||
stat-time
|
||||
|
||||
@ -138,7 +138,7 @@ AC_TYPE_OFF_T
|
||||
gl_SIZE_MAX
|
||||
gl_FUNC_XATTR
|
||||
|
||||
AC_CHECK_FUNCS(geteuid getuid raise sigaction sigprocmask sigsetmask)
|
||||
AC_CHECK_FUNCS_ONCE([geteuid getuid])
|
||||
AC_FUNC_SETMODE_DOS
|
||||
|
||||
AC_PATH_PROG([ED], [ed], [ed])
|
||||
|
||||
@ -71,15 +71,19 @@
|
||||
# parse-datetime \
|
||||
# progname \
|
||||
# quotearg \
|
||||
# raise \
|
||||
# readlinkat \
|
||||
# realloc-gnu \
|
||||
# renameat \
|
||||
# setenv \
|
||||
# signal \
|
||||
# sigaction \
|
||||
# signal-h \
|
||||
# sigprocmask \
|
||||
# size_max \
|
||||
# ssize_t \
|
||||
# stat-time \
|
||||
# stdbool \
|
||||
# stdckdint \
|
||||
# stdlib \
|
||||
# symlinkat \
|
||||
# sys_stat \
|
||||
@ -92,7 +96,8 @@
|
||||
# verror \
|
||||
# xalloc \
|
||||
# xlist \
|
||||
# xmemdup0
|
||||
# xmemdup0 \
|
||||
# year2038-recommended
|
||||
|
||||
AUTOMAKE_OPTIONS = 1.14 gnits subdir-objects
|
||||
|
||||
|
||||
@ -226,7 +226,7 @@ main (int argc, char **argv)
|
||||
outstate.ofp = open_outfile (outfile);
|
||||
|
||||
/* Make sure we clean up in case of disaster. */
|
||||
set_signals (false);
|
||||
init_signals ();
|
||||
|
||||
/* When the file to patch is specified on the command line, allow that file
|
||||
to lie outside the current working tree. Still doesn't allow to follow
|
||||
@ -584,8 +584,10 @@ main (int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (!dry_run)
|
||||
block_signals ();
|
||||
|
||||
/* and put the output where desired */
|
||||
ignore_signals ();
|
||||
if (! skip_rest_of_patch && ! outfile) {
|
||||
bool backup = make_backups
|
||||
|| (backup_if_mismatch && (mismatch | failed));
|
||||
@ -743,7 +745,8 @@ main (int argc, char **argv)
|
||||
say ("\n");
|
||||
}
|
||||
}
|
||||
set_signals (true);
|
||||
if (!dry_run)
|
||||
unblock_signals ();
|
||||
}
|
||||
if (outstate.ofp && (ferror (outstate.ofp) || fclose (outstate.ofp) != 0))
|
||||
write_fatal ();
|
||||
|
||||
124
src/util.c
124
src/util.c
@ -31,13 +31,6 @@
|
||||
#include "error.h"
|
||||
|
||||
#include <signal.h>
|
||||
#if !defined SIGCHLD && defined SIGCLD
|
||||
#define SIGCHLD SIGCLD
|
||||
#endif
|
||||
#if ! HAVE_RAISE && ! defined raise
|
||||
# define raise(sig) kill (getpid (), sig)
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdckdint.h>
|
||||
|
||||
@ -1125,14 +1118,9 @@ ok_to_reverse (char const *format, ...)
|
||||
|
||||
/* How to handle certain events when not in a critical region. */
|
||||
|
||||
#define NUM_SIGS ((int) (sizeof (sigs) / sizeof (*sigs)))
|
||||
static int const sigs[] = {
|
||||
#ifdef SIGHUP
|
||||
SIGHUP,
|
||||
#endif
|
||||
#ifdef SIGPIPE
|
||||
SIGPIPE,
|
||||
#endif
|
||||
#ifdef SIGTERM
|
||||
SIGTERM,
|
||||
#endif
|
||||
@ -1144,104 +1132,48 @@ static int const sigs[] = {
|
||||
#endif
|
||||
SIGINT
|
||||
};
|
||||
enum { NUM_SIGS = sizeof sigs / sizeof *sigs };
|
||||
|
||||
#if !HAVE_SIGPROCMASK
|
||||
#define sigset_t int
|
||||
#define sigemptyset(s) (*(s) = 0)
|
||||
#ifndef sigmask
|
||||
#define sigmask(sig) (1 << ((sig) - 1))
|
||||
#endif
|
||||
#define sigaddset(s, sig) (*(s) |= sigmask (sig))
|
||||
#define sigismember(s, sig) ((*(s) & sigmask (sig)) != 0)
|
||||
#define sigprocmask(how, n, o) \
|
||||
((how) == SIG_BLOCK \
|
||||
? ((o) ? *(o) = sigblock (*(n)) : sigblock (*(n))) \
|
||||
: (how) == SIG_UNBLOCK \
|
||||
? sigsetmask (((o) ? *(o) = sigblock (0) : sigblock (0)) & ~*(n)) \
|
||||
: (o ? *(o) = sigsetmask (*(n)) : sigsetmask (*(n))))
|
||||
#if !HAVE_SIGSETMASK
|
||||
#define sigblock(mask) 0
|
||||
#define sigsetmask(mask) 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* The initial signal mask for the process. */
|
||||
static sigset_t initial_signal_mask;
|
||||
static sigset_t signals_to_block;
|
||||
|
||||
#if ! HAVE_SIGACTION
|
||||
static void fatal_exit_handler (int) __attribute__ ((noreturn));
|
||||
static void
|
||||
fatal_exit_handler (int sig)
|
||||
{
|
||||
signal (sig, SIG_IGN);
|
||||
fatal_exit (sig);
|
||||
}
|
||||
#endif
|
||||
/* How to handle signals. fatal_act.sa_mask lists signals to be
|
||||
blocked when handling signals or in a critical section. */
|
||||
static struct sigaction fatal_act;
|
||||
|
||||
void
|
||||
set_signals (bool reset)
|
||||
init_signals (void)
|
||||
{
|
||||
int i;
|
||||
#if HAVE_SIGACTION
|
||||
struct sigaction initial_act, fatal_act;
|
||||
/* System V fork+wait does not work if SIGCHLD is ignored. */
|
||||
signal (SIGCHLD, SIG_DFL);
|
||||
|
||||
fatal_act.sa_handler = fatal_exit;
|
||||
sigemptyset (&fatal_act.sa_mask);
|
||||
fatal_act.sa_flags = 0;
|
||||
#define setup_handler(sig) sigaction (sig, &fatal_act, (struct sigaction *) 0)
|
||||
#else
|
||||
#define setup_handler(sig) signal (sig, fatal_exit_handler)
|
||||
#endif
|
||||
for (int i = 0; i < NUM_SIGS; i++)
|
||||
{
|
||||
struct sigaction initial_act;
|
||||
if (sigaction (sigs[i], NULL, &initial_act) == 0
|
||||
&& initial_act.sa_handler != SIG_IGN)
|
||||
sigaddset (&fatal_act.sa_mask, sigs[i]);
|
||||
}
|
||||
|
||||
if (!reset)
|
||||
{
|
||||
#ifdef SIGCHLD
|
||||
/* System V fork+wait does not work if SIGCHLD is ignored. */
|
||||
signal (SIGCHLD, SIG_DFL);
|
||||
#endif
|
||||
sigemptyset (&signals_to_block);
|
||||
for (i = 0; i < NUM_SIGS; i++)
|
||||
{
|
||||
bool ignoring_signal;
|
||||
#if HAVE_SIGACTION
|
||||
if (sigaction (sigs[i], (struct sigaction *) 0, &initial_act) != 0)
|
||||
continue;
|
||||
ignoring_signal = initial_act.sa_handler == SIG_IGN;
|
||||
#else
|
||||
ignoring_signal = signal (sigs[i], SIG_IGN) == SIG_IGN;
|
||||
#endif
|
||||
if (! ignoring_signal)
|
||||
{
|
||||
sigaddset (&signals_to_block, sigs[i]);
|
||||
setup_handler (sigs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Undo the effect of ignore_signals. */
|
||||
#if HAVE_SIGPROCMASK || HAVE_SIGSETMASK
|
||||
sigprocmask (SIG_SETMASK, &initial_signal_mask, (sigset_t *) 0);
|
||||
#else
|
||||
for (i = 0; i < NUM_SIGS; i++)
|
||||
if (sigismember (&signals_to_block, sigs[i]))
|
||||
setup_handler (sigs[i]);
|
||||
#endif
|
||||
}
|
||||
for (int i = 0; i < NUM_SIGS; i++)
|
||||
if (sigismember (&fatal_act.sa_mask, sigs[i]))
|
||||
sigaction (sigs[i], &fatal_act, NULL);
|
||||
}
|
||||
|
||||
/* How to handle certain events when in a critical region. */
|
||||
|
||||
void
|
||||
ignore_signals (void)
|
||||
block_signals (void)
|
||||
{
|
||||
#if HAVE_SIGPROCMASK || HAVE_SIGSETMASK
|
||||
sigprocmask (SIG_BLOCK, &signals_to_block, &initial_signal_mask);
|
||||
#else
|
||||
int i;
|
||||
for (i = 0; i < NUM_SIGS; i++)
|
||||
if (sigismember (&signals_to_block, sigs[i]))
|
||||
signal (sigs[i], SIG_IGN);
|
||||
#endif
|
||||
sigprocmask (SIG_BLOCK, &fatal_act.sa_mask, &initial_signal_mask);
|
||||
}
|
||||
|
||||
void
|
||||
unblock_signals (void)
|
||||
{
|
||||
sigprocmask (SIG_BLOCK, &initial_signal_mask, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1251,7 +1183,7 @@ exit_with_signal (int sig)
|
||||
signal (sig, SIG_DFL);
|
||||
sigemptyset (&s);
|
||||
sigaddset (&s, sig);
|
||||
sigprocmask (SIG_UNBLOCK, &s, (sigset_t *) 0);
|
||||
sigprocmask (SIG_UNBLOCK, &s, NULL);
|
||||
raise (sig);
|
||||
exit (2);
|
||||
}
|
||||
|
||||
@ -53,7 +53,9 @@ void copy_file (char const *, struct stat const *,
|
||||
char const *, struct stat *, int, mode_t, bool);
|
||||
void append_to_file (char const *, char const *);
|
||||
void exit_with_signal (int) __attribute__ ((noreturn));
|
||||
void ignore_signals (void);
|
||||
void init_signals (void);
|
||||
void block_signals (void);
|
||||
void unblock_signals (void);
|
||||
void init_backup_hash_table (void);
|
||||
void init_time (void);
|
||||
void xalloc_die (void) __attribute__ ((noreturn));
|
||||
@ -62,7 +64,6 @@ void move_file (char const *, bool *, struct stat const *, char const *, mode_t,
|
||||
void read_fatal (void) __attribute__ ((noreturn));
|
||||
void remove_prefix (char *, size_t);
|
||||
void removedirs (char const *);
|
||||
void set_signals (bool);
|
||||
void write_fatal (void) __attribute__ ((noreturn));
|
||||
void insert_file_id (struct stat const *, enum file_id_type);
|
||||
enum file_id_type lookup_file_id (struct stat const *);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user