名 前
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 新 し く 生 成 さ れ る オ ー プ ン フ ァ イ ル 記 述 |
(open file |
description) の O_NONBLOCK フ ァ イ ル ス テ ー タ ス フ ラ グ を セ ッ ト す る 。 こ の フ ラ グ を 使 う こ と で 、 O_NONBLOCK を セ ッ ト す る た め に fcntl(2) を 追 加 で 呼 び 出 す 必 要 が な く な る 。
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 {
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; /* シ グ ナ ル
を 生 成 し た ア
ド レ ス
(ハ ー ド ウ ェ ア
が 生 成 し た シ
グ ナ ル の 場 合 ) */
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)
を 行 う と 、 子
プ ロ セ ス に 対
す る キ ュ ー に
入 っ て い る シ
グ ナ ル に 関 す
る 情 報 が 返 さ
れ る 。
execve(2) で の 扱 い 他 の フ ァ イ ル デ ィ ス ク リ プ タ ー と 全 く 同 様 に 、 signalfd フ ァ イ ル デ ィ ス ク リ プ タ ー も execve(2) の 前 後 で オ ー プ ン さ れ た ま ま と な る 。 但 し 、 そ の フ ァ イ ル デ ィ ス ク リ プ タ ー に close−on−exec の マ ー ク (fcntl(2) 参 照 ) が 付 い て い る 場 合 は ク ロ ー ズ さ れ る 。 execve(2) の 前 に 読 み 出 し 可 能 と な っ て い た 全 て の シ グ ナ ル は 新 し く 起 動 さ れ た プ ロ グ ラ ム で も 引 き 続 き 読 み 出 し 可 能 で あ る (こ れ は 伝 統 的 な シ グ ナ ル の 扱 い と 同 じ で あ り 、 処 理 待 ち の ブ ロ ッ ク さ れ た シ グ ナ ル は execve(2) の 前 後 で 処 理 待 ち の ま ま と な る )。 ス レ ッ ド で の 扱 い マ ル チ ス レ ッ ド プ ロ グ ラ ム に お け る signalfd フ ァ イ ル デ ィ ス ク リ プ タ ー の 扱 い は シ グ ナ ル の 標 準 的 な 扱 い と 全 く 同 じ で あ る 。 言 い 換 え る と 、 あ る ス レ ッ ド が signalfd フ ァ イ ル デ ィ ス ク リ プ タ ー か ら 読 み 出 し を 行 う と 、 そ の ス レ ッ ド 自 身 宛 て の シ グ ナ ル と プ ロ セ ス (す な わ ち ス レ ッ ド グ ル ー プ 全 体 ) 宛 て の シ グ ナ ル が 読 み 出 さ れ る 。 (ス レ ッ ド は 同 じ プ ロ セ ス の 他 の ス レ ッ ド 宛 て の シ グ ナ ル を 読 み 出 す こ と は で き な い 。 )
返 り 値
成 功 す る と 、 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 に 含 む フ ァ イ ル デ ィ ス ク リ プ タ ー の う ち い ず れ か 一 つ か ら 読 み 出 す こ と が で き る 。
C ラ イ ブ ラ リ と カ ー ネ ル ABI の 違 い 実 際 の 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(struct signalfd_siginfo));
if (s != sizeof(struct signalfd_siginfo))
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 プ ロ ジ ェ ク ト の リ リ ー ス 3.79 の 一 部 で あ る 。 プ ロ ジ ェ ク ト の 説 明 と バ グ 報 告 に 関 す る 情 報 は http://www.kernel.org/doc/man−pages/ に 書 か れ て い る 。