Browse⌘K
tsfeatured.ts
tsxsignals.tsx
tsxsignals.tsxLab · interactive

signals · sigaction, masks, alarm

Signals are interrupts at the userspace level. Press Ctrl-C five times. The fifth one trips a threshold that arms SIGALRM. If you don't respond in 5 seconds, the kernel sends the alarm and the process exits.

Objective
Understand how signal handlers, signal masks, and timer signals (SIGALRM) compose. See why catching a signal isn't the same as handling it cleanly — and what reentrancy looks like when SIGINT can fire mid-handler.
Challenge
Press SIGINT 5 times to trigger the prompt. Then either respond before the 5-second alarm fires or let it expire. Then restart and observe what happens when you fire SIGINT during the prompt — the count keeps ticking.
SIGINTs
0/5
state
running
alarm
off
pending
— pause() —
#0process started · sigaction registered for SIGINT, SIGTSTP, SIGALRM
#1while (1) pause(); // sleeping until a signal arrives

Source

// signals · sigaction(SIGINT), SIGTSTP, SIGALRM
int ctrl_c_count = 0;
#define CTRL_C_THRESHOLD 5

void catch_int(int sig) {
  if (++ctrl_c_count >= CTRL_C_THRESHOLD) {
    alarm(5);                    // arm a 5-second SIGALRM
    fgets(answer, sizeof(answer), stdin);
    alarm(0);                    // cancel if user responded in time
  }
}

void ctch_alarm(int sig) { exit(0); }

int main() {
  sigaction(SIGINT,  &(struct sigaction){.sa_handler=catch_int},  NULL);
  sigaction(SIGTSTP, &(struct sigaction){.sa_handler=catch_tstp}, NULL);
  sigaction(SIGALRM, &(struct sigaction){.sa_handler=ctch_alarm}, NULL);
  while (1) pause();             // wait for signals
}

What's really happening

A signal is the kernel's way of telling a process that something interesting just happened — keyboard interrupt, timer expiry, illegal memory access. Each process has a per-signal handler table (set via sigaction), a pending mask (signals delivered but not yet run), and a blocked mask (signals temporarily ignored).

SIGINT ships when you press Ctrl-C in the terminal. SIGTSTP is Ctrl-Z (job control). SIGALRM is delivered by the kernel when an alarm() timer expires. The handlers above are async-signal-safe in spirit — they only set state and call simple I/O.

Reentrancy: a signal can fire while another signal handler is still running. That's why this lab counts SIGINTs delivered during the prompt — they still execute catch_int, still increment the counter, but the prompt's fgets blocks the main loop until the user types or the alarm fires.

● open to SWE roles·signals.tsx·UTF-8·github: …
·resume·contact··