linux-sysprog · intermediate · ~25 min
Bit manipulation for signal sets.
Build a signal-set bitmask from a list of signal numbers — the same idea a sigset_t uses internally. This is pure bit arithmetic; no signals are actually blocked.
Implement unsigned long mask_block(int *sigs, int n) that returns a bitmask with one bit set per signal in the input list.
sigs, n: an array of n signal numbers. Signal numbers come from these fixed constants (defined for you; <signal.h> is not used):enum { SIG_HUP=1, SIG_INT=2, SIG_QUIT=3, SIG_TERM=15, SIG_USR1=10, SIG_USR2=12 };
Returns an unsigned long where, for each signal s in the array, bit s - 1 is set (signal 1 -> bit 0, signal 2 -> bit 1, and so on).
mask_block({SIG_INT, SIG_TERM}, 2) -> (1<<1) | (1<<14)
mask_block({}, 0) -> 0
mask_block({SIG_INT, SIG_INT, SIG_USR1}, 3)-> (1<<1) | (1<<9) (duplicate counted once)
n == 0 returns 0.Signal handling is one of the trickiest corners of UNIX. Computing the right mask to block a set of signals is the foundation of safe signal-handling code.
An array sigs of n signal numbers (from the SIG_* enum). n >= 0.
An unsigned long bitmask with bit (s-1) set for each signal s in the array.
Use 1UL << (sig - 1). Duplicates set a bit once; n == 0 gives 0.
enum { SIG_HUP=1, SIG_INT=2, SIG_QUIT=3, SIG_TERM=15, SIG_USR1=10, SIG_USR2=12 };
unsigned long mask_block(int *sigs, int n) { /* TODO */ return 0; }
Setting bit sig instead of sig-1 (a real source of off-by-one in libc sigset implementations); using int instead of unsigned (sign extension in shifts).
Duplicate signals — bit set once. n == 0 returns 0.
O(n).
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.