Why is sigset_t on 64-bit Linux 128 bytes large in glibc and musl?

#include <signal.h>
#include <stdio.h>
int main()
    printf("%zu\n", sizeof(sigset_t)); //prints 128 with both glibc and musl

Shouldn't 64 / 8 = 8 (number_of_signals / CHAR_BIT) be enough?


1 Answer 1


I don’t know the original reason; back in 1996, the Linux-specific header was added with the following definition:

/* A `sigset_t' has a bit for each signal.  Having 32 * 4 * 8 bits gives                                           
   us up to 1024 signals.  */                                                                                      
#define _SIGSET_NWORDS 32                                                                                          
typedef struct                                                                                                     
  unsigned int __val[_SIGSET_NWORDS];                                                                              
} __sigset_t;

and this “1024 signal” limit has been preserved in the current definition:

/* A `sigset_t' has a bit for each signal.  */                                                                     

#define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int)))                                                   
typedef struct                                                                                                     
    unsigned long int __val[_SIGSET_NWORDS];                                                                       
  } __sigset_t;

which makes the 1024-based calculation clearer (and results in 16 unsigned longs on 64-bit x86, i.e. 128 bytes).

Presumably the glibc maintainers wanted to leave room for growth...

musl aims for ABI compatibility with glibc for sigaction, so it uses the same 1024-bit (128-byte) size:

TYPEDEF struct __sigset_t { unsigned long __bits[128/sizeof(long)]; } sigset_t;

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .