Man page - signalfd(2)

Packages contains this manual

Available languages:

en fr ja ru

Manual

SIGNALFD

名 前
書 式
説 明
signalfd_siginfo 構 造 体
fork(2) で の 扱 い
Semantics of file descriptor passing
execve(2) で の 扱 い
ス レ ッ ド で の 扱 い
epoll(7) semantics
返 り 値
エ ラ ー
バ ー ジ ョ ン
準 拠
注 意
Limitations
C ラ イ ブ ラ リ と カ ー ネ ル の 違 い
バ グ

プ ロ グ ラ ム の ソ ー ス
関 連 項 目
こ の 文 書 に つ い て

名 前

signalfd - シ グ ナ ル 受 け 付 け 用 の フ ァ イ ル デ ィ ス ク リ プ タ ー を 生 成 す る

書 式

#include <sys/signalfd.h>

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 の 場 合 、 signalfd () は 新 し い フ ァ イ ル デ ィ ス ク リ プ タ ー を 生 成 し 、 mask で 指 定 さ れ た シ グ ナ ル 集 合 を そ の フ ァ イ ル デ ィ ス ク リ プ タ ー に 関 連 付 け る 。 fd 引 数 が -1 以 外 の 場 合 、 fd に は 有 効 な 既 存 の signalfd フ ァ イ ル デ ィ ス ク リ プ タ ー を 指 定 し な け れ ば な ら ず 、 そ の デ ィ ス ク リ プ タ ー に 関 連 付 け ら れ て い る シ グ ナ ル 集 合 は mask を 使 っ て 置 き 換 え ら れ る 。

Linux 2.6.27 以 降 で は 、 以 下 の 値 の い く つ か を ビ ッ ト 単 位 の 論 理 和 (OR) で 指 定 す る こ と で 、 signalfd () の 振 舞 い を 変 更 す る こ と が で き る 。

SFD_NONBLOCK

Set the O_NONBLOCK file status flag on the open file description (see open (2)) referred to by the new file descriptor. Using this flag saves extra calls to fcntl (2) to achieve the same result.

SFD_CLOEXEC

新 し い フ ァ イ ル デ ィ ス ク リ プ タ ー に 対 し て close-on-exec ( FD_CLOEXEC ) フ ラ グ を セ ッ ト す る 。 こ の フ ラ グ が 役 に 立 つ 理 由 に つ い て は 、 open (2) の O_CLOEXEC フ ラ グ の 説 明 を 参 照 の こ と 。

バ ー ジ ョ ン 2.6.26 以 前 の Linux で は 、 flags 引 数 は 未 使 用 で あ り 、 0 を 指 定 し な け れ ば な ら な い 。

signalfd () が 返 す フ ァ イ ル デ ィ ス ク リ プ タ ー は 以 下 の 操 作 を サ ポ ー ト し て い る 。
read
(2)

mask に 指 定 さ れ て い る シ グ ナ ル の う ち 一 つ 以 上 が そ の プ ロ セ ス に 対 し て 処 理 待 ち (pending) で あ れ ば 、 そ れ ら の シ グ ナ ル の 情 報 が read (2) に 渡 さ れ た バ ッ フ ァ ー を 使 っ て 、 signalfd_siginfo 構 造 体 に 格 納 さ れ て 返 さ れ る 。 read (2) は 、 バ ッ フ ァ ー に 格 納 可 能 な 範 囲 で で き る だ け 多 く の 処 理 待 ち の シ グ ナ ル に つ い て の 情 報 を 返 す 。 バ ッ フ ァ ー は 最 低 で も sizeof(struct signalfd_siginfo) バ イ ト の 大 き さ が な け れ ば な ら な い 。 read (2) の 返 り 値 は 読 み 出 さ れ た ト ー タ ル の バ イ ト 数 で あ る 。

