aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2011-07-08 13:39:30 -0700
committerPaul Eggert2011-07-08 13:39:30 -0700
commit1301ac268f19a6ab60d4b43c18bd00393a12a0db (patch)
treea56c1472c22c6a59ccac090e58715994ef275bb3
parent1b85461891d3354aef97bec97fab891ddb24e06e (diff)
parent67517972df013491db07d81f516c7e56ddc214c8 (diff)
downloademacs-1301ac268f19a6ab60d4b43c18bd00393a12a0db.tar.gz
emacs-1301ac268f19a6ab60d4b43c18bd00393a12a0db.zip
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 @@
12011-07-08 Paul Eggert <eggert@cs.ucla.edu> 12011-07-08 Paul Eggert <eggert@cs.ucla.edu>
2 2
3 Add gnulib support for pthread_sigmask (Bug#9010).
4 * Makefile.in (GNULIB_MODULES): Add pthread_sigmask.
5 * configure.in (AC_TYPE_UID_T): New dummy macro.
6 Configure gnulib after adjusting LIBS,
7 so that gnulib can assume the libraries in LIBS.
8 * lib/signal.in.h, m4/pthread_sigmask.m4, m4/signal_h.m4:
9 * lib/pthread_sigprocmask.c, lib/sigprocmask.c, m4/signalblocking.m4:
10 New files, automatically imported from gnulib.
11 * lib/gnulib.mk, m4/gl-comp.m4: Automatically-imported update
12 due to the above changes.
13 * .bzrignore: Add lib/signal.h.
14 * src/Makefile.in (LIB_PTHREAD_SIGMASK): New macro.
15 (LIBES): Use it.
16
3 * lib/getopt.c, lib/unistd.in.h, m4/getopt.m4: Merge from gnulib. 17 * lib/getopt.c, lib/unistd.in.h, m4/getopt.m4: Merge from gnulib.
4 18
52011-07-07 Andreas Schwab <schwab@linux-m68k.org> 192011-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 = \
335 alloca-opt \ 335 alloca-opt \
336 careadlinkat crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr \ 336 careadlinkat crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr \
337 dup2 \ 337 dup2 \
338 filemode getloadavg getopt-gnu ignore-value intprops lstat mktime readlink \ 338 filemode getloadavg getopt-gnu ignore-value intprops lstat \
339 mktime pthread_sigmask readlink \
339 socklen stdarg stdio strftime strtoumax symlink sys_stat 340 socklen stdarg stdio strftime strtoumax symlink sys_stat
340GNULIB_TOOL_FLAGS = \ 341GNULIB_TOOL_FLAGS = \
341 --conditional-dependencies --import --no-changelog --no-vc-files \ 342 --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
984 984
985# Suppress obsolescent Autoconf test for size_t; Emacs assumes C89 or better. 985# Suppress obsolescent Autoconf test for size_t; Emacs assumes C89 or better.
986AC_DEFUN([AC_TYPE_SIZE_T]) 986AC_DEFUN([AC_TYPE_SIZE_T])
987# Likewise for obsolescent test for uid_t, gid_t; Emacs assumes them.
988AC_DEFUN([AC_TYPE_UID_T])
987 989
988dnl Do this early because it can frob feature test macros for Unix-98 &c. 990dnl Do this early because it can frob feature test macros for Unix-98 &c.
989AC_SYS_LARGEFILE 991AC_SYS_LARGEFILE
@@ -2725,11 +2727,6 @@ AC_FUNC_FSEEKO
2725 2727
2726AC_FUNC_GETPGRP 2728AC_FUNC_GETPGRP
2727 2729
2728# Configure gnulib.
2729gl_ASSERT_NO_GNULIB_POSIXCHECK
2730gl_ASSERT_NO_GNULIB_TESTS
2731gl_INIT
2732
2733# UNIX98 PTYs. 2730# UNIX98 PTYs.
2734AC_CHECK_FUNCS(grantpt) 2731AC_CHECK_FUNCS(grantpt)
2735 2732
@@ -3333,6 +3330,10 @@ AC_SUBST(CYGWIN_OBJ)
3333AC_SUBST(PRE_ALLOC_OBJ) 3330AC_SUBST(PRE_ALLOC_OBJ)
3334AC_SUBST(POST_ALLOC_OBJ) 3331AC_SUBST(POST_ALLOC_OBJ)
3335 3332
3333# Configure gnulib here, now that we know LIBS.
3334gl_ASSERT_NO_GNULIB_POSIXCHECK
3335gl_ASSERT_NO_GNULIB_TESTS
3336gl_INIT
3336 3337
3337case "$opsys" in 3338case "$opsys" in
3338 aix4-2) LD_SWITCH_SYSTEM_TEMACS="-Wl,-bnodelcsect" ;; 3339 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 @@
9# the same distribution terms as the rest of that program. 9# the same distribution terms as the rest of that program.
10# 10#
11# Generated by gnulib-tool. 11# Generated by gnulib-tool.
12# 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 12# 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
13 13
14 14
15MOSTLYCLEANFILES += core *.stackdump 15MOSTLYCLEANFILES += core *.stackdump
@@ -294,6 +294,15 @@ EXTRA_libgnu_a_SOURCES += mktime.c
294 294
295## end gnulib module mktime 295## end gnulib module mktime
296 296
297## begin gnulib module pthread_sigmask
298
299
300EXTRA_DIST += pthread_sigmask.c
301
302EXTRA_libgnu_a_SOURCES += pthread_sigmask.c
303
304## end gnulib module pthread_sigmask
305
297## begin gnulib module readlink 306## begin gnulib module readlink
298 307
299 308
@@ -303,6 +312,56 @@ EXTRA_libgnu_a_SOURCES += readlink.c
303 312
304## end gnulib module readlink 313## end gnulib module readlink
305 314
315## begin gnulib module signal
316
317BUILT_SOURCES += signal.h
318
319# We need the following in order to create <signal.h> when the system
320# doesn't have a complete one.
321signal.h: signal.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
322 $(AM_V_GEN)rm -f $@-t $@ && \
323 { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
324 sed -e 's|@''GUARD_PREFIX''@|GL|g' \
325 -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
326 -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
327 -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
328 -e 's|@''NEXT_SIGNAL_H''@|$(NEXT_SIGNAL_H)|g' \
329 -e 's|@''GNULIB_PTHREAD_SIGMASK''@|$(GNULIB_PTHREAD_SIGMASK)|g' \
330 -e 's/@''GNULIB_SIGNAL_H_SIGPIPE''@/$(GNULIB_SIGNAL_H_SIGPIPE)/g' \
331 -e 's/@''GNULIB_SIGPROCMASK''@/$(GNULIB_SIGPROCMASK)/g' \
332 -e 's/@''GNULIB_SIGACTION''@/$(GNULIB_SIGACTION)/g' \
333 -e 's|@''HAVE_POSIX_SIGNALBLOCKING''@|$(HAVE_POSIX_SIGNALBLOCKING)|g' \
334 -e 's|@''HAVE_PTHREAD_SIGMASK''@|$(HAVE_PTHREAD_SIGMASK)|g' \
335 -e 's|@''HAVE_SIGSET_T''@|$(HAVE_SIGSET_T)|g' \
336 -e 's|@''HAVE_SIGINFO_T''@|$(HAVE_SIGINFO_T)|g' \
337 -e 's|@''HAVE_SIGACTION''@|$(HAVE_SIGACTION)|g' \
338 -e 's|@''HAVE_STRUCT_SIGACTION_SA_SIGACTION''@|$(HAVE_STRUCT_SIGACTION_SA_SIGACTION)|g' \
339 -e 's|@''HAVE_TYPE_VOLATILE_SIG_ATOMIC_T''@|$(HAVE_TYPE_VOLATILE_SIG_ATOMIC_T)|g' \
340 -e 's|@''HAVE_SIGHANDLER_T''@|$(HAVE_SIGHANDLER_T)|g' \
341 -e 's|@''REPLACE_PTHREAD_SIGMASK''@|$(REPLACE_PTHREAD_SIGMASK)|g' \
342 -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
343 -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
344 -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
345 < $(srcdir)/signal.in.h; \
346 } > $@-t && \
347 mv $@-t $@
348MOSTLYCLEANFILES += signal.h signal.h-t
349
350EXTRA_DIST += signal.in.h
351
352## end gnulib module signal
353
354## begin gnulib module sigprocmask
355
356if gl_GNULIB_ENABLED_sigprocmask
357
358endif
359EXTRA_DIST += sigprocmask.c
360
361EXTRA_libgnu_a_SOURCES += sigprocmask.c
362
363## end gnulib module sigprocmask
364
306## begin gnulib module stat 365## begin gnulib module stat
307 366
308if gl_GNULIB_ENABLED_stat 367if 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 @@
1/* POSIX compatible signal blocking for threads.
2 Copyright (C) 2011 Free Software Foundation, Inc.
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
16
17#include <config.h>
18
19/* Specification. */
20#include <signal.h>
21
22#include <errno.h>
23
24int
25pthread_sigmask (int how, const sigset_t *new_mask, sigset_t *old_mask)
26{
27 int ret = sigprocmask (how, new_mask, old_mask);
28 return (ret < 0 ? errno : 0);
29}
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 @@
1/* A GNU-like <signal.h>.
2
3 Copyright (C) 2006-2011 Free Software Foundation, Inc.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17
18#if __GNUC__ >= 3
19@PRAGMA_SYSTEM_HEADER@
20#endif
21@PRAGMA_COLUMNS@
22
23#if defined __need_sig_atomic_t || defined __need_sigset_t || defined _GL_ALREADY_INCLUDING_SIGNAL_H || (defined _SIGNAL_H && !defined __SIZEOF_PTHREAD_MUTEX_T)
24/* Special invocation convention:
25 - Inside glibc header files.
26 - On glibc systems we have a sequence of nested includes
27 <signal.h> -> <ucontext.h> -> <signal.h>.
28 In this situation, the functions are not yet declared, therefore we cannot
29 provide the C++ aliases.
30 - On glibc systems with GCC 4.3 we have a sequence of nested includes
31 <csignal> -> </usr/include/signal.h> -> <sys/ucontext.h> -> <signal.h>.
32 In this situation, some of the functions are not yet declared, therefore
33 we cannot provide the C++ aliases. */
34
35# @INCLUDE_NEXT@ @NEXT_SIGNAL_H@
36
37#else
38/* Normal invocation convention. */
39
40#ifndef _@GUARD_PREFIX@_SIGNAL_H
41
42#define _GL_ALREADY_INCLUDING_SIGNAL_H
43
44/* Define pid_t, uid_t.
45 Also, mingw defines sigset_t not in <signal.h>, but in <sys/types.h>.
46 On Solaris 10, <signal.h> includes <sys/types.h>, which eventually includes
47 us; so include <sys/types.h> now, before the second inclusion guard. */
48#include <sys/types.h>
49
50/* The include_next requires a split double-inclusion guard. */
51#@INCLUDE_NEXT@ @NEXT_SIGNAL_H@
52
53#undef _GL_ALREADY_INCLUDING_SIGNAL_H
54
55#ifndef _@GUARD_PREFIX@_SIGNAL_H
56#define _@GUARD_PREFIX@_SIGNAL_H
57
58/* MacOS X 10.3, FreeBSD 6.4, OpenBSD 3.8, OSF/1 4.0, Solaris 2.6 declare
59 pthread_sigmask in <pthread.h>, not in <signal.h>.
60 But avoid namespace pollution on glibc systems.*/
61#if (@GNULIB_PTHREAD_SIGMASK@ || defined GNULIB_POSIXCHECK) \
62 && ((defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ || defined __OpenBSD__ || defined __osf__ || defined __sun) \
63 && ! defined __GLIBC__
64# include <pthread.h>
65#endif
66
67/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
68
69/* The definition of _GL_ARG_NONNULL is copied here. */
70
71/* The definition of _GL_WARN_ON_USE is copied here. */
72
73/* On AIX, sig_atomic_t already includes volatile. C99 requires that
74 'volatile sig_atomic_t' ignore the extra modifier, but C89 did not.
75 Hence, redefine this to a non-volatile type as needed. */
76#if ! @HAVE_TYPE_VOLATILE_SIG_ATOMIC_T@
77# if !GNULIB_defined_sig_atomic_t
78typedef int rpl_sig_atomic_t;
79# undef sig_atomic_t
80# define sig_atomic_t rpl_sig_atomic_t
81# define GNULIB_defined_sig_atomic_t 1
82# endif
83#endif
84
85/* A set or mask of signals. */
86#if !@HAVE_SIGSET_T@
87# if !GNULIB_defined_sigset_t
88typedef unsigned int sigset_t;
89# define GNULIB_defined_sigset_t 1
90# endif
91#endif
92
93/* Define sighandler_t, the type of signal handlers. A GNU extension. */
94#if !@HAVE_SIGHANDLER_T@
95# ifdef __cplusplus
96extern "C" {
97# endif
98# if !GNULIB_defined_sighandler_t
99typedef void (*sighandler_t) (int);
100# define GNULIB_defined_sighandler_t 1
101# endif
102# ifdef __cplusplus
103}
104# endif
105#endif
106
107
108#if @GNULIB_SIGNAL_H_SIGPIPE@
109# ifndef SIGPIPE
110/* Define SIGPIPE to a value that does not overlap with other signals. */
111# define SIGPIPE 13
112# define GNULIB_defined_SIGPIPE 1
113/* To actually use SIGPIPE, you also need the gnulib modules 'sigprocmask',
114 'write', 'stdio'. */
115# endif
116#endif
117
118
119/* Maximum signal number + 1. */
120#ifndef NSIG
121# if defined __TANDEM
122# define NSIG 32
123# endif
124#endif
125
126
127#if @GNULIB_PTHREAD_SIGMASK@
128# if @REPLACE_PTHREAD_SIGMASK@
129# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
130# undef pthread_sigmask
131# define pthread_sigmask rpl_pthread_sigmask
132# endif
133_GL_FUNCDECL_RPL (pthread_sigmask, int,
134 (int how, const sigset_t *new_mask, sigset_t *old_mask));
135_GL_CXXALIAS_RPL (pthread_sigmask, int,
136 (int how, const sigset_t *new_mask, sigset_t *old_mask));
137# else
138# if !@HAVE_PTHREAD_SIGMASK@
139_GL_FUNCDECL_SYS (pthread_sigmask, int,
140 (int how, const sigset_t *new_mask, sigset_t *old_mask));
141# endif
142_GL_CXXALIAS_SYS (pthread_sigmask, int,
143 (int how, const sigset_t *new_mask, sigset_t *old_mask));
144# endif
145_GL_CXXALIASWARN (pthread_sigmask);
146#elif defined GNULIB_POSIXCHECK
147# undef pthread_sigmask
148# if HAVE_RAW_DECL_PTHREAD_SIGMASK
149_GL_WARN_ON_USE (pthread_sigmask, "pthread_sigmask is not portable - "
150 "use gnulib module pthread_sigmask for portability");
151# endif
152#endif
153
154
155#if @GNULIB_SIGPROCMASK@
156# if !@HAVE_POSIX_SIGNALBLOCKING@
157
158/* Maximum signal number + 1. */
159# ifndef NSIG
160# define NSIG 32
161# endif
162
163/* This code supports only 32 signals. */
164# if !GNULIB_defined_verify_NSIG_constraint
165typedef int verify_NSIG_constraint[NSIG <= 32 ? 1 : -1];
166# define GNULIB_defined_verify_NSIG_constraint 1
167# endif
168
169# endif
170
171/* Test whether a given signal is contained in a signal set. */
172# if @HAVE_POSIX_SIGNALBLOCKING@
173/* This function is defined as a macro on MacOS X. */
174# if defined __cplusplus && defined GNULIB_NAMESPACE
175# undef sigismember
176# endif
177# else
178_GL_FUNCDECL_SYS (sigismember, int, (const sigset_t *set, int sig)
179 _GL_ARG_NONNULL ((1)));
180# endif
181_GL_CXXALIAS_SYS (sigismember, int, (const sigset_t *set, int sig));
182_GL_CXXALIASWARN (sigismember);
183
184/* Initialize a signal set to the empty set. */
185# if @HAVE_POSIX_SIGNALBLOCKING@
186/* This function is defined as a macro on MacOS X. */
187# if defined __cplusplus && defined GNULIB_NAMESPACE
188# undef sigemptyset
189# endif
190# else
191_GL_FUNCDECL_SYS (sigemptyset, int, (sigset_t *set) _GL_ARG_NONNULL ((1)));
192# endif
193_GL_CXXALIAS_SYS (sigemptyset, int, (sigset_t *set));
194_GL_CXXALIASWARN (sigemptyset);
195
196/* Add a signal to a signal set. */
197# if @HAVE_POSIX_SIGNALBLOCKING@
198/* This function is defined as a macro on MacOS X. */
199# if defined __cplusplus && defined GNULIB_NAMESPACE
200# undef sigaddset
201# endif
202# else
203_GL_FUNCDECL_SYS (sigaddset, int, (sigset_t *set, int sig)
204 _GL_ARG_NONNULL ((1)));
205# endif
206_GL_CXXALIAS_SYS (sigaddset, int, (sigset_t *set, int sig));
207_GL_CXXALIASWARN (sigaddset);
208
209/* Remove a signal from a signal set. */
210# if @HAVE_POSIX_SIGNALBLOCKING@
211/* This function is defined as a macro on MacOS X. */
212# if defined __cplusplus && defined GNULIB_NAMESPACE
213# undef sigdelset
214# endif
215# else
216_GL_FUNCDECL_SYS (sigdelset, int, (sigset_t *set, int sig)
217 _GL_ARG_NONNULL ((1)));
218# endif
219_GL_CXXALIAS_SYS (sigdelset, int, (sigset_t *set, int sig));
220_GL_CXXALIASWARN (sigdelset);
221
222/* Fill a signal set with all possible signals. */
223# if @HAVE_POSIX_SIGNALBLOCKING@
224/* This function is defined as a macro on MacOS X. */
225# if defined __cplusplus && defined GNULIB_NAMESPACE
226# undef sigfillset
227# endif
228# else
229_GL_FUNCDECL_SYS (sigfillset, int, (sigset_t *set) _GL_ARG_NONNULL ((1)));
230# endif
231_GL_CXXALIAS_SYS (sigfillset, int, (sigset_t *set));
232_GL_CXXALIASWARN (sigfillset);
233
234/* Return the set of those blocked signals that are pending. */
235# if !@HAVE_POSIX_SIGNALBLOCKING@
236_GL_FUNCDECL_SYS (sigpending, int, (sigset_t *set) _GL_ARG_NONNULL ((1)));
237# endif
238_GL_CXXALIAS_SYS (sigpending, int, (sigset_t *set));
239_GL_CXXALIASWARN (sigpending);
240
241/* If OLD_SET is not NULL, put the current set of blocked signals in *OLD_SET.
242 Then, if SET is not NULL, affect the current set of blocked signals by
243 combining it with *SET as indicated in OPERATION.
244 In this implementation, you are not allowed to change a signal handler
245 while the signal is blocked. */
246# if !@HAVE_POSIX_SIGNALBLOCKING@
247# define SIG_BLOCK 0 /* blocked_set = blocked_set | *set; */
248# define SIG_SETMASK 1 /* blocked_set = *set; */
249# define SIG_UNBLOCK 2 /* blocked_set = blocked_set & ~*set; */
250_GL_FUNCDECL_SYS (sigprocmask, int,
251 (int operation, const sigset_t *set, sigset_t *old_set));
252# endif
253_GL_CXXALIAS_SYS (sigprocmask, int,
254 (int operation, const sigset_t *set, sigset_t *old_set));
255_GL_CXXALIASWARN (sigprocmask);
256
257/* Install the handler FUNC for signal SIG, and return the previous
258 handler. */
259# ifdef __cplusplus
260extern "C" {
261# endif
262# if !GNULIB_defined_function_taking_int_returning_void_t
263typedef void (*_gl_function_taking_int_returning_void_t) (int);
264# define GNULIB_defined_function_taking_int_returning_void_t 1
265# endif
266# ifdef __cplusplus
267}
268# endif
269# if !@HAVE_POSIX_SIGNALBLOCKING@
270# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
271# define signal rpl_signal
272# endif
273_GL_FUNCDECL_RPL (signal, _gl_function_taking_int_returning_void_t,
274 (int sig, _gl_function_taking_int_returning_void_t func));
275_GL_CXXALIAS_RPL (signal, _gl_function_taking_int_returning_void_t,
276 (int sig, _gl_function_taking_int_returning_void_t func));
277# else
278_GL_CXXALIAS_SYS (signal, _gl_function_taking_int_returning_void_t,
279 (int sig, _gl_function_taking_int_returning_void_t func));
280# endif
281_GL_CXXALIASWARN (signal);
282
283/* Raise signal SIG. */
284# if !@HAVE_POSIX_SIGNALBLOCKING@ && GNULIB_defined_SIGPIPE
285# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
286# undef raise
287# define raise rpl_raise
288# endif
289_GL_FUNCDECL_RPL (raise, int, (int sig));
290_GL_CXXALIAS_RPL (raise, int, (int sig));
291# else
292_GL_CXXALIAS_SYS (raise, int, (int sig));
293# endif
294_GL_CXXALIASWARN (raise);
295
296#elif defined GNULIB_POSIXCHECK
297# undef sigaddset
298# if HAVE_RAW_DECL_SIGADDSET
299_GL_WARN_ON_USE (sigaddset, "sigaddset is unportable - "
300 "use the gnulib module sigprocmask for portability");
301# endif
302# undef sigdelset
303# if HAVE_RAW_DECL_SIGDELSET
304_GL_WARN_ON_USE (sigdelset, "sigdelset is unportable - "
305 "use the gnulib module sigprocmask for portability");
306# endif
307# undef sigemptyset
308# if HAVE_RAW_DECL_SIGEMPTYSET
309_GL_WARN_ON_USE (sigemptyset, "sigemptyset is unportable - "
310 "use the gnulib module sigprocmask for portability");
311# endif
312# undef sigfillset
313# if HAVE_RAW_DECL_SIGFILLSET
314_GL_WARN_ON_USE (sigfillset, "sigfillset is unportable - "
315 "use the gnulib module sigprocmask for portability");
316# endif
317# undef sigismember
318# if HAVE_RAW_DECL_SIGISMEMBER
319_GL_WARN_ON_USE (sigismember, "sigismember is unportable - "
320 "use the gnulib module sigprocmask for portability");
321# endif
322# undef sigpending
323# if HAVE_RAW_DECL_SIGPENDING
324_GL_WARN_ON_USE (sigpending, "sigpending is unportable - "
325 "use the gnulib module sigprocmask for portability");
326# endif
327# undef sigprocmask
328# if HAVE_RAW_DECL_SIGPROCMASK
329_GL_WARN_ON_USE (sigprocmask, "sigprocmask is unportable - "
330 "use the gnulib module sigprocmask for portability");
331# endif
332#endif /* @GNULIB_SIGPROCMASK@ */
333
334
335#if @GNULIB_SIGACTION@
336# if !@HAVE_SIGACTION@
337
338# if !@HAVE_SIGINFO_T@
339
340# if !GNULIB_defined_siginfo_types
341
342/* Present to allow compilation, but unsupported by gnulib. */
343union sigval
344{
345 int sival_int;
346 void *sival_ptr;
347};
348
349/* Present to allow compilation, but unsupported by gnulib. */
350struct siginfo_t
351{
352 int si_signo;
353 int si_code;
354 int si_errno;
355 pid_t si_pid;
356 uid_t si_uid;
357 void *si_addr;
358 int si_status;
359 long si_band;
360 union sigval si_value;
361};
362typedef struct siginfo_t siginfo_t;
363
364# define GNULIB_defined_siginfo_types 1
365# endif
366
367# endif /* !@HAVE_SIGINFO_T@ */
368
369/* We assume that platforms which lack the sigaction() function also lack
370 the 'struct sigaction' type, and vice versa. */
371
372# if !GNULIB_defined_struct_sigaction
373
374struct sigaction
375{
376 union
377 {
378 void (*_sa_handler) (int);
379 /* Present to allow compilation, but unsupported by gnulib. POSIX
380 says that implementations may, but not must, make sa_sigaction
381 overlap with sa_handler, but we know of no implementation where
382 they do not overlap. */
383 void (*_sa_sigaction) (int, siginfo_t *, void *);
384 } _sa_func;
385 sigset_t sa_mask;
386 /* Not all POSIX flags are supported. */
387 int sa_flags;
388};
389# define sa_handler _sa_func._sa_handler
390# define sa_sigaction _sa_func._sa_sigaction
391/* Unsupported flags are not present. */
392# define SA_RESETHAND 1
393# define SA_NODEFER 2
394# define SA_RESTART 4
395
396# define GNULIB_defined_struct_sigaction 1
397# endif
398
399_GL_FUNCDECL_SYS (sigaction, int, (int, const struct sigaction *restrict,
400 struct sigaction *restrict));
401
402# elif !@HAVE_STRUCT_SIGACTION_SA_SIGACTION@
403
404# define sa_sigaction sa_handler
405
406# endif /* !@HAVE_SIGACTION@, !@HAVE_STRUCT_SIGACTION_SA_SIGACTION@ */
407
408_GL_CXXALIAS_SYS (sigaction, int, (int, const struct sigaction *restrict,
409 struct sigaction *restrict));
410_GL_CXXALIASWARN (sigaction);
411
412#elif defined GNULIB_POSIXCHECK
413# undef sigaction
414# if HAVE_RAW_DECL_SIGACTION
415_GL_WARN_ON_USE (sigaction, "sigaction is unportable - "
416 "use the gnulib module sigaction for portability");
417# endif
418#endif
419
420/* Some systems don't have SA_NODEFER. */
421#ifndef SA_NODEFER
422# define SA_NODEFER 0
423#endif
424
425
426#endif /* _@GUARD_PREFIX@_SIGNAL_H */
427#endif /* _@GUARD_PREFIX@_SIGNAL_H */
428#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 @@
1/* POSIX compatible signal blocking.
2 Copyright (C) 2006-2011 Free Software Foundation, Inc.
3 Written by Bruno Haible <bruno@clisp.org>, 2006.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17
18#include <config.h>
19
20/* Specification. */
21#include <signal.h>
22
23#include <errno.h>
24#include <stdint.h>
25#include <stdlib.h>
26
27/* We assume that a platform without POSIX signal blocking functions
28 also does not have the POSIX sigaction() function, only the
29 signal() function. We also assume signal() has SysV semantics,
30 where any handler is uninstalled prior to being invoked. This is
31 true for Woe32 platforms. */
32
33/* We use raw signal(), but also provide a wrapper rpl_signal() so
34 that applications can query or change a blocked signal. */
35#undef signal
36
37/* Provide invalid signal numbers as fallbacks if the uncatchable
38 signals are not defined. */
39#ifndef SIGKILL
40# define SIGKILL (-1)
41#endif
42#ifndef SIGSTOP
43# define SIGSTOP (-1)
44#endif
45
46/* On native Windows, as of 2008, the signal SIGABRT_COMPAT is an alias
47 for the signal SIGABRT. Only one signal handler is stored for both
48 SIGABRT and SIGABRT_COMPAT. SIGABRT_COMPAT is not a signal of its own. */
49#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
50# undef SIGABRT_COMPAT
51# define SIGABRT_COMPAT 6
52#endif
53#ifdef SIGABRT_COMPAT
54# define SIGABRT_COMPAT_MASK (1U << SIGABRT_COMPAT)
55#else
56# define SIGABRT_COMPAT_MASK 0
57#endif
58
59typedef void (*handler_t) (int);
60
61/* Handling of gnulib defined signals. */
62
63#if GNULIB_defined_SIGPIPE
64static handler_t SIGPIPE_handler = SIG_DFL;
65#endif
66
67#if GNULIB_defined_SIGPIPE
68static handler_t
69ext_signal (int sig, handler_t handler)
70{
71 switch (sig)
72 {
73 case SIGPIPE:
74 {
75 handler_t old_handler = SIGPIPE_handler;
76 SIGPIPE_handler = handler;
77 return old_handler;
78 }
79 default: /* System defined signal */
80 return signal (sig, handler);
81 }
82}
83# define signal ext_signal
84#endif
85
86int
87sigismember (const sigset_t *set, int sig)
88{
89 if (sig >= 0 && sig < NSIG)
90 {
91 #ifdef SIGABRT_COMPAT
92 if (sig == SIGABRT_COMPAT)
93 sig = SIGABRT;
94 #endif
95
96 return (*set >> sig) & 1;
97 }
98 else
99 return 0;
100}
101
102int
103sigemptyset (sigset_t *set)
104{
105 *set = 0;
106 return 0;
107}
108
109int
110sigaddset (sigset_t *set, int sig)
111{
112 if (sig >= 0 && sig < NSIG)
113 {
114 #ifdef SIGABRT_COMPAT
115 if (sig == SIGABRT_COMPAT)
116 sig = SIGABRT;
117 #endif
118
119 *set |= 1U << sig;
120 return 0;
121 }
122 else
123 {
124 errno = EINVAL;
125 return -1;
126 }
127}
128
129int
130sigdelset (sigset_t *set, int sig)
131{
132 if (sig >= 0 && sig < NSIG)
133 {
134 #ifdef SIGABRT_COMPAT
135 if (sig == SIGABRT_COMPAT)
136 sig = SIGABRT;
137 #endif
138
139 *set &= ~(1U << sig);
140 return 0;
141 }
142 else
143 {
144 errno = EINVAL;
145 return -1;
146 }
147}
148
149
150int
151sigfillset (sigset_t *set)
152{
153 *set = ((2U << (NSIG - 1)) - 1) & ~ SIGABRT_COMPAT_MASK;
154 return 0;
155}
156
157/* Set of currently blocked signals. */
158static volatile sigset_t blocked_set /* = 0 */;
159
160/* Set of currently blocked and pending signals. */
161static volatile sig_atomic_t pending_array[NSIG] /* = { 0 } */;
162
163/* Signal handler that is installed for blocked signals. */
164static void
165blocked_handler (int sig)
166{
167 /* Reinstall the handler, in case the signal occurs multiple times
168 while blocked. There is an inherent race where an asynchronous
169 signal in between when the kernel uninstalled the handler and
170 when we reinstall it will trigger the default handler; oh
171 well. */
172 signal (sig, blocked_handler);
173 if (sig >= 0 && sig < NSIG)
174 pending_array[sig] = 1;
175}
176
177int
178sigpending (sigset_t *set)
179{
180 sigset_t pending = 0;
181 int sig;
182
183 for (sig = 0; sig < NSIG; sig++)
184 if (pending_array[sig])
185 pending |= 1U << sig;
186 *set = pending;
187 return 0;
188}
189
190/* The previous signal handlers.
191 Only the array elements corresponding to blocked signals are relevant. */
192static volatile handler_t old_handlers[NSIG];
193
194int
195sigprocmask (int operation, const sigset_t *set, sigset_t *old_set)
196{
197 if (old_set != NULL)
198 *old_set = blocked_set;
199
200 if (set != NULL)
201 {
202 sigset_t new_blocked_set;
203 sigset_t to_unblock;
204 sigset_t to_block;
205
206 switch (operation)
207 {
208 case SIG_BLOCK:
209 new_blocked_set = blocked_set | *set;
210 break;
211 case SIG_SETMASK:
212 new_blocked_set = *set;
213 break;
214 case SIG_UNBLOCK:
215 new_blocked_set = blocked_set & ~*set;
216 break;
217 default:
218 errno = EINVAL;
219 return -1;
220 }
221 to_unblock = blocked_set & ~new_blocked_set;
222 to_block = new_blocked_set & ~blocked_set;
223
224 if (to_block != 0)
225 {
226 int sig;
227
228 for (sig = 0; sig < NSIG; sig++)
229 if ((to_block >> sig) & 1)
230 {
231 pending_array[sig] = 0;
232 if ((old_handlers[sig] = signal (sig, blocked_handler)) != SIG_ERR)
233 blocked_set |= 1U << sig;
234 }
235 }
236
237 if (to_unblock != 0)
238 {
239 sig_atomic_t received[NSIG];
240 int sig;
241
242 for (sig = 0; sig < NSIG; sig++)
243 if ((to_unblock >> sig) & 1)
244 {
245 if (signal (sig, old_handlers[sig]) != blocked_handler)
246 /* The application changed a signal handler while the signal
247 was blocked, bypassing our rpl_signal replacement.
248 We don't support this. */
249 abort ();
250 received[sig] = pending_array[sig];
251 blocked_set &= ~(1U << sig);
252 pending_array[sig] = 0;
253 }
254 else
255 received[sig] = 0;
256
257 for (sig = 0; sig < NSIG; sig++)
258 if (received[sig])
259 raise (sig);
260 }
261 }
262 return 0;
263}
264
265/* Install the handler FUNC for signal SIG, and return the previous
266 handler. */
267handler_t
268rpl_signal (int sig, handler_t handler)
269{
270 /* We must provide a wrapper, so that a user can query what handler
271 they installed even if that signal is currently blocked. */
272 if (sig >= 0 && sig < NSIG && sig != SIGKILL && sig != SIGSTOP
273 && handler != SIG_ERR)
274 {
275 #ifdef SIGABRT_COMPAT
276 if (sig == SIGABRT_COMPAT)
277 sig = SIGABRT;
278 #endif
279
280 if (blocked_set & (1U << sig))
281 {
282 /* POSIX states that sigprocmask and signal are both
283 async-signal-safe. This is not true of our
284 implementation - there is a slight data race where an
285 asynchronous interrupt on signal A can occur after we
286 install blocked_handler but before we have updated
287 old_handlers for signal B, such that handler A can see
288 stale information if it calls signal(B). Oh well -
289 signal handlers really shouldn't try to manipulate the
290 installed handlers of unrelated signals. */
291 handler_t result = old_handlers[sig];
292 old_handlers[sig] = handler;
293 return result;
294 }
295 else
296 return signal (sig, handler);
297 }
298 else
299 {
300 errno = EINVAL;
301 return SIG_ERR;
302 }
303}
304
305#if GNULIB_defined_SIGPIPE
306/* Raise the signal SIG. */
307int
308rpl_raise (int sig)
309# undef raise
310{
311 switch (sig)
312 {
313 case SIGPIPE:
314 if (blocked_set & (1U << sig))
315 pending_array[sig] = 1;
316 else
317 {
318 handler_t handler = SIGPIPE_handler;
319 if (handler == SIG_DFL)
320 exit (128 + SIGPIPE);
321 else if (handler != SIG_IGN)
322 (*handler) (sig);
323 }
324 return 0;
325 default: /* System defined signal */
326 return raise (sig);
327 }
328}
329#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],
52 # Code from module lstat: 52 # Code from module lstat:
53 # Code from module mktime: 53 # Code from module mktime:
54 # Code from module multiarch: 54 # Code from module multiarch:
55 # Code from module pthread_sigmask:
55 # Code from module readlink: 56 # Code from module readlink:
57 # Code from module signal:
58 # Code from module sigprocmask:
56 # Code from module socklen: 59 # Code from module socklen:
57 # Code from module ssize_t: 60 # Code from module ssize_t:
58 # Code from module stat: 61 # Code from module stat:
@@ -140,12 +143,18 @@ if test $REPLACE_MKTIME = 1; then
140fi 143fi
141gl_TIME_MODULE_INDICATOR([mktime]) 144gl_TIME_MODULE_INDICATOR([mktime])
142gl_MULTIARCH 145gl_MULTIARCH
146gl_FUNC_PTHREAD_SIGMASK
147if test $HAVE_PTHREAD_SIGMASK = 0 || test $REPLACE_PTHREAD_SIGMASK = 1; then
148 AC_LIBOBJ([pthread_sigmask])
149fi
150gl_SIGNAL_MODULE_INDICATOR([pthread_sigmask])
143gl_FUNC_READLINK 151gl_FUNC_READLINK
144if test $HAVE_READLINK = 0 || test $REPLACE_READLINK = 1; then 152if test $HAVE_READLINK = 0 || test $REPLACE_READLINK = 1; then
145 AC_LIBOBJ([readlink]) 153 AC_LIBOBJ([readlink])
146 gl_PREREQ_READLINK 154 gl_PREREQ_READLINK
147fi 155fi
148gl_UNISTD_MODULE_INDICATOR([readlink]) 156gl_UNISTD_MODULE_INDICATOR([readlink])
157gl_SIGNAL_H
149gl_TYPE_SOCKLEN_T 158gl_TYPE_SOCKLEN_T
150gt_TYPE_SSIZE_T 159gt_TYPE_SSIZE_T
151gl_STDARG_H 160gl_STDARG_H
@@ -179,6 +188,7 @@ AC_REQUIRE([AC_C_INLINE])
179gl_UNISTD_H 188gl_UNISTD_H
180 gl_gnulib_enabled_dosname=false 189 gl_gnulib_enabled_dosname=false
181 gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36=false 190 gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36=false
191 gl_gnulib_enabled_sigprocmask=false
182 gl_gnulib_enabled_stat=false 192 gl_gnulib_enabled_stat=false
183 gl_gnulib_enabled_strtoull=false 193 gl_gnulib_enabled_strtoull=false
184 gl_gnulib_enabled_verify=false 194 gl_gnulib_enabled_verify=false
@@ -196,6 +206,18 @@ AC_SUBST([LTLIBINTL])
196 gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36=true 206 gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36=true
197 fi 207 fi
198 } 208 }
209 func_gl_gnulib_m4code_sigprocmask ()
210 {
211 if ! $gl_gnulib_enabled_sigprocmask; then
212gl_SIGNALBLOCKING
213if test $HAVE_POSIX_SIGNALBLOCKING = 0; then
214 AC_LIBOBJ([sigprocmask])
215 gl_PREREQ_SIGPROCMASK
216fi
217gl_SIGNAL_MODULE_INDICATOR([sigprocmask])
218 gl_gnulib_enabled_sigprocmask=true
219 fi
220 }
199 func_gl_gnulib_m4code_stat () 221 func_gl_gnulib_m4code_stat ()
200 { 222 {
201 if ! $gl_gnulib_enabled_stat; then 223 if ! $gl_gnulib_enabled_stat; then
@@ -241,6 +263,9 @@ gl_STDLIB_MODULE_INDICATOR([strtoull])
241 if test $REPLACE_LSTAT = 1; then 263 if test $REPLACE_LSTAT = 1; then
242 func_gl_gnulib_m4code_stat 264 func_gl_gnulib_m4code_stat
243 fi 265 fi
266 if test $HAVE_PTHREAD_SIGMASK = 0 || test $REPLACE_PTHREAD_SIGMASK = 1; then
267 func_gl_gnulib_m4code_sigprocmask
268 fi
244 if test $HAVE_READLINK = 0 || test $REPLACE_READLINK = 1; then 269 if test $HAVE_READLINK = 0 || test $REPLACE_READLINK = 1; then
245 func_gl_gnulib_m4code_stat 270 func_gl_gnulib_m4code_stat
246 fi 271 fi
@@ -253,6 +278,7 @@ gl_STDLIB_MODULE_INDICATOR([strtoull])
253 m4_pattern_allow([^gl_GNULIB_ENABLED_]) 278 m4_pattern_allow([^gl_GNULIB_ENABLED_])
254 AM_CONDITIONAL([gl_GNULIB_ENABLED_dosname], [$gl_gnulib_enabled_dosname]) 279 AM_CONDITIONAL([gl_GNULIB_ENABLED_dosname], [$gl_gnulib_enabled_dosname])
255 AM_CONDITIONAL([gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36], [$gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36]) 280 AM_CONDITIONAL([gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36], [$gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36])
281 AM_CONDITIONAL([gl_GNULIB_ENABLED_sigprocmask], [$gl_gnulib_enabled_sigprocmask])
256 AM_CONDITIONAL([gl_GNULIB_ENABLED_stat], [$gl_gnulib_enabled_stat]) 282 AM_CONDITIONAL([gl_GNULIB_ENABLED_stat], [$gl_gnulib_enabled_stat])
257 AM_CONDITIONAL([gl_GNULIB_ENABLED_strtoull], [$gl_gnulib_enabled_strtoull]) 283 AM_CONDITIONAL([gl_GNULIB_ENABLED_strtoull], [$gl_gnulib_enabled_strtoull])
258 AM_CONDITIONAL([gl_GNULIB_ENABLED_verify], [$gl_gnulib_enabled_verify]) 284 AM_CONDITIONAL([gl_GNULIB_ENABLED_verify], [$gl_gnulib_enabled_verify])
@@ -426,6 +452,7 @@ AC_DEFUN([gl_FILE_LIST], [
426 lib/md5.h 452 lib/md5.h
427 lib/mktime-internal.h 453 lib/mktime-internal.h
428 lib/mktime.c 454 lib/mktime.c
455 lib/pthread_sigmask.c
429 lib/readlink.c 456 lib/readlink.c
430 lib/sha1.c 457 lib/sha1.c
431 lib/sha1.h 458 lib/sha1.h
@@ -433,6 +460,8 @@ AC_DEFUN([gl_FILE_LIST], [
433 lib/sha256.h 460 lib/sha256.h
434 lib/sha512.c 461 lib/sha512.c
435 lib/sha512.h 462 lib/sha512.h
463 lib/signal.in.h
464 lib/sigprocmask.c
436 lib/stat.c 465 lib/stat.c
437 lib/stdarg.in.h 466 lib/stdarg.in.h
438 lib/stdbool.in.h 467 lib/stdbool.in.h
@@ -470,10 +499,13 @@ AC_DEFUN([gl_FILE_LIST], [
470 m4/md5.m4 499 m4/md5.m4
471 m4/mktime.m4 500 m4/mktime.m4
472 m4/multiarch.m4 501 m4/multiarch.m4
502 m4/pthread_sigmask.m4
473 m4/readlink.m4 503 m4/readlink.m4
474 m4/sha1.m4 504 m4/sha1.m4
475 m4/sha256.m4 505 m4/sha256.m4
476 m4/sha512.m4 506 m4/sha512.m4
507 m4/signal_h.m4
508 m4/signalblocking.m4
477 m4/socklen.m4 509 m4/socklen.m4
478 m4/ssize_t.m4 510 m4/ssize_t.m4
479 m4/st_dm_mode.m4 511 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 @@
1# pthread_sigmask.m4 serial 7
2dnl Copyright (C) 2011 Free Software Foundation, Inc.
3dnl This file is free software; the Free Software Foundation
4dnl gives unlimited permission to copy and/or distribute it,
5dnl with or without modifications, as long as this notice is preserved.
6
7AC_DEFUN([gl_FUNC_PTHREAD_SIGMASK],
8[
9 AC_CHECK_FUNCS_ONCE([pthread_sigmask])
10 LIB_PTHREAD_SIGMASK=
11 m4_ifdef([gl_THREADLIB], [
12 AC_REQUIRE([gl_THREADLIB])
13 if test "$gl_threads_api" = posix; then
14 if test $ac_cv_func_pthread_sigmask = yes; then
15 dnl pthread_sigmask is available without -lpthread.
16 :
17 else
18 if test -n "$LIBMULTITHREAD"; then
19 AC_CACHE_CHECK([for pthread_sigmask in $LIBMULTITHREAD],
20 [gl_cv_func_pthread_sigmask_in_LIBMULTITHREAD],
21 [gl_save_LIBS="$LIBS"
22 LIBS="$LIBS $LIBMULTITHREAD"
23 AC_LINK_IFELSE(
24 [AC_LANG_PROGRAM(
25 [[#include <pthread.h>
26 #include <signal.h>
27 ]],
28 [[return pthread_sigmask (0, (sigset_t *) 0, (sigset_t *) 0);]])
29 ],
30 [gl_cv_func_pthread_sigmask_in_LIBMULTITHREAD=yes],
31 [gl_cv_func_pthread_sigmask_in_LIBMULTITHREAD=no])
32 LIBS="$gl_save_LIBS"
33 ])
34 if test $gl_cv_func_pthread_sigmask_in_LIBMULTITHREAD = yes; then
35 dnl pthread_sigmask is available with -lpthread.
36 LIB_PTHREAD_SIGMASK="$LIBMULTITHREAD"
37 else
38 dnl pthread_sigmask is not available at all.
39 HAVE_PTHREAD_SIGMASK=0
40 fi
41 else
42 dnl pthread_sigmask is not available at all.
43 HAVE_PTHREAD_SIGMASK=0
44 fi
45 fi
46 else
47 dnl pthread_sigmask may exist but does not interoperate with the chosen
48 dnl multithreading facility.
49 dnl If "$gl_threads_api" = pth, we could use the function pth_sigmask,
50 dnl but it is equivalent to sigprocmask, so we choose to emulate
51 dnl pthread_sigmask with sigprocmask also in this case. This yields fewer
52 dnl link dependencies.
53 if test $ac_cv_func_pthread_sigmask = yes; then
54 REPLACE_PTHREAD_SIGMASK=1
55 else
56 HAVE_PTHREAD_SIGMASK=0
57 fi
58 fi
59 ] ,[
60 dnl gl_THREADLIB is not in use. Assume the application wants
61 dnl POSIX semantics.
62 if test $ac_cv_func_pthread_sigmask != yes; then
63 gl_save_LIBS=$LIBS
64 AC_SEARCH_LIBS([pthread_sigmask], [pthread c_r])
65 LIBS=$gl_save_LIBS
66 if test "$ac_cv_search_pthread_sigmask" = no; then
67 HAVE_PTHREAD_SIGMASK=0
68 elif test "$ac_cv_search_pthread_sigmask" != 'none required'; then
69 LIB_PTHREAD_SIGMASK=$ac_cv_search_pthread_sigmask
70 fi
71 fi
72 ])
73 AC_SUBST([LIB_PTHREAD_SIGMASK])
74 dnl We don't need a variable LTLIB_PTHREAD_SIGMASK, because when
75 dnl "$gl_threads_api" = posix, $LTLIBMULTITHREAD and $LIBMULTITHREAD are the
76 dnl same: either both empty or both "-lpthread".
77])
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 @@
1# signal_h.m4 serial 16
2dnl Copyright (C) 2007-2011 Free Software Foundation, Inc.
3dnl This file is free software; the Free Software Foundation
4dnl gives unlimited permission to copy and/or distribute it,
5dnl with or without modifications, as long as this notice is preserved.
6
7AC_DEFUN([gl_SIGNAL_H],
8[
9 AC_REQUIRE([gl_SIGNAL_H_DEFAULTS])
10 AC_REQUIRE([gl_CHECK_TYPE_SIGSET_T])
11 gl_NEXT_HEADERS([signal.h])
12
13# AIX declares sig_atomic_t to already include volatile, and C89 compilers
14# then choke on 'volatile sig_atomic_t'. C99 requires that it compile.
15 AC_CHECK_TYPE([volatile sig_atomic_t], [],
16 [HAVE_TYPE_VOLATILE_SIG_ATOMIC_T=0], [[
17#include <signal.h>
18 ]])
19
20 AC_REQUIRE([AC_TYPE_UID_T])
21
22 dnl Persuade glibc <signal.h> to define sighandler_t.
23 AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
24 AC_CHECK_TYPE([sighandler_t], [], [HAVE_SIGHANDLER_T=0], [[
25#include <signal.h>
26 ]])
27
28 dnl Check for declarations of anything we want to poison if the
29 dnl corresponding gnulib module is not in use.
30 gl_WARN_ON_USE_PREPARE([[#include <signal.h>
31 ]], [pthread_sigmask sigaction
32 sigaddset sigdelset sigemptyset sigfillset sigismember
33 sigpending sigprocmask])
34])
35
36AC_DEFUN([gl_CHECK_TYPE_SIGSET_T],
37[
38 AC_CHECK_TYPES([sigset_t],
39 [gl_cv_type_sigset_t=yes], [gl_cv_type_sigset_t=no],
40 [[
41 #include <signal.h>
42 /* Mingw defines sigset_t not in <signal.h>, but in <sys/types.h>. */
43 #include <sys/types.h>
44 ]])
45 if test $gl_cv_type_sigset_t != yes; then
46 HAVE_SIGSET_T=0
47 fi
48])
49
50AC_DEFUN([gl_SIGNAL_MODULE_INDICATOR],
51[
52 dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
53 AC_REQUIRE([gl_SIGNAL_H_DEFAULTS])
54 gl_MODULE_INDICATOR_SET_VARIABLE([$1])
55 dnl Define it also as a C macro, for the benefit of the unit tests.
56 gl_MODULE_INDICATOR_FOR_TESTS([$1])
57])
58
59AC_DEFUN([gl_SIGNAL_H_DEFAULTS],
60[
61 GNULIB_PTHREAD_SIGMASK=0; AC_SUBST([GNULIB_PTHREAD_SIGMASK])
62 GNULIB_SIGNAL_H_SIGPIPE=0; AC_SUBST([GNULIB_SIGNAL_H_SIGPIPE])
63 GNULIB_SIGPROCMASK=0; AC_SUBST([GNULIB_SIGPROCMASK])
64 GNULIB_SIGACTION=0; AC_SUBST([GNULIB_SIGACTION])
65 dnl Assume proper GNU behavior unless another module says otherwise.
66 HAVE_POSIX_SIGNALBLOCKING=1; AC_SUBST([HAVE_POSIX_SIGNALBLOCKING])
67 HAVE_PTHREAD_SIGMASK=1; AC_SUBST([HAVE_PTHREAD_SIGMASK])
68 HAVE_SIGSET_T=1; AC_SUBST([HAVE_SIGSET_T])
69 HAVE_SIGINFO_T=1; AC_SUBST([HAVE_SIGINFO_T])
70 HAVE_SIGACTION=1; AC_SUBST([HAVE_SIGACTION])
71 HAVE_STRUCT_SIGACTION_SA_SIGACTION=1;
72 AC_SUBST([HAVE_STRUCT_SIGACTION_SA_SIGACTION])
73 HAVE_TYPE_VOLATILE_SIG_ATOMIC_T=1;
74 AC_SUBST([HAVE_TYPE_VOLATILE_SIG_ATOMIC_T])
75 HAVE_SIGHANDLER_T=1; AC_SUBST([HAVE_SIGHANDLER_T])
76 REPLACE_PTHREAD_SIGMASK=0; AC_SUBST([REPLACE_PTHREAD_SIGMASK])
77])
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 @@
1# signalblocking.m4 serial 12
2dnl Copyright (C) 2001-2002, 2006-2011 Free Software Foundation, Inc.
3dnl This file is free software; the Free Software Foundation
4dnl gives unlimited permission to copy and/or distribute it,
5dnl with or without modifications, as long as this notice is preserved.
6
7# Determine available signal blocking primitives. Three different APIs exist:
8# 1) POSIX: sigemptyset, sigaddset, sigprocmask
9# 2) SYSV: sighold, sigrelse
10# 3) BSD: sigblock, sigsetmask
11# For simplicity, here we check only for the POSIX signal blocking.
12AC_DEFUN([gl_SIGNALBLOCKING],
13[
14 AC_REQUIRE([gl_SIGNAL_H_DEFAULTS])
15 AC_REQUIRE([gl_CHECK_TYPE_SIGSET_T])
16 if test $gl_cv_type_sigset_t = yes; then
17 AC_CHECK_FUNC([sigprocmask], [gl_cv_func_sigprocmask=1])
18 fi
19 if test -z "$gl_cv_func_sigprocmask"; then
20 HAVE_POSIX_SIGNALBLOCKING=0
21 fi
22])
23
24# Prerequisites of lib/sigprocmask.c.
25AC_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 @@
12011-07-08 Paul Eggert <eggert@cs.ucla.edu>
2
3 Use pthread_sigmask, not sigprocmask (Bug#9010).
4 sigprocmask is portable only for single-threaded applications, and
5 Emacs can be multi-threaded when it uses GTK.
6 * Makefile.in (LIB_PTHREAD_SIGMASK): New macro.
7 (LIBES): Use it.
8 * callproc.c (Fcall_process):
9 * process.c (create_process):
10 * sysdep.c (sys_sigblock, sys_sigunblock, sys_sigsetmask):
11 Use pthread_sigmask, not sigprocmask.
12
12011-07-08 Jan Djärv <jan.h.d@swipnet.se> 132011-07-08 Jan Djärv <jan.h.d@swipnet.se>
2 14
3 * gtkutil.c (qttip_cb): Set line wrap to FALSE for tooltip widget. 15 * 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@
269LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@ 269LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@
270LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@ 270LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@
271 271
272LIB_PTHREAD_SIGMASK = @LIB_PTHREAD_SIGMASK@
273
272INTERVALS_H = dispextern.h intervals.h composite.h 274INTERVALS_H = dispextern.h intervals.h composite.h
273 275
274GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ 276GETLOADAVG_LIBS = @GETLOADAVG_LIBS@
@@ -383,7 +385,7 @@ LIBES = $(LIBS) $(LIBX_BASE) $(LIBX_OTHER) $(LIBSOUND) \
383 $(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \ 385 $(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \
384 $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \ 386 $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \
385 $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \ 387 $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \
386 $(LIBGNUTLS_LIBS) \ 388 $(LIBGNUTLS_LIBS) $(LIB_PTHREAD_SIGMASK) \
387 $(LIB_GCC) $(LIB_MATH) $(LIB_STANDARD) $(LIB_GCC) 389 $(LIB_GCC) $(LIB_MATH) $(LIB_STANDARD) $(LIB_GCC)
388 390
389all: emacs$(EXEEXT) $(OTHER_FILES) 391all: 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) */)
596 sigemptyset (&blocked); 596 sigemptyset (&blocked);
597 sigaddset (&blocked, SIGPIPE); 597 sigaddset (&blocked, SIGPIPE);
598 sigaction (SIGPIPE, 0, &sigpipe_action); 598 sigaction (SIGPIPE, 0, &sigpipe_action);
599 sigprocmask (SIG_BLOCK, &blocked, &procmask); 599 pthread_sigmask (SIG_BLOCK, &blocked, &procmask);
600#endif 600#endif
601 601
602 BLOCK_INPUT; 602 BLOCK_INPUT;
@@ -633,7 +633,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
633 in the child. */ 633 in the child. */
634 //signal (SIGPIPE, SIG_DFL); 634 //signal (SIGPIPE, SIG_DFL);
635#ifdef HAVE_WORKING_VFORK 635#ifdef HAVE_WORKING_VFORK
636 sigprocmask (SIG_SETMASK, &procmask, 0); 636 pthread_sigmask (SIG_SETMASK, &procmask, 0);
637#endif 637#endif
638 638
639 child_setup (filefd, fd1, fd_error, (char **) new_argv, 639 child_setup (filefd, fd1, fd_error, (char **) new_argv,
@@ -645,7 +645,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
645#ifdef HAVE_WORKING_VFORK 645#ifdef HAVE_WORKING_VFORK
646 /* Restore the signal state. */ 646 /* Restore the signal state. */
647 sigaction (SIGPIPE, &sigpipe_action, 0); 647 sigaction (SIGPIPE, &sigpipe_action, 0);
648 sigprocmask (SIG_SETMASK, &procmask, 0); 648 pthread_sigmask (SIG_SETMASK, &procmask, 0);
649#endif 649#endif
650 650
651#endif /* not WINDOWSNT */ 651#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)
1652 sigaddset (&blocked, SIGHUP ); sigaction (SIGHUP , 0, &sighup_action ); 1652 sigaddset (&blocked, SIGHUP ); sigaction (SIGHUP , 0, &sighup_action );
1653#endif 1653#endif
1654#endif /* HAVE_WORKING_VFORK */ 1654#endif /* HAVE_WORKING_VFORK */
1655 sigprocmask (SIG_BLOCK, &blocked, &procmask); 1655 pthread_sigmask (SIG_BLOCK, &blocked, &procmask);
1656 1656
1657 FD_SET (inchannel, &input_wait_mask); 1657 FD_SET (inchannel, &input_wait_mask);
1658 FD_SET (inchannel, &non_keyboard_wait_mask); 1658 FD_SET (inchannel, &non_keyboard_wait_mask);
@@ -1808,7 +1808,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1808 signal (SIGPIPE, SIG_DFL); 1808 signal (SIGPIPE, SIG_DFL);
1809 1809
1810 /* Stop blocking signals in the child. */ 1810 /* Stop blocking signals in the child. */
1811 sigprocmask (SIG_SETMASK, &procmask, 0); 1811 pthread_sigmask (SIG_SETMASK, &procmask, 0);
1812 1812
1813 if (pty_flag) 1813 if (pty_flag)
1814 child_setup_tty (xforkout); 1814 child_setup_tty (xforkout);
@@ -1900,7 +1900,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1900#endif 1900#endif
1901#endif /* HAVE_WORKING_VFORK */ 1901#endif /* HAVE_WORKING_VFORK */
1902 /* Stop blocking signals in the parent. */ 1902 /* Stop blocking signals in the parent. */
1903 sigprocmask (SIG_SETMASK, &procmask, 0); 1903 pthread_sigmask (SIG_SETMASK, &procmask, 0);
1904 1904
1905 /* Now generate the error if vfork failed. */ 1905 /* Now generate the error if vfork failed. */
1906 if (pid < 0) 1906 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
1534sys_sigblock (sigset_t new_mask) 1534sys_sigblock (sigset_t new_mask)
1535{ 1535{
1536 sigset_t old_mask; 1536 sigset_t old_mask;
1537 sigprocmask (SIG_BLOCK, &new_mask, &old_mask); 1537 pthread_sigmask (SIG_BLOCK, &new_mask, &old_mask);
1538 return (old_mask); 1538 return (old_mask);
1539} 1539}
1540 1540
@@ -1542,7 +1542,7 @@ sigset_t
1542sys_sigunblock (sigset_t new_mask) 1542sys_sigunblock (sigset_t new_mask)
1543{ 1543{
1544 sigset_t old_mask; 1544 sigset_t old_mask;
1545 sigprocmask (SIG_UNBLOCK, &new_mask, &old_mask); 1545 pthread_sigmask (SIG_UNBLOCK, &new_mask, &old_mask);
1546 return (old_mask); 1546 return (old_mask);
1547} 1547}
1548 1548
@@ -1550,7 +1550,7 @@ sigset_t
1550sys_sigsetmask (sigset_t new_mask) 1550sys_sigsetmask (sigset_t new_mask)
1551{ 1551{
1552 sigset_t old_mask; 1552 sigset_t old_mask;
1553 sigprocmask (SIG_SETMASK, &new_mask, &old_mask); 1553 pthread_sigmask (SIG_SETMASK, &new_mask, &old_mask);
1554 return (old_mask); 1554 return (old_mask);
1555} 1555}
1556 1556