Browse Source

Once again, rework the signal handling to be even more correct. We no
longer segfault when running test/signal/sigchld.c, which exposed a bit
of a rats nest. The problem ended up being a erroneous syscall
defination, but in the process of finding that out, I scrubbed things
up nicely and adapted things to use the rt_ signals if they are
available. This now passes all the signal tests.
-Erik

Eric Andersen 23 years ago
parent
commit
b88ff80f70

+ 5 - 4
libc/signal/Makefile

@@ -24,10 +24,11 @@
 TOPDIR=../../
 include $(TOPDIR)Rules.mak
 
-CSRC=bsd_sig.c raise.c sigblock.c siggetmask.c sigjmp.c signal.c sigintr.c\
-	sigpause.c sigstmsk.c killpg.c allocrtsig.c sigsetops.c \
-	sigaddset.c sigandset.c sigdelset.c sigfillset.c sigorset.c \
-	sigempty.c sighold.c sigisempty.c sigismem.c sigrelse.c sysv_signal.c
+CSRC= allocrtsig.c killpg.c raise.c sigaction.c sigaddset.c sigandset.c \
+	sigblock.c sigdelset.c sigempty.c sigfillset.c siggetmask.c sighold.c \
+	sigignore.c sigintr.c sigisempty.c sigismem.c sigjmp.c signal.c \
+	sigorset.c sigpause.c sigrelse.c sigset.c sigsetmask.c sigsetops.c \
+	sigsuspend.c sysv_signal.c
 COBJS=$(patsubst %.c,%.o, $(CSRC))
 
 OBJS=$(COBJS)

+ 69 - 23
libc/signal/allocrtsig.c

@@ -1,36 +1,82 @@
-/*
- * Ignore/stub out real-time signal allocation.
- *
- * Copyright (C) 2001 by Lineo, inc. and Erik Andersen
- * Copyright (C) 2001 by Erik Andersen <andersen@uclibc.org>
- * Written by Erik Andersen <andersen@uclibc.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 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 Library General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
+/* Handle real-time signal allocation.
+   Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #include <signal.h>
+#include <sys/types.h>
+#include <sys/syscall.h>
+
+
+/* Only enable rt signals when it is supported at compile time */
+#ifdef __NR_rt_sigaction
+/* In these variables we keep track of the used variables.  If the
+   platform does not support any real-time signals we will define the
+   values to some unreasonable value which will signal failing of all
+   the functions below.  */
+
+static int current_rtmin = __SIGRTMIN;
+static int current_rtmax = __SIGRTMAX;
+
 
+
+#ifdef _POSIX_THREADS
+/* Allocate real-time signal with highest/lowest available
+   priority.  Please note that we don't use a lock since we assume
+   this function to be called at program start.  */
+int __libc_allocate_rtsig (int high)
+{
+    if (current_rtmin > current_rtmax)
+	/* We don't have anymore signals available.  */
+	return -1;
+
+    return high ? current_rtmin++ : current_rtmax--;
+}
+#endif
+
+/* Return number of available real-time signal with highest priority.  */
 int __libc_current_sigrtmin (void)
 {
-  return -1;
+    return current_rtmin;
 }
 
+/* Return number of available real-time signal with lowest priority.  */
 int __libc_current_sigrtmax (void)
+{
+    return current_rtmax;
+}
+
+#else
+
+#ifdef _POSIX_THREADS
+int __libc_allocate_rtsig (int high)
+{
+    return -1;
+}
+#endif
+
+int __libc_current_sigrtmin (void)
 {
   return -1;
 }
 
+int __libc_current_sigrtmax (void)
+{
+  return -1;
+}
+#endif

+ 0 - 34
libc/signal/bsd_sig.c

@@ -1,34 +0,0 @@
-#define __USE_BSD_SIGNAL
-
-#include <signal.h>
-
-#undef signal
-
-/* The `sig' bit is set if the interrupt on it
- * is enabled via siginterrupt (). */
-extern sigset_t _sigintr;
-
-__sighandler_t
-__bsd_signal (int sig, __sighandler_t handler)
-{
-  int ret;
-  struct sigaction action, oaction;
-  action.sa_handler = handler;
-  __sigemptyset (&action.sa_mask);
-  if (!__sigismember (&_sigintr, sig)) {
-#ifdef SA_RESTART
-    action.sa_flags = SA_RESTART;
-#else
-    action.sa_flags = 0;
-#endif
-  }
-  else {
-#ifdef SA_INTERRUPT
-    action.sa_flags = SA_INTERRUPT;
-#else
-    action.sa_flags = 0;
-#endif
-  }
-  ret = sigaction (sig, &action, &oaction); 
-  return (ret == -1) ? SIG_ERR : oaction.sa_handler;
-}

+ 5 - 6
libc/signal/killpg.c

@@ -23,14 +23,13 @@
 /* Send SIG to all processes in process group PGRP.
    If PGRP is zero, send SIG to all processes in
    the current process's process group.  */
