From b88ff80f703931b368d27ebd898accdae5b31e60 Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Wed, 2 Jan 2002 12:18:50 +0000 Subject: 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 --- libc/signal/Makefile | 9 +-- libc/signal/allocrtsig.c | 92 ++++++++++++++++++------ libc/signal/bsd_sig.c | 34 --------- libc/signal/killpg.c | 11 ++- libc/signal/raise.c | 5 +- libc/signal/sigaction.c | 177 ++++++++++++++++++++++++++++++++++++++++++++++ libc/signal/sigaddset.c | 29 ++++---- libc/signal/sigandset.c | 30 ++++---- libc/signal/sigblock.c | 51 +++++++------ libc/signal/sigdelset.c | 29 ++++---- libc/signal/sigempty.c | 30 ++++---- libc/signal/sigfillset.c | 30 ++++---- libc/signal/siggetmask.c | 23 +++--- libc/signal/sighold.c | 38 +++++----- libc/signal/sigignore.c | 36 ++++++++++ libc/signal/sigintr.c | 35 +++++---- libc/signal/sigisempty.c | 26 ++++--- libc/signal/sigismem.c | 29 ++++---- libc/signal/signal.c | 60 +++++++++++----- libc/signal/sigorset.c | 30 ++++---- libc/signal/sigrelse.c | 38 +++++----- libc/signal/sigset.c | 78 ++++++++++++++++++++ libc/signal/sigsetmask.c | 53 ++++++++++++++ libc/signal/sigsetops.h | 16 ++--- libc/signal/sigstmsk.c | 46 ------------ libc/signal/sigsuspend.c | 49 +++++++++++++ libc/signal/sysv_signal.c | 46 ++++++------ 27 files changed, 739 insertions(+), 391 deletions(-) delete mode 100644 libc/signal/bsd_sig.c create mode 100644 libc/signal/sigaction.c create mode 100644 libc/signal/sigignore.c create mode 100644 libc/signal/sigset.c create mode 100644 libc/signal/sigsetmask.c delete mode 100644 libc/signal/sigstmsk.c create mode 100644 libc/signal/sigsuspend.c (limited to 'libc/signal') 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 - * Written by Erik Andersen - * - * 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 , 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 +#include +#include + + +/* 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 - -#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 #include -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 +#include +#include +#include + + +/* 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 +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 #define __USE_GNU @@ -23,17 +23,13 @@ #include /* 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 /* 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 #include #include /* 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 #include #include /* 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 -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 , 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 #define __USE_GNU #include -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 , 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 +#define __need_NULL +#include +#include + +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 #define __USE_GNU @@ -23,14 +23,12 @@ #include /* 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 +/* 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 #include -/* 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 #define __USE_GNU @@ -23,17 +23,13 @@ #include /* 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 , 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 #define __USE_GNU #include -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 +#define __need_NULL +#include +#include + + +/* 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 +#include + +/* 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 -#include -#include - -/* 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 +#include +#include +#include + + +/* 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 #include -#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; } -- cgit v1.2.3