summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2002-01-02 12:18:50 +0000
committerEric Andersen <andersen@codepoet.org>2002-01-02 12:18:50 +0000
commitb88ff80f703931b368d27ebd898accdae5b31e60 (patch)
tree79aa8e4d9b249e165973423a04fb3b4889308aa3
parentcac4a2ef934d7ac5314c874b88b62e922fc70690 (diff)
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
-rw-r--r--libc/signal/Makefile9
-rw-r--r--libc/signal/allocrtsig.c92
-rw-r--r--libc/signal/bsd_sig.c34
-rw-r--r--libc/signal/killpg.c11
-rw-r--r--libc/signal/raise.c5
-rw-r--r--libc/signal/sigaction.c177
-rw-r--r--libc/signal/sigaddset.c29
-rw-r--r--libc/signal/sigandset.c30
-rw-r--r--libc/signal/sigblock.c51
-rw-r--r--libc/signal/sigdelset.c29
-rw-r--r--libc/signal/sigempty.c30
-rw-r--r--libc/signal/sigfillset.c30
-rw-r--r--libc/signal/siggetmask.c23
-rw-r--r--libc/signal/sighold.c38
-rw-r--r--libc/signal/sigignore.c36
-rw-r--r--libc/signal/sigintr.c35
-rw-r--r--libc/signal/sigisempty.c26
-rw-r--r--libc/signal/sigismem.c29
-rw-r--r--libc/signal/signal.c60
-rw-r--r--libc/signal/sigorset.c30
-rw-r--r--libc/signal/sigrelse.c38
-rw-r--r--libc/signal/sigset.c78
-rw-r--r--libc/signal/sigsetmask.c53
-rw-r--r--libc/signal/sigsetops.h16
-rw-r--r--libc/signal/sigstmsk.c46
-rw-r--r--libc/signal/sigsuspend.c49
-rw-r--r--libc/signal/sysv_signal.c46
-rw-r--r--libc/sysdeps/linux/common/syscalls.c80
28 files changed, 804 insertions, 406 deletions
diff --git a/libc/signal/Makefile b/libc/signal/Makefile
index 9ee4249f7..c58717547 100644
--- a/libc/signal/Makefile
+++ b/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)
diff --git a/libc/signal/allocrtsig.c b/libc/signal/allocrtsig.c
index 0822999c8..d648f691f 100644
--- a/libc/signal/allocrtsig.c
+++ b/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
diff --git a/libc/signal/bsd_sig.c b/libc/signal/bsd_sig.c
deleted file mode 100644
index 405447eae..000000000
--- a/libc/signal/bsd_sig.c
+++ /dev/null
@@ -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;
-}
diff --git a/libc/signal/killpg.c b/libc/signal/killpg.c
index 6272a46d3..e75cfc483 100644
--- a/libc/signal/killpg.c
+++ b/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);
}
diff --git a/libc/signal/raise.c b/libc/signal/raise.c
index b666789b4..d4137aeb8 100644
--- a/libc/signal/raise.c
+++ b/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);
}
diff --git a/libc/signal/sigaction.c b/libc/signal/sigaction.c
new file mode 100644
index 000000000..58cf57b75
--- /dev/null
+++ b/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
diff --git a/libc/signal/sigaddset.c b/libc/signal/sigaddset.c
index be2968dba..2e4f5c540 100644
--- a/libc/signal/sigaddset.c
+++ b/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);
}
diff --git a/libc/signal/sigandset.c b/libc/signal/sigandset.c
index 4e1abd969..a09e102ae 100644
--- a/libc/signal/sigandset.c
+++ b/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);
}
diff --git a/libc/signal/sigblock.c b/libc/signal/sigblock.c
index f47b75804..1d673f454 100644
--- a/libc/signal/sigblock.c
+++ b/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;
}
diff --git a/libc/signal/sigdelset.c b/libc/signal/sigdelset.c
index 7e2033188..76279a945 100644
--- a/libc/signal/sigdelset.c
+++ b/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);
}
diff --git a/libc/signal/sigempty.c b/libc/signal/sigempty.c
index 0164ed382..36b8f63fa 100644
--- a/libc/signal/sigempty.c
+++ b/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;
}
diff --git a/libc/signal/sigfillset.c b/libc/signal/sigfillset.c
index 3126774cd..6edbb0e6b 100644
--- a/libc/signal/sigfillset.c
+++ b/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;
}
diff --git a/libc/signal/siggetmask.c b/libc/signal/siggetmask.c
index cb5270ddf..0436532a5 100644
--- a/libc/signal/siggetmask.c
+++ b/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")
diff --git a/libc/signal/sighold.c b/libc/signal/sighold.c
index f2978a368..d30a337f2 100644
--- a/libc/signal/sighold.c
+++ b/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);
}
diff --git a/libc/signal/sigignore.c b/libc/signal/sigignore.c
new file mode 100644
index 000000000..64d1852ab
--- /dev/null
+++ b/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);
+}
diff --git a/libc/signal/sigintr.c b/libc/signal/sigintr.c
index 483e5b71c..e8cdd9814 100644
--- a/libc/signal/sigintr.c
+++ b/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
}
diff --git a/libc/signal/sigisempty.c b/libc/signal/sigisempty.c
index 6d1de45a8..9067ff08a 100644
--- a/libc/signal/sigisempty.c
+++ b/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);
diff --git a/libc/signal/sigismem.c b/libc/signal/sigismem.c
index 0a5d6b625..f1c79d2da 100644
--- a/libc/signal/sigismem.c
+++ b/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);
}
diff --git a/libc/signal/signal.c b/libc/signal/signal.c
index 2397c55e7..463de1e50 100644
--- a/libc/signal/signal.c
+++ b/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)
diff --git a/libc/signal/sigorset.c b/libc/signal/sigorset.c
index ffabf3704..017f3ba06 100644
--- a/libc/signal/sigorset.c
+++ b/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);
}
diff --git a/libc/signal/sigrelse.c b/libc/signal/sigrelse.c
index 725a551bc..ae3b20ae2 100644
--- a/libc/signal/sigrelse.c
+++ b/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);
}
diff --git a/libc/signal/sigset.c b/libc/signal/sigset.c
new file mode 100644
index 000000000..a5afa17f3
--- /dev/null
+++ b/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;
+}
diff --git a/libc/signal/sigsetmask.c b/libc/signal/sigsetmask.c
new file mode 100644
index 000000000..632eaff2a
--- /dev/null
+++ b/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;
+}
diff --git a/libc/signal/sigsetops.h b/libc/signal/sigsetops.h
index 16f9b3625..8cdbf0d9b 100644
--- a/libc/signal/sigsetops.h
+++ b/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. */
diff --git a/libc/signal/sigstmsk.c b/libc/signal/sigstmsk.c
deleted file mode 100644
index 5439be243..000000000
--- a/libc/signal/sigstmsk.c
+++ /dev/null
@@ -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;
-}
diff --git a/libc/signal/sigsuspend.c b/libc/signal/sigsuspend.c
new file mode 100644
index 000000000..ad6e0fc8e
--- /dev/null
+++ b/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;
+}
diff --git a/libc/signal/sysv_signal.c b/libc/signal/sysv_signal.c
index 5756ec484..08b76a519 100644
--- a/libc/signal/sysv_signal.c
+++ b/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;
}
diff --git a/libc/sysdeps/linux/common/syscalls.c b/libc/sysdeps/linux/common/syscalls.c
index d2a04a922..889e15616 100644
--- a/libc/sysdeps/linux/common/syscalls.c
+++ b/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