-int
-killpg ( __pid_t pgrp, int sig)
+int killpg ( __pid_t pgrp, int sig)
 {
-  if (pgrp < 0)
+    if (pgrp < 0)
     {
-      __set_errno (EINVAL);
-      return -1;
+	__set_errno (EINVAL);
+	return -1;
     }
 
-  return kill (- pgrp, sig);
+    return kill (- pgrp, sig);
 }

+ 2 - 3
libc/signal/raise.c

@@ -7,9 +7,8 @@
 #include <signal.h>
 #include <sys/types.h>
 
-int raise(signo)
-int signo;
+int raise(int signo)
 {
-	return kill(getpid(), signo);
+    return kill(getpid(), signo);
 }
 

+ 177 - 0
libc/signal/sigaction.c

@@ -0,0 +1,177 @@
+/* Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <errno.h>
+#include <signal.h>
+#include <string.h>
+#include <sys/syscall.h>
+
+
+/* The difference here is that the sigaction structure used in the
+   kernel is not the same as we use in the libc.  Therefore we must
+   translate it here.  */
+#define HAVE_SA_RESTORER
+
+
+#if defined(__hppa__)
+#undef HAVE_SA_RESTORER
+/* This is the sigaction struction from the Linux 2.1.20 kernel.  */
+/* Blah.  This is bogus.  We don't ever use it. */
+struct old_kernel_sigaction {
+    __sighandler_t k_sa_handler;
+    unsigned long sa_mask;
+    unsigned long sa_flags;
+};
+
+/* This is the sigaction structure from the Linux 2.1.68 kernel.  */
+struct kernel_sigaction {
+    __sighandler_t k_sa_handler;
+    unsigned long sa_flags;
+    sigset_t sa_mask;
+};
+#elif defined(__mips__)
+/* This is the sigaction structure from the Linux 2.1.24 kernel.  */
+#include <sgidefs.h>
+struct old_kernel_sigaction {
+    unsigned int    sa_flags;
+    __sighandler_t  k_sa_handler;
+    unsigned long   sa_mask;
+    unsigned int    __pad0[3]; /* reserved, keep size constant */
+
+    /* Abi says here follows reserved int[2] */
+    void            (*sa_restorer)(void);
+#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2)
+    /* For 32 bit code we have to pad struct sigaction to get 
+     * constant size for the ABI */
+    int             pad1[1]; /* reserved */
+#endif
+};
+
+#define _KERNEL_NSIG           128
+#define _KERNEL_NSIG_BPW       32
+#define _KERNEL_NSIG_WORDS     (_KERNEL_NSIG / _KERNEL_NSIG_BPW)
+
+typedef struct {
+    unsigned long sig[_KERNEL_NSIG_WORDS];
+} kernel_sigset_t;
+
+/* This is the sigaction structure from the Linux 2.1.68 kernel.  */
+struct kernel_sigaction {
+    unsigned int    sa_flags;
+    __sighandler_t  k_sa_handler;
+    kernel_sigset_t sa_mask;
+    void            (*sa_restorer)(void);
+    int             s_resv[1]; /* reserved */
+};
+#else
+
+#undef HAVE_SA_RESTORER
+/* This is the sigaction struction from the Linux 2.1.20 kernel.  */
+struct old_kernel_sigaction {
+    __sighandler_t k_sa_handler;
+    unsigned long sa_mask;
+    unsigned int sa_flags;
+};
+
+/* This is the sigaction structure from the Linux 2.1.68 kernel.  */
+
+struct kernel_sigaction {
+    __sighandler_t k_sa_handler;
+    unsigned int sa_flags;
+    sigset_t sa_mask;
+};
+#endif
+
+
+
+#if defined __NR_rt_sigaction
+
+extern int __rt_sigaction (int, const struct kernel_sigaction *__unbounded,
+				   struct kernel_sigaction *__unbounded, size_t);
+
+/* If ACT is not NULL, change the action for SIG to *ACT.
+   If OACT is not NULL, put the old action for SIG in *OACT.  */
+int sigaction (int sig, const struct sigaction *act, struct sigaction *oact)
+{
+    int result;
+    struct kernel_sigaction kact, koact;
+
+    if (act) {
+	kact.k_sa_handler = act->sa_handler;
+	memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t));
+	kact.sa_flags = act->sa_flags;
+# ifdef HAVE_SA_RESTORER
+	kact.sa_restorer = act->sa_restorer;
+# endif
+    }
+
+    /* XXX The size argument hopefully will have to be changed to the
+       real size of the user-level sigset_t.  */
+    result = __rt_sigaction(sig, act ? __ptrvalue (&kact) : NULL,
+	    oact ? __ptrvalue (&koact) : NULL, _NSIG / 8);
+
+    if (oact && result >= 0) {
+	oact->sa_handler = koact.k_sa_handler;
+	memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t));
+	oact->sa_flags = koact.sa_flags;
+# ifdef HAVE_SA_RESTORER
+	oact->sa_restorer = koact.sa_restorer;
+# endif
+    }
+    return result;
+}
+
+
+
+
+
+#else
+
+extern int __sigaction (int, const struct old_kernel_sigaction *__unbounded,
+				struct old_kernel_sigaction *__unbounded);
+
+/* If ACT is not NULL, change the action for SIG to *ACT.
+   If OACT is not NULL, put the old action for SIG in *OACT.  */
+int sigaction (int sig, const struct sigaction *act, struct sigaction *oact)
+{
+    struct old_kernel_sigaction k_sigact, k_osigact;
+    int result;
+
+    if (act) {
+	k_sigact.k_sa_handler = act->sa_handler;
+	k_sigact.sa_mask = act->sa_mask.__val[0];
+	k_sigact.sa_flags = act->sa_flags;
+# ifdef HAVE_SA_RESTORER
+	k_sigact.sa_restorer = act->sa_restorer;
+# endif
+    }
+    result = sigaction(sig, act ? __ptrvalue (&k_sigact) : NULL,
+	    oact ? __ptrvalue (&k_osigact) : NULL);
+
+    if (oact && result >= 0) {
+	oact->sa_handler = k_osigact.k_sa_handler;
+	oact->sa_mask.__val[0] = k_osigact.sa_mask;
+	oact->sa_flags = k_osigact.sa_flags;
+# ifdef HAVE_SA_RESTORER
+	oact->sa_restorer = k_osigact.sa_restorer;
+# endif
+    }
+    return result;
+}
+
+#endif

