diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 19:40:15 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 19:40:15 +0000 |
commit | 399644e47874bff147afb19c89228901ac39340e (patch) | |
tree | 1c4c0b733f4c16b5783b41bebb19194a9ef62ad1 /man2/signalfd.2 | |
parent | Initial commit. (diff) | |
download | manpages-399644e47874bff147afb19c89228901ac39340e.tar.xz manpages-399644e47874bff147afb19c89228901ac39340e.zip |
Adding upstream version 6.05.01.upstream/6.05.01
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'man2/signalfd.2')
-rw-r--r-- | man2/signalfd.2 | 521 |
1 files changed, 521 insertions, 0 deletions
diff --git a/man2/signalfd.2 b/man2/signalfd.2 new file mode 100644 index 0000000..9af22b0 --- /dev/null +++ b/man2/signalfd.2 @@ -0,0 +1,521 @@ +.\" Copyright (C) 2008 Michael Kerrisk <mtk.manpages@gmail.com> +.\" starting from a version by Davide Libenzi <davidel@xmailserver.org> +.\" +.\" SPDX-License-Identifier: GPL-2.0-or-later +.\" +.TH signalfd 2 2023-05-03 "Linux man-pages 6.05.01" +.SH NAME +signalfd \- create a file descriptor for accepting signals +.SH LIBRARY +Standard C library +.RI ( libc ", " \-lc ) +.SH SYNOPSIS +.nf +.B #include <sys/signalfd.h> +.PP +.BI "int signalfd(int " fd ", const sigset_t *" mask ", int " flags ); +.fi +.SH DESCRIPTION +.BR signalfd () +creates a file descriptor that can be used to accept signals +targeted at the caller. +This provides an alternative to the use of a signal handler or +.BR sigwaitinfo (2), +and has the advantage that the file descriptor may be monitored by +.BR select (2), +.BR poll (2), +and +.BR epoll (7). +.PP +The +.I mask +argument specifies the set of signals that the caller +wishes to accept via the file descriptor. +This argument is a signal set whose contents can be initialized +using the macros described in +.BR sigsetops (3). +Normally, the set of signals to be received via the +file descriptor should be blocked using +.BR sigprocmask (2), +to prevent the signals being handled according to their default +dispositions. +It is not possible to receive +.B SIGKILL +or +.B SIGSTOP +signals via a signalfd file descriptor; +these signals are silently ignored if specified in +.IR mask . +.PP +If the +.I fd +argument is \-1, +then the call creates a new file descriptor and associates the +signal set specified in +.I mask +with that file descriptor. +If +.I fd +is not \-1, +then it must specify a valid existing signalfd file descriptor, and +.I mask +is used to replace the signal set associated with that file descriptor. +.PP +Starting with Linux 2.6.27, the following values may be bitwise ORed in +.I flags +to change the behavior of +.BR signalfd (): +.TP 14 +.B SFD_NONBLOCK +Set the +.B O_NONBLOCK +file status flag on the open file description (see +.BR open (2)) +referred to by the new file descriptor. +Using this flag saves extra calls to +.BR fcntl (2) +to achieve the same result. +.TP +.B SFD_CLOEXEC +Set the close-on-exec +.RB ( FD_CLOEXEC ) +flag on the new file descriptor. +See the description of the +.B O_CLOEXEC +flag in +.BR open (2) +for reasons why this may be useful. +.PP +Up to Linux 2.6.26, the +.I flags +argument is unused, and must be specified as zero. +.PP +.BR signalfd () +returns a file descriptor that supports the following operations: +.TP +.BR read (2) +If one or more of the signals specified in +.I mask +is pending for the process, then the buffer supplied to +.BR read (2) +is used to return one or more +.I signalfd_siginfo +structures (see below) that describe the signals. +The +.BR read (2) +returns information for as many signals as are pending and will +fit in the supplied buffer. +The buffer must be at least +.I "sizeof(struct signalfd_siginfo)" +bytes. +The return value of the +.BR read (2) +is the total number of bytes read. +.IP +As a consequence of the +.BR read (2), +the signals are consumed, +so that they are no longer pending for the process +(i.e., will not be caught by signal handlers, +and cannot be accepted using +.BR sigwaitinfo (2)). +.IP +If none of the signals in +.I mask +is pending for the process, then the +.BR read (2) +either blocks until one of the signals in +.I mask +is generated for the process, +or fails with the error +.B EAGAIN +if the file descriptor has been made nonblocking. +.TP +.BR poll "(2), " select "(2) (and similar)" +The file descriptor is readable +(the +.BR select (2) +.I readfds +argument; the +.BR poll (2) +.B POLLIN +flag) +if one or more of the signals in +.I mask +is pending for the process. +.IP +The signalfd file descriptor also supports the other file-descriptor +multiplexing APIs: +.BR pselect (2), +.BR ppoll (2), +and +.BR epoll (7). +.TP +.BR close (2) +When the file descriptor is no longer required it should be closed. +When all file descriptors associated with the same signalfd object +have been closed, the resources for object are freed by the kernel. +.SS The signalfd_siginfo structure +The format of the +.I signalfd_siginfo +structure(s) returned by +.BR read (2)s +from a signalfd file descriptor is as follows: +.PP +.in +4n +.EX +struct signalfd_siginfo { + uint32_t ssi_signo; /* Signal number */ + int32_t ssi_errno; /* Error number (unused) */ + int32_t ssi_code; /* Signal code */ + uint32_t ssi_pid; /* PID of sender */ + uint32_t ssi_uid; /* Real UID of sender */ + int32_t ssi_fd; /* File descriptor (SIGIO) */ + uint32_t ssi_tid; /* Kernel timer ID (POSIX timers) + uint32_t ssi_band; /* Band event (SIGIO) */ + uint32_t ssi_overrun; /* POSIX timer overrun count */ + uint32_t ssi_trapno; /* Trap number that caused signal */ +.\" ssi_trapno is unused on most arches + int32_t ssi_status; /* Exit status or signal (SIGCHLD) */ + int32_t ssi_int; /* Integer sent by sigqueue(3) */ + uint64_t ssi_ptr; /* Pointer sent by sigqueue(3) */ + uint64_t ssi_utime; /* User CPU time consumed (SIGCHLD) */ + uint64_t ssi_stime; /* System CPU time consumed + (SIGCHLD) */ + uint64_t ssi_addr; /* Address that generated signal + (for hardware\-generated signals) */ + uint16_t ssi_addr_lsb; /* Least significant bit of address + (SIGBUS; since Linux 2.6.37) */ +.\" ssi_addr_lsb: commit b8aeec34175fc8fe8b0d40efea4846dfc1ba663e + uint8_t pad[\fIX\fP]; /* Pad size to 128 bytes (allow for + additional fields in the future) */ +}; +.EE +.in +.PP +Each of the fields in this structure +is analogous to the similarly named field in the +.I siginfo_t +structure. +The +.I siginfo_t +structure is described in +.BR sigaction (2). +Not all fields in the returned +.I signalfd_siginfo +structure will be valid for a specific signal; +the set of valid fields can be determined from the value returned in the +.I ssi_code +field. +This field is the analog of the +.I siginfo_t +.I si_code +field; see +.BR sigaction (2) +for details. +.SS fork(2) semantics +After a +.BR fork (2), +the child inherits a copy of the signalfd file descriptor. +A +.BR read (2) +from the file descriptor in the child will return information +about signals queued to the child. +.SS Semantics of file descriptor passing +As with other file descriptors, +signalfd file descriptors can be passed to another process +via a UNIX domain socket (see +.BR unix (7)). +In the receiving process, a +.BR read (2) +from the received file descriptor will return information +about signals queued to that process. +.SS execve(2) semantics +Just like any other file descriptor, +a signalfd file descriptor remains open across an +.BR execve (2), +unless it has been marked for close-on-exec (see +.BR fcntl (2)). +Any signals that were available for reading before the +.BR execve (2) +remain available to the newly loaded program. +(This is analogous to traditional signal semantics, +where a blocked signal that is pending remains pending across an +.BR execve (2).) +.SS Thread semantics +The semantics of signalfd file descriptors in a multithreaded program +mirror the standard semantics for signals. +In other words, +when a thread reads from a signalfd file descriptor, +it will read the signals that are directed to the thread +itself and the signals that are directed to the process +(i.e., the entire thread group). +(A thread will not be able to read signals that are directed +to other threads in the process.) +.\" +.SS epoll(7) semantics +If a process adds (via +.BR epoll_ctl (2)) +a signalfd file descriptor to an +.BR epoll (7) +instance, then +.BR epoll_wait (2) +returns events only for signals sent to that process. +In particular, if the process then uses +.BR fork (2) +to create a child process, then the child will be able to +.BR read (2) +signals that are sent to it using the signalfd file descriptor, but +.BR epoll_wait (2) +will +.B not +indicate that the signalfd file descriptor is ready. +In this scenario, a possible workaround is that after the +.BR fork (2), +the child process can close the signalfd file descriptor that it inherited +from the parent process and then create another signalfd file descriptor +and add it to the epoll instance. +Alternatively, the parent and the child could delay creating their +(separate) signalfd file descriptors and adding them to the +epoll instance until after the call to +.BR fork (2). +.SH RETURN VALUE +On success, +.BR signalfd () +returns a signalfd file descriptor; +this is either a new file descriptor (if +.I fd +was \-1), or +.I fd +if +.I fd +was a valid signalfd file descriptor. +On error, \-1 is returned and +.I errno +is set to indicate the error. +.SH ERRORS +.TP +.B EBADF +The +.I fd +file descriptor is not a valid file descriptor. +.TP +.B EINVAL +.I fd +is not a valid signalfd file descriptor. +.\" or, the +.\" .I sizemask +.\" argument is not equal to +.\" .IR sizeof(sigset_t) ; +.TP +.B EINVAL +.I flags +is invalid; +or, in Linux 2.6.26 or earlier, +.I flags +is nonzero. +.TP +.B EMFILE +The per-process limit on the number of open file descriptors has been reached. +.TP +.B ENFILE +The system-wide limit on the total number of open files has been +reached. +.TP +.B ENODEV +Could not mount (internal) anonymous inode device. +.TP +.B ENOMEM +There was insufficient memory to create a new signalfd file descriptor. +.SH VERSIONS +.SS C library/kernel differences +The underlying Linux system call requires an additional argument, +.IR "size_t sizemask" , +which specifies the size of the +.I mask +argument. +The glibc +.BR signalfd () +wrapper function does not include this argument, +since it provides the required value for the underlying system call. +.PP +There are two underlying Linux system calls: +.BR signalfd () +and the more recent +.BR signalfd4 (). +The former system call does not implement a +.I flags +argument. +The latter system call implements the +.I flags +values described above. +Starting with glibc 2.9, the +.BR signalfd () +wrapper function will use +.BR signalfd4 () +where it is available. +.SH STANDARDS +Linux. +.SH HISTORY +.TP +.BR signalfd () +Linux 2.6.22, +glibc 2.8. +.\" signalfd() is in glibc 2.7, but reportedly does not build +.TP +.BR signalfd4 () +Linux 2.6.27. +.SH NOTES +A process can create multiple signalfd file descriptors. +This makes it possible to accept different signals +on different file descriptors. +(This may be useful if monitoring the file descriptors using +.BR select (2), +.BR poll (2), +or +.BR epoll (7): +the arrival of different signals will make different file descriptors ready.) +If a signal appears in the +.I mask +of more than one of the file descriptors, then occurrences +of that signal can be read (once) from any one of the file descriptors. +.PP +Attempts to include +.B SIGKILL +and +.B SIGSTOP +in +.I mask +are silently ignored. +.PP +The signal mask employed by a signalfd file descriptor can be viewed +via the entry for the corresponding file descriptor in the process's +.IR /proc/ pid /fdinfo +directory. +See +.BR proc (5) +for further details. +.\" +.SS Limitations +The signalfd mechanism can't be used to receive signals that +are synchronously generated, such as the +.B SIGSEGV +signal that results from accessing an invalid memory address +or the +.B SIGFPE +signal that results from an arithmetic error. +Such signals can be caught only via signal handler. +.PP +As described above, +in normal usage one blocks the signals that will be accepted via +.BR signalfd (). +If spawning a child process to execute a helper program +(that does not need the signalfd file descriptor), +then, after the call to +.BR fork (2), +you will normally want to unblock those signals before calling +.BR execve (2), +so that the helper program can see any signals that it expects to see. +Be aware, however, +that this won't be possible in the case of a helper program spawned +behind the scenes by any library function that the program may call. +In such cases, one must fall back to using a traditional signal +handler that writes to a file descriptor monitored by +.BR select (2), +.BR poll (2), +or +.BR epoll (7). +.SH BUGS +Before Linux 2.6.25, the +.I ssi_ptr +and +.I ssi_int +fields are not filled in with the data accompanying a signal sent by +.BR sigqueue (3). +.\" The fix also was put into Linux 2.6.24.5 +.SH EXAMPLES +The program below accepts the signals +.B SIGINT +and +.B SIGQUIT +via a signalfd file descriptor. +The program terminates after accepting a +.B SIGQUIT +signal. +The following shell session demonstrates the use of the program: +.PP +.in +4n +.EX +.RB "$" " ./signalfd_demo" +.BR "\[ha]C" " # Control\-C generates SIGINT" +Got SIGINT +.B \[ha]C +Got SIGINT +\fB\[ha]\e\fP # Control\-\e generates SIGQUIT +Got SIGQUIT +$ +.EE +.in +.SS Program source +\& +.\" SRC BEGIN (signalfd.c) +.EX +#include <err.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/signalfd.h> +#include <unistd.h> +\& +int +main(void) +{ + int sfd; + ssize_t s; + sigset_t mask; + struct signalfd_siginfo fdsi; +\& + sigemptyset(&mask); + sigaddset(&mask, SIGINT); + sigaddset(&mask, SIGQUIT); +\& + /* Block signals so that they aren\[aq]t handled + according to their default dispositions. */ +\& + if (sigprocmask(SIG_BLOCK, &mask, NULL) == \-1) + err(EXIT_FAILURE, "sigprocmask"); +\& + sfd = signalfd(\-1, &mask, 0); + if (sfd == \-1) + err(EXIT_FAILURE, "signalfd"); +\& + for (;;) { + s = read(sfd, &fdsi, sizeof(fdsi)); + if (s != sizeof(fdsi)) + err(EXIT_FAILURE, "read"); +\& + if (fdsi.ssi_signo == SIGINT) { + printf("Got SIGINT\en"); + } else if (fdsi.ssi_signo == SIGQUIT) { + printf("Got SIGQUIT\en"); + exit(EXIT_SUCCESS); + } else { + printf("Read unexpected signal\en"); + } + } +} +.EE +.\" SRC END +.SH SEE ALSO +.BR eventfd (2), +.BR poll (2), +.BR read (2), +.BR select (2), +.BR sigaction (2), +.BR sigprocmask (2), +.BR sigwaitinfo (2), +.BR timerfd_create (2), +.BR sigsetops (3), +.BR sigwait (3), +.BR epoll (7), +.BR signal (7) |