summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2011-07-08 13:39:30 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2011-07-08 13:39:30 -0700
commit1301ac268f19a6ab60d4b43c18bd00393a12a0db (patch)
treea56c1472c22c6a59ccac090e58715994ef275bb3
parent1b85461891d3354aef97bec97fab891ddb24e06e (diff)
parent67517972df013491db07d81f516c7e56ddc214c8 (diff)
downloademacs-1301ac268f19a6ab60d4b43c18bd00393a12a0db.tar.gz
Merge: Use pthread_sigmask, not sigprocmask (Bug#9010).
-rw-r--r--ChangeLog14
-rw-r--r--Makefile.in3
-rw-r--r--configure.in11
-rw-r--r--lib/gnulib.mk61
-rw-r--r--lib/pthread_sigmask.c29
-rw-r--r--lib/signal.in.h428
-rw-r--r--lib/sigprocmask.c329
-rw-r--r--m4/gl-comp.m432
-rw-r--r--m4/pthread_sigmask.m477
-rw-r--r--m4/signal_h.m477
-rw-r--r--m4/signalblocking.m425
-rw-r--r--src/ChangeLog12
-rw-r--r--src/Makefile.in4
-rw-r--r--src/callproc.c6
-rw-r--r--src/process.c6
-rw-r--r--src/sysdep.c6
16 files changed, 1103 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index d04d7e2e279..1a25ba8e33d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
2011-07-08 Paul Eggert <eggert@cs.ucla.edu>
+ Add gnulib support for pthread_sigmask (Bug#9010).
+ * Makefile.in (GNULIB_MODULES): Add pthread_sigmask.
+ * configure.in (AC_TYPE_UID_T): New dummy macro.
+ Configure gnulib after adjusting LIBS,
+ so that gnulib can assume the libraries in LIBS.
+ * lib/signal.in.h, m4/pthread_sigmask.m4, m4/signal_h.m4:
+ * lib/pthread_sigprocmask.c, lib/sigprocmask.c, m4/signalblocking.m4:
+ New files, automatically imported from gnulib.
+ * lib/gnulib.mk, m4/gl-comp.m4: Automatically-imported update
+ due to the above changes.
+ * .bzrignore: Add lib/signal.h.
+ * src/Makefile.in (LIB_PTHREAD_SIGMASK): New macro.
+ (LIBES): Use it.
+
* lib/getopt.c, lib/unistd.in.h, m4/getopt.m4: Merge from gnulib.
2011-07-07 Andreas Schwab <schwab@linux-m68k.org>
diff --git a/Makefile.in b/Makefile.in
index 457b5d6472e..a3d85bad22a 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -335,7 +335,8 @@ GNULIB_MODULES = \
alloca-opt \
careadlinkat crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr \
dup2 \
- filemode getloadavg getopt-gnu ignore-value intprops lstat mktime readlink \
+ filemode getloadavg getopt-gnu ignore-value intprops lstat \
+ mktime pthread_sigmask readlink \
socklen stdarg stdio strftime strtoumax symlink sys_stat
GNULIB_TOOL_FLAGS = \
--conditional-dependencies --import --no-changelog --no-vc-files \
diff --git a/configure.in b/configure.in
index 5014a793a85..3dd1f035d2b 100644
--- a/configure.in
+++ b/configure.in
@@ -984,6 +984,8 @@ fi
# Suppress obsolescent Autoconf test for size_t; Emacs assumes C89 or better.
AC_DEFUN([AC_TYPE_SIZE_T])
+# Likewise for obsolescent test for uid_t, gid_t; Emacs assumes them.
+AC_DEFUN([AC_TYPE_UID_T])
dnl Do this early because it can frob feature test macros for Unix-98 &c.
AC_SYS_LARGEFILE
@@ -2725,11 +2727,6 @@ AC_FUNC_FSEEKO
AC_FUNC_GETPGRP
-# Configure gnulib.
-gl_ASSERT_NO_GNULIB_POSIXCHECK
-gl_ASSERT_NO_GNULIB_TESTS
-gl_INIT
-
# UNIX98 PTYs.
AC_CHECK_FUNCS(grantpt)
@@ -3333,6 +3330,10 @@ AC_SUBST(CYGWIN_OBJ)
AC_SUBST(PRE_ALLOC_OBJ)
AC_SUBST(POST_ALLOC_OBJ)
+# Configure gnulib here, now that we know LIBS.
+gl_ASSERT_NO_GNULIB_POSIXCHECK
+gl_ASSERT_NO_GNULIB_TESTS
+gl_INIT
case "$opsys" in
aix4-2) LD_SWITCH_SYSTEM_TEMACS="-Wl,-bnodelcsect" ;;
diff --git a/lib/gnulib.mk b/lib/gnulib.mk
index 18abe4536fa..25647f0399c 100644
--- a/lib/gnulib.mk
+++ b/lib/gnulib.mk
@@ -9,7 +9,7 @@
# the same distribution terms as the rest of that program.
#
# Generated by gnulib-tool.
-# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt careadlinkat crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dup2 filemode getloadavg getopt-gnu ignore-value intprops lstat mktime readlink socklen stdarg stdio strftime strtoumax symlink sys_stat
+# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt careadlinkat crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dup2 filemode getloadavg getopt-gnu ignore-value intprops lstat mktime pthread_sigmask readlink socklen stdarg stdio strftime strtoumax symlink sys_stat
MOSTLYCLEANFILES += core *.stackdump
@@ -294,6 +294,15 @@ EXTRA_libgnu_a_SOURCES += mktime.c
## end gnulib module mktime
+## begin gnulib module pthread_sigmask
+
+
+EXTRA_DIST += pthread_sigmask.c
+
+EXTRA_libgnu_a_SOURCES += pthread_sigmask.c
+
+## end gnulib module pthread_sigmask
+
## begin gnulib module readlink
@@ -303,6 +312,56 @@ EXTRA_libgnu_a_SOURCES += readlink.c
## end gnulib module readlink
+## begin gnulib module signal
+
+BUILT_SOURCES += signal.h
+
+# We need the following in order to create <signal.h> when the system
+# doesn't have a complete one.
+signal.h: signal.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
+ sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+ -e 's|@''NEXT_SIGNAL_H''@|$(NEXT_SIGNAL_H)|g' \
+ -e 's|@''GNULIB_PTHREAD_SIGMASK''@|$(GNULIB_PTHREAD_SIGMASK)|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' \
+ -e 's|@''HAVE_PTHREAD_SIGMASK''@|$(HAVE_PTHREAD_SIGMASK)|g' \
+ -e 's|@''HAVE_SIGSET_T''@|$(HAVE_SIGSET_T)|g' \
+ -e 's|@''HAVE_SIGINFO_T''@|$(HAVE_SIGINFO_T)|g' \
+ -e 's|@''HAVE_SIGACTION''@|$(HAVE_SIGACTION)|g' \
+ -e 's|@''HAVE_STRUCT_SIGACTION_SA_SIGACTION''@|$(HAVE_STRUCT_SIGACTION_SA_SIGACTION)|g' \
+ -e 's|@''HAVE_TYPE_VOLATILE_SIG_ATOMIC_T''@|$(HAVE_TYPE_VOLATILE_SIG_ATOMIC_T)|g' \
+ -e 's|@''HAVE_SIGHANDLER_T''@|$(HAVE_SIGHANDLER_T)|g' \
+ -e 's|@''REPLACE_PTHREAD_SIGMASK''@|$(REPLACE_PTHREAD_SIGMASK)|g' \
+ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
+ -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
+ -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
+ < $(srcdir)/signal.in.h; \
+ } > $@-t && \
+ mv $@-t $@
+MOSTLYCLEANFILES += signal.h signal.h-t
+
+EXTRA_DIST += signal.in.h
+
+## end gnulib module signal
+
+## begin gnulib module sigprocmask
+
+if gl_GNULIB_ENABLED_sigprocmask
+
+endif
+EXTRA_DIST += sigprocmask.c
+
+EXTRA_libgnu_a_SOURCES += sigprocmask.c
+
+## end gnulib module sigprocmask
+
## begin gnulib module stat
if gl_GNULIB_ENABLED_stat
diff --git a/lib/pthread_sigmask.c b/lib/pthread_sigmask.c
new file mode 100644
index 00000000000..1f460f13c48
--- /dev/null
+++ b/lib/pthread_sigmask.c
@@ -0,0 +1,29 @@
+/* POSIX compatible signal blocking for threads.
+ Copyright (C) 2011 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+/* Specification. */
+#include <signal.h>
+
+#include <errno.h>
+
+int
+pthread_sigmask (int how, const sigset_t *new_mask, sigset_t *old_mask)
+{
+ int ret = sigprocmask (how, new_mask, old_mask);
+ return (ret < 0 ? errno : 0);
+}
diff --git a/lib/signal.in.h b/lib/signal.in.h
new file mode 100644
index 00000000000..93787f753fa
--- /dev/null
+++ b/lib/signal.in.h
@@ -0,0 +1,428 @@
+/* A GNU-like <signal.h>.
+
+ Copyright (C) 2006-2011 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+@PRAGMA_COLUMNS@
+
+#if defined __need_sig_atomic_t || defined __need_sigset_t || defined _GL_ALREADY_INCLUDING_SIGNAL_H || (defined _SIGNAL_H && !defined __SIZEOF_PTHREAD_MUTEX_T)
+/* Special invocation convention:
+ - Inside glibc header files.
+ - On glibc systems we have a sequence of nested includes
+ <signal.h> -> <ucontext.h> -> <signal.h>.
+ In this situation, the functions are not yet declared, therefore we cannot
+ provide the C++ aliases.
+ - On glibc systems with GCC 4.3 we have a sequence of nested includes
+ <csignal> -> </usr/include/signal.h> -> <sys/ucontext.h> -> <signal.h>.
+ In this situation, some of the functions are not yet declared, therefore
+ we cannot provide the C++ aliases. */
+
+# @INCLUDE_NEXT@ @NEXT_SIGNAL_H@
+
+#else
+/* Normal invocation convention. */
+
+#ifndef _@GUARD_PREFIX@_SIGNAL_H
+
+#define _GL_ALREADY_INCLUDING_SIGNAL_H
+
+/* Define pid_t, uid_t.
+ Also, mingw defines sigset_t not in <signal.h>, but in <sys/types.h>.
+ On Solaris 10, <signal.h> includes <sys/types.h>, which eventually includes
+ us; so include <sys/types.h> now, before the second inclusion guard. */
+#include <sys/types.h>
+
+/* The include_next requires a split double-inclusion guard. */
+#@INCLUDE_NEXT@ @NEXT_SIGNAL_H@
+
+#undef _GL_ALREADY_INCLUDING_SIGNAL_H
+
+#ifndef _@GUARD_PREFIX@_SIGNAL_H
+#define _@GUARD_PREFIX@_SIGNAL_H
+
+/* MacOS X 10.3, FreeBSD 6.4, OpenBSD 3.8, OSF/1 4.0, Solaris 2.6 declare
+ pthread_sigmask in <pthread.h>, not in <signal.h>.
+ But avoid namespace pollution on glibc systems.*/
+#if (@GNULIB_PTHREAD_SIGMASK@ || defined GNULIB_POSIXCHECK) \
+ && ((defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ || defined __OpenBSD__ || defined __osf__ || defined __sun) \
+ && ! defined __GLIBC__
+# include <pthread.h>
+#endif
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
+
+/* The definition of _GL_ARG_NONNULL is copied here. */
+
+/* The definition of _GL_WARN_ON_USE is copied here. */
+
+/* On AIX, sig_atomic_t already includes volatile. C99 requires that
+ 'volatile sig_atomic_t' ignore the extra modifier, but C89 did not.
+ Hence, redefine this to a non-volatile type as needed. */
+#if ! @HAVE_TYPE_VOLATILE_SIG_ATOMIC_T@
+# if !GNULIB_defined_sig_atomic_t
+typedef int rpl_sig_atomic_t;
+# undef sig_atomic_t
+# define sig_atomic_t rpl_sig_atomic_t
+# define GNULIB_defined_sig_atomic_t 1
+# endif
+#endif
+
+/* A set or mask of signals. */
+#if !@HAVE_SIGSET_T@
+# if !GNULIB_defined_sigset_t
+typedef unsigned int sigset_t;
+# define GNULIB_defined_sigset_t 1
+# endif
+#endif
+
+/* Define sighandler_t, the type of signal handlers. A GNU extension. */
+#if !@HAVE_SIGHANDLER_T@
+# ifdef __cplusplus
+extern "C" {
+# endif
+# if !GNULIB_defined_sighandler_t
+typedef void (*sighandler_t) (int);
+# define GNULIB_defined_sighandler_t 1
+# endif
+# ifdef __cplusplus
+}
+# endif
+#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
+
+
+/* Maximum signal number + 1. */
+#ifndef NSIG
+# if defined __TANDEM
+# define NSIG 32
+# endif
+#endif
+
+
+#if @GNULIB_PTHREAD_SIGMASK@
+# if @REPLACE_PTHREAD_SIGMASK@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef pthread_sigmask
+# define pthread_sigmask rpl_pthread_sigmask
+# endif
+_GL_FUNCDECL_RPL (pthread_sigmask, int,
+ (int how, const sigset_t *new_mask, sigset_t *old_mask));
+_GL_CXXALIAS_RPL (pthread_sigmask, int,
+ (int how, const sigset_t *new_mask, sigset_t *old_mask));
+# else
+# if !@HAVE_PTHREAD_SIGMASK@
+_GL_FUNCDECL_SYS (pthread_sigmask, int,
+ (int how, const sigset_t *new_mask, sigset_t *old_mask));
+# endif
+_GL_CXXALIAS_SYS (pthread_sigmask, int,
+ (int how, const sigset_t *new_mask, sigset_t *old_mask));
+# endif
+_GL_CXXALIASWARN (pthread_sigmask);
+#elif defined GNULIB_POSIXCHECK
+# undef pthread_sigmask
+# if HAVE_RAW_DECL_PTHREAD_SIGMASK
+_GL_WARN_ON_USE (pthread_sigmask, "pthread_sigmask is not portable - "
+ "use gnulib module pthread_sigmask for portability");
+# endif
+#endif
+
+
+#if @GNULIB_SIGPROCMASK@
+# if !@HAVE_POSIX_SIGNALBLOCKING@
+
+/* Maximum signal number + 1. */
+# ifndef NSIG
+# define NSIG 32
+# endif
+
+/* This code supports only 32 signals. */
+# if !GNULIB_defined_verify_NSIG_constraint
+typedef int verify_NSIG_constraint[NSIG <= 32 ? 1 : -1];
+# define GNULIB_defined_verify_NSIG_constraint 1
+# endif
+
+# endif
+
+/* Test whether a given signal is contained in a signal set. */
+# if @HAVE_POSIX_SIGNALBLOCKING@
+/* This function is defined as a macro on MacOS X. */
+# if defined __cplusplus && defined GNULIB_NAMESPACE
+# undef sigismember
+# endif
+# else
+_GL_FUNCDECL_SYS (sigismember, int, (const sigset_t *set, int sig)
+ _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (sigismember, int, (const sigset_t *set, int sig));
+_GL_CXXALIASWARN (sigismember);
+
+/* Initialize a signal set to the empty set. */
+# if @HAVE_POSIX_SIGNALBLOCKING@
+/* This function is defined as a macro on MacOS X. */
+# if defined __cplusplus && defined GNULIB_NAMESPACE
+# undef sigemptyset
+# endif
+# else
+_GL_FUNCDECL_SYS (sigemptyset, int, (sigset_t *set) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (sigemptyset, int, (sigset_t *set));
+_GL_CXXALIASWARN (sigemptyset);
+
+/* Add a signal to a signal set. */
+# if @HAVE_POSIX_SIGNALBLOCKING@
+/* This function is defined as a macro on MacOS X. */
+# if defined __cplusplus && defined GNULIB_NAMESPACE
+# undef sigaddset
+# endif
+# else
+_GL_FUNCDECL_SYS (sigaddset, int, (sigset_t *set, int sig)
+ _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (sigaddset, int, (sigset_t *set, int sig));
+_GL_CXXALIASWARN (sigaddset);
+
+/* Remove a signal from a signal set. */
+# if @HAVE_POSIX_SIGNALBLOCKING@
+/* This function is defined as a macro on MacOS X. */
+# if defined __cplusplus && defined GNULIB_NAMESPACE
+# undef sigdelset
+# endif
+# else
+_GL_FUNCDECL_SYS (sigdelset, int, (sigset_t *set, int sig)
+ _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (sigdelset, int, (sigset_t *set, int sig));
+_GL_CXXALIASWARN (sigdelset);
+
+/* Fill a signal set with all possible signals. */
+# if @HAVE_POSIX_SIGNALBLOCKING@
+/* This function is defined as a macro on MacOS X. */
+# if defined __cplusplus && defined GNULIB_NAMESPACE
+# undef sigfillset
+# endif
+# else
+_GL_FUNCDECL_SYS (sigfillset, int, (sigset_t *set) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (sigfillset, int, (sigset_t *set));
+_GL_CXXALIASWARN (sigfillset);
+
+/* Return the set of those blocked signals that are pending. */
+# if !@HAVE_POSIX_SIGNALBLOCKING@
+_GL_FUNCDECL_SYS (sigpending, int, (sigset_t *set) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (sigpending, int, (sigset_t *set));
+_GL_CXXALIASWARN (sigpending);
+
+/* If OLD_SET is not NULL, put the current set of blocked signals in *OLD_SET.
+ Then, if SET is not NULL, affect the current set of blocked signals by
+ combining it with *SET as indicated in OPERATION.
+ In this implementation, you are not allowed to change a signal handler
+ while the signal is blocked. */
+# if !@HAVE_POSIX_SIGNALBLOCKING@
+# define SIG_BLOCK 0 /* blocked_set = blocked_set | *set; */
+# define SIG_SETMASK 1 /* blocked_set = *set; */
+# define SIG_UNBLOCK 2 /* blocked_set = blocked_set & ~*set; */
+_GL_FUNCDECL_SYS (sigprocmask, int,
+ (int operation, const sigset_t *set, sigset_t *old_set));
+# endif
+_GL_CXXALIAS_SYS (sigprocmask, int,
+ (int operation, const sigset_t *set, sigset_t *old_set));
+_GL_CXXALIASWARN (sigprocmask);
+
+/* Install the handler FUNC for signal SIG, and return the previous
+ handler. */
+# ifdef __cplusplus
+extern "C" {
+# endif
+# if !GNULIB_defined_function_taking_int_returning_void_t
+typedef void (*_gl_function_taking_int_returning_void_t) (int);
+# define GNULIB_defined_function_taking_int_returning_void_t 1
+# endif
+# ifdef __cplusplus
+}
+# endif
+# if !@HAVE_POSIX_SIGNALBLOCKING@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define signal rpl_signal
+# endif
+_GL_FUNCDECL_RPL (signal, _gl_function_taking_int_returning_void_t,
+ (int sig, _gl_function_taking_int_returning_void_t func));
+_GL_CXXALIAS_RPL (signal, _gl_function_taking_int_returning_void_t,
+ (int sig, _gl_function_taking_int_returning_void_t func));
+# else
+_GL_CXXALIAS_SYS (signal, _gl_function_taking_int_returning_void_t,
+ (int sig, _gl_function_taking_int_returning_void_t func));
+# endif
+_GL_CXXALIASWARN (signal);
+
+/* Raise signal SIG. */
+# if !@HAVE_POSIX_SIGNALBLOCKING@ && GNULIB_defined_SIGPIPE
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef raise
+# define raise rpl_raise
+# endif
+_GL_FUNCDECL_RPL (raise, int, (int sig));
+_GL_CXXALIAS_RPL (raise, int, (int sig));
+# else
+_GL_CXXALIAS_SYS (raise, int, (int sig));
+# endif
+_GL_CXXALIASWARN (raise);
+
+#elif defined GNULIB_POSIXCHECK
+# undef sigaddset
+# if HAVE_RAW_DECL_SIGADDSET
+_GL_WARN_ON_USE (sigaddset, "sigaddset is unportable - "
+ "use the gnulib module sigprocmask for portability");
+# endif
+# undef sigdelset
+# if HAVE_RAW_DECL_SIGDELSET
+_GL_WARN_ON_USE (sigdelset, "sigdelset is unportable - "
+ "use the gnulib module sigprocmask for portability");
+# endif
+# undef sigemptyset
+# if HAVE_RAW_DECL_SIGEMPTYSET
+_GL_WARN_ON_USE (sigemptyset, "sigemptyset is unportable - "
+ "use the gnulib module sigprocmask for portability");
+# endif
+# undef sigfillset
+# if HAVE_RAW_DECL_SIGFILLSET
+_GL_WARN_ON_USE (sigfillset, "sigfillset is unportable - "
+ "use the gnulib module sigprocmask for portability");
+# endif
+# undef sigismember
+# if HAVE_RAW_DECL_SIGISMEMBER
+_GL_WARN_ON_USE (sigismember, "sigismember is unportable - "
+ "use the gnulib module sigprocmask for portability");
+# endif
+# undef sigpending
+# if HAVE_RAW_DECL_SIGPENDING
+_GL_WARN_ON_USE (sigpending, "sigpending is unportable - "
+ "use the gnulib module sigprocmask for portability");
+# endif
+# undef sigprocmask
+# if HAVE_RAW_DECL_SIGPROCMASK
+_GL_WARN_ON_USE (sigprocmask, "sigprocmask is unportable - "
+ "use the gnulib module sigprocmask for portability");
+# endif
+#endif /* @GNULIB_SIGPROCMASK@ */
+
+
+#if @GNULIB_SIGACTION@
+# if !@HAVE_SIGACTION@
+
+# if !@HAVE_SIGINFO_T@
+
+# if !GNULIB_defined_siginfo_types
+
+/* Present to allow compilation, but unsupported by gnulib. */
+union sigval
+{
+ int sival_int;
+ void *sival_ptr;
+};
+
+/* Present to allow compilation, but unsupported by gnulib. */
+struct siginfo_t
+{
+ int si_signo;
+ int si_code;
+ int si_errno;
+ pid_t si_pid;
+ uid_t si_uid;
+ void *si_addr;
+ int si_status;
+ long si_band;
+ union sigval si_value;
+};
+typedef struct siginfo_t siginfo_t;
+
+# define GNULIB_defined_siginfo_types 1
+# endif
+
+# endif /* !@HAVE_SIGINFO_T@ */
+
+/* We assume that platforms which lack the sigaction() function also lack
+ the 'struct sigaction' type, and vice versa. */
+
+# if !GNULIB_defined_struct_sigaction
+
+struct sigaction
+{
+ union
+ {
+ void (*_sa_handler) (int);
+ /* Present to allow compilation, but unsupported by gnulib. POSIX
+ says that implementations may, but not must, make sa_sigaction
+ overlap with sa_handler, but we know of no implementation where
+ they do not overlap. */
+ void (*_sa_sigaction) (int, siginfo_t *, void *);
+ } _sa_func;
+ sigset_t sa_mask;
+ /* Not all POSIX flags are supported. */
+ int sa_flags;
+};
+# define sa_handler _sa_func._sa_handler
+# define sa_sigaction _sa_func._sa_sigaction
+/* Unsupported flags are not present. */
+# define SA_RESETHAND 1
+# define SA_NODEFER 2
+# define SA_RESTART 4
+
+# define GNULIB_defined_struct_sigaction 1
+# endif
+
+_GL_FUNCDECL_SYS (sigaction, int, (int, const struct sigaction *restrict,
+ struct sigaction *restrict));
+
+# elif !@HAVE_STRUCT_SIGACTION_SA_SIGACTION@
+
+# define sa_sigaction sa_handler
+
+# endif /* !@HAVE_SIGACTION@, !@HAVE_STRUCT_SIGACTION_SA_SIGACTION@ */
+
+_GL_CXXALIAS_SYS (sigaction, int, (int, const struct sigaction *restrict,
+ struct sigaction *restrict));
+_GL_CXXALIASWARN (sigaction);
+
+#elif defined GNULIB_POSIXCHECK
+# undef sigaction
+# if HAVE_RAW_DECL_SIGACTION
+_GL_WARN_ON_USE (sigaction, "sigaction is unportable - "
+ "use the gnulib module sigaction for portability");
+# endif
+#endif
+
+/* Some systems don't have SA_NODEFER. */
+#ifndef SA_NODEFER
+# define SA_NODEFER 0
+#endif
+
+
+#endif /* _@GUARD_PREFIX@_SIGNAL_H */
+#endif /* _@GUARD_PREFIX@_SIGNAL_H */
+#endif
diff --git a/lib/sigprocmask.c b/lib/sigprocmask.c
new file mode 100644
index 00000000000..6780a37b14f
--- /dev/null
+++ b/lib/sigprocmask.c
@@ -0,0 +1,329 @@
+/* POSIX compatible signal blocking.
+ Copyright (C) 2006-2011 Free Software Foundation, Inc.
+ Written by Bruno Haible <bruno@clisp.org>, 2006.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+/* Specification. */
+#include <signal.h>
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+/* We assume that a platform without POSIX signal blocking functions
+ also does not have the POSIX sigaction() function, only the
+ signal() function. We also assume signal() has SysV semantics,
+ where any handler is uninstalled prior to being invoked. This is
+ true for Woe32 platforms. */
+
+/* We use raw signal(), but also provide a wrapper rpl_signal() so
+ that applications can query or change a blocked signal. */
+#undef signal
+
+/* Provide invalid signal numbers as fallbacks if the uncatchable
+ signals are not defined. */
+#ifndef SIGKILL
+# define SIGKILL (-1)
+#endif
+#ifndef SIGSTOP
+# define SIGSTOP (-1)
+#endif
+
+/* On native Windows, as of 2008, the signal SIGABRT_COMPAT is an alias
+ for the signal SIGABRT. Only one signal handler is stored for both
+ SIGABRT and SIGABRT_COMPAT. SIGABRT_COMPAT is not a signal of its own. */
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+# undef SIGABRT_COMPAT
+# define SIGABRT_COMPAT 6
+#endif
+#ifdef SIGABRT_COMPAT
+# define SIGABRT_COMPAT_MASK (1U << SIGABRT_COMPAT)
+#else
+# define SIGABRT_COMPAT_MASK 0
+#endif
+
+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)
+{
+ if (sig >= 0 && sig < NSIG)
+ {
+ #ifdef SIGABRT_COMPAT
+ if (sig == SIGABRT_COMPAT)
+ sig = SIGABRT;
+ #endif
+
+ return (*set >> sig) & 1;
+ }
+ else
+ return 0;
+}
+
+int
+sigemptyset (sigset_t *set)
+{
+ *set = 0;
+ return 0;
+}
+
+int
+sigaddset (sigset_t *set, int sig)
+{
+ if (sig >= 0 && sig < NSIG)
+ {
+ #ifdef SIGABRT_COMPAT
+ if (sig == SIGABRT_COMPAT)
+ sig = SIGABRT;
+ #endif
+
+ *set |= 1U << sig;
+ return 0;
+ }
+ else
+ {
+ errno = EINVAL;
+ return -1;
+ }
+}
+
+int
+sigdelset (sigset_t *set, int sig)
+{
+ if (sig >= 0 && sig < NSIG)
+ {
+ #ifdef SIGABRT_COMPAT
+ if (sig == SIGABRT_COMPAT)
+ sig = SIGABRT;
+ #endif
+
+ *set &= ~(1U << sig);
+ return 0;
+ }
+ else
+ {
+ errno = EINVAL;
+ return -1;
+ }
+}
+
+
+int
+sigfillset (sigset_t *set)
+{
+ *set = ((2U << (NSIG - 1)) - 1) & ~ SIGABRT_COMPAT_MASK;
+ return 0;
+}
+
+/* Set of currently blocked signals. */
+static volatile sigset_t blocked_set /* = 0 */;
+
+/* Set of currently blocked and pending signals. */
+static volatile sig_atomic_t pending_array[NSIG] /* = { 0 } */;
+
+/* Signal handler that is installed for blocked signals. */
+static void
+blocked_handler (int sig)
+{
+ /* Reinstall the handler, in case the signal occurs multiple times
+ while blocked. There is an inherent race where an asynchronous
+ signal in between when the kernel uninstalled the handler and
+ when we reinstall it will trigger the default handler; oh
+ well. */
+ signal (sig, blocked_handler);
+ if (sig >= 0 && sig < NSIG)
+ pending_array[sig] = 1;
+}
+
+int
+sigpending (sigset_t *set)
+{
+ sigset_t pending = 0;
+ int sig;
+
+ for (sig = 0; sig < NSIG; sig++)
+ if (pending_array[sig])
+ pending |= 1U << sig;
+ *set = pending;
+ return 0;
+}
+
+/* The previous signal handlers.
+ Only the array elements corresponding to blocked signals are relevant. */
+static volatile handler_t old_handlers[NSIG];
+
+int
+sigprocmask (int operation, const sigset_t *set, sigset_t *old_set)
+{
+ if (old_set != NULL)
+ *old_set = blocked_set;
+
+ if (set != NULL)
+ {
+ sigset_t new_blocked_set;
+ sigset_t to_unblock;
+ sigset_t to_block;
+
+ switch (operation)
+ {
+ case SIG_BLOCK:
+ new_blocked_set = blocked_set | *set;
+ break;
+ case SIG_SETMASK:
+ new_blocked_set = *set;
+ break;
+ case SIG_UNBLOCK:
+ new_blocked_set = blocked_set & ~*set;
+ break;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+ to_unblock = blocked_set & ~new_blocked_set;
+ to_block = new_blocked_set & ~blocked_set;
+
+ if (to_block != 0)
+ {
+ int sig;
+
+ for (sig = 0; sig < NSIG; sig++)
+ if ((to_block >> sig) & 1)
+ {
+ pending_array[sig] = 0;
+ if ((old_handlers[sig] = signal (sig, blocked_handler)) != SIG_ERR)
+ blocked_set |= 1U << sig;
+ }
+ }
+
+ if (to_unblock != 0)
+ {
+ sig_atomic_t received[NSIG];
+ int sig;
+
+ for (sig = 0; sig < NSIG; sig++)
+ if ((to_unblock >> sig) & 1)
+ {
+ if (signal (sig, old_handlers[sig]) != blocked_handler)
+ /* The application changed a signal handler while the signal
+ was blocked, bypassing our rpl_signal replacement.
+ We don't support this. */
+ abort ();
+ received[sig] = pending_array[sig];
+ blocked_set &= ~(1U << sig);
+ pending_array[sig] = 0;
+ }
+ else
+ received[sig] = 0;
+
+ for (sig = 0; sig < NSIG; sig++)
+ if (received[sig])
+ raise (sig);
+ }
+ }
+ return 0;
+}
+
+/* Install the handler FUNC for signal SIG, and return the previous
+ handler. */
+handler_t
+rpl_signal (int sig, handler_t handler)
+{
+ /* We must provide a wrapper, so that a user can query what handler
+ they installed even if that signal is currently blocked. */
+ if (sig >= 0 && sig < NSIG && sig != SIGKILL && sig != SIGSTOP
+ && handler != SIG_ERR)
+ {
+ #ifdef SIGABRT_COMPAT
+ if (sig == SIGABRT_COMPAT)
+ sig = SIGABRT;
+ #endif
+
+ if (blocked_set & (1U << sig))
+ {
+ /* POSIX states that sigprocmask and signal are both
+ async-signal-safe. This is not true of our
+ implementation - there is a slight data race where an
+ asynchronous interrupt on signal A can occur after we
+ install blocked_handler but before we have updated
+ old_handlers for signal B, such that handler A can see
+ stale information if it calls signal(B). Oh well -
+ signal handlers really shouldn't try to manipulate the
+ installed handlers of unrelated signals. */
+ handler_t result = old_handlers[sig];
+ old_handlers[sig] = handler;
+ return result;
+ }
+ else
+ return signal (sig, handler);
+ }
+ else
+ {
+ errno = EINVAL;
+ 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
diff --git a/m4/gl-comp.m4 b/m4/gl-comp.m4
index 16bb02e686f..6c94e373871 100644
--- a/m4/gl-comp.m4
+++ b/m4/gl-comp.m4
@@ -52,7 +52,10 @@ AC_DEFUN([gl_EARLY],
# Code from module lstat:
# Code from module mktime:
# Code from module multiarch:
+ # Code from module pthread_sigmask:
# Code from module readlink:
+ # Code from module signal:
+ # Code from module sigprocmask:
# Code from module socklen:
# Code from module ssize_t:
# Code from module stat:
@@ -140,12 +143,18 @@ if test $REPLACE_MKTIME = 1; then
fi
gl_TIME_MODULE_INDICATOR([mktime])
gl_MULTIARCH
+gl_FUNC_PTHREAD_SIGMASK
+if test $HAVE_PTHREAD_SIGMASK = 0 || test $REPLACE_PTHREAD_SIGMASK = 1; then
+ AC_LIBOBJ([pthread_sigmask])
+fi
+gl_SIGNAL_MODULE_INDICATOR([pthread_sigmask])
gl_FUNC_READLINK
if test $HAVE_READLINK = 0 || test $REPLACE_READLINK = 1; then
AC_LIBOBJ([readlink])
gl_PREREQ_READLINK
fi
gl_UNISTD_MODULE_INDICATOR([readlink])
+gl_SIGNAL_H
gl_TYPE_SOCKLEN_T
gt_TYPE_SSIZE_T
gl_STDARG_H
@@ -179,6 +188,7 @@ AC_REQUIRE([AC_C_INLINE])
gl_UNISTD_H
gl_gnulib_enabled_dosname=false
gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36=false
+ gl_gnulib_enabled_sigprocmask=false
gl_gnulib_enabled_stat=false
gl_gnulib_enabled_strtoull=false
gl_gnulib_enabled_verify=false
@@ -196,6 +206,18 @@ AC_SUBST([LTLIBINTL])
gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36=true
fi
}
+ func_gl_gnulib_m4code_sigprocmask ()
+ {
+ if ! $gl_gnulib_enabled_sigprocmask; then
+gl_SIGNALBLOCKING
+if test $HAVE_POSIX_SIGNALBLOCKING = 0; then
+ AC_LIBOBJ([sigprocmask])
+ gl_PREREQ_SIGPROCMASK
+fi
+gl_SIGNAL_MODULE_INDICATOR([sigprocmask])
+ gl_gnulib_enabled_sigprocmask=true
+ fi
+ }
func_gl_gnulib_m4code_stat ()
{
if ! $gl_gnulib_enabled_stat; then
@@ -241,6 +263,9 @@ gl_STDLIB_MODULE_INDICATOR([strtoull])
if test $REPLACE_LSTAT = 1; then
func_gl_gnulib_m4code_stat
fi
+ if test $HAVE_PTHREAD_SIGMASK = 0 || test $REPLACE_PTHREAD_SIGMASK = 1; then
+ func_gl_gnulib_m4code_sigprocmask
+ fi
if test $HAVE_READLINK = 0 || test $REPLACE_READLINK = 1; then
func_gl_gnulib_m4code_stat
fi
@@ -253,6 +278,7 @@ gl_STDLIB_MODULE_INDICATOR([strtoull])
m4_pattern_allow([^gl_GNULIB_ENABLED_])
AM_CONDITIONAL([gl_GNULIB_ENABLED_dosname], [$gl_gnulib_enabled_dosname])
AM_CONDITIONAL([gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36], [$gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36])
+ AM_CONDITIONAL([gl_GNULIB_ENABLED_sigprocmask], [$gl_gnulib_enabled_sigprocmask])
AM_CONDITIONAL([gl_GNULIB_ENABLED_stat], [$gl_gnulib_enabled_stat])
AM_CONDITIONAL([gl_GNULIB_ENABLED_strtoull], [$gl_gnulib_enabled_strtoull])
AM_CONDITIONAL([gl_GNULIB_ENABLED_verify], [$gl_gnulib_enabled_verify])
@@ -426,6 +452,7 @@ AC_DEFUN([gl_FILE_LIST], [
lib/md5.h
lib/mktime-internal.h
lib/mktime.c
+ lib/pthread_sigmask.c
lib/readlink.c
lib/sha1.c
lib/sha1.h
@@ -433,6 +460,8 @@ AC_DEFUN([gl_FILE_LIST], [
lib/sha256.h
lib/sha512.c
lib/sha512.h
+ lib/signal.in.h
+ lib/sigprocmask.c
lib/stat.c
lib/stdarg.in.h
lib/stdbool.in.h
@@ -470,10 +499,13 @@ AC_DEFUN([gl_FILE_LIST], [
m4/md5.m4
m4/mktime.m4
m4/multiarch.m4
+ m4/pthread_sigmask.m4
m4/readlink.m4
m4/sha1.m4
m4/sha256.m4
m4/sha512.m4
+ m4/signal_h.m4
+ m4/signalblocking.m4
m4/socklen.m4
m4/ssize_t.m4
m4/st_dm_mode.m4
diff --git a/m4/pthread_sigmask.m4 b/m4/pthread_sigmask.m4
new file mode 100644
index 00000000000..dfa0f660a75
--- /dev/null
+++ b/m4/pthread_sigmask.m4
@@ -0,0 +1,77 @@
+# pthread_sigmask.m4 serial 7
+dnl Copyright (C) 2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_PTHREAD_SIGMASK],
+[
+ AC_CHECK_FUNCS_ONCE([pthread_sigmask])
+ LIB_PTHREAD_SIGMASK=
+ m4_ifdef([gl_THREADLIB], [
+ AC_REQUIRE([gl_THREADLIB])
+ if test "$gl_threads_api" = posix; then
+ if test $ac_cv_func_pthread_sigmask = yes; then
+ dnl pthread_sigmask is available without -lpthread.
+ :
+ else
+ if test -n "$LIBMULTITHREAD"; then
+ AC_CACHE_CHECK([for pthread_sigmask in $LIBMULTITHREAD],
+ [gl_cv_func_pthread_sigmask_in_LIBMULTITHREAD],
+ [gl_save_LIBS="$LIBS"
+ LIBS="$LIBS $LIBMULTITHREAD"
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <pthread.h>
+ #include <signal.h>
+ ]],
+ [[return pthread_sigmask (0, (sigset_t *) 0, (sigset_t *) 0);]])
+ ],
+ [gl_cv_func_pthread_sigmask_in_LIBMULTITHREAD=yes],
+ [gl_cv_func_pthread_sigmask_in_LIBMULTITHREAD=no])
+ LIBS="$gl_save_LIBS"
+ ])
+ if test $gl_cv_func_pthread_sigmask_in_LIBMULTITHREAD = yes; then
+ dnl pthread_sigmask is available with -lpthread.
+ LIB_PTHREAD_SIGMASK="$LIBMULTITHREAD"
+ else
+ dnl pthread_sigmask is not available at all.
+ HAVE_PTHREAD_SIGMASK=0
+ fi
+ else
+ dnl pthread_sigmask is not available at all.
+ HAVE_PTHREAD_SIGMASK=0
+ fi
+ fi
+ else
+ dnl pthread_sigmask may exist but does not interoperate with the chosen
+ dnl multithreading facility.
+ dnl If "$gl_threads_api" = pth, we could use the function pth_sigmask,
+ dnl but it is equivalent to sigprocmask, so we choose to emulate
+ dnl pthread_sigmask with sigprocmask also in this case. This yields fewer
+ dnl link dependencies.
+ if test $ac_cv_func_pthread_sigmask = yes; then
+ REPLACE_PTHREAD_SIGMASK=1
+ else
+ HAVE_PTHREAD_SIGMASK=0
+ fi
+ fi
+ ] ,[
+ dnl gl_THREADLIB is not in use. Assume the application wants
+ dnl POSIX semantics.
+ if test $ac_cv_func_pthread_sigmask != yes; then
+ gl_save_LIBS=$LIBS
+ AC_SEARCH_LIBS([pthread_sigmask], [pthread c_r])
+ LIBS=$gl_save_LIBS
+ if test "$ac_cv_search_pthread_sigmask" = no; then
+ HAVE_PTHREAD_SIGMASK=0
+ elif test "$ac_cv_search_pthread_sigmask" != 'none required'; then
+ LIB_PTHREAD_SIGMASK=$ac_cv_search_pthread_sigmask
+ fi
+ fi
+ ])
+ AC_SUBST([LIB_PTHREAD_SIGMASK])
+ dnl We don't need a variable LTLIB_PTHREAD_SIGMASK, because when
+ dnl "$gl_threads_api" = posix, $LTLIBMULTITHREAD and $LIBMULTITHREAD are the
+ dnl same: either both empty or both "-lpthread".
+])
diff --git a/m4/signal_h.m4 b/m4/signal_h.m4
new file mode 100644
index 00000000000..b9536fb0e3c
--- /dev/null
+++ b/m4/signal_h.m4
@@ -0,0 +1,77 @@
+# signal_h.m4 serial 16
+dnl Copyright (C) 2007-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_SIGNAL_H],
+[
+ AC_REQUIRE([gl_SIGNAL_H_DEFAULTS])
+ AC_REQUIRE([gl_CHECK_TYPE_SIGSET_T])
+ gl_NEXT_HEADERS([signal.h])
+
+# AIX declares sig_atomic_t to already include volatile, and C89 compilers
+# then choke on 'volatile sig_atomic_t'. C99 requires that it compile.
+ AC_CHECK_TYPE([volatile sig_atomic_t], [],
+ [HAVE_TYPE_VOLATILE_SIG_ATOMIC_T=0], [[
+#include <signal.h>
+ ]])
+
+ AC_REQUIRE([AC_TYPE_UID_T])
+
+ dnl Persuade glibc <signal.h> to define sighandler_t.
+ AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+ AC_CHECK_TYPE([sighandler_t], [], [HAVE_SIGHANDLER_T=0], [[
+#include <signal.h>
+ ]])
+
+ dnl Check for declarations of anything we want to poison if the
+ dnl corresponding gnulib module is not in use.
+ gl_WARN_ON_USE_PREPARE([[#include <signal.h>
+ ]], [pthread_sigmask sigaction
+ sigaddset sigdelset sigemptyset sigfillset sigismember
+ sigpending sigprocmask])
+])
+
+AC_DEFUN([gl_CHECK_TYPE_SIGSET_T],
+[
+ AC_CHECK_TYPES([sigset_t],
+ [gl_cv_type_sigset_t=yes], [gl_cv_type_sigset_t=no],
+ [[
+ #include <signal.h>
+ /* Mingw defines sigset_t not in <signal.h>, but in <sys/types.h>. */
+ #include <sys/types.h>
+ ]])
+ if test $gl_cv_type_sigset_t != yes; then
+ HAVE_SIGSET_T=0
+ fi
+])
+
+AC_DEFUN([gl_SIGNAL_MODULE_INDICATOR],
+[
+ dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
+ AC_REQUIRE([gl_SIGNAL_H_DEFAULTS])
+ gl_MODULE_INDICATOR_SET_VARIABLE([$1])
+ dnl Define it also as a C macro, for the benefit of the unit tests.
+ gl_MODULE_INDICATOR_FOR_TESTS([$1])
+])
+
+AC_DEFUN([gl_SIGNAL_H_DEFAULTS],
+[
+ GNULIB_PTHREAD_SIGMASK=0; AC_SUBST([GNULIB_PTHREAD_SIGMASK])
+ 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.
+ HAVE_POSIX_SIGNALBLOCKING=1; AC_SUBST([HAVE_POSIX_SIGNALBLOCKING])
+ HAVE_PTHREAD_SIGMASK=1; AC_SUBST([HAVE_PTHREAD_SIGMASK])
+ HAVE_SIGSET_T=1; AC_SUBST([HAVE_SIGSET_T])
+ HAVE_SIGINFO_T=1; AC_SUBST([HAVE_SIGINFO_T])
+ HAVE_SIGACTION=1; AC_SUBST([HAVE_SIGACTION])
+ HAVE_STRUCT_SIGACTION_SA_SIGACTION=1;
+ AC_SUBST([HAVE_STRUCT_SIGACTION_SA_SIGACTION])
+ HAVE_TYPE_VOLATILE_SIG_ATOMIC_T=1;
+ AC_SUBST([HAVE_TYPE_VOLATILE_SIG_ATOMIC_T])
+ HAVE_SIGHANDLER_T=1; AC_SUBST([HAVE_SIGHANDLER_T])
+ REPLACE_PTHREAD_SIGMASK=0; AC_SUBST([REPLACE_PTHREAD_SIGMASK])
+])
diff --git a/m4/signalblocking.m4 b/m4/signalblocking.m4
new file mode 100644
index 00000000000..15b74253ba6
--- /dev/null
+++ b/m4/signalblocking.m4
@@ -0,0 +1,25 @@
+# signalblocking.m4 serial 12
+dnl Copyright (C) 2001-2002, 2006-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+# Determine available signal blocking primitives. Three different APIs exist:
+# 1) POSIX: sigemptyset, sigaddset, sigprocmask
+# 2) SYSV: sighold, sigrelse
+# 3) BSD: sigblock, sigsetmask
+# For simplicity, here we check only for the POSIX signal blocking.
+AC_DEFUN([gl_SIGNALBLOCKING],
+[
+ AC_REQUIRE([gl_SIGNAL_H_DEFAULTS])
+ AC_REQUIRE([gl_CHECK_TYPE_SIGSET_T])
+ if test $gl_cv_type_sigset_t = yes; then
+ AC_CHECK_FUNC([sigprocmask], [gl_cv_func_sigprocmask=1])
+ fi
+ if test -z "$gl_cv_func_sigprocmask"; then
+ HAVE_POSIX_SIGNALBLOCKING=0
+ fi
+])
+
+# Prerequisites of lib/sigprocmask.c.
+AC_DEFUN([gl_PREREQ_SIGPROCMASK], [:])
diff --git a/src/ChangeLog b/src/ChangeLog
index 52b6bf15e1d..3cf90d10289 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,15 @@
+2011-07-08 Paul Eggert <eggert@cs.ucla.edu>
+
+ Use pthread_sigmask, not sigprocmask (Bug#9010).
+ sigprocmask is portable only for single-threaded applications, and
+ Emacs can be multi-threaded when it uses GTK.
+ * Makefile.in (LIB_PTHREAD_SIGMASK): New macro.
+ (LIBES): Use it.
+ * callproc.c (Fcall_process):
+ * process.c (create_process):
+ * sysdep.c (sys_sigblock, sys_sigunblock, sys_sigsetmask):
+ Use pthread_sigmask, not sigprocmask.
+
2011-07-08 Jan Djärv <jan.h.d@swipnet.se>
* gtkutil.c (qttip_cb): Set line wrap to FALSE for tooltip widget.
diff --git a/src/Makefile.in b/src/Makefile.in
index f628c321f70..f68fa5c2240 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -269,6 +269,8 @@ LIBSELINUX_LIBS = @LIBSELINUX_LIBS@
LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@
LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@
+LIB_PTHREAD_SIGMASK = @LIB_PTHREAD_SIGMASK@
+
INTERVALS_H = dispextern.h intervals.h composite.h
GETLOADAVG_LIBS = @GETLOADAVG_LIBS@
@@ -383,7 +385,7 @@ LIBES = $(LIBS) $(LIBX_BASE) $(LIBX_OTHER) $(LIBSOUND) \
$(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \
$(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \
$(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \
- $(LIBGNUTLS_LIBS) \
+ $(LIBGNUTLS_LIBS) $(LIB_PTHREAD_SIGMASK) \
$(LIB_GCC) $(LIB_MATH) $(LIB_STANDARD) $(LIB_GCC)
all: emacs$(EXEEXT) $(OTHER_FILES)
diff --git a/src/callproc.c b/src/callproc.c
index b339f343f62..ad3eddbdd39 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -596,7 +596,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
sigemptyset (&blocked);
sigaddset (&blocked, SIGPIPE);
sigaction (SIGPIPE, 0, &sigpipe_action);
- sigprocmask (SIG_BLOCK, &blocked, &procmask);
+ pthread_sigmask (SIG_BLOCK, &blocked, &procmask);
#endif
BLOCK_INPUT;
@@ -633,7 +633,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
in the child. */
//signal (SIGPIPE, SIG_DFL);
#ifdef HAVE_WORKING_VFORK
- sigprocmask (SIG_SETMASK, &procmask, 0);
+ pthread_sigmask (SIG_SETMASK, &procmask, 0);
#endif
child_setup (filefd, fd1, fd_error, (char **) new_argv,
@@ -645,7 +645,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
#ifdef HAVE_WORKING_VFORK
/* Restore the signal state. */
sigaction (SIGPIPE, &sigpipe_action, 0);
- sigprocmask (SIG_SETMASK, &procmask, 0);
+ pthread_sigmask (SIG_SETMASK, &procmask, 0);
#endif
#endif /* not WINDOWSNT */
diff --git a/src/process.c b/src/process.c
index 6bd168d8840..1a884357b86 100644
--- a/src/process.c
+++ b/src/process.c
@@ -1652,7 +1652,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
sigaddset (&blocked, SIGHUP ); sigaction (SIGHUP , 0, &sighup_action );
#endif
#endif /* HAVE_WORKING_VFORK */
- sigprocmask (SIG_BLOCK, &blocked, &procmask);
+ pthread_sigmask (SIG_BLOCK, &blocked, &procmask);
FD_SET (inchannel, &input_wait_mask);
FD_SET (inchannel, &non_keyboard_wait_mask);
@@ -1808,7 +1808,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
signal (SIGPIPE, SIG_DFL);
/* Stop blocking signals in the child. */
- sigprocmask (SIG_SETMASK, &procmask, 0);
+ pthread_sigmask (SIG_SETMASK, &procmask, 0);
if (pty_flag)
child_setup_tty (xforkout);
@@ -1900,7 +1900,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
#endif
#endif /* HAVE_WORKING_VFORK */
/* Stop blocking signals in the parent. */
- sigprocmask (SIG_SETMASK, &procmask, 0);
+ pthread_sigmask (SIG_SETMASK, &procmask, 0);
/* Now generate the error if vfork failed. */
if (pid < 0)
diff --git a/src/sysdep.c b/src/sysdep.c
index 8b6939b91fe..46667cf292f 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -1534,7 +1534,7 @@ sigset_t
sys_sigblock (sigset_t new_mask)
{
sigset_t old_mask;
- sigprocmask (SIG_BLOCK, &new_mask, &old_mask);
+ pthread_sigmask (SIG_BLOCK, &new_mask, &old_mask);
return (old_mask);
}
@@ -1542,7 +1542,7 @@ sigset_t
sys_sigunblock (sigset_t new_mask)
{
sigset_t old_mask;
- sigprocmask (SIG_UNBLOCK, &new_mask, &old_mask);
+ pthread_sigmask (SIG_UNBLOCK, &new_mask, &old_mask);
return (old_mask);
}
@@ -1550,7 +1550,7 @@ sigset_t
sys_sigsetmask (sigset_t new_mask)
{
sigset_t old_mask;
- sigprocmask (SIG_SETMASK, &new_mask, &old_mask);
+ pthread_sigmask (SIG_SETMASK, &new_mask, &old_mask);
return (old_mask);
}