+ 13 - 16
libc/signal/sigaddset.c

@@ -2,33 +2,30 @@
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
 
    The GNU C Library 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
-   Lesser General Public License for more details.
+   Library General Public License for more details.
 
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #include "sigsetops.h"
 
 /* Add SIGNO to SET.  */
-int
-sigaddset (set, signo)
-     sigset_t *set;
-     int signo;
+int sigaddset (sigset_t *set, int signo)
 {
-  if (set == NULL || signo <= 0 || signo >= NSIG)
+    if (set == NULL || signo <= 0 || signo >= NSIG)
     {
-      __set_errno (EINVAL);
-      return -1;
+	__set_errno (EINVAL);
+	return -1;
     }
 
-  return __sigaddset (set, signo);
+    return __sigaddset (set, signo);
 }

+ 13 - 17
libc/signal/sigandset.c

@@ -2,19 +2,19 @@
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
 
    The GNU C Library 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
-   Lesser General Public License for more details.
+   Library General Public License for more details.
 
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #include <errno.h>
 #define __USE_GNU
@@ -23,17 +23,13 @@
 #include <stddef.h>
 
 /* Combine sets LEFT and RIGHT by logical AND and place result in DEST.  */
-int
-sigandset (dest, left, right)
-     sigset_t *dest;
-     const sigset_t *left;
-     const sigset_t *right;
+int sigandset (sigset_t *dest, const sigset_t *left, const sigset_t *right)
 {
-  if (dest == NULL || left == NULL || right == NULL)
+    if (dest == NULL || left == NULL || right == NULL)
     {
-      __set_errno (EINVAL);
-      return -1;
+	__set_errno (EINVAL);
+	return -1;
     }
 
-  return __sigandset (dest, left, right);
+    return __sigandset (dest, left, right);
 }

+ 25 - 26
libc/signal/sigblock.c

@@ -21,36 +21,35 @@
 #include <signal.h>
 
 /* Block signals in MASK, returning the old mask.  */
-int sigblock (mask)
-     int mask;
+int sigblock (int mask)
 {
-  register unsigned int sig;
-  sigset_t set, oset;
-
-  if (__sigemptyset (&set) < 0)
-    return -1;
-
-  if (sizeof (mask) == sizeof (set))
-    *(int *) &set = mask;
-  else if (sizeof (unsigned long int) == sizeof (set))
-    *(unsigned long int *) &set = (unsigned int) mask;
-  else
-    for (sig = 1; sig < NSIG && sig <= sizeof (mask) * 8; ++sig)
-      if ((mask & sigmask (sig)) && __sigaddset (&set, sig) < 0)
+    register unsigned int sig;
+    sigset_t set, oset;
+
+    if (__sigemptyset (&set) < 0)
 	return -1;
 
-  if (sigprocmask (SIG_BLOCK, &set, &oset) < 0)
-    return -1;
+    if (sizeof (mask) == sizeof (set))
+	*(int *) &set = mask;
+    else if (sizeof (unsigned long int) == sizeof (set))
+	*(unsigned long int *) &set = (unsigned int) mask;
+    else
+	for (sig = 1; sig < NSIG && sig <= sizeof (mask) * 8; ++sig)
+	    if ((mask & sigmask (sig)) && __sigaddset (&set, sig) < 0)
+		return -1;
+
+    if (sigprocmask (SIG_BLOCK, &set, &oset) < 0)
+	return -1;
 
-  if (sizeof (mask) == sizeof (oset))
-    mask = *(int *) &oset;
-  else if (sizeof (unsigned long int) == sizeof (oset))
-    mask = *(unsigned long int*) &oset;
-  else
-    for (sig = 1, mask = 0; sig < NSIG && sig <= sizeof (mask) * 8; ++sig)
-      if (__sigismember (&oset, sig))
-	mask |= sigmask (sig);
+    if (sizeof (mask) == sizeof (oset))
+	mask = *(int *) &oset;
+    else if (sizeof (unsigned long int) == sizeof (oset))
+	mask = *(unsigned long int*) &oset;
+    else
+	for (sig = 1, mask = 0; sig < NSIG && sig <= sizeof (mask) * 8; ++sig)
+	    if (__sigismember (&oset, sig))
+		mask |= sigmask (sig);
 
-  return mask;
+    return mask;
 }
 

