mirror of https://github.com/mkerrisk/man-pages
404 lines
10 KiB
Groff
404 lines
10 KiB
Groff
.\" Copyright (C) 2008 Michael Kerrisk <mtk.manpages@gmail.com>
|
|
.\" starting from a version by Davide Libenzi <davidel@xmailserver.org>
|
|
.\"
|
|
.\" This program is free software; you can redistribute it and/or modify
|
|
.\" it under the terms of the GNU General Public License as published by
|
|
.\" the Free Software Foundation; either version 2 of the License, or
|
|
.\" (at your option) any later version.
|
|
.\"
|
|
.\" This program is distributed in the hope that it will be useful,
|
|
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
.\" GNU General Public License for more details.
|
|
.\"
|
|
.\" You should have received a copy of the GNU General Public License
|
|
.\" along with this program; if not, write to the Free Software
|
|
.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
.\" MA 02111-1307 USA
|
|
.\"
|
|
.TH SIGNALFD 2 2008-02-11 Linux "Linux Programmer's Manual"
|
|
.SH NAME
|
|
signalfd \- create a file descriptor for accepting signals
|
|
.SH SYNOPSIS
|
|
.B #include <sys/signalfd.h>
|
|
.sp
|
|
.BI "int signalfd(int " fd ", const sigset_t *" mask ", int " flags );
|
|
.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).
|
|
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 .
|
|
|
|
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 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 descriptor.
|
|
|
|
The
|
|
.I flags
|
|
argument is currently unused, and must be specified as zero.
|
|
In the future, it may be used to request additional functionality.
|
|
|
|
.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 non-blocking
|
|
(via the use of the
|
|
.BR fcntl (2)
|
|
.B F_SETFL
|
|
operation to set the
|
|
.B O_NONBLOCK
|
|
flag).
|
|
.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:
|
|
.in +4n
|
|
.nf
|
|
|
|
struct signalfd_siginfo {/
|
|
uint32_t ssi_signo;
|
|
int32_t ssi_errno;
|
|
int32_t ssi_code;
|
|
uint32_t ssi_pid;
|
|
uint32_t ssi_uid;
|
|
int32_t ssi_fd;
|
|
uint32_t ssi_tid;
|
|
uint32_t ssi_band;
|
|
uint32_t ssi_overrun;
|
|
uint32_t ssi_trapno;
|
|
.\" ssi_trapno is unused on most (all?) arches?
|
|
int32_t ssi_status;
|
|
int32_t ssi_int;
|
|
uintptr_t ssi_ptr;
|
|
uint64_t ssi_utime;
|
|
uint64_t ssi_stime;
|
|
uint64_t ssi_addr;
|
|
uint8_t pad[\fIX\fP]; /* Pad size to 128 bytes (allow space
|
|
additional fields in the future) */
|
|
};
|
|
|
|
.fi
|
|
.in
|
|
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.
|
|
The file descriptor refers to the same underlying
|
|
file object as the corresponding descriptor in the parent,
|
|
and
|
|
.BR read (2)s
|
|
in the child will return information about signals generated
|
|
for the parent
|
|
(the process that created the object using
|
|
.BR signalfd ().
|
|
.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).)
|
|
(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.)
|
|
.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,
|
|
.I flags
|
|
is nonzero.
|
|
.\" Eventually glibc may support some flags
|
|
.\" or, the
|
|
.\" .I sizemask
|
|
.\" argument is not equal to
|
|
.\" .IR sizeof(sigset_t) ;
|
|
.TP
|
|
.B EMFILE
|
|
The per-process limit 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
|
|
.BR signalfd ()
|
|
is available on Linux since kernel 2.6.22.
|
|
Working support is provided in glibc since version 2.8.
|
|
.\" signalfd() is in glibc 2.7, but reportedly does not build
|
|
.SH CONFORMING TO
|
|
.BR signalfd ()
|
|
is Linux-specific.
|
|
.SH NOTES
|
|
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.
|
|
|
|
The
|
|
.I flags
|
|
argument is a glibc addition to the underlying system call.
|
|
|
|
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 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 descriptors.
|
|
.SH EXAMPLE
|
|
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:
|
|
.in +4n
|
|
.nf
|
|
|
|
$ ./signalfd_demo
|
|
^C # Control\-C generates SIGINT
|
|
Got SIGINT
|
|
^C
|
|
Got SIGINT
|
|
^\\ # Control\-\\ generates SIGQUIT
|
|
Got SIGQUIT
|
|
$
|
|
.fi
|
|
.in
|
|
.nf
|
|
|
|
#include <sys/signalfd.h>
|
|
#include <signal.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
|
|
#define handle_error(msg) \\
|
|
do { perror(msg); exit(EXIT_FAILURE); } while (0)
|
|
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
sigset_t mask;
|
|
int sfd;
|
|
struct signalfd_siginfo fdsi;
|
|
ssize_t s;
|
|
|
|
sigemptyset(&mask);
|
|
sigaddset(&mask, SIGINT);
|
|
sigaddset(&mask, SIGQUIT);
|
|
|
|
/* Block signals so that they aren't handled
|
|
according to their default dispositions */
|
|
|
|
if (sigprocmask(SIG_BLOCK, &mask, NULL) == \-1)
|
|
handle_error("sigprocmask");
|
|
|
|
sfd = signalfd(\-1, &mask, 0);
|
|
if (sfd == \-1)
|
|
handle_error("signalfd");
|
|
|
|
for (;;) {
|
|
s = read(sfd, &fdsi, sizeof(struct signalfd_siginfo));
|
|
if (s != sizeof(struct signalfd_siginfo))
|
|
handle_error("read");
|
|
|
|
if (fdsi.signo == SIGINT) {
|
|
printf("Got SIGINT\\n");
|
|
} else if (fdsi.signo == SIGQUIT) {
|
|
printf("Got SIGQUIT\\n");
|
|
exit(EXIT_SUCCESS);
|
|
} else {
|
|
printf("Read unexpected signal\\n");
|
|
}
|
|
}
|
|
}
|
|
.fi
|
|
.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 epoll (7),
|
|
.BR signal (7)
|
|
.\" FIXME add SEE ALSO from signal.7, signal.2, sigwaitinfo.2,
|
|
.\" sigaction.2 to this page
|