summary refs log tree commit diff
path: root/sysdeps/unix/sysv/linux/sigsetops.h
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2020-04-23 10:58:01 -0300
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2020-07-07 14:10:58 -0300
commitf26d456b98abf02b3ff92f1a3c0d4473b7ffd85c (patch)
treee61f7a38a3f7ce9b8394d1ce8001cf6a3a9dc33e /sysdeps/unix/sysv/linux/sigsetops.h
parentf13d260190d47bd38c0ae939080001e7bb58bd04 (diff)
downloadglibc-f26d456b98abf02b3ff92f1a3c0d4473b7ffd85c.tar.gz
glibc-f26d456b98abf02b3ff92f1a3c0d4473b7ffd85c.tar.xz
glibc-f26d456b98abf02b3ff92f1a3c0d4473b7ffd85c.zip
linux: Fix __NSIG_WORDS and add __NSIG_BYTES
The __NSIG_WORDS value is based on minimum number of words to hold
the maximum number of signals supported by the architecture.

This patch also adds __NSIG_BYTES, which is the number of bytes
required to represent the supported number of signals.  It is used in
syscalls which takes a sigset_t.

Checked on x86_64-linux-gnu and i686-linux-gnu.

Tested-by: Carlos O'Donell <carlos@redhat.com>
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Diffstat (limited to 'sysdeps/unix/sysv/linux/sigsetops.h')
-rw-r--r--sysdeps/unix/sysv/linux/sigsetops.h18
1 files changed, 13 insertions, 5 deletions
diff --git a/sysdeps/unix/sysv/linux/sigsetops.h b/sysdeps/unix/sysv/linux/sigsetops.h
index db8f378cf0..3f29ead009 100644
--- a/sysdeps/unix/sysv/linux/sigsetops.h
+++ b/sysdeps/unix/sysv/linux/sigsetops.h
@@ -20,23 +20,31 @@
 #define _SIGSETOPS_H 1
 
 #include <signal.h>
+#include <limits.h>
+#include <libc-pointer-arith.h>
 
 /* Return a mask that includes the bit for SIG only.  */
-# define __sigmask(sig) \
-  (((unsigned long int) 1) << (((sig) - 1) % (8 * sizeof (unsigned long int))))
+#define __sigmask(sig) \
+  (1UL << (((sig) - 1) % ULONG_WIDTH))
 
 /* Return the word index for SIG.  */
 static inline unsigned long int
 __sigword (int sig)
 {
-  return (sig - 1) / (8 * sizeof (unsigned long int));
+  return (sig - 1) / ULONG_WIDTH;
 }
 
 /* Linux sig* functions only handle up to __NSIG_WORDS words instead of
    full _SIGSET_NWORDS sigset size.  The signal numbers are 1-based, and
    bit 0 of a signal mask is for signal 1.  */
-
-# define __NSIG_WORDS (_NSIG / (8 * sizeof (unsigned long int )))
+#define __NSIG_WORDS (ALIGN_UP ((_NSIG - 1), ULONG_WIDTH) / ULONG_WIDTH)
+_Static_assert (__NSIG_WORDS <= _SIGSET_NWORDS,
+		"__NSIG_WORDS > _SIGSET_WORDS");
+
+/* This macro is used on syscall that takes a sigset_t to specify the expected
+   size in bytes.  As for glibc, kernel sigset is implemented as an array of
+   unsigned long.  */
+#define __NSIG_BYTES (__NSIG_WORDS * (ULONG_WIDTH / UCHAR_WIDTH))
 
 static inline void
 __sigemptyset (sigset_t *set)