+ 13 - 16
libc/signal/sigdelset.c

@@ -2,33 +2,30 @@
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
 
    The GNU C Library 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
-   Lesser General Public License for more details.
+   Library General Public License for more details.
 
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #include "sigsetops.h"
 
 /* Add SIGNO to SET.  */
-int
-sigdelset (set, signo)
-     sigset_t *set;
-     int signo;
+int sigdelset (sigset_t *set, int signo)
 {
-  if (set == NULL || signo <= 0 || signo >= NSIG)
+    if (set == NULL || signo <= 0 || signo >= NSIG)
     {
-      __set_errno (EINVAL);
-      return -1;
+	__set_errno (EINVAL);
+	return -1;
     }
 
-  return __sigdelset (set, signo);
+    return __sigdelset (set, signo);
 }

+ 14 - 16
libc/signal/sigempty.c

@@ -2,36 +2,34 @@
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
 
    The GNU C Library 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
-   Lesser General Public License for more details.
+   Library General Public License for more details.
 
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #include <errno.h>
 #include <signal.h>
 #include <string.h>
 
 /* Clear all signals from SET.  */
-int
-sigemptyset (set)
-     sigset_t *set;
+int sigemptyset (sigset_t *set)
 {
-  if (set == NULL)
+    if (set == NULL)
     {
-      __set_errno (EINVAL);
-      return -1;
+	__set_errno (EINVAL);
+	return -1;
     }
 
-  memset (set, 0, sizeof (sigset_t));
+    memset (set, 0, sizeof (sigset_t));
 
-  return 0;
+    return 0;
 }

+ 14 - 16
libc/signal/sigfillset.c

@@ -2,36 +2,34 @@
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
 
    The GNU C Library 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
-   Lesser General Public License for more details.
+   Library General Public License for more details.
 
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #include <errno.h>
 #include <signal.h>
 #include <string.h>
 
 /* Set all signals in SET.  */
-int
-sigfillset (set)
-     sigset_t *set;
+int sigfillset (sigset_t *set)
 {
-  if (set == NULL)
+    if (set == NULL)
     {
-      __set_errno (EINVAL);
-      return -1;
+	__set_errno (EINVAL);
+	return -1;
     }
 
-  memset (set, 0xff, sizeof (sigset_t));
+    memset (set, 0xff, sizeof (sigset_t));
 
-  return 0;
+    return 0;
 }

+ 10 - 13
libc/signal/siggetmask.c

@@ -3,28 +3,25 @@
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
 
    The GNU C Library 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
-   Lesser General Public License for more details.
+   Library General Public License for more details.
 
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #define __USE_GNU
 #include <signal.h>
 
-int
-siggetmask (void)
+int siggetmask (void)
 {
-  return sigblock (0);
+    return sigblock (0);
 }
 
-link_warning (siggetmask,
-	      "warning: `siggetmask' is obsolete; `sigprocmask' is best")

+ 18 - 20
libc/signal/sighold.c

@@ -4,39 +4,37 @@
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
    The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
 
    The GNU C Library 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
-   Lesser General Public License for more details.
+   Library General Public License for more details.
 
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #define __need_NULL
 #include <stddef.h>
 #define __USE_GNU
 #include <signal.h>
 
-int
-sighold (sig)
-     int sig;
+int sighold (int sig)
 {
-  sigset_t set;
+    sigset_t set;
 
-  /* Retrieve current signal set.  */
-  if (sigprocmask (SIG_SETMASK, NULL, &set) < 0)
-    return -1;
+    /* Retrieve current signal set.  */
+    if (sigprocmask (SIG_SETMASK, NULL, &set) < 0)
+	return -1;
 
-  /* Add the specified signal.  */
-  if (__sigaddset (&set, sig) < 0)
-    return -1;
+    /* Add the specified signal.  */
+    if (__sigaddset (&set, sig) < 0)
+	return -1;
 
-  /* Set the new mask.  */
-  return sigprocmask (SIG_SETMASK, &set, NULL);
+    /* Set the new mask.  */
+    return sigprocmask (SIG_SETMASK, &set, NULL);
 }

+ 36 - 0
libc/signal/sigignore.c

@@ -0,0 +1,36 @@
+/* Set the disposition of SIG to SIG_IGN.
+   Copyright (C) 1998 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <errno.h>
+#define __need_NULL
+#include <stddef.h>
+#include <signal.h>
+
+int sigignore (int sig)
+{
+    struct sigaction act;
+
+    act.sa_handler = SIG_IGN;
+    if (__sigemptyset (&act.sa_mask) < 0)
+	return -1;
+    act.sa_flags = 0;
+
+    return sigaction (sig, &act, NULL);
+}

+ 16 - 19
libc/signal/sigintr.c

@@ -23,35 +23,32 @@
 /* If INTERRUPT is nonzero, make signal SIG interrupt system calls
    (causing them to fail with EINTR); if INTERRUPT is zero, make system
    calls be restarted after signal SIG.  */
