Signals
Signal handling for interactive mode, command execution, and child processes.
- Author
pulgamecanica
Typedefs
-
typedef struct s_shell t_shell
Functions
-
void signals_setup_interactive(void)
SIGINT - custom handler: newline + redisplay prompt (like bash)
SIGQUIT - ignored (Ctrl-\ does nothing at prompt)
SIGTSTP - ignored (Ctrl-Z at prompt is a no-op; children handle it)
SIGTTIN - ignored (shell never blocks reading from a bg tty)
SIGTTOU - ignored (tcsetpgrp/tcsetattr from shell must not self-stop)
-
void signals_setup_executing(void)
SIGINT - ignored (let signal reach the child process)
SIGQUIT - ignored (let signal reach the child process)
SIGTSTP - ignored (let signal reach the child process)
Note
The parent simply waits; the child handles or dies from the signal.
-
void signals_setup_child(void)
After fork the child inherits the parent’s signal dispositions (SIG_IGN for interactive mode). We must reset them to SIG_DFL so the executed program responds to signals normally. SIGPIPE is reset alongside the others: this matches dash/ash and gives children a predictable disposition regardless of how the shell itself was launched — e.g. an IDE-embedded terminal or CI runner that sets SIGPIPE=SIG_IGN upstream cannot otherwise sneak that into our children and cause SIGPIPE-targeted probes (signals.sh’s kill -PIPE case) to silently no-op. (bash leaves it inherited; we deliberately diverge.) The pipeline-test stderr-vs-bash comparison still needs a canonical SIGPIPE environment for symmetry; the test side handles that via a perl trampoline in b_case (tests/integration/posix_baseline.sh).
Variables
-
volatile sig_atomic_t g_signal_received
Global signal flag (volatile for signal handler safety)
Forward declaration to avoid circular dependency with 42sh.h
Note
if you remember in the parser_parse function we pass the shell this is the variable which can help us detect heredoc signals!