名 前
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()
が 返 す フ ァ イ
ル デ ィ ス ク リ
プ タ ー は 以 下
の 操 作 を サ ポ
ー ト し て い る
。 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
構 造 体 struct
signalfd_siginfo { signalfd_siginfo
構 造 体 の 各 フ
ィ ー ル ド は 、
siginfo_t 構 造 体 の
同 じ よ う な 名
前 の フ ィ ー ル
ド と 同 様 で あ
る 。 siginfo_t 構 造
体 に つ い て は
sigaction(2) に 説 明 が
あ る 。 返 さ れ
た signalfd_siginfo 構 造 体
の 全 て の フ ィ
ー ル ド が あ る
シ グ ナ ル に 対
し て 有 効 な わ
け で は な い 。
ど の フ ィ ー ル
ド が 有 効 か は
、 ssi_code フ ィ ー ル
ド で 返 さ れ る
値 か ら 判 定 す
る こ と が で き
る 。 こ の フ ィ
ー ル ド は siginfo_t
の si_code フ ィ ー ル
ド と 同 様 で あ
る 。 詳 細 は
sigaction(2) を 参 照 。 fork(2)
で の 扱 い execve(2)
で の 扱 い
read(2)
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; /* シ グ ナ ル
を 生 成 し た ア
ド レ ス
(ハ ー ド ウ ェ ア
が 生 成 し た シ
グ ナ ル の 場 合 ) */
uint8_t pad[X]; /* pad の 大 き
さ は 128 バ イ ト
(将 来 の フ ィ ー
ル ド 追 加 用 の
場 所 の 確 保 ) */ };
fork(2) が 行 わ れ る
と 、 子 プ ロ セ
ス は signalfd フ ァ イ
ル デ ィ ス ク リ
プ タ ー の コ ピ
ー を 継 承 す る
。 子 プ ロ セ ス
で こ の フ ァ イ
ル デ ィ ス ク リ
プ タ ー か ら read(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 に 含 む フ ァ イ ル デ ィ ス ク リ プ タ ー の う ち い ず れ か 一 つ か ら 読 み 出 す こ と が で き る 。
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/ に 書 か れ て い る 。