-int
-siginterrupt (sig, interrupt)
-     int sig;
-     int interrupt;
+int siginterrupt (int sig, int interrupt)
 {
 #ifdef	SA_RESTART
-  extern sigset_t _sigintr;	/* Defined in signal.c.  */
-  struct sigaction action;
+    extern sigset_t _sigintr;	/* Defined in signal.c.  */
+    struct sigaction action;
 
-  if (sigaction (sig, (struct sigaction *) NULL, &action) < 0)
-    return -1;
+    if (sigaction (sig, (struct sigaction *) NULL, &action) < 0)
+	return -1;
 
-  if (interrupt)
+    if (interrupt)
     {
-      sigaddset (&_sigintr, sig);
-      action.sa_flags &= ~SA_RESTART;
+	__sigaddset (&_sigintr, sig);
+	action.sa_flags &= ~SA_RESTART;
     }
-  else
+    else
     {
-      sigdelset (&_sigintr, sig);
-      action.sa_flags |= SA_RESTART;
+	__sigdelset (&_sigintr, sig);
+	action.sa_flags |= SA_RESTART;
     }
 
-  if (sigaction (sig, &action, (struct sigaction *) NULL) < 0)
-    return -1;
+    if (sigaction (sig, &action, (struct sigaction *) NULL) < 0)
+	return -1;
 
-  return 0;
+    return 0;
 #else
-  __set_errno (ENOSYS);
-  return -1;
+    __set_errno (ENOSYS);
+    return -1;
 #endif
 }

+ 12 - 14
libc/signal/sigisempty.c

@@ -2,19 +2,19 @@
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
 
    The GNU C Library 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
-   Lesser General Public License for more details.
+   Library General Public License for more details.
 
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #include <errno.h>
 #define __USE_GNU
@@ -23,14 +23,12 @@
 #include <stddef.h>
 
 /* Test whether SET is empty.  */
