Simplify Emacs part of pthread_sigmask support.
authorPaul Eggert <eggert@cs.ucla.edu>
Fri, 8 Jul 2011 20:20:19 +0000 (13:20 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Fri, 8 Jul 2011 20:20:19 +0000 (13:20 -0700)
* 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.

15 files changed:
ChangeLog
Makefile.in
configure.in
lib/getopt.c
lib/gnulib.mk
lib/pthread_sigmask.c [new file with mode: 0644]
lib/signal.in.h
lib/sigprocmask.c [new file with mode: 0644]
lib/unistd.in.h
m4/getopt.m4
m4/gl-comp.m4
m4/pthread_sigmask.m4
m4/signal_h.m4
m4/signalblocking.m4 [new file with mode: 0644]
src/Makefile.in

index 6aaebbc..845fce5 100644 (file)
--- 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  <schwab@linux-m68k.org>
 
index 07a2c6a..a3d85ba 100644 (file)
@@ -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)
index 5014a79..3dd1f03 100644 (file)
@@ -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" ;;
index 2af8352..7c9f704 100644 (file)
@@ -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] == ':')
       {
index 88a7919..25647f0 100644 (file)
@@ -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 (file)
index 0000000..1f460f1
--- /dev/null
@@ -0,0 +1,29 @@
+/* POSIX compatible signal blocking for threads.
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <signal.h>
+
+#include <errno.h>
+
+int
+pthread_sigmask (int how, const sigset_t *new_mask, sigset_t *old_mask)
+{
+  int ret = sigprocmask (how, new_mask, old_mask);
+  return (ret < 0 ? errno : 0);
+}
index 01987a7..93787f7 100644 (file)
 #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
+     <signal.h> -> <ucontext.h> -> <signal.h>.
+     In this situation, the functions are not yet declared, therefore we cannot
+     provide the C++ aliases.
+   - On glibc systems with GCC 4.3 we have a sequence of nested includes
+     <csignal> -> </usr/include/signal.h> -> <sys/ucontext.h> -> <signal.h>.
+     In this situation, some of the functions are not yet declared, therefore
+     we cannot provide the C++ aliases.  */
 
 # @INCLUDE_NEXT@ @NEXT_SIGNAL_H@
 
@@ -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 <signal.h>, but in <sys/types.h>.
    On Solaris 10, <signal.h> includes <sys/types.h>, which eventually includes
 /* The include_next requires a split double-inclusion guard.  */
 #@INCLUDE_NEXT@ @NEXT_SIGNAL_H@
 
+#undef _GL_ALREADY_INCLUDING_SIGNAL_H
+
 #ifndef _@GUARD_PREFIX@_SIGNAL_H
 #define _@GUARD_PREFIX@_SIGNAL_H
 
+/* MacOS X 10.3, FreeBSD 6.4, OpenBSD 3.8, OSF/1 4.0, Solaris 2.6 declare
+   pthread_sigmask in <pthread.h>, not in <signal.h>.
+   But avoid namespace pollution on glibc systems.*/
+#if (@GNULIB_PTHREAD_SIGMASK@ || defined GNULIB_POSIXCHECK) \
+    && ((defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ || defined __OpenBSD__ || defined __osf__ || defined __sun) \
+    && ! defined __GLIBC__
+# include <pthread.h>
+#endif
+
 /* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
 
 /* The definition of _GL_ARG_NONNULL is copied here.  */
@@ -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 (file)
index 0000000..6780a37
--- /dev/null
@@ -0,0 +1,329 @@
+/* POSIX compatible signal blocking.
+   Copyright (C) 2006-2011 Free Software Foundation, Inc.
+   Written by Bruno Haible <bruno@clisp.org>, 2006.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <signal.h>
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+/* We assume that a platform without POSIX signal blocking functions
+   also does not have the POSIX sigaction() function, only the
+   signal() function.  We also assume signal() has SysV semantics,
+   where any handler is uninstalled prior to being invoked.  This is
+   true for Woe32 platforms.  */
+
+/* We use raw signal(), but also provide a wrapper rpl_signal() so
+   that applications can query or change a blocked signal.  */
+#undef signal
+
+/* Provide invalid signal numbers as fallbacks if the uncatchable
+   signals are not defined.  */
+#ifndef SIGKILL
+# define SIGKILL (-1)
+#endif
+#ifndef SIGSTOP
+# define SIGSTOP (-1)
+#endif
+
+/* On native Windows, as of 2008, the signal SIGABRT_COMPAT is an alias
+   for the signal SIGABRT.  Only one signal handler is stored for both
+   SIGABRT and SIGABRT_COMPAT.  SIGABRT_COMPAT is not a signal of its own.  */
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+# undef SIGABRT_COMPAT
+# define SIGABRT_COMPAT 6
+#endif
+#ifdef SIGABRT_COMPAT
+# define SIGABRT_COMPAT_MASK (1U << SIGABRT_COMPAT)
+#else
+# define SIGABRT_COMPAT_MASK 0
+#endif
+
+typedef void (*handler_t) (int);
+
+/* Handling of gnulib defined signals.  */
+
+#if GNULIB_defined_SIGPIPE
+static handler_t SIGPIPE_handler = SIG_DFL;
+#endif
+
+#if GNULIB_defined_SIGPIPE
+static handler_t
+ext_signal (int sig, handler_t handler)
+{
+  switch (sig)
+    {
+    case SIGPIPE:
+      {
+        handler_t old_handler = SIGPIPE_handler;
+        SIGPIPE_handler = handler;
+        return old_handler;
+      }
+    default: /* System defined signal */
+      return signal (sig, handler);
+    }
+}
+# define signal ext_signal
+#endif
+
+int
+sigismember (const sigset_t *set, int sig)
+{
+  if (sig >= 0 && sig < NSIG)
+    {
+      #ifdef SIGABRT_COMPAT
+      if (sig == SIGABRT_COMPAT)
+        sig = SIGABRT;
+      #endif
+
+      return (*set >> sig) & 1;
+    }
+  else
+    return 0;
+}
+
+int
+sigemptyset (sigset_t *set)
+{
+  *set = 0;
+  return 0;
+}
+
+int
+sigaddset (sigset_t *set, int sig)
+{
+  if (sig >= 0 && sig < NSIG)
+    {
+      #ifdef SIGABRT_COMPAT
+      if (sig == SIGABRT_COMPAT)
+        sig = SIGABRT;
+      #endif
+
+      *set |= 1U << sig;
+      return 0;
+    }
+  else
+    {
+      errno = EINVAL;
+      return -1;
+    }
+}
+
+int
+sigdelset (sigset_t *set, int sig)
+{
+  if (sig >= 0 && sig < NSIG)
+    {
+      #ifdef SIGABRT_COMPAT
+      if (sig == SIGABRT_COMPAT)
+        sig = SIGABRT;
+      #endif
+
+      *set &= ~(1U << sig);
+      return 0;
+    }
+  else
+    {
+      errno = EINVAL;
+      return -1;
+    }
+}
+
+
+int
+sigfillset (sigset_t *set)
+{
+  *set = ((2U << (NSIG - 1)) - 1) & ~ SIGABRT_COMPAT_MASK;
+  return 0;
+}
+
+/* Set of currently blocked signals.  */
+static volatile sigset_t blocked_set /* = 0 */;
+
+/* Set of currently blocked and pending signals.  */
+static volatile sig_atomic_t pending_array[NSIG] /* = { 0 } */;
+
+/* Signal handler that is installed for blocked signals.  */
+static void
+blocked_handler (int sig)
+{
+  /* Reinstall the handler, in case the signal occurs multiple times
+     while blocked.  There is an inherent race where an asynchronous
+     signal in between when the kernel uninstalled the handler and
+     when we reinstall it will trigger the default handler; oh
+     well.  */
+  signal (sig, blocked_handler);
+  if (sig >= 0 && sig < NSIG)
+    pending_array[sig] = 1;
+}
+
+int
+sigpending (sigset_t *set)
+{
+  sigset_t pending = 0;
+  int sig;
+
+  for (sig = 0; sig < NSIG; sig++)
+    if (pending_array[sig])
+      pending |= 1U << sig;
+  *set = pending;
+  return 0;
+}
+
+/* The previous signal handlers.
+   Only the array elements corresponding to blocked signals are relevant.  */
+static volatile handler_t old_handlers[NSIG];
+
+int
+sigprocmask (int operation, const sigset_t *set, sigset_t *old_set)
+{
+  if (old_set != NULL)
+    *old_set = blocked_set;
+
+  if (set != NULL)
+    {
+      sigset_t new_blocked_set;
+      sigset_t to_unblock;
+      sigset_t to_block;
+
+      switch (operation)
+        {
+        case SIG_BLOCK:
+          new_blocked_set = blocked_set | *set;
+          break;
+        case SIG_SETMASK:
+          new_blocked_set = *set;
+          break;
+        case SIG_UNBLOCK:
+          new_blocked_set = blocked_set & ~*set;
+          break;
+        default:
+          errno = EINVAL;
+          return -1;
+        }
+      to_unblock = blocked_set & ~new_blocked_set;
+      to_block = new_blocked_set & ~blocked_set;
+
+      if (to_block != 0)
+        {
+          int sig;
+
+          for (sig = 0; sig < NSIG; sig++)
+            if ((to_block >> sig) & 1)
+              {
+                pending_array[sig] = 0;
+                if ((old_handlers[sig] = signal (sig, blocked_handler)) != SIG_ERR)
+                  blocked_set |= 1U << sig;
+              }
+        }
+
+      if (to_unblock != 0)
+        {
+          sig_atomic_t received[NSIG];
+          int sig;
+
+          for (sig = 0; sig < NSIG; sig++)
+            if ((to_unblock >> sig) & 1)
+              {
+                if (signal (sig, old_handlers[sig]) != blocked_handler)
+                  /* The application changed a signal handler while the signal
+                     was blocked, bypassing our rpl_signal replacement.
+                     We don't support this.  */
+                  abort ();
+                received[sig] = pending_array[sig];
+                blocked_set &= ~(1U << sig);
+                pending_array[sig] = 0;
+              }
+            else
+              received[sig] = 0;
+
+          for (sig = 0; sig < NSIG; sig++)
+            if (received[sig])
+              raise (sig);
+        }
+    }
+  return 0;
+}
+
+/* Install the handler FUNC for signal SIG, and return the previous
+   handler.  */
+handler_t
+rpl_signal (int sig, handler_t handler)
+{
+  /* We must provide a wrapper, so that a user can query what handler
+     they installed even if that signal is currently blocked.  */
+  if (sig >= 0 && sig < NSIG && sig != SIGKILL && sig != SIGSTOP
+      && handler != SIG_ERR)
+    {
+      #ifdef SIGABRT_COMPAT
+      if (sig == SIGABRT_COMPAT)
+        sig = SIGABRT;
+      #endif
+
+      if (blocked_set & (1U << sig))
+        {
+          /* POSIX states that sigprocmask and signal are both
+             async-signal-safe.  This is not true of our
+             implementation - there is a slight data race where an
+             asynchronous interrupt on signal A can occur after we
+             install blocked_handler but before we have updated
+             old_handlers for signal B, such that handler A can see
+             stale information if it calls signal(B).  Oh well -
+             signal handlers really shouldn't try to manipulate the
+             installed handlers of unrelated signals.  */
+          handler_t result = old_handlers[sig];
+          old_handlers[sig] = handler;
+          return result;
+        }
+      else
+        return signal (sig, handler);
+    }
+  else
+    {
+      errno = EINVAL;
+      return SIG_ERR;
+    }
+}
+
+#if GNULIB_defined_SIGPIPE
+/* Raise the signal SIG.  */
+int
+rpl_raise (int sig)
+# undef raise
+{
+  switch (sig)
+    {
+    case SIGPIPE:
+      if (blocked_set & (1U << sig))
+        pending_array[sig] = 1;
+      else
+        {
+          handler_t handler = SIGPIPE_handler;
+          if (handler == SIG_DFL)
+            exit (128 + SIGPIPE);
+          else if (handler != SIG_IGN)
+            (*handler) (sig);
+        }
+      return 0;
+    default: /* System defined signal */
+      return raise (sig);
+    }
+}
+#endif
index fdf0fca..769ecf0 100644 (file)
 /* 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 <sys/socket.h>");
-     _GL_WARN_ON_USE (connect,
-                      "connect() used without including <sys/socket.h>");
-     _GL_WARN_ON_USE (accept,
-                      "accept() used without including <sys/socket.h>");
-     _GL_WARN_ON_USE (bind,
-                      "bind() used without including <sys/socket.h>");
-     _GL_WARN_ON_USE (getpeername,
-                      "getpeername() used without including <sys/socket.h>");
-     _GL_WARN_ON_USE (getsockname,
-                      "getsockname() used without including <sys/socket.h>");
-     _GL_WARN_ON_USE (getsockopt,
-                      "getsockopt() used without including <sys/socket.h>");
-     _GL_WARN_ON_USE (listen,
-                      "listen() used without including <sys/socket.h>");
-     _GL_WARN_ON_USE (recv,
-                      "recv() used without including <sys/socket.h>");
-     _GL_WARN_ON_USE (send,
-                      "send() used without including <sys/socket.h>");
-     _GL_WARN_ON_USE (recvfrom,
-                      "recvfrom() used without including <sys/socket.h>");
-     _GL_WARN_ON_USE (sendto,
-                      "sendto() used without including <sys/socket.h>");
-     _GL_WARN_ON_USE (setsockopt,
-                      "setsockopt() used without including <sys/socket.h>");
-     _GL_WARN_ON_USE (shutdown,
-                      "shutdown() used without including <sys/socket.h>");
-#   endif
+/* Hide some function declarations from <winsock2.h>.  */
+
+#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 <sys/socket.h>");
+    _GL_WARN_ON_USE (connect,
+                     "connect() used without including <sys/socket.h>");
+    _GL_WARN_ON_USE (accept,
+                     "accept() used without including <sys/socket.h>");
+    _GL_WARN_ON_USE (bind,
+                     "bind() used without including <sys/socket.h>");
+    _GL_WARN_ON_USE (getpeername,
+                     "getpeername() used without including <sys/socket.h>");
+    _GL_WARN_ON_USE (getsockname,
+                     "getsockname() used without including <sys/socket.h>");
+    _GL_WARN_ON_USE (getsockopt,
+                     "getsockopt() used without including <sys/socket.h>");
+    _GL_WARN_ON_USE (listen,
+                     "listen() used without including <sys/socket.h>");
+    _GL_WARN_ON_USE (recv,
+                     "recv() used without including <sys/socket.h>");
+    _GL_WARN_ON_USE (send,
+                     "send() used without including <sys/socket.h>");
+    _GL_WARN_ON_USE (recvfrom,
+                     "recvfrom() used without including <sys/socket.h>");
+    _GL_WARN_ON_USE (sendto,
+                     "sendto() used without including <sys/socket.h>");
+    _GL_WARN_ON_USE (setsockopt,
+                     "setsockopt() used without including <sys/socket.h>");
+    _GL_WARN_ON_USE (shutdown,
+                     "shutdown() used without including <sys/socket.h>");
 #  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 <sys/select.h>");
-#   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 <sys/select.h>");
 #  endif
 # endif
 #endif
index 4d8450f..7e49ddd 100644 (file)
@@ -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 <unistd.h>]],
              [[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],
index 004c01a..6c94e37 100644 (file)
@@ -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
index d25e2cc..dfa0f66 100644 (file)
@@ -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 <pthread.h>
+                    #include <signal.h>
+                  ]],
+                  [[return pthread_sigmask (0, (sigset_t *) 0, (sigset_t *) 0);]])
+               ],
+               [gl_cv_func_pthread_sigmask_in_LIBMULTITHREAD=yes],
+               [gl_cv_func_pthread_sigmask_in_LIBMULTITHREAD=no])
+             LIBS="$gl_save_LIBS"
+            ])
+          if test $gl_cv_func_pthread_sigmask_in_LIBMULTITHREAD = yes; then
+            dnl pthread_sigmask is available with -lpthread.
+            LIB_PTHREAD_SIGMASK="$LIBMULTITHREAD"
+          else
+            dnl pthread_sigmask is not available at all.
+            HAVE_PTHREAD_SIGMASK=0
+          fi
+        else
+          dnl pthread_sigmask is not available at all.
+          HAVE_PTHREAD_SIGMASK=0
+        fi
+      fi
     else
-      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".
 ])
index 53972fb..b9536fb 100644 (file)
@@ -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 (file)
index 0000000..15b7425
--- /dev/null
@@ -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], [:])
index f628c32..f68fa5c 100644 (file)
@@ -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)