read (2) が 行 わ れ た 結 果 、 シ グ ナ ル は 消 費 さ れ 、 こ れ ら の シ グ ナ ル は そ の プ ロ セ ス に 対 し て は 処 理 待 ち で は な く な る (つ ま り 、 シ グ ナ ル ハ ン ド ラ ー で 捕 捉 さ れ る こ と も な く 、 sigwaitinfo (2) を 使 っ て 受 け 取 る こ と も で き な く な る )。

mask に 指 定 さ れ て い る シ グ ナ ル が そ の プ ロ セ ス に 対 し て 一 つ も 処 理 待 ち で な け れ ば 、 read (2) は 、 mask で 指 定 さ れ た シ グ ナ ル の う ち い ず れ か 一 つ が そ の プ ロ セ ス に 対 し て 発 生 す る ま で 停 止 (block) す る 、 も し く は フ ァ イ ル デ ィ ス ク リ プ タ ー が 非 停 止 (nonblocking) に 設 定 さ れ て い る 場 合 は エ ラ ー EAGAIN で 失 敗 す る 。

poll (2), select (2) (と 同 様 の 操 作 )

mask に 指 定 さ れ た シ グ ナ ル の う ち 一 つ 以 上 が そ の プ ロ セ ス に 対 し て 処 理 待 ち で あ れ ば 、 フ ァ イ ル デ ィ ス ク リ プ タ ー は 読 み 出 し 可 能 と な る ( select (2) の readfds 引 数 や poll (2) の POLLIN フ ラ グ )。

signalfd フ ァ イ ル デ ィ ス ク リ プ タ ー は 、 こ れ 以 外 の フ ァ イ ル デ ィ ス ク リ プ タ ー 多 重 API で あ る pselect (2), ppoll (2), epoll (7) も サ ポ ー ト し て い る 。

close (2)

フ ァ イ ル デ ィ ス ク リ プ タ ー が そ れ 以 降 は 必 要 な く な っ た 際 に は 、 ク ロ ー ズ す べ き で あ る 。 同 じ signalfd オ ブ ジ ェ ク ト に 関 連 付 け ら れ た フ ァ イ ル デ ィ ス ク リ プ タ ー が 全 て ク ロ ー ズ さ れ る と 、 そ の オ ブ ジ ェ ク ト 用 の 資 源 が カ ー ネ ル に よ り 解 放 さ れ る 。

signalfd_siginfo 構 造 体

signalfd フ ァ イ ル デ ィ ス ク リ プ タ ー か ら の read (2) で 返 さ れ る signalfd_siginfo 構 造 体 の フ ォ ー マ ッ ト は 以 下 の 通 り で あ る 。

struct signalfd_siginfo {
uint32_t ssi_signo; /* シ グ ナ ル 番 号 */
int32_t ssi_errno; /* エ ラ ー 番 号 (未 使 用 ) */
int32_t ssi_code; /* シ グ ナ ル コ ー ド */
uint32_t ssi_pid; /* 送 信 元 の PID */
uint32_t ssi_uid; /* 送 信 元 の 実 UID */
int32_t ssi_fd; /* フ ァ イ ル デ ィ ス ク リ プ タ ー (SIGIO) */
uint32_t ssi_tid; /* カ ー ネ ル タ イ マ ー ID (POSIX タ イ マ ー )
uint32_t ssi_band; /* Band イ ベ ン ト (SIGIO) */
uint32_t ssi_overrun; /* POSIX タ イ マ ー の オ ー バ ー ラ ン 回 数 */
uint32_t ssi_trapno; /* シ グ ナ ル の 原 因 と な っ た ト ラ ッ プ 番 号 */
int32_t ssi_status; /* 終 了 ス テ ー タ ス か シ グ ナ ル (SIGCHLD) */
int32_t ssi_int; /* sigqueue(3) か ら 送 ら れ た 整 数 */
uint64_t ssi_ptr; /* sigqueue(3) か ら 送 ら れ た ポ イ ン タ ー */
uint64_t ssi_utime; /* 消 費 し た ユ ー ザ ー CPU 時 間 (SIGCHLD) */
uint64_t ssi_stime; /* 消 費 し た シ ス テ ム CPU 時 間 (SIGCHLD) */
uint64_t ssi_addr; /* シ グ ナ ル を 生 成 し た ア ド レ ス
(ハ ー ド ウ ェ ア が 生 成 し た シ グ ナ ル の 場 合 ) */
uint16_t ssi_addr_lsb; /* ア ド レ ス の 最 下 位 ビ ッ ト (LSB)
(SIGBUS; Linux 2.6.37 以 降 ) */
uint8_t pad[ X ]; /* pad の 大 き さ は 128 バ イ ト
(将 来 の フ ィ ー ル ド 追 加 用 の 場 所 の 確 保 ) */
};

