# sigaction

## NAME



           sigaction, rt_sigaction - examine and change a signal action
    


## LIBRARY



           Standard C library (_libc_ , _-lc_)
    


## SYNOPSIS



           **#include <signal.h>**
    
           **int sigaction(int** _signum_**,**
                         **const struct sigaction *_Nullable restrict** _act_**,**
                         **struct sigaction *_Nullable restrict** _oldact_**);**
    
       Feature Test Macro Requirements for glibc (see
       feature_test_macros(7)):
    
           **sigaction**():
               _POSIX_C_SOURCE
    
           _siginfo_t_ :
               _POSIX_C_SOURCE >= 199309L
    


## DESCRIPTION



           The **sigaction**() system call is used to change the action taken by
           a process on receipt of a specific signal.  (See signal(7) for an
           overview of signals.)
    
           _signum_ specifies the signal and can be any valid signal except
           **SIGKILL** and **SIGSTOP**.
    
           If _act_ is non-NULL, the new action for signal _signum_ is installed
           from _act_.  If _oldact_ is non-NULL, the previous action is saved in
           _oldact_.
    
           The _sigaction_ structure is defined as something like:
    
               struct sigaction {
                   void     (*sa_handler)(int);
                   void     (*sa_sigaction)(int, siginfo_t *, void *);
                   sigset_t   sa_mask;
                   int        sa_flags;
                   void     (*sa_restorer)(void);
               };
    
           On some architectures a union is involved: do not assign to both
           _sa_handler_ and _sa_sigaction_.
    
           The _sa_restorer_ field is not intended for application use.  (POSIX
           does not specify a _sa_restorer_ field.)  Some further details of
           the purpose of this field can be found in sigreturn(2).
    
           _sa_handler_ specifies the action to be associated with _signum_ and
           can be one of the following:
    
           •  **SIG_DFL** for the default action.
    
           •  **SIG_IGN** to ignore this signal.
    
           •  A pointer to a signal handling function.  This function
              receives the signal number as its only argument.
    
           If **SA_SIGINFO** is specified in _sa_flags_ , then _sa_sigaction_ (instead
           of _sa_handler_) specifies the signal-handling function for _signum_.
           This function receives three arguments, as described below.
    
           _sa_mask_ specifies a mask of signals which should be blocked (i.e.,
           added to the signal mask of the thread in which the signal handler
           is invoked) during execution of the signal handler.  In addition,
           the signal which triggered the handler will be blocked, unless the
           **SA_NODEFER** flag is used.
    
           _sa_flags_ specifies a set of flags which modify the behavior of the
           signal.  It is formed by the bitwise OR of zero or more of the
           following:
    
           **SA_NOCLDSTOP**
                  If _signum_ is **SIGCHLD** , do not receive notification when
                  child processes stop (i.e., when they receive one of
                  **SIGSTOP** , **SIGTSTP** , **SIGTTIN** , or **SIGTTOU**) or resume (i.e.,
                  they receive **SIGCONT**) (see wait(2)).  This flag is
                  meaningful only when establishing a handler for **SIGCHLD**.
    
           **SA_NOCLDWAIT**(since Linux 2.6)
                  If _signum_ is **SIGCHLD** , do not transform children into
                  zombies when they terminate.  See also waitpid(2).  This
                  flag is meaningful only when establishing a handler for
                  **SIGCHLD** , or when setting that signal's disposition to
                  **SIG_DFL**.
    
                  If the **SA_NOCLDWAIT** flag is set when establishing a handler
                  for **SIGCHLD** , POSIX.1 leaves it unspecified whether a
                  **SIGCHLD** signal is generated when a child process
                  terminates.  On Linux, a **SIGCHLD** signal is generated in
                  this case; on some other implementations, it is not.
    
           **SA_NODEFER**
                  Do not add the signal to the thread's signal mask while the
                  handler is executing, unless the signal is specified in
                  _act.sa_mask_.  Consequently, a further instance of the
                  signal may be delivered to the thread while it is executing
                  the handler.  This flag is meaningful only when
                  establishing a signal handler.
    
                  **SA_NOMASK** is an obsolete, nonstandard synonym for this
                  flag.
    
           **SA_ONSTACK**
                  Call the signal handler on an alternate signal stack
                  provided by sigaltstack(2).  If an alternate stack is not
                  available, the default stack will be used.  This flag is
                  meaningful only when establishing a signal handler.
    
           **SA_RESETHAND**
                  Restore the signal action to the default upon entry to the
                  signal handler.  This flag is meaningful only when
                  establishing a signal handler.
    
                  **SA_ONESHOT** is an obsolete, nonstandard synonym for this
                  flag.
    
           **SA_RESTART**
                  Provide behavior compatible with BSD signal semantics by
                  making certain system calls restartable across signals.
                  This flag is meaningful only when establishing a signal
                  handler.  See signal(7) for a discussion of system call
                  restarting.
    
           **SA_RESTORER**
                  _Not intended for application use_.  This flag is used by C
                  libraries to indicate that the _sa_restorer_ field contains
                  the address of a "signal trampoline".  See sigreturn(2) for
                  more details.
    
           **SA_SIGINFO**(since Linux 2.2)
                  The signal handler takes three arguments, not one.  In this
                  case, _sa_sigaction_ should be set instead of _sa_handler_.
                  This flag is meaningful only when establishing a signal
                  handler.
    
           **SA_UNSUPPORTED**(since Linux 5.11)
                  Used to dynamically probe for flag bit support.
    
                  If an attempt to register a handler succeeds with this flag
                  set in _act- >sa_flags_ alongside other flags that are
                  potentially unsupported by the kernel, and an immediately
                  subsequent **sigaction**() call specifying the same signal
                  number and with a non-NULL _oldact_ argument yields
                  **SA_UNSUPPORTED** _clear_ in _oldact- >sa_flags_, then
                  _oldact- >sa_flags_ may be used as a bitmask describing which
                  of the potentially unsupported flags are, in fact,
                  supported.  See the section "Dynamically probing for flag
                  bit support" below for more details.
    
           **SA_EXPOSE_TAGBITS**(since Linux 5.11)
                  Normally, when delivering a signal, an architecture-
                  specific set of tag bits are cleared from the _si_addr_ field
                  of _siginfo_t_.  If this flag is set, an architecture-
                  specific subset of the tag bits will be preserved in
                  _si_addr_.
    
                  Programs that need to be compatible with Linux versions
                  older than 5.11 must use **SA_UNSUPPORTED** to probe for
                  support.
    
       **The siginfo_t argument to a SA_SIGINFO handler**
           When the **SA_SIGINFO** flag is specified in _act.sa_flags_ , the signal
           handler address is passed via the _act.sa_sigaction_ field.  This
           handler takes three arguments, as follows:
    
               void
               handler(int sig, siginfo_t *info, void *ucontext)
               {
                   ...
               }
    
           These three arguments are as follows
    
           _sig_    The number of the signal that caused invocation of the
                  handler.
    
           _info_   A pointer to a _siginfo_t_ , which is a structure containing
                  further information about the signal, as described below.
    
           _ucontext_
                  This is a pointer to a _ucontext_t_ structure, cast to
                  _void *_.  The structure pointed to by this field contains
                  signal context information that was saved on the user-space
                  stack by the kernel; for details, see sigreturn(2).
                  Further information about the _ucontext_t_ structure can be
                  found in getcontext(3) and signal(7).  Commonly, the
                  handler function doesn't make any use of the third
                  argument.
    
           The _siginfo_t_ data type is a structure with the following fields:
    
               siginfo_t {
                   int      si_signo;     /* Signal number */
                   int      si_errno;     /* An errno value */
                   int      si_code;      /* Signal code */
                   int      si_trapno;    /* Trap number that caused
                                             hardware-generated signal
                                             (unused on most architectures) */
                   pid_t    si_pid;       /* Sending process ID */
                   uid_t    si_uid;       /* Real user ID of sending process */
                   int      si_status;    /* Exit value or signal */
                   clock_t  si_utime;     /* User time consumed */
                   clock_t  si_stime;     /* System time consumed */
                   union sigval si_value; /* Signal value */
                   int      si_int;       /* POSIX.1b signal */
                   void    *si_ptr;       /* POSIX.1b signal */
                   int      si_overrun;   /* Timer overrun count;
                                             POSIX.1b timers */
                   int      si_timerid;   /* Timer ID; POSIX.1b timers */
                   void    *si_addr;      /* Memory location which caused fault */
                   long     si_band;      /* Band event (was _int_ in
                                             glibc 2.3.2 and earlier) */
                   int      si_fd;        /* File descriptor */
                   short    si_addr_lsb;  /* Least significant bit of address
                                             (since Linux 2.6.32) */
                   void    *si_lower;     /* Lower bound when address violation
                                             occurred (since Linux 3.19) */
                   void    *si_upper;     /* Upper bound when address violation
                                             occurred (since Linux 3.19) */
                   int      si_pkey;      /* Protection key on PTE that caused
                                             fault (since Linux 4.6) */
                   void    *si_call_addr; /* Address of system call instruction
                                             (since Linux 3.5) */
                   int      si_syscall;   /* Number of attempted system call
                                             (since Linux 3.5) */
                   unsigned int si_arch;  /* Architecture of attempted system call
                                             (since Linux 3.5) */
               }
    
           _si_signo_ , _si_errno_ and _si_code_ are defined for all signals.
           (_si_errno_ is generally unused on Linux.)  The rest of the struct
           may be a union, so that one should read only the fields that are
           meaningful for the given signal:
    
           •  Signals sent with kill(2) and sigqueue(3) fill in _si_pid_ and
              _si_uid_.  In addition, signals sent with sigqueue(3) fill in
              _si_int_ and _si_ptr_ with the values specified by the sender of
              the signal; see sigqueue(3) for more details.
    
           •  Signals sent by POSIX.1b timers (since Linux 2.6) fill in
              _si_overrun_ and _si_timerid_.  The _si_timerid_ field is an internal
              ID used by the kernel to identify the timer; it is not the same
              as the timer ID returned by timer_create(2).  The _si_overrun_
              field is the timer overrun count; this is the same information
              as is obtained by a call to timer_getoverrun(2).  These fields
              are nonstandard Linux extensions.
    
           •  Signals sent for message queue notification (see the
              description of **SIGEV_SIGNAL** in mq_notify(3)) fill in
              _si_int_ /_si_ptr_ , with the _sigev_value_ supplied to mq_notify(3);
              _si_pid_ , with the process ID of the message sender; and _si_uid_ ,
              with the real user ID of the message sender.
    
           •  **SIGCHLD** fills in _si_pid_ , _si_uid_ , _si_status_ , _si_utime_ , and
              _si_stime_ , providing information about the child.  The _si_pid_
              field is the process ID of the child; _si_uid_ is the child's
              real user ID.  The _si_status_ field contains the exit status of
              the child (if _si_code_ is **CLD_EXITED**), or the signal number that
              caused the process to change state.  The _si_utime_ and _si_stime_
              contain the user and system CPU time used by the child process;
              these fields do not include the times used by waited-for
              children (unlike getrusage(2) and times(2)).  Up to Linux 2.6,
              and since Linux 2.6.27, these fields report CPU time in units
              of _sysconf(_SC_CLK_TCK)_.  In Linux 2.6 kernels before Linux
              2.6.27, a bug meant that these fields reported time in units of
              the (configurable) system jiffy (see time(7)).
    
           •  **SIGILL** , **SIGFPE** , **SIGSEGV** , **SIGBUS** , and **SIGTRAP** fill in _si_addr_
              with the address of the fault.  On some architectures, these
              signals also fill in the _si_trapno_ field.
    
              Some suberrors of **SIGBUS** , in particular **BUS_MCEERR_AO** and
              **BUS_MCEERR_AR** , also fill in _si_addr_lsb_.  This field indicates
              the least significant bit of the reported address and therefore
              the extent of the corruption.  For example, if a full page was
              corrupted, _si_addr_lsb_ contains _log2(sysconf(_SC_PAGESIZE))_.
              When **SIGTRAP** is delivered in response to a ptrace(2) event
              (PTRACE_EVENT_foo), _si_addr_ is not populated, but _si_pid_ and
              _si_uid_ are populated with the respective process ID and user ID
              responsible for delivering the trap.  In the case of
              seccomp(2), the tracee will be shown as delivering the event.
              **BUS_MCEERR_*** and _si_addr_lsb_ are Linux-specific extensions.
    
              The **SEGV_BNDERR** suberror of **SIGSEGV** populates _si_lower_ and
              _si_upper_.
    
              The **SEGV_PKUERR** suberror of **SIGSEGV** populates _si_pkey_.
    
           •  **SIGIO** /**SIGPOLL**(the two names are synonyms on Linux) fills in
              _si_band_ and _si_fd_.  The _si_band_ event is a bit mask containing
              the same values as are filled in the _revents_ field by poll(2).
              The _si_fd_ field indicates the file descriptor for which the I/O
              event occurred; for further details, see the description of
              **F_SETSIG** in fcntl(2).
    
           •  **SIGSYS** , generated (since Linux 3.5) when a seccomp filter
              returns **SECCOMP_RET_TRAP** , fills in _si_call_addr_ , _si_syscall_ ,
              _si_arch_ , _si_errno_ , and other fields as described in seccomp(2).
    
       **The si_code field**
           The _si_code_ field inside the _siginfo_t_ argument that is passed to
           a **SA_SIGINFO** signal handler is a value (not a bit mask) indicating
           why this signal was sent.  For a ptrace(2) event, _si_code_ will
           contain **SIGTRAP** and have the ptrace event in the high byte:
    
               (SIGTRAP | PTRACE_EVENT_foo << 8).
    
           For a non-ptrace(2) event, the values that can appear in _si_code_
           are described in the remainder of this section.  Since glibc 2.20,
           the definitions of most of these symbols are obtained from
           _< signal.h>_ by defining feature test macros (before including _any_
           header file) as follows:
    
           •  **_XOPEN_SOURCE** with the value 500 or greater;
    
           •  **_XOPEN_SOURCE** and **_XOPEN_SOURCE_EXTENDED** ; or
    
           •  **_POSIX_C_SOURCE** with the value 200809L or greater.
    
           For the **TRAP_*** constants, the symbol definitions are provided only
           in the first two cases.  Before glibc 2.20, no feature test macros
           were required to obtain these symbols.
    
           For a regular signal, the following list shows the values which
           can be placed in _si_code_ for any signal, along with the reason
           that the signal was generated.
    
               **SI_USER**
                      kill(2).
    
               **SI_KERNEL**
                      Sent by the kernel.
    
               **SI_QUEUE**
                      sigqueue(3).
    
               **SI_TIMER**
                      POSIX, or setitimer(2) or alarm(2) timer expired.
    
               **SI_MESGQ**(since Linux 2.6.6)
                      POSIX message queue state changed; see mq_notify(3).
    
               **SI_ASYNCIO**
                      AIO completed.
    
               **SI_SIGIO**
                      Queued **SIGIO**(only up to Linux 2.2; from Linux 2.4
                      onward **SIGIO** /**SIGPOLL** fills in _si_code_ as described
                      below).
    
               **SI_TKILL**(since Linux 2.4.19)
                      tkill(2) or tgkill(2).
    
           The following values can be placed in _si_code_ for a **SIGILL** signal:
    
               **ILL_ILLOPC**
                      Illegal opcode.
    
               **ILL_ILLOPN**
                      Illegal operand.
    
               **ILL_ILLADR**
                      Illegal addressing mode.
    
               **ILL_ILLTRP**
                      Illegal trap.
    
               **ILL_PRVOPC**
                      Privileged opcode.
    
               **ILL_PRVREG**
                      Privileged register.
    
               **ILL_COPROC**
                      Coprocessor error.
    
               **ILL_BADSTK**
                      Internal stack error.
    
           The following values can be placed in _si_code_ for a **SIGFPE** signal:
    
               **FPE_INTDIV**
                      Integer divide by zero.
    
               **FPE_INTOVF**
                      Integer overflow.
    
               **FPE_FLTDIV**
                      Floating-point divide by zero.
    
               **FPE_FLTOVF**
                      Floating-point overflow.
    
               **FPE_FLTUND**
                      Floating-point underflow.
    
               **FPE_FLTRES**
                      Floating-point inexact result.
    
               **FPE_FLTINV**
                      Floating-point invalid operation.
    
               **FPE_FLTSUB**
                      Subscript out of range.
    
           The following values can be placed in _si_code_ for a **SIGSEGV**
           signal:
    
               **SEGV_MAPERR**
                      Address not mapped to object.
    
               **SEGV_ACCERR**
                      Invalid permissions for mapped object.
    
               **SEGV_BNDERR**(since Linux 3.19)
                      Failed address bound checks.
    
               **SEGV_PKUERR**(since Linux 4.6)
                      Access was denied by memory protection keys.  See
                      pkeys(7).  The protection key which applied to this
                      access is available via _si_pkey_.
    
           The following values can be placed in _si_code_ for a **SIGBUS** signal:
    
               **BUS_ADRALN**
                      Invalid address alignment.
    
               **BUS_ADRERR**
                      Nonexistent physical address.
    
               **BUS_OBJERR**
                      Object-specific hardware error.
    
               **BUS_MCEERR_AR**(since Linux 2.6.32)
                      Hardware memory error consumed on a machine check;
                      action required.
    
               **BUS_MCEERR_AO**(since Linux 2.6.32)
                      Hardware memory error detected in process but not
                      consumed; action optional.
    
           The following values can be placed in _si_code_ for a **SIGTRAP**
           signal:
    
               **TRAP_BRKPT**
                      Process breakpoint.
    
               **TRAP_TRACE**
                      Process trace trap.
    
               **TRAP_BRANCH**(since Linux 2.4, IA64 only)
                      Process taken branch trap.
    
               **TRAP_HWBKPT**(since Linux 2.4, IA64 only)
                      Hardware breakpoint/watchpoint.
    
           The following values can be placed in _si_code_ for a **SIGCHLD**
           signal:
    
               **CLD_EXITED**
                      Child has exited.
    
               **CLD_KILLED**
                      Child was killed.
    
               **CLD_DUMPED**
                      Child terminated abnormally.
    
               **CLD_TRAPPED**
                      Traced child has trapped.
    
               **CLD_STOPPED**
                      Child has stopped.
    
               **CLD_CONTINUED**(since Linux 2.6.9)
                      Stopped child has continued.
    
           The following values can be placed in _si_code_ for a **SIGIO** /**SIGPOLL**
           signal:
    
               **POLL_IN**
                      Data input available.
    
               **POLL_OUT**
                      Output buffers available.
    
               **POLL_MSG**
                      Input message available.
    
               **POLL_ERR**
                      I/O error.
    
               **POLL_PRI**
                      High priority input available.
    
               **POLL_HUP**
                      Device disconnected.
    
           The following value can be placed in _si_code_ for a **SIGSYS** signal:
    
               **SYS_SECCOMP**(since Linux 3.5)
                      Triggered by a seccomp(2) filter rule.
    
       **Dynamically probing for flag bit support**
           The **sigaction**() call on Linux accepts unknown bits set in
           _act- >sa_flags_ without error.  The behavior of the kernel starting
           with Linux 5.11 is that a second **sigaction**() will clear unknown
           bits from _oldact- >sa_flags_.  However, historically, a second
           **sigaction**() call would typically leave those bits set in
           _oldact- >sa_flags_.
    
           This means that support for new flags cannot be detected simply by
           testing for a flag in _sa_flags_ , and a program must test that
           **SA_UNSUPPORTED** has been cleared before relying on the contents of
           _sa_flags_.
    
           Since the behavior of the signal handler cannot be guaranteed
           unless the check passes, it is wise to either block the affected
           signal while registering the handler and performing the check in
           this case, or where this is not possible, for example if the
           signal is synchronous, to issue the second **sigaction**() in the
           signal handler itself.
    
           In kernels that do not support a specific flag, the kernel's
           behavior is as if the flag was not set, even if the flag was set
           in _act- >sa_flags_.
    
           The flags **SA_NOCLDSTOP** , **SA_NOCLDWAIT** , **SA_SIGINFO** , **SA_ONSTACK** ,
           **SA_RESTART** , **SA_NODEFER** , **SA_RESETHAND** , and, if defined by the
           architecture, **SA_RESTORER** may not be reliably probed for using
           this mechanism, because they were introduced before Linux 5.11.
           However, in general, programs may assume that these flags are
           supported, since they have all been supported since Linux 2.6,
           which was released in the year 2003.
    
           See EXAMPLES below for a demonstration of the use of
           **SA_UNSUPPORTED**.
    


## RETURN VALUE



           **sigaction**() returns 0 on success; on error, -1 is returned, and
           _errno_ is set to indicate the error.
    


## ERRORS



           **EFAULT** _act_ or _oldact_ points to memory which is not a valid part of
                  the process address space.
    
           **EINVAL** An invalid signal was specified.  This will also be
                  generated if an attempt is made to change the action for
                  **SIGKILL** or **SIGSTOP** , which cannot be caught or ignored.
    


## VERSIONS



       **C library/kernel differences**
           The glibc wrapper function for **sigaction**() gives an error (**EINVAL**)
           on attempts to change the disposition of the two real-time signals
           used internally by the NPTL threading implementation.  See nptl(7)
           for details.
    
           On architectures where the signal trampoline resides in the C
           library, the glibc wrapper function for **sigaction**() places the
           address of the trampoline code in the _act.sa_restorer_ field and
           sets the **SA_RESTORER** flag in the _act.sa_flags_ field.  See
           sigreturn(2).
    
           The original Linux system call was named **sigaction**().  However,
           with the addition of real-time signals in Linux 2.2, the fixed-
           size, 32-bit _sigset_t_ type supported by that system call was no
           longer fit for purpose.  Consequently, a new system call,
           **rt_sigaction**(), was added to support an enlarged _sigset_t_ type.
           The new system call takes a fourth argument, _size_t sigsetsize_ ,
           which specifies the size in bytes of the signal sets in
           _act.sa_mask_ and _oldact.sa_mask_.  This argument is currently
           required to have the value _sizeof(sigset_t)_ (or the error **EINVAL**
           results).  The glibc **sigaction**() wrapper function hides these
           details from us, transparently calling **rt_sigaction**() when the
           kernel provides it.
    


## STANDARDS



           POSIX.1-2008.
    


## NOTES



           A child created via fork(2) inherits a copy of its parent's signal
           dispositions.  During an execve(2), the dispositions of handled
           signals are reset to the default; the dispositions of ignored
           signals are left unchanged.
    
           According to POSIX, the behavior of a process is undefined after
           it ignores a **SIGFPE** , **SIGILL** , or **SIGSEGV** signal that was not
           generated by kill(2) or raise(3).  Integer division by zero has
           undefined result.  On some architectures it will generate a **SIGFPE**
           signal.  (Also dividing the most negative integer by -1 may
           generate **SIGFPE**.)  Ignoring this signal might lead to an endless
           loop.
    
           **sigaction**() can be called with a NULL second argument to query the
           current signal handler.  It can also be used to check whether a
           given signal is valid for the current machine by calling it with
           NULL second and third arguments.
    
           It is not possible to block **SIGKILL** or **SIGSTOP**(by specifying them
           in _sa_mask_).  Attempts to do so are silently ignored.
    
           See sigsetops(3) for details on manipulating signal sets.
    
           See signal-safety(7) for a list of the async-signal-safe functions
           that can be safely called inside from inside a signal handler.
    
           POSIX only guarantees **SI_TIMER** for signals created by
           timer_create(2).  Implementations are free to also provide it for
           other types of timers.  The Linux behaviour matches NetBSD.
    
       **Undocumented**
           Before the introduction of **SA_SIGINFO** , it was also possible to get
           some additional information about the signal.  This was done by
           providing an _sa_handler_ signal handler with a second argument of
           type _struct sigcontext_ , which is the same structure as the one
           that is passed in the _uc_mcontext_ field of the _ucontext_ structure
           that is passed (via a pointer) in the third argument of the
           _sa_sigaction_ handler.  See the relevant Linux kernel sources for
           details.  This use is obsolete now.
    


## BUGS



           When delivering a signal resulting from a hardware exception with
           a **SA_SIGINFO** handler, the kernel does not always provide
           meaningful values for all of the fields of the _siginfo_t_ that are
           relevant for that signal.  For example, when the x86 _int_
           instruction is called with a forbidden argument (any number other
           than 3 or 128), a **SIGSEGV** signal is delivered, but the _siginfo_t_
           passed to the signal handler has all its fields besides _si_signo_
           and _si_code_ set to zero, even if other fields should be set (as an
           example, _si_addr_ should be non-zero for all **SIGSEGV** signals).
    
           Up to and including Linux 2.6.13, specifying **SA_NODEFER** in
           _sa_flags_ prevents not only the delivered signal from being masked
           during execution of the handler, but also the signals specified in
           _sa_mask_.  This bug was fixed in Linux 2.6.14.
    


## EXAMPLES



           See mprotect(2).
    
       **Probing for flag support**
           The following example program exits with status **EXIT_SUCCESS** if
           **SA_EXPOSE_TAGBITS** is determined to be supported, and **EXIT_FAILURE**
           otherwise.
    
           #include <signal.h>
           #include <stdio.h>
           #include <stdlib.h>
           #include <unistd.h>
    
           static void
           handler(int signo, siginfo_t *info, void *context)
           {
               struct sigaction oldact;
    
               if (sigaction(SIGSEGV, NULL, &oldact) == -1
                   || (oldact.sa_flags & SA_UNSUPPORTED)
                   || !(oldact.sa_flags & SA_EXPOSE_TAGBITS))
               {
                   _exit(EXIT_FAILURE);
               }
               _exit(EXIT_SUCCESS);
           }
    
           int
           main(void)
           {
               struct sigaction act = { 0 };
    
               act.sa_flags = SA_SIGINFO | SA_UNSUPPORTED | SA_EXPOSE_TAGBITS;
               act.sa_sigaction = &handler;
               if (sigaction(SIGSEGV, &act, NULL) == -1) {
                   perror("sigaction");
                   exit(EXIT_FAILURE);
               }
    
               raise(SIGSEGV);
           }
    


* * *