1 .\" Copyright (C) 2008 Michael Kerrisk <mtk.manpages@gmail.com>
2 .\" starting from a version by Davide Libenzi <davidel@xmailserver.org>
4 .\" This program is free software; you can redistribute it and/or modify
5 .\" it under the terms of the GNU General Public License as published by
6 .\" the Free Software Foundation; either version 2 of the License, or
7 .\" (at your option) any later version.
9 .\" This program is distributed in the hope that it will be useful,
10 .\" but WITHOUT ANY WARRANTY; without even the implied warranty of
11 .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 .\" GNU General Public License for more details.
14 .\" You should have received a copy of the GNU General Public License
15 .\" along with this program; if not, write to the Free Software
16 .\" Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 .\"*******************************************************************
21 .\" This file was generated with po4a. Translate the source file.
23 .\"*******************************************************************
24 .TH SIGNALFD 2 2009\-01\-13 Linux "Linux Programmer's Manual"
26 signalfd \- シグナル受け付け用のファイルディスクリプタを生成する
28 \fB#include <sys/signalfd.h>\fP
30 \fBint signalfd(int \fP\fIfd\fP\fB, const sigset_t *\fP\fImask\fP\fB, int \fP\fIflags\fP\fB);\fP
32 \fBsignalfd\fP() は、呼び出し元宛てのシグナルを受け付けるために使用されるファイル ディスクリプタを生成する。 この方法はシグナルハンドラや
33 \fBsigwaitinfo\fP(2) を用いる方法の代わりとなるものであり、このファイルディスクリプタを \fBselect\fP(2),
34 \fBpoll\fP(2), \fBepoll\fP(7) で監視できるという利点がある。
36 \fImask\fP 引き数には、呼び出し元がこのファイルディスクリプタ経由で受け付けたい シグナル集合を指定する。この引き数で指定するシグナル集合の内容は、
37 \fBsigsetops\fP(3) で説明されているマクロを使って初期化することができる。 通常、ファイルディスクリプタ経由で受信するシグナル集合は、
38 そのシグナルがデフォルトの配送方法に基いて処理されるのを防ぐために、 \fBsigprocmask\fP(2) を使ってブロックしておくべきである。
39 シグナル \fBSIGKILL\fP と \fBSIGSTOP\fP を signalfd ファイルディスクリプタ経由で受信することはできない。 これらのシグナルが
40 \fImask\fP で指定された場合には黙って無視される。
42 \fIfd\fP 引き数が \-1 の場合、 \fBsignalfd\fP() は新しいファイルディスクリプタを生成し、 \fImask\fP
43 で指定されたシグナル集合をそのファイルディスクリプタに関連付ける。 \fIfd\fP 引き数が \-1 以外の場合、 \fIfd\fP には有効な既存の
44 signalfd ファイルディスクリプタを指定しなければならず、 そのディスクリプタに関連付けられているシグナル集合は \fImask\fP
47 Linux 2.6.27 以降では、 以下の値のいくつかをビット単位の論理和 (OR) で指定することで、 \fBsignalfd\fP()
51 新しく生成されるオープンファイル記述 (open file description) の \fBO_NONBLOCK\fP
52 ファイルステータスフラグをセットする。 このフラグを使うことで、 \fBO_NONBLOCK\fP をセットするために \fBfcntl\fP(2)
56 新しいファイルディスクリプタに対して close\-on\-exec (\fBFD_CLOEXEC\fP) フラグをセットする。
57 このフラグが役に立つ理由については、 \fBopen\fP(2) の \fBO_CLOEXEC\fP フラグの説明を参照のこと。
59 バージョン 2.6.26 以前の Linux では、 \fIflags\fP 引き数は未使用であり、0 を指定しなければならない。
61 \fBsignalfd\fP() が返すファイルディスクリプタは以下の操作をサポートしている。
64 \fImask\fP に指定されているシグナルのうち一つ以上がそのプロセスに対して 処理待ち (pending) であれば、それらのシグナルの情報が
65 \fBread\fP(2) に渡されたバッファを使って、 \fIsignalfd_siginfo\fP 構造体に格納されて返される。 \fBread\fP(2)
66 は、バッファに格納可能な範囲でできるだけ多くの処理待ちのシグナルに ついての情報を返す。 バッファは最低でも \fIsizeof(struct
67 signalfd_siginfo)\fP バイトの大きさがなければならない。 \fBread\fP(2) の返り値は読み出されたトータルのバイト数である。
69 \fBread\fP(2) が行われた結果、シグナルは消費され、 これらのシグナルはそのプロセスに対しては処理待ちではなくなる
70 (つまり、シグナルハンドラで捕捉されることもなく、 \fBsigwaitinfo\fP(2) を使って受け取ることもできなくなる)。
72 \fImask\fP に指定されているシグナルがそのプロセスに対して一つも処理待ちでなければ、 \fBread\fP(2) は、 \fImask\fP
73 で指定されたシグナルのうちいずれか一つがそのプロセスに対して発生するまで 停止 (block) する、もしくはファイルディスクリプタが非停止
74 (nonblocking) に設定されている場合はエラー \fBEAGAIN\fP で失敗する。
76 \fBpoll\fP(2), \fBselect\fP(2) (と同様の操作)
77 \fImask\fP に指定されたシグナルのうち一つ以上がそのプロセスに対して処理待ちであれば、 ファイルディスクリプタは読み出し可能となる
78 (\fBselect\fP(2) の \fIreadfds\fP 引き数や \fBpoll\fP(2) の \fBPOLLIN\fP フラグ)。
80 signalfd ファイルディスクリプタは、これ以外のファイルディスクリプタ 多重 API である \fBpselect\fP(2),
81 \fBppoll\fP(2), \fBepoll\fP(7) もサポートしている。
84 ファイルディスクリプタがそれ以降は必要なくなった際には、クローズすべきである。 同じ signalfd
85 オブジェクトに関連付けられたファイルディスクリプタが全て クローズされると、そのオブジェクト用の資源がカーネルにより解放される。
86 .SS "signalfd_siginfo 構造体"
87 signalfd ファイルディスクリプタからの \fBread\fP(2) で返される \fIsignalfd_siginfo\fP
92 .\" ssi_trapno is unused on most arches
93 struct signalfd_siginfo {
94 struct signalfd_siginfo {
95 uint32_t ssi_signo; /* シグナル番号 */
96 int32_t ssi_errno; /* エラー番号 (未使用) */
97 int32_t ssi_code; /* シグナルコード */
98 uint32_t ssi_pid; /* 送信元の PID */
99 uint32_t ssi_uid; /* 送信元の実 UID */
100 int32_t ssi_fd; /* ファイルディスクリプタ (SIGIO) */
101 uint32_t ssi_tid; /* カーネルタイマ ID (POSIX タイマ)
102 uint32_t ssi_band; /* Band イベント (SIGIO) */
103 uint32_t ssi_overrun; /* POSIX タイマのオーバーラン回数 */
104 uint32_t ssi_trapno; /* シグナルの原因となったトラップ番号 */
105 int32_t ssi_status; /* 終了ステータスかシグナル (SIGCHLD) */
106 int32_t ssi_int; /* sigqueue(3) から送られた整数 */
107 uint64_t ssi_ptr; /* sigqueue(3) から送られたポインタ */
108 uint64_t ssi_utime; /* 消費したユーザ CPU 時間 (SIGCHLD) */
109 uint64_t ssi_stime; /* 消費したシステム CPU 時間 (SIGCHLD) */
110 uint64_t ssi_addr; /* シグナルを生成したアドレス
111 (ハードウェアが生成したシグナルの場合) */
112 uint8_t pad[\fIX\fP]; /* pad の大きさは 128 バイト
113 (将来のフィールド追加用の場所の確保) */
118 \fIsignalfd_siginfo\fP 構造体の各フィールドは、 \fIsiginfo_t\fP 構造体の同じような名前のフィールドと同様である。
119 \fIsiginfo_t\fP 構造体については \fBsigaction\fP(2) に説明がある。 返された \fIsignalfd_siginfo\fP
120 構造体の全てのフィールドがあるシグナルに対して有効なわけではない。 どのフィールドが有効かは、 \fIssi_code\fP
121 フィールドで返される値から判定することができる。 このフィールドは \fIsiginfo_t\fP の \fIsi_code\fP フィールドと同様である。詳細は
122 \fBsigaction\fP(2) を参照。
124 \fBfork\fP(2) が行われると、子プロセスは signalfd ファイルディスクリプタのコピーを 継承する。
125 子プロセスでこのファイルディスクリプタから \fBread\fP(2) を行うと、子プロセスに対するキューに入っているシグナルに関する 情報が返される。
127 他のファイルディスクリプタと全く同様に、 signalfd ファイルディスクリプタも \fBexecve\fP(2)
128 の前後でオープンされたままとなる。但し、そのファイルディスクリプタに close\-on\-exec のマーク (\fBfcntl\fP(2) 参照)
129 が付いている場合はクローズされる。 \fBexecve\fP(2) の前に読み出し可能となっていた全てのシグナルは新しく起動されたプログラム
130 でも引き続き読み出し可能である (これは伝統的なシグナルの扱いと同じであり、 処理待ちのブロックされたシグナルは \fBexecve\fP(2)
133 マルチスレッドプログラムにおける signalfd ファイルディスクリプタの扱いは シグナルの標準的な扱いと全く同じである。
134 言い換えると、あるスレッドが signalfd ファイルディスクリプタから 読み出しを行うと、そのスレッド自身宛てのシグナルとプロセス (すなわち
135 スレッドグループ全体) 宛てのシグナルが読み出される。 (スレッドは同じプロセスの他のスレッド宛てのシグナルを読み出すことはできない。)
137 成功すると、 \fBsignalfd\fP() は signalfd ファイルディスクリプタを返す。 返されるファイルディスクリプタは、 \fIfd\fP が
138 \-1 の場合は新規のファイルディスクリプタであり、 \fIfd\fP が有効な signalfd ファイルディスクリプタだった場合は \fIfd\fP 自身である。
139 エラーの場合、\-1 を返し、 \fIerrno\fP にエラーを示す値を設定する。
143 ファイルディスクリプタ \fIfd\fP が有効なファイルディスクリプタでない。
148 .\" argument is not equal to
149 .\" .IR sizeof(sigset_t) ;
150 \fIfd\fP が有効な signalfd ファイルディスクリプタではない。
153 \fIflags\fP が無効である。もしくは、Linux 2.6.26 以前の場合には \fIflags\fP が 0 以外である。
156 オープン済みのファイルディスクリプタの数がプロセスあたりの上限に 達していた。
159 オープン済みのファイル総数がシステム全体の上限に達していた。
162 (カーネル内の) 無名 inode デバイスをマウントできなかった。
165 新しい signalfd ファイルディスクリプタを生成するのに十分なメモリがなかった。
167 .\" signalfd() is in glibc 2.7, but reportedly does not build
168 \fBsignalfd\fP() はカーネル 2.6.22 以降の Linux で利用可能である。 正しく動作する glibc 側のサポートはバージョン
169 2.8 以降で提供されている。 \fBsignalfd4\fP() システムコール (「注意」参照) は カーネル 2.6.27 以降の Linux
172 \fBsignalfd\fP() と \fBsignalfd4\fP() は Linux 固有である。
174 実際の Linux のシステムコールでは \fIsize_t sizemask\fP という引き数が追加で必要である。この引き数で \fImask\fP
175 のサイズを指定する。 glibc の \fBsignalfd\fP() ラッパー関数にはこの引き数は含まれず、
176 ラッパー関数が必要な値を計算して内部で呼び出すシステムコールに提供する。
178 一つのプロセスは複数の signalfd ファイルディスクリプタを生成することができる。
179 これにより、異なるファイルディスクリプタで異なるシグナルを受け取ることが できる (この機能は \fBselect\fP(2), \fBpoll\fP(2),
180 \fBepoll\fP(7) を使ってファイルディスクリプタを監視する場合に有用かもしれない。
181 異なるシグナルが到着すると、異なるファイルディスクリプタが利用可能に なるからだ)。 一つのシグナルが二つ以上のファイルディスクリプタの \fImask\fP
182 に含まれている場合、そのシグナルの発生はそのシグナルを \fImask\fP に含むファイルディスクリプタのうちいずれか一つから読み出すことができる。
183 .SS "下層にある Linux のシステムコール"
184 下層にある Linux システムコールは二種類あり、 \fBsignalfd\fP() と、もっと新しい \fBsignalfd4\fP() である。
185 \fBsignalfd\fP() は \fIflags\fP 引き数を実装していない。 \fBsignalfd4\fP() では上記の値の \fIflags\fP
186 が実装されている。 glibc 2.9 以降では、 \fBsignalfd\fP() のラッパー関数は、 \fBsignalfd4\fP()
189 .\" The fix also was put into 2.6.24.5
190 カーネル 2.6.25 より前では、 \fBsigqueue\fP(3) により送信されたシグナルと一緒に渡されるデータでは、フィールド
191 \fIssi_ptr\fP と \fIssi_int\fP は設定されない。
193 下記のプログラムは、シグナル \fBSIGINT\fP と \fBSIGQUIT\fP を signalfd ファイルディスクリプタ経由で受信する。 シグナル
194 \fBSIGQUIT\fP 受信後にプログラムは終了する。 以下に示すシェルセッションにこのプログラムの使い方を示す。
198 $\fB ./signalfd_demo\fP
199 \fB^C\fP # Control\-C generates SIGINT
203 \fB^\e\fP # Control\-\e generates SIGQUIT
211 #include <sys/signalfd.h>
217 #define handle_error(msg) \e
218 do { perror(msg); exit(EXIT_FAILURE); } while (0)
221 main(int argc, char *argv[])
225 struct signalfd_siginfo fdsi;
229 sigaddset(&mask, SIGINT);
230 sigaddset(&mask, SIGQUIT);
232 /* Block signals so that they aren\(aqt handled
233 according to their default dispositions */
235 if (sigprocmask(SIG_BLOCK, &mask, NULL) == \-1)
236 handle_error("sigprocmask");
238 sfd = signalfd(\-1, &mask, 0);
240 handle_error("signalfd");
243 s = read(sfd, &fdsi, sizeof(struct signalfd_siginfo));
244 if (s != sizeof(struct signalfd_siginfo))
245 handle_error("read");
247 if (fdsi.ssi_signo == SIGINT) {
248 printf("Got SIGINT\en");
249 } else if (fdsi.ssi_signo == SIGQUIT) {
250 printf("Got SIGQUIT\en");
253 printf("Read unexpected signal\en");
259 \fBeventfd\fP(2), \fBpoll\fP(2), \fBread\fP(2), \fBselect\fP(2), \fBsigaction\fP(2),
260 \fBsigprocmask\fP(2), \fBsigwaitinfo\fP(2), \fBtimerfd_create\fP(2), \fBsigsetops\fP(3),
261 \fBsigwait\fP(3), \fBepoll\fP(7), \fBsignal\fP(7)
263 この man ページは Linux \fIman\-pages\fP プロジェクトのリリース 3.41 の一部
264 である。プロジェクトの説明とバグ報告に関する情報は
265 http://www.kernel.org/doc/man\-pages/ に書かれている。