signalfd_siginfo 構 造 体 の 各 フ ィ ー ル ド は 、 siginfo_t 構 造 体 の 同 じ よ う な 名 前 の フ ィ ー ル ド と 同 様 で あ る 。 siginfo_t 構 造 体 に つ い て は sigaction (2) に 説 明 が あ る 。 返 さ れ た signalfd_siginfo 構 造 体 の 全 て の フ ィ ー ル ド が あ る シ グ ナ ル に 対 し て 有 効 な わ け で は な い 。 ど の フ ィ ー ル ド が 有 効 か は 、 ssi_code フ ィ ー ル ド で 返 さ れ る 値 か ら 判 定 す る こ と が で き る 。 こ の フ ィ ー ル ド は siginfo_t si_code フ ィ ー ル ド と 同 様 で あ る 。 詳 細 は sigaction (2) を 参 照 。

fork(2) で の 扱 い

fork (2) が 行 わ れ る と 、 子 プ ロ セ ス は signalfd フ ァ イ ル デ ィ ス ク リ プ タ ー の コ ピ ー を 継 承 す る 。 子 プ ロ セ ス で こ の フ ァ イ ル デ ィ ス ク リ プ タ ー か ら read (2) を 行 う と 、 子 プ ロ セ ス に 対 す る キ ュ ー に 入 っ て い る シ グ ナ ル に 関 す る 情 報 が 返 さ れ る 。

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 unix (7)). In the receiving process, a read (2) from the received file descriptor will return information about signals queued to that process.

execve(2) で の 扱 い

他 の フ ァ イ ル デ ィ ス ク リ プ タ ー と 全 く 同 様 に 、 signalfd フ ァ イ ル デ ィ ス ク リ プ タ ー も execve (2) の 前 後 で オ ー プ ン さ れ た ま ま と な る 。 但 し 、 そ の フ ァ イ ル デ ィ ス ク リ プ タ ー に close-on-exec の マ ー ク ( fcntl (2) 参 照 ) が 付 い て い る 場 合 は ク ロ ー ズ さ れ る 。 execve (2) の 前 に 読 み 出 し 可 能 と な っ て い た 全 て の シ グ ナ ル は 新 し く 起 動 さ れ た プ ロ グ ラ ム で も 引 き 続 き 読 み 出 し 可 能 で あ る (こ れ は 伝 統 的 な シ グ ナ ル の 扱 い と 同 じ で あ り 、 処 理 待 ち の ブ ロ ッ ク さ れ た シ グ ナ ル は execve (2) の 前 後 で 処 理 待 ち の ま ま と な る )。

ス レ ッ ド で の 扱 い

マ ル チ ス レ ッ ド プ ロ グ ラ ム に お け る signalfd フ ァ イ ル デ ィ ス ク リ プ タ ー の 扱 い は シ グ ナ ル の 標 準 的 な 扱 い と 全 く 同 じ で あ る 。 言 い 換 え る と 、 あ る ス レ ッ ド が signalfd フ ァ イ ル デ ィ ス ク リ プ タ ー か ら 読 み 出 し を 行 う と 、 そ の ス レ ッ ド 自 身 宛 て の シ グ ナ ル と プ ロ セ ス (す な わ ち ス レ ッ ド グ ル ー プ 全 体 ) 宛 て の シ グ ナ ル が 読 み 出 さ れ る 。 (ス レ ッ ド は 同 じ プ ロ セ ス の 他 の ス レ ッ ド 宛 て の シ グ ナ ル を 読 み 出 す こ と は で き な い 。 )

