summaryrefslogtreecommitdiff
path: root/libc/signal
diff options
context:
space:
mode:
Diffstat (limited to 'libc/signal')
-rw-r--r--libc/signal/sigblock.c41
-rw-r--r--libc/signal/sigpause.c19
-rw-r--r--libc/signal/sigset-cvt-mask.h44
-rw-r--r--libc/signal/sigsetmask.c45
4 files changed, 76 insertions, 73 deletions
diff --git a/libc/signal/sigblock.c b/libc/signal/sigblock.c
index c02c234b6..62ef060ac 100644
--- a/libc/signal/sigblock.c
+++ b/libc/signal/sigblock.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 94, 95, 96, 97, 98, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1994-1998, 2001-2002 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
@@ -19,37 +19,20 @@
#include <errno.h>
#include <signal.h>
+#include "sigset-cvt-mask.h"
+
/* Block signals in MASK, returning the old 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)
- 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);
-
- return mask;
+ sigset_t set, oset;
+
+ if (sigset_set_old_mask (&set, mask) < 0)
+ return -1;
+
+ if (sigprocmask (SIG_BLOCK, &set, &oset) < 0)
+ return -1;
+
+ return sigset_get_old_mask (&oset);
}
strong_alias (__sigblock, sigblock)
diff --git a/libc/signal/sigpause.c b/libc/signal/sigpause.c
index dd05e6e0a..e25803a9b 100644
--- a/libc/signal/sigpause.c
+++ b/libc/signal/sigpause.c
@@ -21,12 +21,13 @@
#include <signal.h>
#include <stddef.h> /* For NULL. */
+#include "sigset-cvt-mask.h"
+
/* Set the mask of blocked signals to MASK,
wait for a signal to arrive, and then restore the mask. */
int __sigpause (int sig_or_mask, int is_sig)
{
sigset_t set;
- int sig;
if (is_sig != 0)
{
@@ -36,20 +37,8 @@ int __sigpause (int sig_or_mask, int is_sig)
|| sigdelset (&set, sig_or_mask) < 0)
return -1;
}
- else
- {
- if (sigemptyset (&set) < 0)
- return -1;
-
- if (sizeof (sig_or_mask) == sizeof (set))
- *(int *) &set = sig_or_mask;
- else if (sizeof (unsigned long int) == sizeof (set))
- *(unsigned long int *) &set = (unsigned int) sig_or_mask;
- else
- for (sig = 1; sig < NSIG; ++sig)
- if ((sig_or_mask & sigmask (sig)) && __sigaddset (&set, sig) < 0)
- return -1;
- }
+ else if (sigset_set_old_mask (&set, sig_or_mask) < 0)
+ return -1;
return sigsuspend (&set);
}
diff --git a/libc/signal/sigset-cvt-mask.h b/libc/signal/sigset-cvt-mask.h
new file mode 100644
index 000000000..ca4774dbd
--- /dev/null
+++ b/libc/signal/sigset-cvt-mask.h
@@ -0,0 +1,44 @@
+/* Convert between lowlevel sigmask and libc representation of sigset_t.
+ Linux version.
+ Copyright (C) 1998, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Joe Keane <jgk@jgk.org>.
+
+ 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.
+
+ 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.
+
+ 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. */
+
+static inline int __attribute__ ((unused))
+sigset_set_old_mask (sigset_t *set, int mask)
+{
+ unsigned long int *ptr;
+ int cnt;
+
+ ptr = &set->__val[0];
+
+ *ptr++ = (unsigned int) mask;
+
+ cnt = _SIGSET_NWORDS - 2;
+ do
+ *ptr++ = 0ul;
+ while (--cnt >= 0);
+
+ return 0;
+}
+
+static inline int __attribute__ ((unused))
+sigset_get_old_mask (const sigset_t *set)
+{
+ return (unsigned int) set->__val[0];
+}
diff --git a/libc/signal/sigsetmask.c b/libc/signal/sigsetmask.c
index 4c7a43e5f..4b27b54a9 100644
--- a/libc/signal/sigsetmask.c
+++ b/libc/signal/sigsetmask.c
@@ -19,35 +19,22 @@
#include <errno.h>
#include <signal.h>
+#include "sigset-cvt-mask.h"
+
/* Set the mask of blocked signals to MASK, returning the old mask. */
-int sigsetmask (int 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;
+ sigset_t set, oset;
+
+ if (sigset_set_old_mask (&set, mask) < 0)
+ return -1;
+
+ if (sigprocmask (SIG_SETMASK, &set, &oset) < 0)
+ return -1;
+
+
+ return sigset_get_old_mask (&oset);
}
+
+weak_alias (__sigsetmask, sigsetmask)