File: signalfd.2

package info (click to toggle)
manpages-ja 0.5.0.0.20221215%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 29,304 kB
  • sloc: perl: 161; makefile: 61
file content (320 lines) | stat: -rw-r--r-- 19,570 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
.\" Copyright (C) 2008 Michael Kerrisk <mtk.manpages@gmail.com>
.\" starting from a version by Davide Libenzi <davidel@xmailserver.org>
.\"
.\" %%%LICENSE_START(GPLv2+_SW_3_PARA)
.\" This program is free software; you can redistribute it and/or modify
.\" it under the terms of the GNU General Public License as published by
.\" the Free Software Foundation; either version 2 of the License, or
.\" (at your option) any later version.
.\"
.\" This program is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
.\" GNU General Public License for more details.
.\"
.\" You should have received a copy of the GNU General Public
.\" License along with this manual; if not, see
.\" <http://www.gnu.org/licenses/>.
.\" %%%LICENSE_END
.\"
.\"*******************************************************************
.\"
.\" This file was generated with po4a. Translate the source file.
.\"
.\"*******************************************************************
.\"
.\" Japanese Version Copyright (c) 2008  Akihiro MOTOKI
.\"         all rights reserved.
.\" Translated 2008-04-06, Akihiro MOTOKI <amotoki@dd.iij4u.or.jp>, LDP v2.79
.\" Updated 2008-11-10, Akihiro MOTOKI <amotoki@dd.iij4u.or.jp>, LDP v3.13
.\" Updated 2009-02-23, Akihiro MOTOKI <amotoki@dd.iij4u.or.jp>, LDP v3.18
.\"
.TH SIGNALFD 2 2020\-11\-01 Linux "Linux Programmer's Manual"
.SH 名前
signalfd \- シグナル受け付け用のファイルディスクリプターを生成する
.SH 書式
\fB#include <sys/signalfd.h>\fP
.PP
\fBint signalfd(int \fP\fIfd\fP\fB, const sigset_t *\fP\fImask\fP\fB, int \fP\fIflags\fP\fB);\fP
.SH 説明
\fBsignalfd\fP()  は、呼び出し元宛てのシグナルを受け付けるために使用されるファイル ディスクリプターを生成する。
この方法はシグナルハンドラーや \fBsigwaitinfo\fP(2)  を用いる方法の代わりとなるものであり、このファイルディスクリプターを
\fBselect\fP(2), \fBpoll\fP(2), \fBepoll\fP(7)  で監視できるという利点がある。
.PP
\fImask\fP 引数には、呼び出し元がこのファイルディスクリプター経由で受け付けたい シグナル集合を指定する。この引数で指定するシグナル集合の内容は、
\fBsigsetops\fP(3)  で説明されているマクロを使って初期化することができる。 通常、ファイルディスクリプター経由で受信するシグナル集合は、
そのシグナルがデフォルトの配送方法に基いて処理されるのを防ぐために、 \fBsigprocmask\fP(2)  を使ってブロックしておくべきである。
シグナル \fBSIGKILL\fP と \fBSIGSTOP\fP を signalfd ファイルディスクリプター経由で受信することはできない。
これらのシグナルが \fImask\fP で指定された場合には黙って無視される。
.PP
\fIfd\fP 引数が \-1 の場合、 \fBsignalfd\fP()  は新しいファイルディスクリプターを生成し、 \fImask\fP
で指定されたシグナル集合をそのファイルディスクリプターに関連付ける。 \fIfd\fP 引数が \-1 以外の場合、 \fIfd\fP には有効な既存の
signalfd ファイルディスクリプターを指定しなければならず、 そのディスクリプターに関連付けられているシグナル集合は \fImask\fP
を使って置き換えられる。
.PP
Linux 2.6.27 以降では、 以下の値のいくつかをビット単位の論理和 (OR) で指定することで、 \fBsignalfd\fP()
の振舞いを変更することができる。
.TP  14
\fBSFD_NONBLOCK\fP
Set the \fBO_NONBLOCK\fP file status flag on the open file description (see
\fBopen\fP(2))  referred to by the new file descriptor.  Using this flag saves
extra calls to \fBfcntl\fP(2)  to achieve the same result.
.TP 
\fBSFD_CLOEXEC\fP
新しいファイルディスクリプターに対して close\-on\-exec (\fBFD_CLOEXEC\fP)  フラグをセットする。
このフラグが役に立つ理由については、 \fBopen\fP(2)  の \fBO_CLOEXEC\fP フラグの説明を参照のこと。
.PP
バージョン 2.6.26 以前の Linux では、 \fIflags\fP 引数は未使用であり、0 を指定しなければならない。
.PP
\fBsignalfd\fP()  が返すファイルディスクリプターは以下の操作をサポートしている。
.TP 
\fBread\fP(2)
\fImask\fP に指定されているシグナルのうち一つ以上がそのプロセスに対して 処理待ち (pending) であれば、それらのシグナルの情報が
\fBread\fP(2)  に渡されたバッファーを使って、 \fIsignalfd_siginfo\fP 構造体に格納されて返される。 \fBread\fP(2)
は、バッファーに格納可能な範囲でできるだけ多くの処理待ちのシグナルに ついての情報を返す。 バッファーは最低でも \fIsizeof(struct
signalfd_siginfo)\fP バイトの大きさがなければならない。 \fBread\fP(2)  の返り値は読み出されたトータルのバイト数である。
.IP
\fBread\fP(2)  が行われた結果、シグナルは消費され、 これらのシグナルはそのプロセスに対しては処理待ちではなくなる
(つまり、シグナルハンドラーで捕捉されることもなく、 \fBsigwaitinfo\fP(2)  を使って受け取ることもできなくなる)。
.IP
\fImask\fP に指定されているシグナルがそのプロセスに対して一つも処理待ちでなければ、 \fBread\fP(2)  は、 \fImask\fP
で指定されたシグナルのうちいずれか一つがそのプロセスに対して発生するまで 停止 (block) する、もしくはファイルディスクリプターが非停止
(nonblocking)  に設定されている場合はエラー \fBEAGAIN\fP で失敗する。
.TP 
\fBpoll\fP(2), \fBselect\fP(2) (と同様の操作)
\fImask\fP に指定されたシグナルのうち一つ以上がそのプロセスに対して処理待ちであれば、 ファイルディスクリプターは読み出し可能となる
(\fBselect\fP(2)  の \fIreadfds\fP 引数や \fBpoll\fP(2)  の \fBPOLLIN\fP フラグ)。
.IP
signalfd ファイルディスクリプターは、これ以外のファイルディスクリプター 多重 API である \fBpselect\fP(2),
\fBppoll\fP(2), \fBepoll\fP(7)  もサポートしている。
.TP 
\fBclose\fP(2)
ファイルディスクリプターがそれ以降は必要なくなった際には、クローズすべきである。 同じ signalfd
オブジェクトに関連付けられたファイルディスクリプターが全て クローズされると、そのオブジェクト用の資源がカーネルにより解放される。
.SS "signalfd_siginfo 構造体"
signalfd ファイルディスクリプターからの \fBread\fP(2)  で返される \fIsignalfd_siginfo\fP
構造体のフォーマットは以下の通りである。
.PP
.in +4n
.EX
.\" ssi_trapno is unused on most arches
.\" ssi_addr_lsb: commit b8aeec34175fc8fe8b0d40efea4846dfc1ba663e
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[\fIX\fP];    /* pad の大きさは 128 バイト
                              (将来のフィールド追加用の場所の確保) */
};
.EE
.in
.PP
\fIsignalfd_siginfo\fP 構造体の各フィールドは、 \fIsiginfo_t\fP 構造体の同じような名前のフィールドと同様である。
\fIsiginfo_t\fP 構造体については \fBsigaction\fP(2)  に説明がある。 返された \fIsignalfd_siginfo\fP
構造体の全てのフィールドがあるシグナルに対して有効なわけではない。 どのフィールドが有効かは、 \fIssi_code\fP
フィールドで返される値から判定することができる。 このフィールドは \fIsiginfo_t\fP の \fIsi_code\fP フィールドと同様である。詳細は
\fBsigaction\fP(2)  を参照。
.SS "fork(2) での扱い"
\fBfork\fP(2)  が行われると、子プロセスは signalfd ファイルディスクリプターのコピーを 継承する。
子プロセスでこのファイルディスクリプターから \fBread\fP(2)  を行うと、子プロセスに対するキューに入っているシグナルに関する 情報が返される。
.SS "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 \fBunix\fP(7)).  In the receiving
process, a \fBread\fP(2)  from the received file descriptor will return
information about signals queued to that process.
.SS "execve(2) での扱い"
他のファイルディスクリプターと全く同様に、 signalfd ファイルディスクリプターも \fBexecve\fP(2)
の前後でオープンされたままとなる。但し、そのファイルディスクリプターに close\-on\-exec のマーク (\fBfcntl\fP(2)  参照)
が付いている場合はクローズされる。 \fBexecve\fP(2)  の前に読み出し可能となっていた全てのシグナルは新しく起動されたプログラム
でも引き続き読み出し可能である (これは伝統的なシグナルの扱いと同じであり、 処理待ちのブロックされたシグナルは \fBexecve\fP(2)
の前後で処理待ちのままとなる)。
.SS スレッドでの扱い
.\"
マルチスレッドプログラムにおける signalfd ファイルディスクリプターの扱いは シグナルの標準的な扱いと全く同じである。
言い換えると、あるスレッドが signalfd ファイルディスクリプターから 読み出しを行うと、そのスレッド自身宛てのシグナルとプロセス (すなわち
スレッドグループ全体) 宛てのシグナルが読み出される。 (スレッドは同じプロセスの他のスレッド宛てのシグナルを読み出すことはできない。)
.SS "epoll(7) semantics"
If a process adds (via \fBepoll_ctl\fP(2))  a signalfd file descriptor to an
\fBepoll\fP(7)  instance, then \fBepoll_wait\fP(2)  returns events only for
signals sent to that process.  In particular, if the process then uses
\fBfork\fP(2)  to create a child process, then the child will be able to
\fBread\fP(2)  signals that are sent to it using the signalfd file descriptor,
but \fBepoll_wait\fP(2)  will \fBnot\fP indicate that the signalfd file descriptor
is ready.  In this scenario, a possible workaround is that after the
\fBfork\fP(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 \fBfork\fP(2).
.SH 返り値
成功すると、 \fBsignalfd\fP()  は signalfd ファイルディスクリプターを返す。 返されるファイルディスクリプターは、 \fIfd\fP が
\-1 の場合は新規のファイルディスクリプターであり、 \fIfd\fP が有効な signalfd ファイルディスクリプターだった場合は \fIfd\fP
自身である。 エラーの場合、\-1 を返し、 \fIerrno\fP にエラーを示す値を設定する。
.SH エラー
.TP 
\fBEBADF\fP
ファイルディスクリプター \fIfd\fP が有効なファイルディスクリプターでない。
.TP 
\fBEINVAL\fP
.\" or, the
.\" .I sizemask
.\" argument is not equal to
.\" .IR sizeof(sigset_t) ;
\fIfd\fP が有効な signalfd ファイルディスクリプターではない。
.TP 
\fBEINVAL\fP
\fIflags\fP が無効である。もしくは、Linux 2.6.26 以前の場合には \fIflags\fP が 0 以外である。
.TP 
\fBEMFILE\fP
オープン済みのファイルディスクリプターの数がプロセスあたりの上限に 達していた。
.TP 
\fBENFILE\fP
オープン済みのファイル総数がシステム全体の上限に達していた。
.TP 
\fBENODEV\fP
(カーネル内の) 無名 inode デバイスをマウントできなかった。
.TP 
\fBENOMEM\fP
新しい signalfd ファイルディスクリプターを生成するのに十分なメモリーがなかった。
.SH バージョン
.\" signalfd() is in glibc 2.7, but reportedly does not build
\fBsignalfd\fP()  はカーネル 2.6.22 以降の Linux で利用可能である。 正しく動作する glibc 側のサポートはバージョン
2.8 以降で提供されている。 \fBsignalfd4\fP()  システムコール (「注意」参照) は カーネル 2.6.27 以降の Linux
で利用可能である。
.SH 準拠
\fBsignalfd\fP()  と \fBsignalfd4\fP()  は Linux 固有である。
.SH 注意
一つのプロセスは複数の signalfd ファイルディスクリプターを生成することができる。
これにより、異なるファイルディスクリプターで異なるシグナルを受け取ることが できる (この機能は \fBselect\fP(2), \fBpoll\fP(2),
\fBepoll\fP(7)  を使ってファイルディスクリプターを監視する場合に有用かもしれない。
異なるシグナルが到着すると、異なるファイルディスクリプターが利用可能に なるからだ)。 一つのシグナルが二つ以上のファイルディスクリプターの
\fImask\fP に含まれている場合、そのシグナルの発生はそのシグナルを \fImask\fP
に含むファイルディスクリプターのうちいずれか一つから読み出すことができる。
.PP
Attempts to include \fBSIGKILL\fP and \fBSIGSTOP\fP in \fImask\fP are silently
ignored.
.PP
.\"
The signal mask employed by a signalfd file descriptor can be viewed via the
entry for the corresponding file descriptor in the process's
\fI/proc/[pid]/fdinfo\fP directory.  See \fBproc\fP(5)  for further details.
.SS Limitations
The signalfd mechanism can't be used to receive signals that are
synchronously generated, such as the \fBSIGSEGV\fP signal that results from
accessing an invalid memory address or the \fBSIGFPE\fP signal that results
from an arithmetic error.  Such signals can be caught only via signal
handler.
.PP
.\"
As described above, in normal usage one blocks the signals that will be
accepted via \fBsignalfd\fP().  If spawning a child process to execute a helper
program (that does not need the signalfd file descriptor), then, after the
call to \fBfork\fP(2), you will normally want to unblock those signals before
calling \fBexecve\fP(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
\fBselect\fP(2), \fBpoll\fP(2), or \fBepoll\fP(7).
.SS "C ライブラリとカーネルの違い"
実際の Linux のシステムコールでは \fIsize_t sizemask\fP という引数が追加で必要である。この引数で \fImask\fP
のサイズを指定する。 glibc の \fBsignalfd\fP()  ラッパー関数にはこの引数は含まれず、
ラッパー関数が必要な値を計算して内部で呼び出すシステムコールに提供する。
.PP
下層にある Linux システムコールは二種類あり、 \fBsignalfd\fP()  と、もっと新しい \fBsignalfd4\fP()  である。
\fBsignalfd\fP()  は \fIflags\fP 引数を実装していない。 \fBsignalfd4\fP()  では上記の値の \fIflags\fP
が実装されている。 glibc 2.9 以降では、 \fBsignalfd\fP()  のラッパー関数は、 \fBsignalfd4\fP()
が利用可能であれば、これを使用する。
.SH バグ
.\" The fix also was put into 2.6.24.5
カーネル 2.6.25 より前では、 \fBsigqueue\fP(3)  により送信されたシグナルと一緒に渡されるデータでは、フィールド
\fIssi_ptr\fP と \fIssi_int\fP は設定されない。
.SH 例
下記のプログラムは、シグナル \fBSIGINT\fP と \fBSIGQUIT\fP を signalfd ファイルディスクリプター経由で受信する。 シグナル
\fBSIGQUIT\fP 受信後にプログラムは終了する。 以下に示すシェルセッションにこのプログラムの使い方を示す。
.PP
.in +4n
.EX
$\fB ./signalfd_demo\fP
\fB\(haC\fP                   # Control\-C generates SIGINT
Got SIGINT
\fB\(haC\fP
Got SIGINT
\fB\(ha\e\fP                    # Control\-\e generates SIGQUIT
Got SIGQUIT
$
.EE
.in
.SS プログラムのソース
\&
.EX
#include <sys/signalfd.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

#define handle_error(msg) \e
    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\(aqt 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\en");
        } else if (fdsi.ssi_signo == SIGQUIT) {
            printf("Got SIGQUIT\en");
            exit(EXIT_SUCCESS);
        } else {
            printf("Read unexpected signal\en");
        }
    }
}
.EE
.SH 関連項目
\fBeventfd\fP(2), \fBpoll\fP(2), \fBread\fP(2), \fBselect\fP(2), \fBsigaction\fP(2),
\fBsigprocmask\fP(2), \fBsigwaitinfo\fP(2), \fBtimerfd_create\fP(2), \fBsigsetops\fP(3),
\fBsigwait\fP(3), \fBepoll\fP(7), \fBsignal\fP(7)
.SH この文書について
この man ページは Linux \fIman\-pages\fP プロジェクトのリリース 5.10 の一部である。プロジェクトの説明とバグ報告に関する情報は
\%https://www.kernel.org/doc/man\-pages/ に書かれている。