-int
-sigisemptyset (set)
-     const sigset_t *set;
+int sigisemptyset (const sigset_t *set)
 {
-  if (set == NULL)
+    if (set == NULL)
     {
-      __set_errno (EINVAL);
-      return -1;
+	__set_errno (EINVAL);
+	return -1;
     }
 
     return __sigisemptyset (set);

+ 13 - 16
libc/signal/sigismem.c

@@ -2,33 +2,30 @@
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
 
    The GNU C Library 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
-   Lesser General Public License for more details.
+   Library General Public License for more details.
 
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #include "sigsetops.h"
 
 /* Return 1 if SIGNO is in SET, 0 if not.  */
-int
-sigismember (set, signo)
-     const sigset_t *set;
-     int signo;
+int sigismember (const sigset_t *set, int signo)
 {
-  if (set == NULL || signo <= 0 || signo >= NSIG)
+    if (set == NULL || signo <= 0 || signo >= NSIG)
     {
-      __set_errno (EINVAL);
-      return -1;
+	__set_errno (EINVAL);
+	return -1;
     }
 
-  return __sigismember (set, signo);
+    return __sigismember (set, signo);
 }

+ 43 - 17
libc/signal/signal.c

@@ -1,23 +1,49 @@
-#include <string.h>
+/* BSD-like signal function.
+   Copyright (C) 1991, 1992, 1996, 1997, 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <errno.h>
 #include <signal.h>
 
-/* Global variable */
-sigset_t _sigintr;              /* Set by siginterrupt.  */
 
-__sighandler_t
-__signal (int sig, __sighandler_t handler, int flags)
-{
-  int ret;
-  struct sigaction action, oaction;
-  memset(&action, 0, sizeof(struct sigaction));
-  action.sa_handler = handler;
-  action.sa_flags = flags;
-  ret = sigaction (sig, &action, &oaction); 
-  return (ret == -1) ? SIG_ERR : oaction.sa_handler;
-}
+sigset_t _sigintr;		/* Set by siginterrupt.  */
 
-__sighandler_t
-signal (int sig, __sighandler_t handler)
+/* Set the handler for the signal SIG to HANDLER,
+   returning the old handler, or SIG_ERR on error.  */
+__sighandler_t bsd_signal (int sig, __sighandler_t handler)
 {
-  return __signal(sig, handler, (SA_ONESHOT | SA_NOMASK | SA_INTERRUPT) & ~SA_RESTART);
+    struct sigaction act, oact;
+
+    /* Check signal extents to protect __sigismember.  */
+    if (handler == SIG_ERR || sig < 1 || sig >= NSIG)
+    {
+	__set_errno (EINVAL);
+	return SIG_ERR;
+    }
+
+    act.sa_handler = handler;
+    if (__sigemptyset (&act.sa_mask) < 0
+	    || __sigaddset (&act.sa_mask, sig) < 0)
+	return SIG_ERR;
+    act.sa_flags = __sigismember (&_sigintr, sig) ? 0 : SA_RESTART;
+    if (sigaction (sig, &act, &oact) < 0)
+	return SIG_ERR;
+
+    return oact.sa_handler;
 }
+weak_alias (bsd_signal, signal)

+ 13 - 17
libc/signal/sigorset.c

@@ -2,19 +2,19 @@
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
 
    The GNU C Library 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
-   Lesser General Public License for more details.
+   Library General Public License for more details.
 
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #include <errno.h>
 #define __USE_GNU
@@ -23,17 +23,13 @@
 #include <stddef.h>
 
 /* Combine sets LEFT and RIGHT by logical OR and place result in DEST.  */
-int
-sigorset (dest, left, right)
-     sigset_t *dest;
-     const sigset_t *left;
-     const sigset_t *right;
+int sigorset (sigset_t *dest, const sigset_t *left, const sigset_t *right)
 {
-  if (dest == NULL || left == NULL || right == NULL)
+    if (dest == NULL || left == NULL || right == NULL)
     {
-      __set_errno (EINVAL);
-      return -1;
+	__set_errno (EINVAL);
+	return -1;
     }
 
-  return __sigorset (dest, left, right);
+    return __sigorset (dest, left, right);
 }

+ 18 - 20
libc/signal/sigrelse.c

@@ -4,39 +4,37 @@
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
    The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
 
    The GNU C Library 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
-   Lesser General Public License for more details.
+   Library General Public License for more details.
 
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #define __need_NULL
 #include <stddef.h>
 #define __USE_GNU
 #include <signal.h>
 
-int
-sigrelse (sig)
-     int sig;
+int sigrelse (int sig)
 {
-  sigset_t set;
+    sigset_t set;
 
-  /* Retrieve current signal set.  */
-  if (sigprocmask (SIG_SETMASK, NULL, &set) < 0)
-    return -1;
+    /* Retrieve current signal set.  */
+    if (sigprocmask (SIG_SETMASK, NULL, &set) < 0)
+	return -1;
 
-  /* Remove the specified signal.  */
-  if (__sigdelset (&set, sig) < 0)
-    return -1;
+    /* Remove the specified signal.  */
+    if (__sigdelset (&set, sig) < 0)
+	return -1;
 
-  /* Set the new mask.  */
-  return sigprocmask (SIG_SETMASK, &set, NULL);
+    /* Set the new mask.  */
+    return sigprocmask (SIG_SETMASK, &set, NULL);
 }

+ 78 - 0
libc/signal/sigset.c

@@ -0,0 +1,78 @@
+/* Copyright (C) 1998, 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <errno.h>
+#define __need_NULL
+#include <stddef.h>
+#include <signal.h>
+
+
+/* Set the disposition for SIG.  */
+__sighandler_t sigset (int sig, __sighandler_t disp)
+{
+    struct sigaction act, oact;
+    sigset_t set;
+
+#ifdef SIG_HOLD
+    /* Handle SIG_HOLD first.  */
+    if (disp == SIG_HOLD)
+    {
+	/* Create an empty signal set.  */
+	if (__sigemptyset (&set) < 0)
+	    return SIG_ERR;
+
+	/* Add the specified signal.  */
+	if (__sigaddset (&set, sig) < 0)
+	    return SIG_ERR;
+
+	/* Add the signal set to the current signal mask.  */
+	if (__sigprocmask (SIG_BLOCK, &set, NULL) < 0)
+	    return SIG_ERR;
+
+	return SIG_HOLD;
+    }
+#endif	/* SIG_HOLD */
+
+    /* Check signal extents to protect __sigismember.  */
+    if (disp == SIG_ERR || sig < 1 || sig >= NSIG)
+    {
+	__set_errno (EINVAL);
+	return SIG_ERR;
+    }
+
+    act.sa_handler = disp;
+    if (__sigemptyset (&act.sa_mask) < 0)
+	return SIG_ERR;
+    act.sa_flags = 0;
+    if (sigaction (sig, &act, &oact) < 0)
+	return SIG_ERR;
+
+    /* Create an empty signal set.  */
+    if (__sigemptyset (&set) < 0)
+	return SIG_ERR;
+
+    /* Add the specified signal.  */
+    if (__sigaddset (&set, sig) < 0)
+	return SIG_ERR;
+
+    /* Remove the signal set from the current signal mask.  */
+    if (sigprocmask (SIG_UNBLOCK, &set, NULL) < 0)
+	return SIG_ERR;
+
+    return oact.sa_handler;
+}

+ 53 - 0
libc/signal/sigsetmask.c

@@ -0,0 +1,53 @@
+/* Copyright (C) 1991,1994,1995,1996,1997,2001 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <errno.h>
+#include <signal.h>
+
+/* Set the mask of blocked signals to MASK, returning the old mask.  */
+int sigsetmask (int mask)
+{
+    register unsigned int sig;
+    sigset_t set, oset;
+
+    if (__sigemptyset (&set) < 0)
+	return -1;
+
+    if (sizeof (mask) == sizeof (set))
+	*(int *) &set = mask;
+    else if (sizeof (unsigned long int) == sizeof (set))
+	*(unsigned long int *) &set = (unsigned int) mask;
+    else
+	for (sig = 1; sig < NSIG && sig <= sizeof (mask) * 8; ++sig)
+	    if ((mask & sigmask (sig)) && __sigaddset (&set, sig) < 0)
+		return -1;
+
+    if (sigprocmask (SIG_SETMASK, &set, &oset) < 0)
+	return -1;
+
+    if (sizeof (mask) == sizeof (oset))
+	mask = *(int *) &oset;
+    else if (sizeof (unsigned long int) == sizeof (oset))
+	mask = *(unsigned long int *) &oset;
+    else
+	for (sig = 1, mask = 0; sig < NSIG && sig <= sizeof (mask) * 8; ++sig)
+	    if (__sigismember (&oset, sig))
+		mask |= sigmask (sig);
+
+    return mask;
+}

+ 8 - 8
libc/signal/sigsetops.h

@@ -2,19 +2,19 @@
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
 
    The GNU C Library 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
-   Lesser General Public License for more details.
+   Library General Public License for more details.
 
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 /* Definitions relevant to functions that operate on `sigset_t's.  */
 

+ 0 - 46
libc/signal/sigstmsk.c

@@ -1,46 +0,0 @@
-/* Copyright (C) 1993 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The GNU C Library 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
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
-
-#include <stdlib.h>
-#include <errno.h>
-#include <signal.h>
-
-/* Set the mask of blocked signals to MASK, returning the old mask.  */
-int sigsetmask (int mask)
-{
-  register int sig;
-  sigset_t set, oset;
-
-  if (sigemptyset(&set) < 0)
-    return -1;
-  
-  for (sig = 1; sig < NSIG; ++sig)
-    if ((mask & sigmask(sig)) &&
-      sigaddset(&set, sig) < 0)
-      return -1;
-
-  if (sigprocmask(SIG_SETMASK, &set, &oset) < 0)
-    return -1;
-
-  mask = 0;
-  for (sig = 1; sig < NSIG; ++sig)
-    if (sigismember(&oset, sig) == 1)
-      mask |= sigmask(sig);
-
-  return mask;
-}

+ 49 - 0
libc/signal/sigsuspend.c

@@ -0,0 +1,49 @@
+/* Copyright (C) 1991, 1996, 1997, 1998 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <errno.h>
+#include <signal.h>
+#include <stddef.h>
+#include <unistd.h>
+
+
+/* Change the set of blocked signals to SET,
+   wait until a signal arrives, and restore the set of blocked signals.  */
+int __sigsuspend (const sigset_t *set)
+{
+    sigset_t oset;
+    int save;
+
+    if (set == NULL)
+    {
+	__set_errno (EINVAL);
+	return -1;
+    }
+
+    if (sigprocmask (SIG_SETMASK, set, &oset) < 0)
+	return -1;
+
+    (void) pause();
+    save = errno;
+
+    if (sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL) < 0)
+	return -1;
+
+    __set_errno (save);
+    return -1;
+}

