mirror of
https://https.git.savannah.gnu.org/git/gnulib.git
synced 2026-05-13 15:13:36 +00:00
Support signal handling with SIGPIPE on native Windows platforms.
This commit is contained in:
10
ChangeLog
10
ChangeLog
@@ -23,6 +23,16 @@
|
||||
|
||||
2008-09-26 Bruno Haible <bruno@clisp.org>
|
||||
|
||||
* lib/signal.in.h (SIGPIPE): Define to a replacement value.
|
||||
(raise): New declaration.
|
||||
* lib/sigprocmask.c (SIGPIPE_handler): New variable.
|
||||
(ext_signal): New function.
|
||||
(rpl_raise): New function.
|
||||
* m4/signal_h.m4 (gl_SIGNAL_H_DEFAULTS): Initialize
|
||||
GNULIB_SIGNAL_H_SIGPIPE.
|
||||
* modules/signal (Makefile.am): Substitute GNULIB_SIGNAL_H_SIGPIPE.
|
||||
* doc/posix-headers/signal.texi: Mention the SIGPIPE issue.
|
||||
|
||||
* modules/sigpipe: New file.
|
||||
* m4/sigpipe.m4: New file.
|
||||
|
||||
|
||||
@@ -10,18 +10,22 @@ Portability problems fixed by Gnulib:
|
||||
@item
|
||||
@code{sigset_t} is only declared in <sys/types.h> on some platforms:
|
||||
mingw.
|
||||
|
||||
@item
|
||||
@code{struct sigaction} and @code{siginfo_t} are missing on some
|
||||
platforms:
|
||||
mingw.
|
||||
|
||||
@item
|
||||
@code{struct sigaction} lacks the @code{sa_sigaction} member on some
|
||||
platforms:
|
||||
Irix 5.3, Interix 3.5.
|
||||
@item
|
||||
The signal @code{SIGPIPE} is not defined on some platforms:
|
||||
mingw.
|
||||
@end itemize
|
||||
|
||||
Portability problems not fixed by Gnulib:
|
||||
@itemize
|
||||
@item
|
||||
Many signals are not defined on some platforms:
|
||||
mingw.
|
||||
@end itemize
|
||||
|
||||
@@ -44,6 +44,17 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#if @GNULIB_SIGNAL_H_SIGPIPE@
|
||||
# ifndef SIGPIPE
|
||||
/* Define SIGPIPE to a value that does not overlap with other signals. */
|
||||
# define SIGPIPE 13
|
||||
# define GNULIB_defined_SIGPIPE 1
|
||||
/* To actually use SIGPIPE, you also need the gnulib modules 'sigprocmask',
|
||||
'write', 'stdio'. */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#if !@HAVE_POSIX_SIGNALBLOCKING@
|
||||
|
||||
/* Maximum signal number + 1. */
|
||||
@@ -92,8 +103,18 @@ extern int sigprocmask (int operation, const sigset_t *set, sigset_t *old_set);
|
||||
handler. */
|
||||
extern void (*signal (int sig, void (*func) (int))) (int);
|
||||
|
||||
# if GNULIB_defined_SIGPIPE
|
||||
|
||||
/* Raise signal SIG. */
|
||||
# undef raise
|
||||
# define raise rpl_raise
|
||||
extern int raise (int sig);
|
||||
|
||||
# endif
|
||||
|
||||
#endif /* !@HAVE_POSIX_SIGNALBLOCKING@ */
|
||||
|
||||
|
||||
#if !@HAVE_SIGACTION@
|
||||
|
||||
# if !@HAVE_SIGINFO_T@
|
||||
|
||||
@@ -45,6 +45,31 @@
|
||||
|
||||
typedef void (*handler_t) (int);
|
||||
|
||||
/* Handling of gnulib defined signals. */
|
||||
|
||||
#if GNULIB_defined_SIGPIPE
|
||||
static handler_t SIGPIPE_handler = SIG_DFL;
|
||||
#endif
|
||||
|
||||
#if GNULIB_defined_SIGPIPE
|
||||
static handler_t
|
||||
ext_signal (int sig, handler_t handler)
|
||||
{
|
||||
switch (sig)
|
||||
{
|
||||
case SIGPIPE:
|
||||
{
|
||||
handler_t old_handler = SIGPIPE_handler;
|
||||
SIGPIPE_handler = handler;
|
||||
return old_handler;
|
||||
}
|
||||
default: /* System defined signal */
|
||||
return signal (sig, handler);
|
||||
}
|
||||
}
|
||||
# define signal ext_signal
|
||||
#endif
|
||||
|
||||
int
|
||||
sigismember (const sigset_t *set, int sig)
|
||||
{
|
||||
@@ -240,3 +265,29 @@ rpl_signal (int sig, handler_t handler)
|
||||
return SIG_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
#if GNULIB_defined_SIGPIPE
|
||||
/* Raise the signal SIG. */
|
||||
int
|
||||
rpl_raise (int sig)
|
||||
# undef raise
|
||||
{
|
||||
switch (sig)
|
||||
{
|
||||
case SIGPIPE:
|
||||
if (blocked_set & (1U << sig))
|
||||
pending_array[sig] = 1;
|
||||
else
|
||||
{
|
||||
handler_t handler = SIGPIPE_handler;
|
||||
if (handler == SIG_DFL)
|
||||
exit (128 + SIGPIPE);
|
||||
else if (handler != SIG_IGN)
|
||||
(*handler) (sig);
|
||||
}
|
||||
return 0;
|
||||
default: /* System defined signal */
|
||||
return raise (sig);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# signal_h.m4 serial 5
|
||||
# signal_h.m4 serial 6
|
||||
dnl Copyright (C) 2007, 2008 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
@@ -19,6 +19,7 @@ AC_DEFUN([gl_SIGNAL_MODULE_INDICATOR],
|
||||
|
||||
AC_DEFUN([gl_SIGNAL_H_DEFAULTS],
|
||||
[
|
||||
GNULIB_SIGNAL_H_SIGPIPE=0; AC_SUBST([GNULIB_SIGNAL_H_SIGPIPE])
|
||||
GNULIB_SIGPROCMASK=0; AC_SUBST([GNULIB_SIGPROCMASK])
|
||||
GNULIB_SIGACTION=0; AC_SUBST([GNULIB_SIGACTION])
|
||||
dnl Assume proper GNU behavior unless another module says otherwise.
|
||||
|
||||
@@ -23,6 +23,7 @@ signal.h: signal.in.h
|
||||
sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
|
||||
-e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
|
||||
-e 's|@''NEXT_SIGNAL_H''@|$(NEXT_SIGNAL_H)|g' \
|
||||
-e 's|@''GNULIB_SIGNAL_H_SIGPIPE''@|$(GNULIB_SIGNAL_H_SIGPIPE)|g' \
|
||||
-e 's|@''GNULIB_SIGPROCMASK''@|$(GNULIB_SIGPROCMASK)|g' \
|
||||
-e 's|@''GNULIB_SIGACTION''@|$(GNULIB_SIGACTION)|g' \
|
||||
-e 's|@''HAVE_POSIX_SIGNALBLOCKING''@|$(HAVE_POSIX_SIGNALBLOCKING)|g' \
|
||||
|
||||
Reference in New Issue
Block a user