epoll(7) semantics

If a process adds (via epoll_ctl (2)) a signalfd file descriptor to an epoll (7) instance, then epoll_wait (2) returns events only for signals sent to that process. In particular, if the process then uses fork (2) to create a child process, then the child will be able to read (2) signals that are sent to it using the signalfd file descriptor, but epoll_wait (2) will not indicate that the signalfd file descriptor is ready. In this scenario, a possible workaround is that after the 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 fork (2).

返 り 値

成 功 す る と 、 signalfd () は signalfd フ ァ イ ル デ ィ ス ク リ プ タ ー を 返 す 。 返 さ れ る フ ァ イ ル デ ィ ス ク リ プ タ ー は 、 fd が -1 の 場 合 は 新 規 の フ ァ イ ル デ ィ ス ク リ プ タ ー で あ り 、 fd が 有 効 な signalfd フ ァ イ ル デ ィ ス ク リ プ タ ー だ っ た 場 合 は fd 自 身 で あ る 。 エ ラ ー の 場 合 、 -1 を 返 し 、 errno に エ ラ ー を 示 す 値 を 設 定 す る 。

エ ラ ー

EBADF

フ ァ イ ル デ ィ ス ク リ プ タ ー fd が 有 効 な フ ァ イ ル デ ィ ス ク リ プ タ ー で な い 。

EINVAL

fd が 有 効 な signalfd フ ァ イ ル デ ィ ス ク リ プ タ ー で は な い 。

EINVAL

flags が 無 効 で あ る 。 も し く は 、 Linux 2.6.26 以 前 の 場 合 に は flags が 0 以 外 で あ る 。

EMFILE

オ ー プ ン 済 み の フ ァ イ ル デ ィ ス ク リ プ タ ー の 数 が プ ロ セ ス あ た り の 上 限 に 達 し て い た 。

ENFILE

オ ー プ ン 済 み の フ ァ イ ル 総 数 が シ ス テ ム 全 体 の 上 限 に 達 し て い た 。

ENODEV

(カ ー ネ ル 内 の ) 無 名 inode デ バ イ ス を マ ウ ン ト で き な か っ た 。

ENOMEM

新 し い signalfd フ ァ イ ル デ ィ ス ク リ プ タ ー を 生 成 す る の に 十 分 な メ モ リ ー が な か っ た 。

バ ー ジ ョ ン

signalfd () は カ ー ネ ル 2.6.22 以 降 の Linux で 利 用 可 能 で あ る 。 正 し く 動 作 す る glibc 側 の サ ポ ー ト は バ ー ジ ョ ン 2.8 以 降 で 提 供 さ れ て い る 。 signalfd4 () シ ス テ ム コ ー ル (「 注 意 」 参 照 ) は カ ー ネ ル 2.6.27 以 降 の Linux で 利 用 可 能 で あ る 。

準 拠

signalfd () と signalfd4 () は Linux 固 有 で あ る 。

注 意

一 つ の プ ロ セ ス は 複 数 の signalfd フ ァ イ ル デ ィ ス ク リ プ タ ー を 生 成 す る こ と が で き る 。 こ れ に よ り 、 異 な る フ ァ イ ル デ ィ ス ク リ プ タ ー で 異 な る シ グ ナ ル を 受 け 取 る こ と が で き る (こ の 機 能 は select (2), poll (2), epoll (7) を 使 っ て フ ァ イ ル デ ィ ス ク リ プ タ ー を 監 視 す る 場 合 に 有 用 か も し れ な い 。 異 な る シ グ ナ ル が 到 着 す る と 、 異 な る フ ァ イ ル デ ィ ス ク リ プ タ ー が 利 用 可 能 に な る か ら だ )。 一 つ の シ グ ナ ル が 二 つ 以 上 の フ ァ イ ル デ ィ ス ク リ プ タ ー の mask に 含 ま れ て い る 場 合 、 そ の シ グ ナ ル の 発 生 は そ の シ グ ナ ル を mask に 含 む フ ァ イ ル デ ィ ス ク リ プ タ ー の う ち い ず れ か 一 つ か ら 読 み 出 す こ と が で き る 。

