mirror of https://github.com/mkerrisk/man-pages
sigaction.2: Document SA_EXPOSE_TAGBITS and the flag support detection protocol
Signed-off-by: Peter Collingbourne <pcc@google.com> Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com> Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
This commit is contained in:
parent
9b6cce9936
commit
7dd4af5158
123
man2/sigaction.2
123
man2/sigaction.2
|
@ -261,6 +261,44 @@ This flag is meaningful only when establishing a signal handler.
|
|||
.\" .I sa_sigaction
|
||||
.\" field was added in Linux 2.1.86.)
|
||||
.\"
|
||||
.TP
|
||||
.B SA_UNSUPPORTED
|
||||
Used to dynamically probe for flag bit support.
|
||||
.IP
|
||||
If an attempt to register a handler succeeds with this flag set in
|
||||
.I act->sa_flags
|
||||
alongside other flags that are potentially unsupported by the kernel,
|
||||
and an immediately subsequent
|
||||
.BR sigaction ()
|
||||
call specifying the same signal number n and with non-NULL
|
||||
.I oldact
|
||||
yields
|
||||
.B SA_UNSUPPORTED
|
||||
.I clear
|
||||
in
|
||||
.IR oldact->sa_flags ,
|
||||
then
|
||||
.I 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.
|
||||
.TP
|
||||
.BR SA_EXPOSE_TAGBITS " (since Linux 5.11)"
|
||||
Normally, when delivering a signal,
|
||||
an architecture-specific set of tag bits are cleared from the
|
||||
.I si_addr
|
||||
field of
|
||||
.IR siginfo_t .
|
||||
If this flag is set,
|
||||
an architecture-specific subset of the tag bits will be preserved in
|
||||
.IR si_addr .
|
||||
.IP
|
||||
Programs that need to be compatible with Linux versions older than 5.11
|
||||
must use
|
||||
.B SA_UNSUPPORTED
|
||||
to probe for support.
|
||||
.SS The siginfo_t argument to a SA_SIGINFO handler
|
||||
When the
|
||||
.B SA_SIGINFO
|
||||
|
@ -846,6 +884,91 @@ Triggered by a
|
|||
.BR seccomp (2)
|
||||
filter rule.
|
||||
.RE
|
||||
.SS Dynamically probing for flag bit support
|
||||
The
|
||||
.BR sigaction ()
|
||||
call on Linux accepts unknown bits set in
|
||||
.I act->sa_flags
|
||||
without error.
|
||||
The behavior of the kernel starting with Linux 5.11 is that a second
|
||||
.BR sigaction ()
|
||||
will clear unknown bits from
|
||||
.IR oldact->sa_flags .
|
||||
However, historically, a second
|
||||
.BR sigaction ()
|
||||
call would typically leave those bits set in
|
||||
.IR oldact->sa_flags .
|
||||
.PP
|
||||
This means that support for new flags cannot be detected
|
||||
simply by testing for a flag in
|
||||
.IR sa_flags ,
|
||||
and a program must test that
|
||||
.B SA_UNSUPPORTED
|
||||
has been cleared before relying on the contents of
|
||||
.IR sa_flags .
|
||||
.PP
|
||||
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
|
||||
.BR sigaction ()
|
||||
in the signal handler itself.
|
||||
.PP
|
||||
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
|
||||
.IR act->sa_flags .
|
||||
.PP
|
||||
The flags
|
||||
.BR SA_NOCLDSTOP ,
|
||||
.BR SA_NOCLDWAIT ,
|
||||
.BR SA_SIGINFO ,
|
||||
.BR SA_ONSTACK ,
|
||||
.BR SA_RESTART ,
|
||||
.BR SA_NODEFER ,
|
||||
.BR SA_RESETHAND ,
|
||||
and, if defined by the architecture,
|
||||
.B 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.
|
||||
.PP
|
||||
The following example program exits with status 0 if
|
||||
.B SA_EXPOSE_TAGBITS
|
||||
is determined to be supported, and 1 otherwise.
|
||||
.PP
|
||||
.EX
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void handler(int signo, siginfo_t *info, void *context) {
|
||||
struct sigaction oldact;
|
||||
if (sigaction(SIGSEGV, 0, &oldact) == 0 &&
|
||||
!(oldact.sa_flags & SA_UNSUPPORTED) &&
|
||||
(oldact.sa_flags & SA_EXPOSE_TAGBITS)) {
|
||||
_exit(0);
|
||||
} else {
|
||||
_exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
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, 0) != 0) {
|
||||
perror("sigaction");
|
||||
return 1;
|
||||
}
|
||||
|
||||
raise(SIGSEGV);
|
||||
}
|
||||
.EE
|
||||
.SH RETURN VALUE
|
||||
.BR sigaction ()
|
||||
returns 0 on success; on error, \-1 is returned, and
|
||||
|
|
Loading…
Reference in New Issue