+ 22 - 24
libc/signal/sysv_signal.c

@@ -2,25 +2,23 @@
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
 
    The GNU C Library 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
-   Lesser General Public License for more details.
+   Library General Public License for more details.
 
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #include <errno.h>
 #include <signal.h>
 
-#undef signal
-
 /* Tolerate non-threads versions of Posix */
 #ifndef SA_ONESHOT
 #define SA_ONESHOT 0
@@ -34,25 +32,25 @@
 
 /* Set the handler for the signal SIG to HANDLER,
    returning the old handler, or SIG_ERR on error.  */
-__sighandler_t __sysv_signal (int sig, __sighandler_t handler)
+__sighandler_t sysv_signal (int sig, __sighandler_t handler)
 {
-  struct sigaction act, oact;
+    struct sigaction act, oact;
 
-  /* Check signal extents to protect __sigismember.  */
-  if (handler == SIG_ERR || sig < 1 || sig >= NSIG)
+    /* Check signal extents to protect __sigismember.  */
+    if (handler == SIG_ERR || sig < 1 || sig >= NSIG)
     {
-      __set_errno (EINVAL);
-      return SIG_ERR;
+	__set_errno (EINVAL);
+	return SIG_ERR;
     }
 
-  act.sa_handler = handler;
-  if (__sigemptyset (&act.sa_mask) < 0)
-    return SIG_ERR;
-  act.sa_flags = SA_ONESHOT | SA_NOMASK | SA_INTERRUPT;
-  act.sa_flags &= ~SA_RESTART;
-  if (sigaction (sig, &act, &oact) < 0)
-    return SIG_ERR;
+    act.sa_handler = handler;
+    if (__sigemptyset (&act.sa_mask) < 0)
+	return SIG_ERR;
+    act.sa_flags = SA_ONESHOT | SA_NOMASK | SA_INTERRUPT;
+    act.sa_flags &= ~SA_RESTART;
+    if (sigaction (sig, &act, &oact) < 0)
+	return SIG_ERR;
 
-  return oact.sa_handler;
+    return oact.sa_handler;
 }
 

+ 65 - 15
libc/sysdeps/linux/common/syscalls.c

@@ -503,12 +503,15 @@ _syscall0(pid_t, setsid);
 #endif
 
 //#define __NR_sigaction        67
+#ifndef __NR_rt_sigaction
+#define __NR___sigaction __NR_sigaction
 #ifdef L_sigaction
 #include <signal.h>
 #undef sigaction
