Unix - Signals and Signal Handling in UNIX
Signals are a fundamental mechanism in UNIX that allow the operating system and processes to communicate with each other. A signal is a software-generated notification sent to a process to inform it that a specific event has occurred. These events can be generated by the operating system, another process, or even the process itself.
Signals provide a way to interrupt the normal flow of execution and trigger a predefined response. They are widely used for process control, error handling, and communication between processes.
What is a Signal?
A signal is an asynchronous event notification delivered to a process. Unlike regular function calls, signals can occur at any time during a program's execution.
When a signal is delivered to a process, one of the following actions takes place:
-
The signal is ignored.
-
The default action associated with the signal is executed.
-
A custom signal handler defined by the programmer is executed.
Signals are identified by symbolic names and corresponding integer values.
Why Signals are Used
Signals serve several important purposes in UNIX systems:
-
Terminating processes.
-
Pausing or resuming process execution.
-
Handling exceptional conditions.
-
Notifying processes about external events.
-
Facilitating communication between processes.
-
Managing child process status changes.
Common UNIX Signals
SIGINT
This signal is generated when a user presses Ctrl+C in the terminal.
Purpose:
Interrupt and terminate a running process.
Example:
Ctrl + C
Default action:
Terminate the process.
SIGTERM
SIGTERM is a request to terminate a process gracefully.
Purpose:
Allow a process to perform cleanup operations before exiting.
Example:
kill -15 PID
Default action:
Terminate the process.
SIGKILL
SIGKILL immediately stops a process.
Purpose:
Forcefully terminate an unresponsive process.
Example:
kill -9 PID
Characteristics:
-
Cannot be caught.
-
Cannot be ignored.
-
Cannot be handled.
Default action:
Immediate process termination.
SIGSTOP
Suspends a process.
Example:
kill -19 PID
Characteristics:
-
Cannot be ignored.
-
Cannot be caught.
Default action:
Stop the process.
SIGCONT
Resumes a stopped process.
Example:
kill -18 PID
Default action:
Continue execution.
SIGSEGV
Occurs when a program accesses invalid memory.
Common causes:
-
Null pointer dereferencing.
-
Accessing memory outside allocated boundaries.
Default action:
Terminate process and create a core dump.
SIGCHLD
Sent to a parent process when a child process terminates or changes state.
Purpose:
Allows the parent process to collect child process status information.
SIGHUP
Originally used when a terminal connection was lost.
Modern use:
Often used to instruct daemons to reload configuration files.
Example:
kill -HUP PID
Viewing Available Signals
To display all supported signals:
kill -l
Sample output:
1) SIGHUP
2) SIGINT
3) SIGQUIT
9) SIGKILL
15) SIGTERM
17) SIGCHLD
18) SIGCONT
19) SIGSTOP
Signal Generation
Signals can be generated in several ways.
By the User
Keyboard shortcuts can generate signals.
Examples:
Ctrl+C
Generates SIGINT.
Ctrl+Z
Generates SIGTSTP.
By the Operating System
The kernel sends signals when certain events occur.
Examples:
-
Invalid memory access generates SIGSEGV.
-
Division by zero may generate SIGFPE.
-
Child process termination generates SIGCHLD.
By Another Process
One process can send signals to another.
Example:
kill -SIGTERM 1234
or
kill -15 1234
By the Process Itself
A process may raise a signal internally.
Example in C:
raise(SIGINT);
Signal Handling
Signal handling refers to the process of defining actions that occur when a signal is received.
The programmer can install a signal handler function to manage signals.
Basic flow:
-
Signal arrives.
-
Current execution is interrupted.
-
Signal handler executes.
-
Control returns to the interrupted code.
Signal Handling in C
The signal() function is commonly used.
Syntax:
signal(signal_number, handler_function);
Example:
#include <stdio.h>
#include <signal.h>
void handler(int sig)
{
printf("Signal received: %d\n", sig);
}
int main()
{
signal(SIGINT, handler);
while(1);
return 0;
}
Working:
-
Program runs continuously.
-
User presses Ctrl+C.
-
SIGINT is generated.
-
Handler function executes instead of terminating the program.
Ignoring Signals
Some signals can be ignored.
Example:
signal(SIGINT, SIG_IGN);
Effect:
Pressing Ctrl+C will not terminate the process.
However, signals like SIGKILL and SIGSTOP cannot be ignored.
Default Signal Actions
Every signal has a predefined default action.
Common default actions include:
| Action | Description |
|---|---|
| Terminate | End the process |
| Ignore | Do nothing |
| Stop | Suspend process execution |
| Continue | Resume execution |
| Core Dump | Terminate and create memory dump |
Sending Signals Using kill Command
The kill command is commonly used to send signals.
Syntax:
kill [signal] PID
Examples:
Terminate process gracefully:
kill -15 1234
Force termination:
kill -9 1234
Reload configuration:
kill -HUP 1234
Signal Handling with sigaction()
Modern UNIX systems prefer sigaction() over signal().
Advantages:
-
More reliable.
-
Better control.
-
Portable across UNIX variants.
-
Supports advanced signal handling features.
Example:
struct sigaction sa;
sa.sa_handler = handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGINT, &sa, NULL);
Real-Time Signals
UNIX also supports real-time signals.
Features:
-
Delivered in order.
-
Multiple instances are queued.
-
Carry additional information.
Applications:
-
Embedded systems.
-
Process synchronization.
-
Event-driven applications.
Practical Applications of Signals
Process Termination
System administrators use signals to stop applications.
Example:
kill -SIGTERM PID
Daemon Management
Services often reload configurations using SIGHUP.
Example:
kill -HUP PID
Parent-Child Process Coordination
SIGCHLD informs parents about child process completion.
Error Detection
Signals help detect issues such as:
-
Illegal instructions.
-
Memory violations.
-
Arithmetic exceptions.
Advantages of Signal Handling
-
Enables asynchronous event processing.
-
Provides efficient process communication.
-
Supports graceful program termination.
-
Helps manage system resources.
-
Facilitates process synchronization.
Limitations of Signals
-
Limited amount of information can be transferred.
-
Signal delivery timing is unpredictable.
-
Multiple signals of the same type may be merged in traditional signaling.
-
Complex applications may require more advanced communication mechanisms.
Conclusion
Signals are a core feature of UNIX operating systems that enable communication between processes and the kernel. They provide a lightweight and efficient mechanism for notifying processes about events such as user interruptions, errors, process termination requests, and system-level conditions. Proper signal handling allows applications to respond gracefully to events, improve reliability, and maintain better control over process execution. Understanding signals and signal handling is essential for UNIX system programming, process management, and administration.