Attempts to include SIGKILL and SIGSTOP in mask are silently ignored.

The signal mask employed by a signalfd file descriptor can be viewed via the entry for the corresponding file descriptor in the process’s /proc/[pid]/fdinfo directory. See proc (5) for further details.

Limitations

The signalfd mechanism can’t be used to receive signals that are synchronously generated, such as the SIGSEGV signal that results from accessing an invalid memory address or the SIGFPE signal that results from an arithmetic error. Such signals can be caught only via signal handler.

As described above, in normal usage one blocks the signals that will be accepted via signalfd (). If spawning a child process to execute a helper program (that does not need the signalfd file descriptor), then, after the call to fork (2), you will normally want to unblock those signals before calling 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 select (2), poll (2), or epoll (7).

C ラ イ ブ ラ リ と カ ー ネ ル の 違 い

実 際 の Linux の シ ス テ ム コ ー ル で は size_t sizemask と い う 引 数 が 追 加 で 必 要 で あ る 。 こ の 引 数 で mask の サ イ ズ を 指 定 す る 。 glibc の signalfd () ラ ッ パ ー 関 数 に は こ の 引 数 は 含 ま れ ず 、 ラ ッ パ ー 関 数 が 必 要 な 値 を 計 算 し て 内 部 で 呼 び 出 す シ ス テ ム コ ー ル に 提 供 す る 。

下 層 に あ る Linux シ ス テ ム コ ー ル は 二 種 類 あ り 、 signalfd () と 、 も っ と 新 し い signalfd4 () で あ る 。 signalfd () は flags 引 数 を 実 装 し て い な い 。 signalfd4 () で は 上 記 の 値 の flags が 実 装 さ れ て い る 。 glibc 2.9 以 降 で は 、 signalfd () の ラ ッ パ ー 関 数 は 、 signalfd4 () が 利 用 可 能 で あ れ ば 、 こ れ を 使 用 す る 。

バ グ

カ ー ネ ル 2.6.25 よ り 前 で は 、 sigqueue (3) に よ り 送 信 さ れ た シ グ ナ ル と 一 緒 に 渡 さ れ る デ ー タ で は 、 フ ィ ー ル ド ssi_ptr ssi_int は 設 定 さ れ な い 。

下 記 の プ ロ グ ラ ム は 、 シ グ ナ ル SIGINT SIGQUIT を signalfd フ ァ イ ル デ ィ ス ク リ プ タ ー 経 由 で 受 信 す る 。 シ グ ナ ル SIGQUIT 受 信 後 に プ ロ グ ラ ム は 終 了 す る 。 以 下 に 示 す シ ェ ル セ ッ シ ョ ン に こ の プ ロ グ ラ ム の 使 い 方 を 示 す 。

$ ./signalfd_demo
^C
# Control-C generates SIGINT
Got SIGINT
^C

Got SIGINT
^\
# Control-\ generates SIGQUIT
Got SIGQUIT
$

プ ロ グ ラ ム の ソ ー ス

#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(fdsi));
if (s != sizeof(fdsi))
handle_error("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)

こ の 文 書 に つ い て

こ の man ペ ー ジ は Linux man-pages プ ロ ジ ェ ク ト の リ リ ー ス 5.10 の 一 部 で あ る 。 プ ロ ジ ェ ク ト の 説 明 と バ グ 報 告 に 関 す る 情 報 は https://www.kernel.org/doc/man-pages/ に 書 か れ て い る 。