Sigaction: Difference between revisions
m Robot: tagging as uncategorised |
No edit summary |
||
(41 intermediate revisions by 27 users not shown) | |||
Line 1: | Line 1: | ||
{{One source|date=February 2010}} |
|||
{{notability|date=August 2020}} |
|||
{{lowercase|title=sigaction()}} |
{{lowercase|title=sigaction()}} |
||
In computing, <code>sigaction</code> is a function API defined by [[POSIX]] to give the programmer access to what a program's behavior should be when receiving specific OS [[Signal (computing)|signals]]. |
|||
In computing, <code>sigaction</code> is a function API defined by [[POSIX]] to give the programmer access to what should be a program's behavior when receiving specific OS [[signals]]. |
|||
== General == |
== General == |
||
In Unix-like |
In [[Unix-like]] operating systems, one means of [[inter-process communication]] is through signals. When an executing unit ([[Process (computing)|process]] or [[Thread (computer science)|thread]]) receives a signal from the OS, it should react in some way defined by the datasheet and the conventional meaning of this signal (i.e. by dumping its data, stopping execution, synchronizing something...). |
||
The <code>sigaction()</code> system call is used to declare the behavior of the program should it receive one particular non-system-reserved signal. This is done by giving along with the system call a structure containing, among others, a function pointer to the signal handling routine. Some predefined signals (such as <code>SIGKILL</code>) have locked behavior that is handled by the system and cannot be overridden by such system calls. |
|||
== sigaction structure == |
|||
The POSIX standard requires that the sigaction structure be defined as below in the <signal.h> header file and it should contain at least the following fields: |
|||
<syntaxhighlight lang="c"> |
|||
struct sigaction { |
|||
void (*sa_handler)(int); /* address of signal handler */ |
|||
sigset_t sa_mask; /* additional signals to block */ |
|||
int sa_flags; /* signal options */ |
|||
/* alternate signal handler */ |
|||
void (*sa_sigaction)(int, siginfo_t *, void*); |
|||
}; |
|||
</syntaxhighlight> |
|||
Implementations are free to define additional, possibly non-portable fields. The sa_handler member specifies the address of a function to be called when the process receives the signal. The signal number is passed as an integer argument to this function. The sa_mask member specifies additional signals to be blocked during the execution of signal handler. sa_mask must be initialized with sigemptyset(3). The sa_flags member specifies some additional flags. sa_sigaction is an alternate signal handler with different set of parameters. Only one signal handler must be specified, either sa_handler or sa_sigaction. If it is desired to use sa_sigaction instead of sa_handler, SA_SIGINFO flag must be set. |
|||
== Replacement for <code>signal()</code> == |
|||
The <code>sigaction()</code> function provides an interface for reliable signals in replacement of the unreliable <code>signal()</code> function. Signal handlers installed by the <code>signal()</code> interface will be uninstalled immediately prior to execution of the handler. Permanent handlers must therefore be reinstalled by a call to <code>signal()</code> during the handler's execution, causing unreliability in the event a signal of the same type is received during the handler's execution but before the reinstall. Handlers installed by the <code>sigaction()</code> interface can be installed permanently and a custom set of signals can be blocked during the execution of the handler. These signals will be unblocked immediately following the normal termination of the handler (but not in the event of an abnormal termination such as a C++ exception throw.) |
|||
== Use in C++ == |
|||
In C++, the <code>try {/* ... */} catch {/* ... */}</code> programming structure may be (depending on host platforms) based on signalling. To <code>catch</code> signals translated into C++ exceptions, special compiler switches may be necessary on some platforms such as <code>-fnon-call-exceptions</code> for [[GNU Compiler Collection|GCC]] and the Intel C Compiler.<ref>[http://software.intel.com/sites/products/documentation/doclib/iss/2013/compiler/cpp-lin/GUID-79E461EF-631C-4AC4-AEDE-2CB5880F1933.htm Option -fnon-call-exceptions]</ref> |
|||
== Example == |
|||
<syntaxhighlight lang="c"> |
|||
#include <stdio.h> |
|||
#include <stdlib.h> |
|||
#include <string.h> |
|||
#include <unistd.h> |
|||
#include <sys/wait.h> |
|||
#include <signal.h> |
|||
#define NUMCHLDS 10 |
|||
void sigchld_handler(int, siginfo_t*, void*); |
|||
sig_atomic_t nexitedchlds = 0; |
|||
int |
|||
main(int argc, char *argv[]) |
|||
{ |
|||
struct sigaction act; |
|||
memset(&act, 0, sizeof(struct sigaction)); |
|||
sigemptyset(&act.sa_mask); |
|||
act.sa_sigaction = sigchld_handler; |
|||
act.sa_flags = SA_SIGINFO; |
|||
if (-1 == sigaction(SIGCHLD, &act, NULL)) |
|||
{ |
|||
perror("sigaction()"); |
|||
exit(EXIT_FAILURE); |
|||
} |
|||
for (int i = 0; i < NUMCHLDS; i++) |
|||
{ |
|||
switch(fork()) |
|||
{ |
|||
case 0: |
|||
/* |
|||
* Older OS implementations that do not correctly implement |
|||
* the siginfo structure will truncate the exit code |
|||
* by masking it with 0xFF. |
|||
*/ |
|||
return 1234567890; |
|||
/* NOTREACHED */ |
|||
case -1: |
|||
write(STDERR_FILENO, "fork ERROR!", 11); |
|||
exit(EXIT_FAILURE); |
|||
/* NOTREACHED */ |
|||
default: |
|||
printf("Child created\n"); |
|||
} |
|||
} |
|||
<code>sigaction()</code> system call is used to declare the behavior of the program should it receive one particular non-system-reserved signal. This is done by giving along with the system call a structure containing, among others, a function pointer to the signal handling routine. |
|||
Some predefined signals (such as SIGKILL) have locked behavior that is handled by the system and cannot be overriden by such system calls. |
|||
while (1) |
|||
== Definition of the function == |
|||
{ |
|||
if (nexitedchlds < NUMCHLDS) |
|||
pause(); |
|||
else |
|||
exit(EXIT_SUCCESS); |
|||
} |
|||
/* NOTREACHED */ |
|||
return 0; |
|||
} |
|||
void |
|||
The <code>int sigaction(int signum, const struct '''sigaction''' *act, struct sigaction *oldact)</code> function defined in <code>#include <signal.h></code> specifies the action which should be taken when a signal is received. |
|||
sigchld_handler(int signo, siginfo_t *sinfo, void *context) |
|||
{ |
|||
pid_t proc; |
|||
=== Replacement of deprecated <code>signal()</code> === |
|||
The <code>sigaction()</code> function provides an interface for reliable signals in replacement of the unreliable and deprecated <code>signal()</code> function. |
|||
while ((proc = waitpid(-1, NULL, WNOHANG)) > 0) |
|||
Signal handlers installed by the <code>signal()</code> interface will be uninstalled immediately prior to execution of the handler. Permanent handlers must therefore be reinstalled by a call to <code>signal()</code> during the handler's execution, causing unreliability in the event a signal of the same type is received during the handler's execution but before the reinstall. Handlers installed by the <code>sigaction()</code> interface can be installed permanently and a custom set of signals can be blocked during the execution of the handler. These signals will be unblocked immediately following the normal termination of the handler (but not in the event of an abnormal termination such as a C++ exception throw.) |
|||
{ |
|||
/* signal main thread */ |
|||
nexitedchlds++; |
|||
/* |
|||
=== Use in C++ === |
|||
* note: printf() is not signal-safe! |
|||
* don't use it in a signal handler. |
|||
* si_code is the full 32 bit exit code from the child (see also waitid()). |
|||
*/ |
|||
printf("sinfo->si_pid = %ld\nproc = %ld\nexit code %d exit reason %d\n", |
|||
(long)sinfo->si_pid, (long)proc, sinfo->si_status, sinfo->si_code); |
|||
} |
|||
} |
|||
</syntaxhighlight> |
|||
== References == |
|||
In C++, the <code>try{..}catch{..}</code> programming structure may be (depending on host platforms) based on signalling. |
|||
{{Reflist}} |
|||
To <code>catch(...)</code> signals translated into C++ exceptions, special compiler switches may be necessary on some platforms such as [[-fnon-call-exceptions]] for the gcc compiler. (reference and confirmation needed) |
|||
== External links == |
|||
== References (need to be expanded) == |
|||
* {{man|sh|sigaction|SUS|examine and change a signal action}} |
|||
[[Category:C POSIX library]] |
|||
*[http://www.die.net/doc/linux/man/man2/sigaction.2.html| Linux manual (2) Page] for <code>sigaction</code> |
|||
[[Category:Unix signals]] |
|||
{{Uncategorized|December 2006}} |
Latest revision as of 14:04, 30 July 2024
This article relies largely or entirely on a single source. (February 2010) |
The topic of this article may not meet Wikipedia's general notability guideline. (August 2020) |
In computing, sigaction
is a function API defined by POSIX to give the programmer access to what a program's behavior should be when receiving specific OS signals.
General
[edit]In Unix-like operating systems, one means of inter-process communication is through signals. When an executing unit (process or thread) receives a signal from the OS, it should react in some way defined by the datasheet and the conventional meaning of this signal (i.e. by dumping its data, stopping execution, synchronizing something...).
The sigaction()
system call is used to declare the behavior of the program should it receive one particular non-system-reserved signal. This is done by giving along with the system call a structure containing, among others, a function pointer to the signal handling routine. Some predefined signals (such as SIGKILL
) have locked behavior that is handled by the system and cannot be overridden by such system calls.
sigaction structure
[edit]The POSIX standard requires that the sigaction structure be defined as below in the <signal.h> header file and it should contain at least the following fields:
struct sigaction {
void (*sa_handler)(int); /* address of signal handler */
sigset_t sa_mask; /* additional signals to block */
int sa_flags; /* signal options */
/* alternate signal handler */
void (*sa_sigaction)(int, siginfo_t *, void*);
};
Implementations are free to define additional, possibly non-portable fields. The sa_handler member specifies the address of a function to be called when the process receives the signal. The signal number is passed as an integer argument to this function. The sa_mask member specifies additional signals to be blocked during the execution of signal handler. sa_mask must be initialized with sigemptyset(3). The sa_flags member specifies some additional flags. sa_sigaction is an alternate signal handler with different set of parameters. Only one signal handler must be specified, either sa_handler or sa_sigaction. If it is desired to use sa_sigaction instead of sa_handler, SA_SIGINFO flag must be set.
Replacement for signal()
[edit]The sigaction()
function provides an interface for reliable signals in replacement of the unreliable signal()
function. Signal handlers installed by the signal()
interface will be uninstalled immediately prior to execution of the handler. Permanent handlers must therefore be reinstalled by a call to signal()
during the handler's execution, causing unreliability in the event a signal of the same type is received during the handler's execution but before the reinstall. Handlers installed by the sigaction()
interface can be installed permanently and a custom set of signals can be blocked during the execution of the handler. These signals will be unblocked immediately following the normal termination of the handler (but not in the event of an abnormal termination such as a C++ exception throw.)
Use in C++
[edit]In C++, the try {/* ... */} catch {/* ... */}
programming structure may be (depending on host platforms) based on signalling. To catch
signals translated into C++ exceptions, special compiler switches may be necessary on some platforms such as -fnon-call-exceptions
for GCC and the Intel C Compiler.[1]
Example
[edit]#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#define NUMCHLDS 10
void sigchld_handler(int, siginfo_t*, void*);
sig_atomic_t nexitedchlds = 0;
int
main(int argc, char *argv[])
{
struct sigaction act;
memset(&act, 0, sizeof(struct sigaction));
sigemptyset(&act.sa_mask);
act.sa_sigaction = sigchld_handler;
act.sa_flags = SA_SIGINFO;
if (-1 == sigaction(SIGCHLD, &act, NULL))
{
perror("sigaction()");
exit(EXIT_FAILURE);
}
for (int i = 0; i < NUMCHLDS; i++)
{
switch(fork())
{
case 0:
/*
* Older OS implementations that do not correctly implement
* the siginfo structure will truncate the exit code
* by masking it with 0xFF.
*/
return 1234567890;
/* NOTREACHED */
case -1:
write(STDERR_FILENO, "fork ERROR!", 11);
exit(EXIT_FAILURE);
/* NOTREACHED */
default:
printf("Child created\n");
}
}
while (1)
{
if (nexitedchlds < NUMCHLDS)
pause();
else
exit(EXIT_SUCCESS);
}
/* NOTREACHED */
return 0;
}
void
sigchld_handler(int signo, siginfo_t *sinfo, void *context)
{
pid_t proc;
while ((proc = waitpid(-1, NULL, WNOHANG)) > 0)
{
/* signal main thread */
nexitedchlds++;
/*
* note: printf() is not signal-safe!
* don't use it in a signal handler.
* si_code is the full 32 bit exit code from the child (see also waitid()).
*/
printf("sinfo->si_pid = %ld\nproc = %ld\nexit code %d exit reason %d\n",
(long)sinfo->si_pid, (long)proc, sinfo->si_status, sinfo->si_code);
}
}
References
[edit]External links
[edit]- The Single UNIX Specification, Version 4 from The Open Group : examine and change a signal action – System Interfaces Reference,