The sigaction function within the C programming language enables modification of a process's reaction to a particular signal. This function empowers developers to specify a custom signal handler function or alter the behavior of a signal. Through the utilization of sigaction, it becomes feasible to adjust a process's behavior upon receipt of a specific signal, offering enhanced adaptability and supervision compared to the former signal function.
Syntax:
It has the following syntax:
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
Parameters:
- signum: The number designated by which the action is to be taken.
- act: A reference to a sigaction structure that details the new action that has to be performed.
- oldact: It is an optional pointer to the previous action's storage location in a sigaction structure.
Return Value:
This function will return a value of -1 to signify a failure scenario, or return a value of 0 to indicate a successful outcome. The particular error can be identified by examining the 'errno' value.
struct sigaction:
Details regarding the suitable response for a specific signal are stored within this framework.
Typically, it consists of members like:
- sa_handler: A pointer, if any, to the signal handling program.
- sa_sigaction: A pointer, if any, to a different signal handling function.
- SAFlags: Flags designate extra actions (such as SARESTART , which initiates system calls automatically when interrupted).
- Asynchronous notifications are known as signals. These are transmitted to a process to notify it when particular event occurs, such as software bugs or hardware problems.
- Software interrupts, user-defined events, and hardware exceptions are examples of events.
- Signal handlers are activated when a process receives a certain signal.
- They can perform operations like cleaning up, logging, or changing the program's behaviour in response to the signal.
- Change how the process responds to a signal using sigaction method .
- To do this, you may ignore the signal, carry out the default action, or call a signal handler function you created.
Signal Handling:
Handlers of Signals:
Changing Signal Actions:
In the event of a malfunction, the function will yield a return value of -1 and assign the appropriate error code to errno. Typical issues encompass improper signal identifiers, inadequate privileges, and erroneous input arguments.
In contrast to the signal function, sigaction offers enhanced management of signal handling behavior, making it a preferable choice for handling signals in programs that involve multiple threads.
Example:
Let's consider a scenario to demonstrate the Sigaction function in the C programming language.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
// Signal handler for SIGINT
void sigint_handler(int signum)
{
printf("Caught the signal SIGINT (%d)\n", signum);
}
// Signal handler for SIGQUIT
void sigquit_handler(int signum)
{
printf("Caught the signal SIGQUIT (%d)\n", signum);
}
// Signal handler for SIGTERM
void sigterm_handler(int signum)
{
printf("Caught the signal SIGTERM (%d)\n", signum);
}
int main()
{
// Defining sigaction structs for each signal
struct sigaction sa_int, sa_quit, sa_term;
// Initializing signal handlers
sa_int.sa_handler = sigint_handler;
sa_quit.sa_handler = sigquit_handler;
sa_term.sa_handler = sigterm_handler;
// Set all of the signal masks empty.
sigemptyset(&sa_int.sa_mask);
sigemptyset(&sa_quit.sa_mask);
sigemptyset(&sa_term.sa_mask);
// None of the signals have any special flags.
sa_int.sa_flags = 0;
sa_quit.sa_flags = 0;
sa_term.sa_flags = 0;
// Use signal action to install signal handlers.
if (sigaction(SIGINT, &sa_int, NULL) == -1)
{
perror("sigaction SIGINT");
return 1;
}
if (sigaction(SIGQUIT, &sa_quit, NULL) == -1)
{
perror("sigaction SIGQUIT");
return 1;
}
if (sigaction(SIGTERM, &sa_term, NULL) == -1)
{
perror("sigaction SIGTERM");
return 1;
}
// Loop infinite
printf("Running. Press Ctrl+C, Ctrl+\\ or kill to generate signals...\n");
while (1)
{
sleep(1);
}
return 0;
}
Output:
Running. Press Ctrl+C, Ctrl+\, or kill to generate signals...
Explanation:
This C code utilizes the sigaction function to set up signal handlers for signals like SIGINT, SIGQUIT, and SIGTERM. For each signal, there is a specific handler function that displays a message indicating the signal number and the signal received. Following the message display, the program enters an infinite loop to indicate its operational status. To trigger the respective signals (SIGINT, SIGQUIT, SIGTERM), users can use Ctrl+C, Ctrl+\, or the kill command in the terminal where the program is running. When a signal is intercepted, the corresponding handler function is invoked, and a message showing the signal number and the intercepted signal is printed. Robust error handling is implemented for each sigaction call to address any installation complications.
In most cases, the sigaction function in C plays a vital role in managing signal handling within processes, offering a higher level of control and reliability compared to alternative signal-handling approaches. This function is commonly used for handling exceptions, asynchronous I/O operations, and in system programming tasks.