signalfd(2) System Calls Manual signalfd(2) signalfd - (libc -lc) #include int signalfd(int fd, const sigset_t *mask, int flags); signalfd() . sigwaitinfo(2) select(2) poll(2) epoll(7). mask . sigsetops(3). sigprocmask(2) . SIGKILL SIGSTOP signalfd mask. fd -1 mask . fd -1 signalfd mask . 2.6.27 OR flags signalfd(): SFD_NONBLOCK O_NONBLOCK ( open(2)) . fcntl(2) . SFD_CLOEXEC (FD_CLOEXEC) . O_CLOEXEC open(2) . 2.6.26 flags . signalfd() : read(2) mask read(2) signalfd_siginfo ( ) . read(2) . sizeof(struct signalfd_siginfo) . read(2) . read(2) ( sigwaitinfo(2)). mask read(2) mask EAGAIN . poll(2) select(2) ( ) ( select(2) readfds poll(2) POLLIN) mask . signalfd : pselect(2) ppoll(2) epoll(7). close(2) . signalfd . signalfd_siginfo () signalfd_siginfo read(2) signalfd : 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 */ 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) */ uint8_t pad[X]; /* Pad size to 128 bytes (allow for additional fields in the future) */ }; siginfo_t. siginfo_t sigaction(2). signalfd_siginfo ssi_code. si_code siginfo_t sigaction(2) . fork(2) fork(2) signalfd. read(2) . signalfd UNIX ( unix(7)). read(2) . execve(2) signalfd execve(2) ( fcntl(2)). execve(2) . ( execve(2).) signalfd . signalfd ( ). ( .) epoll(7) ( epoll_ctl(2)) signalfd epoll(7) epoll_wait(2) . fork(2) read(2) signalfd epoll_wait(2) signalfd . fork(2) signalfd signalfd epoll. signalfd () epoll fork(2). signalfd() signalfd ( fd -1) fd fd signalfd . -1 errno . EBADF fd . EINVAL fd signalfd . EINVAL flags 2.6.26 flags . EMFILE . ENFILE . ENODEV inode () . ENOMEM signalfd . C Linux size_t sizemask mask. signalfd() glibc . Linux: signalfd() signalfd4(). flags. flags . glibc 2.9 signalfd() signalfd4() . . signalfd() 2.6.22 glibc 2.8. signalfd4() 2.6.27. signalfd . . ( select(2) poll(2) epoll(7): .) mask ( ) . SIGKILL SIGSTOP mask . signalfd /proc/pid/fdinfo . proc(5) . signalfd SIGSEGV SIGFPE . . signalfd(). ( signalfd) fork(2) execve(2) . . select(2) poll(2) epoll(7). 2.6.25 ssi_ptr ssi_int sigqueue(3). SIGINT SIGQUIT signalfd. SIGQUIT. : $ ./signalfd_demo ^C # Control-C generates SIGINT Got SIGINT ^C Got SIGINT ^\ # Control-\ generates SIGQUIT Got SIGQUIT $ #include #include #include #include #include #include #include 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'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\n"); } else if (fdsi.ssi_signo == SIGQUIT) { printf("Got SIGQUIT\n"); exit(EXIT_SUCCESS); } else { printf("Read unexpected signal\n"); } } } eventfd(2), poll(2), read(2), select(2), sigaction(2), sigprocmask(2), sigwaitinfo(2), timerfd_create(2), sigsetops(3), sigwait(3), epoll(7), signal(7) 3 . . : . 6.18 8 2026 signalfd(2)