Unix - UNIX Signal Handling
UNIX signal handling is a mechanism used by the operating system to notify a process that a specific event has occurred. A signal is a software-generated interrupt sent to a process to indicate events such as user actions, errors, invalid operations, or requests from other processes. It acts as a communication channel between the kernel and running processes.
Signals are important in UNIX because they allow the system to manage process behavior dynamically. For example, when a user presses Ctrl+C in a terminal, the operating system sends a signal to stop the running process. Similarly, when a process tries to access invalid memory, the system sends a signal indicating an error condition.
What Is a Signal
A signal is a notification sent to a process to inform it of an event. It does not carry detailed data but simply indicates that something has happened. Each signal has a unique name and number.
Signals may be generated by:
-
The user from the terminal
-
The operating system kernel
-
Another process
-
Hardware exceptions
-
System events such as timers or child process termination
A signal can instruct a process to terminate, pause, continue, or execute a custom signal handler function.
Common UNIX Signals
Some frequently used signals in UNIX systems include:
-
SIGINT
Sent when the user interrupts a process, usually by pressing Ctrl+C. -
SIGTERM
Requests a process to terminate gracefully. -
SIGKILL
Forces immediate termination of a process and cannot be ignored. -
SIGSTOP
Pauses a process execution. -
SIGCONT
Resumes a stopped process. -
SIGSEGV
Generated when a process accesses invalid memory. -
SIGHUP
Sent when a terminal session ends or a process needs to reload configuration. -
SIGCHLD
Sent to a parent process when a child process stops or terminates.
Signal Generation
Signals can be generated in different ways.
By User
A user may send signals directly from the terminal using keyboard shortcuts or commands.
Examples:
-
Ctrl+C sends SIGINT
-
Ctrl+Z sends SIGSTOP
-
killcommand sends signals to a process
Example command:
kill -SIGTERM 1234
This sends the SIGTERM signal to process ID 1234.
By Kernel
The kernel generates signals when exceptional events occur.
Examples:
-
Invalid memory access causes SIGSEGV
-
Arithmetic error may cause SIGFPE
-
Child process termination causes SIGCHLD
By Other Processes
One process can signal another process using system calls.
For example, a parent process may notify a child process or vice versa.
Default Signal Actions
Every signal has a default action defined by the system. These actions determine how the process behaves if no custom handling is provided.
Possible default actions include:
-
Terminate the process
-
Ignore the signal
-
Stop the process
-
Continue the process
-
Create a core dump for debugging
Example:
SIGKILL always terminates a process immediately. It cannot be intercepted or blocked.
Signal Handling Mechanism
When a signal is sent to a process, the operating system checks whether the process has defined a custom action for that signal.
The process can:
-
Accept default behavior
-
Ignore the signal
-
Execute a custom signal handler function
A signal handler is a user-defined function that runs when a specific signal is received.
Signal Handler Function
A signal handler is written inside the program and linked to a specific signal.
Example in C:
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
void handler(int sig) {
printf("Signal received: %d\n", sig);
}
int main() {
signal(SIGINT, handler);
while(1) {
sleep(1);
}
return 0;
}
In this program:
-
SIGINT is connected to the handler function
-
Pressing Ctrl+C does not terminate immediately
-
The custom function executes instead
Signal Delivery Process
The UNIX signal delivery process involves several stages.
Step 1
An event occurs, such as user interruption or process request.
Step 2
The kernel identifies the target process.
Step 3
The signal is marked as pending for the process.
Step 4
The process scheduler checks pending signals.
Step 5
The signal is delivered when the process is ready.
Step 6
The process executes the signal handler or default action.
Pending Signals
A signal may not be handled immediately. If the process is busy or the signal is blocked, it remains in a pending state.
Pending signals wait until:
-
The process becomes active
-
The signal becomes unblocked
-
The process completes a critical operation
Blocking Signals
Processes can temporarily block certain signals. Blocking prevents signal interruption during sensitive operations.
For example:
During file updates or shared memory access, signals may be blocked to avoid corruption.
Blocked signals are not lost. They remain pending until unblocked.
Ignoring Signals
A process can choose to ignore some signals.
Example:
signal(SIGINT, SIG_IGN);
This tells the program to ignore Ctrl+C interruption.
Some signals cannot be ignored:
-
SIGKILL
-
SIGSTOP
These are enforced by the kernel for system control.
Signal Masking
Signal masking means defining which signals are blocked for a process at a particular time.
The signal mask is stored for each process.
This allows safe execution of critical sections without unexpected interruption.
Signal Queue
Traditional UNIX signals do not queue multiple instances of the same signal. If the same signal arrives multiple times before handling, only one may be recorded.
Modern systems support real-time signals that can queue multiple signal events.
Real-Time Signals
Real-time signals provide:
-
Guaranteed delivery
-
Signal queuing
-
Priority order
-
Additional data transfer
They are useful in advanced applications such as device control and process synchronization.
Signal and Process Control
Signals are central to process management in UNIX.
Administrators use signals to:
-
Stop processes
-
Restart services
-
Terminate applications
-
Debug programs
-
Manage background jobs
Examples:
Restart a service by sending SIGHUP.
Terminate a process using SIGTERM.
Force close using SIGKILL.
Signal System Calls
Several system calls manage signals.
Important system calls include:
-
signal()
-
sigaction()
-
kill()
-
raise()
-
alarm()
-
pause()
signal()
Sets signal behavior.
sigaction()
Advanced signal management with greater control.
kill()
Sends a signal to another process.
raise()
Sends a signal to itself.
Difference Between signal() and sigaction()
signal() is simpler but less reliable on modern systems.
sigaction() provides:
-
Better portability
-
Signal masking control
-
Reliable behavior
-
More detailed configuration
Because of this, modern UNIX programs often use sigaction().
Practical Uses of Signals
Signals are used in many real-world operations.
Process Termination
System administrators stop unwanted programs.
Error Detection
Programs detect illegal operations.
Child Monitoring
Parent processes monitor child completion.
Timer Events
Programs trigger actions after intervals.
Service Management
Servers reload configurations without restarting.
Signal in Shell
The shell handles signals automatically.
Examples:
-
Ctrl+C terminates current command
-
Ctrl+Z suspends process
-
killsends custom signals
Shell scripts can also trap signals.
Example:
trap "echo Interrupted" SIGINT
This executes a command when interrupted.
Advantages of Signal Handling
Signal handling offers several benefits.
-
Efficient event notification
-
Fast process communication
-
Immediate system response
-
Better process control
-
Error management
-
Supports multitasking
Limitations of Signal Handling
Signal handling also has limitations.
-
Signals carry limited information
-
Complex handling in large programs
-
Race conditions may occur
-
Signals may interrupt unexpectedly
-
Difficult debugging in asynchronous systems
Signal Safety
Certain functions are unsafe inside signal handlers because interruption may occur at any moment.
Signal-safe functions should be used to avoid corruption.
For example:
Using printf in signal handlers can be risky in complex applications.
Safer system functions are recommended.
Importance in UNIX
Signal handling is a core feature of UNIX process management. It provides asynchronous communication between the kernel and processes. It enables immediate response to events without constant checking.
Without signals, operating systems would need continuous polling, which wastes resources.
Signals improve:
-
System responsiveness
-
Process synchronization
-
Error recovery
-
Resource management
-
User interaction
Conclusion
UNIX signal handling is a powerful mechanism that enables the operating system and processes to communicate asynchronously. Signals notify processes about system events, user requests, or exceptional conditions. Each signal has predefined behavior, but programs can define custom handlers for specialized responses.
This feature is essential for process control, system administration, service management, and application reliability. By understanding signal handling, users and developers gain deeper knowledge of how UNIX controls running processes and manages system events efficiently.