-_syscall3(int, sigaction, int, signum, const struct sigaction *, act,
+_syscall3(int, __sigaction, int, signum, const struct sigaction *, act,
 		  struct sigaction *, oldact);
 #endif
+#endif
 
 //#define __NR_sgetmask         68
 
@@ -527,24 +530,28 @@ _syscall2(int, setregid, gid_t, rgid, gid_t, egid);
 #endif
 
 //#define __NR_sigsuspend       72
-#define __NR__sigsuspend __NR_sigsuspend
+#ifndef __NR_rt_sigsuspend
+#define __NR___sigsuspend __NR_sigsuspend
 #ifdef L__sigsuspend
 #include <signal.h>
-#undef _sigsuspend
-_syscall1(int, _sigsuspend, unsigned long int, mask);
+#undef sigsuspend
+_syscall3(int, __sigsuspend, int a, unsigned long int b, unsigned long int, c);
 
 int sigsuspend (const sigset_t *set)
 {
-	return _sigsuspend(set->__val[0]);
+	return __sigsuspend(0, 0, set->__val[0]);
 }
 #endif
+#endif
 
 //#define __NR_sigpending       73
+#ifndef __NR_rt_sigpending
 #ifdef L_sigpending
 #include <signal.h>
 #undef sigpending
 _syscall1(int, sigpending, sigset_t *, set);
 #endif
+#endif
 
 //#define __NR_sethostname      74
 #ifdef L_sethostname
@@ -956,11 +963,13 @@ _syscall3(int, mprotect, void *, addr, size_t, len, int, prot);
 #endif
 
 //#define __NR_sigprocmask      126
+#ifndef __NR_rt_sigprocmask
 #ifdef L_sigprocmask
 #include <signal.h>
 #undef sigprocmask
-_syscall3(int, sigprocmask, int, how, const sigset_t *, set, sigset_t *,
-		  oldset);
+_syscall3(int, sigprocmask, int, how, const sigset_t *, set, 
+		sigset_t *, oldset);
+#endif
 #endif
 
 //#define __NR_create_module    127
@@ -1058,15 +1067,9 @@ _syscall3(int, getdents, int, fd, char *, dirp, size_t, count);
 #include <unistd.h>
 extern int _newselect(int n, fd_set *readfds, fd_set *writefds,
 					  fd_set *exceptfds, struct timeval *timeout);
-
 _syscall5(int, _newselect, int, n, fd_set *, readfds, fd_set *, writefds,
-		  fd_set *, exceptfds, struct timeval *, timeout);
-
-int select(int n, fd_set * readfds, fd_set * writefds, fd_set * exceptfds,
-		   struct timeval *timeout)
-{
-	return (_newselect(n, readfds, writefds, exceptfds, timeout));
-}
+		fd_set *, exceptfds, struct timeval *, timeout);
+weak_alias(_newselect, select);
 #endif
 
 //#define __NR_flock            143
@@ -1186,11 +1189,58 @@ _syscall3(int, poll, struct pollfd *, fds, unsigned long int, nfds, int, timeout
 //#define __NR_prctl                    172
 //#define __NR_rt_sigreturn             173
 //#define __NR_rt_sigaction             174
+#define __NR___rt_sigaction __NR_rt_sigaction
+#ifdef L___rt_sigaction
+#include <signal.h>
+#undef sigaction
+_syscall4(int, __rt_sigaction, int, signum, const struct sigaction *, act, 
+		struct sigaction *, oldact, size_t, size); 
+#endif
+
 //#define __NR_rt_sigprocmask           175
+#define __NR___rt_sigprocmask __NR_rt_sigprocmask
+#ifdef L___rt_sigprocmask
+#include <signal.h>
+#undef sigprocmask
+_syscall4(int, __rt_sigprocmask, int, how, const sigset_t *, set, 
+		sigset_t *, oldset, size_t, size);
+
+int sigprocmask(int how, const sigset_t *set, sigset_t *oldset) 
+{
+	  return __rt_sigprocmask(how, set, oldset, _NSIG/8);
+}
+
+#endif
+
 //#define __NR_rt_sigpending            176
+#define __NR___rt_sigpending __NR_rt_sigpending
+#ifdef L___rt_sigpending
+#include <signal.h>
+#undef sigpending
+_syscall2(int, __rt_sigpending, sigset_t *, set, size_t, size);
+
+int sigpending(sigset_t *set) 
+{
+	return __rt_sigpending(set, _NSIG/8);
+}
+#endif
+
 //#define __NR_rt_sigtimedwait          177
 //#define __NR_rt_sigqueueinfo          178
+
 //#define __NR_rt_sigsuspend            179
+#define __NR___rt_sigsuspend __NR_rt_sigsuspend
+#ifdef L___rt_sigsuspend
+#include <signal.h>
+#undef _sigsuspend
+_syscall2(int, __rt_sigsuspend, const sigset_t *, mask, size_t, size);
+
+int sigsuspend (const sigset_t *mask)
+{
+	return __rt_sigsuspend(mask, _NSIG/8);
+}
+#endif
+
 //#define __NR_pread                    180
 //#define __NR_pwrite                   181
 //#define __NR_chown                    182