From 6db30f83447f4667d2ca84c33979f2745ca96bd5 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 6 Jul 2011 10:58:37 -0700 Subject: Add gnulib support for pthread_sigmask. * Makefile.in (GNULIB_MODULES): Add pthread_sigmask. (GNULIB_TOOL_FLAGS): Avoid sigprocmask. Emacs does its own implementation of 'sigprocmask' on Windows, and it assumes 'sigprocmask' on non-Windows hosts, so it doesn't need the sigprocmask module. * lib/signal.in.h, m4/pthread_sigmask.m4, m4/signal_h.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. --- ChangeLog | 14 ++ Makefile.in | 4 +- lib/gnulib.mk | 40 +++++- lib/signal.in.h | 392 ++++++++++++++++++++++++++++++++++++++++++++++++++ m4/gl-comp.m4 | 11 ++ m4/pthread_sigmask.m4 | 26 ++++ m4/signal_h.m4 | 76 ++++++++++ 7 files changed, 561 insertions(+), 2 deletions(-) create mode 100644 lib/signal.in.h create mode 100644 m4/pthread_sigmask.m4 create mode 100644 m4/signal_h.m4 diff --git a/ChangeLog b/ChangeLog index 19dcf6818e3..0d69b94943e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2011-07-06 Paul Eggert + + Add gnulib support for pthread_sigmask. + * Makefile.in (GNULIB_MODULES): Add pthread_sigmask. + (GNULIB_TOOL_FLAGS): Avoid sigprocmask. Emacs does its own + implementation of 'sigprocmask' on Windows, and it assumes + 'sigprocmask' on non-Windows hosts, so it doesn't need the + sigprocmask module. + * lib/signal.in.h, m4/pthread_sigmask.m4, m4/signal_h.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. + 2011-07-05 Jan Djärv * configure.in (HAVE_GCONF): Allow both HAVE_GCONF and HAVE_GSETTINGS. diff --git a/Makefile.in b/Makefile.in index 457b5d6472e..07a2c6a017d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -335,9 +335,11 @@ 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 = \ + --avoid=sigprocmask \ --conditional-dependencies --import --no-changelog --no-vc-files \ --makefile-name=gnulib.mk sync-from-gnulib: $(gnulib_srcdir) diff --git a/lib/gnulib.mk b/lib/gnulib.mk index 18abe4536fa..88a7919b7af 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=. --avoid=sigprocmask --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 @@ -303,6 +303,44 @@ 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 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_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 stat if gl_GNULIB_ENABLED_stat diff --git a/lib/signal.in.h b/lib/signal.in.h new file mode 100644 index 00000000000..01987a7aff1 --- /dev/null +++ b/lib/signal.in.h @@ -0,0 +1,392 @@ +/* A GNU-like . + + 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 . */ + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +#if defined __need_sig_atomic_t || defined __need_sigset_t +/* Special invocation convention inside glibc header files. */ + +# @INCLUDE_NEXT@ @NEXT_SIGNAL_H@ + +#else +/* Normal invocation convention. */ + +#ifndef _@GUARD_PREFIX@_SIGNAL_H + +/* Define pid_t, uid_t. + Also, mingw defines sigset_t not in , but in . + On Solaris 10, includes , which eventually includes + us; so include now, before the second inclusion guard. */ +#include + +/* The include_next requires a split double-inclusion guard. */ +#@INCLUDE_NEXT@ @NEXT_SIGNAL_H@ + +#ifndef _@GUARD_PREFIX@_SIGNAL_H +#define _@GUARD_PREFIX@_SIGNAL_H + +/* 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@ +# undef pthread_sigmask +# define pthread_sigmask sigprocmask +# endif +#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/m4/gl-comp.m4 b/m4/gl-comp.m4 index 16bb02e686f..004c01a10a0 100644 --- a/m4/gl-comp.m4 +++ b/m4/gl-comp.m4 @@ -52,7 +52,9 @@ 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 socklen: # Code from module ssize_t: # Code from module stat: @@ -140,12 +142,15 @@ if test $REPLACE_MKTIME = 1; then fi gl_TIME_MODULE_INDICATOR([mktime]) gl_MULTIARCH +gl_PTHREAD_SIGMASK +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 @@ -241,6 +246,9 @@ gl_STDLIB_MODULE_INDICATOR([strtoull]) if test $REPLACE_LSTAT = 1; then func_gl_gnulib_m4code_stat fi + if 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 @@ -433,6 +441,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/sha256.h lib/sha512.c lib/sha512.h + lib/signal.in.h lib/stat.c lib/stdarg.in.h lib/stdbool.in.h @@ -470,10 +479,12 @@ 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/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..d25e2cc3e70 --- /dev/null +++ b/m4/pthread_sigmask.m4 @@ -0,0 +1,26 @@ +# pthread_sigmask.m4 serial 2 +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_PTHREAD_SIGMASK], +[ + m4_ifdef([gl_THREADLIB], [ + AC_REQUIRE([gl_THREADLIB]) + if test "$gl_threads_api" = posix; then + gl_save_LIBS="$LIBS" + LIBS="$LIBS $LIBMULTITHREAD" + AC_CHECK_FUNCS([pthread_sigmask]) + LIBS="$gl_save_LIBS" + else + ac_cv_func_pthread_sigmask=no + fi + ], [ + AC_CHECK_FUNCS_ONCE([pthread_sigmask]) + ]) + + if test $ac_cv_func_pthread_sigmask = no; then + REPLACE_PTHREAD_SIGMASK=1 + fi +]) diff --git a/m4/signal_h.m4 b/m4/signal_h.m4 new file mode 100644 index 00000000000..53972fba54f --- /dev/null +++ b/m4/signal_h.m4 @@ -0,0 +1,76 @@ +# signal_h.m4 serial 14 +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 + ]]) + + AC_REQUIRE([AC_TYPE_UID_T]) + + dnl Persuade glibc to define sighandler_t. + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + AC_CHECK_TYPE([sighandler_t], [], [HAVE_SIGHANDLER_T=0], [[ +#include + ]]) + + 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 + ]], [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 + /* Mingw defines sigset_t not in , but in . */ + #include + ]]) + 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_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]) +]) -- cgit v1.2.3 From 123403e42f1a1d556fb33cfd60cbec124d740837 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 6 Jul 2011 11:04:23 -0700 Subject: Use pthread_sigmask, not sigprocmask. * callproc.c (Fcall_process): * sysdep.c (sys_sigblock, sys_sigunblock, sys_sigsetmask): * process.c (create_process): sigprocmask is portable only for single-threaded applications, and Emacs can be multi-threaded when it uses GTK. --- src/ChangeLog | 9 +++++++++ src/callproc.c | 6 +++--- src/process.c | 6 +++--- src/sysdep.c | 6 +++--- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index dc62da2035b..9c73cb9ed85 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,12 @@ +2011-07-06 Paul Eggert + + Use pthread_sigmask, not sigprocmask. + * callproc.c (Fcall_process): + * sysdep.c (sys_sigblock, sys_sigunblock, sys_sigsetmask): + * process.c (create_process): + sigprocmask is portable only for single-threaded applications, and + Emacs can be multi-threaded when it uses GTK. + 2011-07-05 Jan Djärv * xsettings.c: Use both GConf and GSettings if both are available. 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); } -- cgit v1.2.3 From 8a6ebd580bafa45ca1d8cc6294ea91facacfdbe0 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 6 Jul 2011 16:29:03 -0700 Subject: Add Bug#. --- ChangeLog | 2 +- src/ChangeLog | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0d69b94943e..62847460778 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,6 @@ 2011-07-06 Paul Eggert - Add gnulib support for pthread_sigmask. + Add gnulib support for pthread_sigmask (Bug#9010). * Makefile.in (GNULIB_MODULES): Add pthread_sigmask. (GNULIB_TOOL_FLAGS): Avoid sigprocmask. Emacs does its own implementation of 'sigprocmask' on Windows, and it assumes diff --git a/src/ChangeLog b/src/ChangeLog index 9c73cb9ed85..41dd4c0e9c1 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,6 +1,6 @@ 2011-07-06 Paul Eggert - Use pthread_sigmask, not sigprocmask. + Use pthread_sigmask, not sigprocmask (Bug#9010). * callproc.c (Fcall_process): * sysdep.c (sys_sigblock, sys_sigunblock, sys_sigsetmask): * process.c (create_process): -- cgit v1.2.3 From 2a84b02da8b20138fad7fafdea92d7c8f0564ee0 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 8 Jul 2011 13:20:19 -0700 Subject: Simplify Emacs part of pthread_sigmask support. * Makefile.in (GNULIB_TOOL_FLAGS): Do not avoid sigprocmask. * configure.in (AC_TYPE_UID_T): New dummy macro. Configure gnulib after adjusting LIBS, so that gnulib can assume the libraries in LIBS. * lib/pthread_sigmask.c, lib/sigprocmask.c, m4/signalblocking.m4: New files, automatically imported from gnulib. * lib/gnulib.mk, m4/gl-comp.m4: Regenerate. * src/Makefile.in (LIB_PTHREAD_SIGMASK): New macro. (LIBES): Use it. --- ChangeLog | 10 +- Makefile.in | 1 - configure.in | 11 +- lib/getopt.c | 11 +- lib/gnulib.mk | 23 +++- lib/pthread_sigmask.c | 29 +++++ lib/signal.in.h | 44 ++++++- lib/sigprocmask.c | 329 ++++++++++++++++++++++++++++++++++++++++++++++++++ lib/unistd.in.h | 141 +++++++++++----------- m4/getopt.m4 | 83 ++++++++----- m4/gl-comp.m4 | 25 +++- m4/pthread_sigmask.m4 | 77 ++++++++++-- m4/signal_h.m4 | 3 +- m4/signalblocking.m4 | 25 ++++ src/Makefile.in | 4 +- 15 files changed, 677 insertions(+), 139 deletions(-) create mode 100644 lib/pthread_sigmask.c create mode 100644 lib/sigprocmask.c create mode 100644 m4/signalblocking.m4 diff --git a/ChangeLog b/ChangeLog index 6aaebbc80e9..845fce543b6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,15 +2,17 @@ Add gnulib support for pthread_sigmask (Bug#9010). * Makefile.in (GNULIB_MODULES): Add pthread_sigmask. - (GNULIB_TOOL_FLAGS): Avoid sigprocmask. Emacs does its own - implementation of 'sigprocmask' on Windows, and it assumes - 'sigprocmask' on non-Windows hosts, so it doesn't need the - sigprocmask module. + * 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. 2011-07-07 Andreas Schwab diff --git a/Makefile.in b/Makefile.in index 07a2c6a017d..a3d85bad22a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -339,7 +339,6 @@ GNULIB_MODULES = \ mktime pthread_sigmask readlink \ socklen stdarg stdio strftime strtoumax symlink sys_stat GNULIB_TOOL_FLAGS = \ - --avoid=sigprocmask \ --conditional-dependencies --import --no-changelog --no-vc-files \ --makefile-name=gnulib.mk sync-from-gnulib: $(gnulib_srcdir) 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/getopt.c b/lib/getopt.c index 2af8352ee9c..7c9f7040612 100644 --- a/lib/getopt.c +++ b/lib/getopt.c @@ -829,7 +829,7 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, return '?'; } /* Convenience. Treat POSIX -W foo same as long option --foo */ - if (temp[0] == 'W' && temp[1] == ';' && longopts) + if (temp[0] == 'W' && temp[1] == ';') { char *nameend; const struct option *p; @@ -839,6 +839,9 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, int indfound = 0; int option_index; + if (longopts == NULL) + goto no_longs; + /* This is an option that requires an argument. */ if (*d->__nextchar != '\0') { @@ -1046,8 +1049,10 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, } return pfound->val; } - d->__nextchar = NULL; - return 'W'; /* Let the application handle it. */ + + no_longs: + d->__nextchar = NULL; + return 'W'; /* Let the application handle it. */ } if (temp[1] == ':') { diff --git a/lib/gnulib.mk b/lib/gnulib.mk index 88a7919b7af..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=. --avoid=sigprocmask --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 +# 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 @@ -322,6 +331,7 @@ signal.h: signal.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -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' \ @@ -341,6 +351,17 @@ 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 . */ + +#include + +/* Specification. */ +#include + +#include + +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 index 01987a7aff1..93787f753fa 100644 --- a/lib/signal.in.h +++ b/lib/signal.in.h @@ -20,8 +20,17 @@ #endif @PRAGMA_COLUMNS@ -#if defined __need_sig_atomic_t || defined __need_sigset_t -/* Special invocation convention inside glibc header files. */ +#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 + -> -> . + 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 + -> -> -> . + In this situation, some of the functions are not yet declared, therefore + we cannot provide the C++ aliases. */ # @INCLUDE_NEXT@ @NEXT_SIGNAL_H@ @@ -30,6 +39,8 @@ #ifndef _@GUARD_PREFIX@_SIGNAL_H +#define _GL_ALREADY_INCLUDING_SIGNAL_H + /* Define pid_t, uid_t. Also, mingw defines sigset_t not in , but in . On Solaris 10, includes , which eventually includes @@ -39,9 +50,20 @@ /* 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 , not in . + 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 +#endif + /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ /* The definition of _GL_ARG_NONNULL is copied here. */ @@ -104,9 +126,23 @@ typedef void (*sighandler_t) (int); #if @GNULIB_PTHREAD_SIGMASK@ # if @REPLACE_PTHREAD_SIGMASK@ -# undef pthread_sigmask -# define pthread_sigmask sigprocmask +# 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 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 , 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 . */ + +#include + +/* Specification. */ +#include + +#include +#include +#include + +/* 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/lib/unistd.in.h b/lib/unistd.in.h index fdf0fca54e9..769ecf0d43f 100644 --- a/lib/unistd.in.h +++ b/lib/unistd.in.h @@ -117,78 +117,77 @@ /* The definition of _GL_WARN_ON_USE is copied here. */ -#if @GNULIB_GETHOSTNAME@ -/* Get all possible declarations of gethostname(). */ -# if @UNISTD_H_HAVE_WINSOCK2_H@ -# if !defined _@GUARD_PREFIX@_SYS_SOCKET_H -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef socket -# define socket socket_used_without_including_sys_socket_h -# undef connect -# define connect connect_used_without_including_sys_socket_h -# undef accept -# define accept accept_used_without_including_sys_socket_h -# undef bind -# define bind bind_used_without_including_sys_socket_h -# undef getpeername -# define getpeername getpeername_used_without_including_sys_socket_h -# undef getsockname -# define getsockname getsockname_used_without_including_sys_socket_h -# undef getsockopt -# define getsockopt getsockopt_used_without_including_sys_socket_h -# undef listen -# define listen listen_used_without_including_sys_socket_h -# undef recv -# define recv recv_used_without_including_sys_socket_h -# undef send -# define send send_used_without_including_sys_socket_h -# undef recvfrom -# define recvfrom recvfrom_used_without_including_sys_socket_h -# undef sendto -# define sendto sendto_used_without_including_sys_socket_h -# undef setsockopt -# define setsockopt setsockopt_used_without_including_sys_socket_h -# undef shutdown -# define shutdown shutdown_used_without_including_sys_socket_h -# else - _GL_WARN_ON_USE (socket, - "socket() used without including "); - _GL_WARN_ON_USE (connect, - "connect() used without including "); - _GL_WARN_ON_USE (accept, - "accept() used without including "); - _GL_WARN_ON_USE (bind, - "bind() used without including "); - _GL_WARN_ON_USE (getpeername, - "getpeername() used without including "); - _GL_WARN_ON_USE (getsockname, - "getsockname() used without including "); - _GL_WARN_ON_USE (getsockopt, - "getsockopt() used without including "); - _GL_WARN_ON_USE (listen, - "listen() used without including "); - _GL_WARN_ON_USE (recv, - "recv() used without including "); - _GL_WARN_ON_USE (send, - "send() used without including "); - _GL_WARN_ON_USE (recvfrom, - "recvfrom() used without including "); - _GL_WARN_ON_USE (sendto, - "sendto() used without including "); - _GL_WARN_ON_USE (setsockopt, - "setsockopt() used without including "); - _GL_WARN_ON_USE (shutdown, - "shutdown() used without including "); -# endif +/* Hide some function declarations from . */ + +#if @GNULIB_GETHOSTNAME@ && @UNISTD_H_HAVE_WINSOCK2_H@ +# if !defined _@GUARD_PREFIX@_SYS_SOCKET_H +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef socket +# define socket socket_used_without_including_sys_socket_h +# undef connect +# define connect connect_used_without_including_sys_socket_h +# undef accept +# define accept accept_used_without_including_sys_socket_h +# undef bind +# define bind bind_used_without_including_sys_socket_h +# undef getpeername +# define getpeername getpeername_used_without_including_sys_socket_h +# undef getsockname +# define getsockname getsockname_used_without_including_sys_socket_h +# undef getsockopt +# define getsockopt getsockopt_used_without_including_sys_socket_h +# undef listen +# define listen listen_used_without_including_sys_socket_h +# undef recv +# define recv recv_used_without_including_sys_socket_h +# undef send +# define send send_used_without_including_sys_socket_h +# undef recvfrom +# define recvfrom recvfrom_used_without_including_sys_socket_h +# undef sendto +# define sendto sendto_used_without_including_sys_socket_h +# undef setsockopt +# define setsockopt setsockopt_used_without_including_sys_socket_h +# undef shutdown +# define shutdown shutdown_used_without_including_sys_socket_h +# else + _GL_WARN_ON_USE (socket, + "socket() used without including "); + _GL_WARN_ON_USE (connect, + "connect() used without including "); + _GL_WARN_ON_USE (accept, + "accept() used without including "); + _GL_WARN_ON_USE (bind, + "bind() used without including "); + _GL_WARN_ON_USE (getpeername, + "getpeername() used without including "); + _GL_WARN_ON_USE (getsockname, + "getsockname() used without including "); + _GL_WARN_ON_USE (getsockopt, + "getsockopt() used without including "); + _GL_WARN_ON_USE (listen, + "listen() used without including "); + _GL_WARN_ON_USE (recv, + "recv() used without including "); + _GL_WARN_ON_USE (send, + "send() used without including "); + _GL_WARN_ON_USE (recvfrom, + "recvfrom() used without including "); + _GL_WARN_ON_USE (sendto, + "sendto() used without including "); + _GL_WARN_ON_USE (setsockopt, + "setsockopt() used without including "); + _GL_WARN_ON_USE (shutdown, + "shutdown() used without including "); # endif -# if !defined _@GUARD_PREFIX@_SYS_SELECT_H -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef select -# define select select_used_without_including_sys_select_h -# else - _GL_WARN_ON_USE (select, - "select() used without including "); -# endif +# endif +# if !defined _@GUARD_PREFIX@_SYS_SELECT_H +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef select +# define select select_used_without_including_sys_select_h +# else + _GL_WARN_ON_USE (select, + "select() used without including "); # endif # endif #endif diff --git a/m4/getopt.m4 b/m4/getopt.m4 index 4d8450ff907..7e49ddde9f6 100644 --- a/m4/getopt.m4 +++ b/m4/getopt.m4 @@ -1,4 +1,4 @@ -# getopt.m4 serial 35 +# getopt.m4 serial 38 dnl Copyright (C) 2002-2006, 2008-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, @@ -89,15 +89,15 @@ AC_DEFUN([gl_GETOPT_CHECK_HEADERS], AC_CACHE_CHECK([whether getopt is POSIX compatible], [gl_cv_func_getopt_posix], [ - dnl BSD getopt_long uses an incompatible method to reset - dnl option processing. Existence of the variable, in and of + dnl BSD getopt_long uses an incompatible method to reset option + dnl processing. Existence of the optreset variable, in and of dnl itself, is not a reason to replace getopt, but knowledge dnl of the variable is needed to determine how to reset and dnl whether a reset reparses the environment. Solaris dnl supports neither optreset nor optind=0, but keeps no state dnl that needs a reset beyond setting optind=1; detect Solaris dnl by getopt_clip. - AC_COMPILE_IFELSE( + AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[#include ]], [[int *p = &optreset; return optreset;]])], @@ -121,22 +121,20 @@ int main () { { - int argc = 0; - char *argv[10]; + static char program[] = "program"; + static char a[] = "-a"; + static char foo[] = "foo"; + static char bar[] = "bar"; + char *argv[] = { program, a, foo, bar, NULL }; int c; - argv[argc++] = "program"; - argv[argc++] = "-a"; - argv[argc++] = "foo"; - argv[argc++] = "bar"; - argv[argc] = NULL; optind = OPTIND_MIN; opterr = 0; - c = getopt (argc, argv, "ab"); + c = getopt (4, argv, "ab"); if (!(c == 'a')) return 1; - c = getopt (argc, argv, "ab"); + c = getopt (4, argv, "ab"); if (!(c == -1)) return 2; if (!(optind == 2)) @@ -144,22 +142,20 @@ main () } /* Some internal state exists at this point. */ { - int argc = 0; - char *argv[10]; + static char program[] = "program"; + static char donald[] = "donald"; + static char p[] = "-p"; + static char billy[] = "billy"; + static char duck[] = "duck"; + static char a[] = "-a"; + static char bar[] = "bar"; + char *argv[] = { program, donald, p, billy, duck, a, bar, NULL }; int c; - argv[argc++] = "program"; - argv[argc++] = "donald"; - argv[argc++] = "-p"; - argv[argc++] = "billy"; - argv[argc++] = "duck"; - argv[argc++] = "-a"; - argv[argc++] = "bar"; - argv[argc] = NULL; optind = OPTIND_MIN; opterr = 0; - c = getopt (argc, argv, "+abp:q:"); + c = getopt (7, argv, "+abp:q:"); if (!(c == -1)) return 4; if (!(strcmp (argv[0], "program") == 0)) @@ -181,7 +177,9 @@ main () } /* Detect MacOS 10.5, AIX 7.1 bug. */ { - char *argv[3] = { "program", "-ab", NULL }; + static char program[] = "program"; + static char ab[] = "-ab"; + char *argv[3] = { program, ab, NULL }; optind = OPTIND_MIN; opterr = 0; if (getopt (2, argv, "ab:") != 'a') @@ -239,19 +237,22 @@ dnl is ambiguous with environment values that contain newlines. and fails on MacOS X 10.5, AIX 5.2, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 10. */ { - char *myargv[3]; - myargv[0] = "conftest"; - myargv[1] = "-+"; - myargv[2] = 0; + static char conftest[] = "conftest"; + static char plus[] = "-+"; + char *argv[3] = { conftest, plus, NULL }; opterr = 0; - if (getopt (2, myargv, "+a") != '?') + if (getopt (2, argv, "+a") != '?') result |= 1; } /* This code succeeds on glibc 2.8, mingw, and fails on MacOS X 10.5, OpenBSD 4.0, AIX 5.2, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin 1.5.x. */ { - char *argv[] = { "program", "-p", "foo", "bar", NULL }; + static char program[] = "program"; + static char p[] = "-p"; + static char foo[] = "foo"; + static char bar[] = "bar"; + char *argv[] = { program, p, foo, bar, NULL }; optind = 1; if (getopt (4, argv, "p::") != 'p') @@ -265,7 +266,10 @@ dnl is ambiguous with environment values that contain newlines. } /* This code succeeds on glibc 2.8 and fails on Cygwin 1.7.0. */ { - char *argv[] = { "program", "foo", "-p", NULL }; + static char program[] = "program"; + static char foo[] = "foo"; + static char p[] = "-p"; + char *argv[] = { program, foo, p, NULL }; optind = 0; if (getopt (3, argv, "-p") != 1) result |= 16; @@ -274,13 +278,26 @@ dnl is ambiguous with environment values that contain newlines. } /* This code fails on glibc 2.11. */ { - char *argv[] = { "program", "-b", "-a", NULL }; + static char program[] = "program"; + static char b[] = "-b"; + static char a[] = "-a"; + char *argv[] = { program, b, a, NULL }; optind = opterr = 0; if (getopt (3, argv, "+:a:b") != 'b') result |= 64; else if (getopt (3, argv, "+:a:b") != ':') result |= 64; } + /* This code dumps core on glibc 2.14. */ + { + static char program[] = "program"; + static char w[] = "-W"; + static char dummy[] = "dummy"; + char *argv[] = { program, w, dummy, NULL }; + optind = opterr = 1; + if (getopt (3, argv, "W;") != 'W') + result |= 128; + } return result; ]])], [gl_cv_func_getopt_gnu=yes], diff --git a/m4/gl-comp.m4 b/m4/gl-comp.m4 index 004c01a10a0..6c94e373871 100644 --- a/m4/gl-comp.m4 +++ b/m4/gl-comp.m4 @@ -55,6 +55,7 @@ AC_DEFUN([gl_EARLY], # 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: @@ -142,7 +143,10 @@ if test $REPLACE_MKTIME = 1; then fi gl_TIME_MODULE_INDICATOR([mktime]) gl_MULTIARCH -gl_PTHREAD_SIGMASK +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 @@ -184,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 @@ -201,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 @@ -246,7 +263,7 @@ gl_STDLIB_MODULE_INDICATOR([strtoull]) if test $REPLACE_LSTAT = 1; then func_gl_gnulib_m4code_stat fi - if test $REPLACE_PTHREAD_SIGMASK = 1; then + 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 @@ -261,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]) @@ -434,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 @@ -442,6 +461,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/sha512.c lib/sha512.h lib/signal.in.h + lib/sigprocmask.c lib/stat.c lib/stdarg.in.h lib/stdbool.in.h @@ -485,6 +505,7 @@ AC_DEFUN([gl_FILE_LIST], [ 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 index d25e2cc3e70..dfa0f660a75 100644 --- a/m4/pthread_sigmask.m4 +++ b/m4/pthread_sigmask.m4 @@ -1,26 +1,77 @@ -# pthread_sigmask.m4 serial 2 +# 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_PTHREAD_SIGMASK], +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 - gl_save_LIBS="$LIBS" - LIBS="$LIBS $LIBMULTITHREAD" - AC_CHECK_FUNCS([pthread_sigmask]) - LIBS="$gl_save_LIBS" + 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 + #include + ]], + [[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 - ac_cv_func_pthread_sigmask=no + 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_CHECK_FUNCS_ONCE([pthread_sigmask]) ]) - - if test $ac_cv_func_pthread_sigmask = no; then - REPLACE_PTHREAD_SIGMASK=1 - 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 index 53972fba54f..b9536fb0e3c 100644 --- a/m4/signal_h.m4 +++ b/m4/signal_h.m4 @@ -1,4 +1,4 @@ -# signal_h.m4 serial 14 +# 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, @@ -64,6 +64,7 @@ AC_DEFUN([gl_SIGNAL_H_DEFAULTS], 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]) 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/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) -- cgit v1.2.3