日本語 man コマンド類 (ja-man-1.1j_5) と日本語 man ドキュメント (ja-man-doc-5.4 (5.4-RELEASE 用) など) をインストールすると、以下のような man コマンド閲覧、キーワード検索が コンソールからできるようになります。
4.11-RELEASE-K, 5.4-RELEASE-K, 5.5-RELEASE-K, 6.0-RELEASE-K から 6.4-RELEASE-K, 7.0-RELEASE-K から 7.4-RELEASE-K, 8.0-RELEASE-K から 8.4-RELEASE-K, 9.0-RELEASE-K から 9.3-RELEASE-K, 10.0-RELEASE-K から 10.3-RELEASE-K, 11.0-RELEASE-K から 11.4-RELEASE-K, 12.0-RELEASE-K, 12.1-RELEASE-K は、 プライベート版 (小金丸が編集してまとめたもの) ですが、 より多くの翻訳したファイルが含まれています。 (5.4-RELEASE-K から 6.4-RELEASE-K, 7.0-RELEASE-K から 7.4-RELEASE-K, 8.0-RELEASE-K から 8.4-RELEASE-K, 9.0-RELEASE-K から 9.3-RELEASE-K, 10.0-RELEASE-K から 10.3-RELEASE-K, 11.0-RELEASE-K から 11.4-RELEASE-K, 12.0-RELEASE-K から 12.4-RELEASE-K, 13.0-RELEASE-K から 13.3-RELEASE-K, 14.0-RELEASE-K から 14.1-RELEASE-K は、全翻訳済み)
13.3-STABLE-K, 15.0-CURRENT-K は現在、作成中で日々更新されています。
Table of Contents
KQUEUE(2) FreeBSD システムコールマニュアル KQUEUE(2) 名称 kqueue, kevent -- カーネルイベント通知メカニズム ライブラリ 標準 C ライブラリ (libc, -lc) 書式 #include <sys/types.h> #include <sys/event.h> #include <sys/time.h> int kqueue(void); int kevent(int kq, const struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout); EV_SET(kev, ident, filter, flags, fflags, data, udata); 解説 kqueue() システムコールは、イベントが起こるか、または条件が保持されると き、フィルタと名前が付けられたカーネルコードの小さな部分の結果に基づい て、ユーザに通知する一般的方法を提供しています。kevent は、(ident, fil ter) のペアによって識別されます。単に kqueue ごとに 1 つのユニークな kevent があります。 フィルタは、既存の条件が存在していることを検出するために kevent の初期登 録に実行され、また、イベントが評価のためのフィルタに渡されるときはいつで も実行されます。条件が報告されるべきであることをフィルタが決定するなら、 kevent は、検索するユーザのために kqueue に置かれます。 また、フィルタは、ユーザが kqueue から kevent を検索することを試みるとき も実行されます。イベントをトリガした条件がもはや保持されないことをフィル タが示すなら、kevent は、kqueue から削除され、返されません。 フィルタをトリガする複数のイベントは、複数の kevent が kqueue に置かれて いるような結果となりません。代わりに、フィルタは、単一の struct kevent に イベントを集めます。ファイル記述子で close() を呼び出すことは、記述子を参 照しているあらゆる kevent を削除します。 kqueue() システムコールは、新しいカーネルイベントのキューを作成し、記述子 を返します。キューは、fork(2) で作成された子どもによって継承されません。 しかしながら、rfork(2) が RFFDG フラグなしで呼び出されるなら、記述子テー ブルは、2 つのプロセス間で kqueue の共有を許可するように共有されます。 kevent() システムコールは、キューでイベントを登録し、ユーザにあらゆる保留 中 (pending) のイベントを返すために使用されます。changelist 引数は、 <sys/event.h> で定義されているように、kevent 構造体の配列へのポインタで す。changelist に含まれているすべての変更は、あらゆる保留中のイベントが キューから読み込まれる前に、適用されます。nchanges 引数は、changelist の サイズを与えます。eventlist 引数は、kevent 構造体の配列へのポインタです。 nevents 引数は、eventlist のサイズを決定します。nevents が 0 であるとき、 kevent() は、select(2) と違って、たとえ指定された timeout があっても、直 ちに返ります。timeout が NULL ポインタでないなら、struct timespec として 解釈される、イベントを待つ最大のインターバルを指定します。timeout が NULL ポインタであるなら、kevent() は、永久に待ちます。ポーリングを引き起こすた めに、timeout 引数は、0 の値の timespec 構造体を指し、NULL であってはなり ません。同じ配列は、changelist と eventlist のために使用されます。 EV_SET() マクロは、kevent 構造体を容易に初期化するために提供されていま す。 kevent 構造体は、次のように定義されています: struct kevent { uintptr_t ident; /* このイベントのための識別子 */ short filter; /* イベントのためのフィルタ */ u_short flags; /* kqueue のためのアクションフラグ */ u_int fflags; /* フィルタのフラグ値 */ intptr_t data; /* フィルタのデータ値 */ void *udata; /* 不透明なユーザデータ識別子 */ }; struct kevent のフィールドは、次の通りです: ident このイベントを識別するために使用される値。正確な解釈は、アタッ チされたフィルタによって決定されますが、多くの場合、ファイル記 述子です。 filter このイベントを処理するために使用されるカーネルフィルタを特定し ます。あらかじめ定義されたシステムフィルタは、下記に説明されま す。 flags イベントで実行するアクション。 fflags フィルタに特有のフラグ。 data フィルタに特有のデータ値。 udata 変更されずにカーネル通して渡される不透明なユーザ定義の値。 flags フィールドは、次の値を含むことができます: EV_ADD kqueue にイベントを追加します。既存のイベントに再び追加する ことは、オリジナルのイベントのパラメータを修正し、複製された エントリとはなりません。イベントを追加することは、EV_DISABLE フラグによって上書きされなければ、自動的にそれを有効にしま す。 EV_ENABLE イベントがトリガされるなら、kevent() に、イベントを返すこと を許可します。 EV_DISABLE イベントを無効にするので、kevent() は、イベントを返しませ ん。フィルタ自体は、無効にされません。 EV_DISPATCH イベントの配信の直後にイベントの発信元を無効にします。上記の EV_DISABLE を参照してください。 EV_DELETE kqueue からイベントを削除します。ファイル記述子にアタッチさ れているイベントは、記述子の最後のクローズで自動的に削除され ます。 EV_RECEIPT このフラグは、あらゆる保留中のイベントを排出 (drain) せずに kqueue への大量の変更を行うために役に立ちます。入力として渡 されるとき、常に強制的に EV_ERROR が返されます。フィルタが追 加に成功するとき、data フィールドは、0 となります。このフラ グが、遭遇し、EV_ERROR イベントを保持するために、eventlist に残りの空間がないなら、その後の変更は、処理されないことに注 意してください。 EV_ONESHOT イベントは、トリガされているフィルタの最初の発生だけを返しま す。ユーザが kqueue からイベントを検索した後、それは、削除さ れます。 EV_CLEAR イベントがユーザによって検索された後、その状態は、リセットさ れます。これは、現在の状態の代わりに状態遷移を報告するフィル タのために役に立ちます。いくつかのフィルタが、内部でこのフラ グを自動的に設定するかもしれないことに注意してください。 EV_EOF フィルタは、フィルタに特有の EOF 状態を示すために、このフラ グを設定します。 EV_ERROR 下記の「戻り値」を参照してください。 あらかじめ定義されたシステムフィルタは、以下にリストされます。引数は、 kevent 構造体の fflags と data フィールドを通してフィルタをやりとりして渡 されます。 EVFILT_READ 識別子として記述子を取り、読み込むことができるデータ があるときはいつでも返ります。フィルタの振る舞いは、 記述子タイプによって少し異なります。 ソケット listen() (接続を受け付け) するために以前に渡され たソケットは、保留中の着信接続があるとき、返りま す。data は、listen するバックログ (backlog) のサ イズを含んでいます。 他のソケットの記述子は、ソケットバッファの SO_RCVLOWAT 値に従って、読み込まれるデータがある とき、返ります。これは、フィルタが fflags の NOTE_LOWAT フラグを設定することによって、そして data に新しい最低点 (low water mark) を指定するこ とによって追加される時点で、フィルタごとの最低点 で上書きされます。返り時に、data は、読み込むこと ができるプロトコルデータのバイト数を含んでいま す。 ソケットの読み込み方向がシャットダウンしたなら、 フィルタは、flags の EV_EOF も設定し、(もしあるな ら) fflags のソケットエラーを返します。ソケット バッファに保留中のデータがまだある間に、(接続がな くなったことを示す) EOF を返すことができます。 vnode ファイルポインタがファイルの終りでないとき、返り ます。data は、現在位置からファイルの終りまでのオ フセットを含んでいて、負であるもしれません。 この振る舞いは、読み込まれたイベントが、無条件に 通常のファイルのための引き金となるところで、 poll(2) と異なります。このイベントは、 NOTE_FILE_POLL フラグを fflags に設定することに よって無条件に引き金となることができます。 FIFO, PIPE 読み込むデータがあるとき、返ります。data は、利用 可能なバイトの数を含んでいます。 最後の書き込み処理が切断するとき、フィルタは、 flags に EV_EOF を設定します。フィルタが、データ を返す前に利用可能になるのを待って再開する時点 で、これは、EV_CLEAR で渡されることによってクリア されます。 BPF デバイス BPF バッファが満杯であるとき、BPF のタイムアウト が満了するか、または BPF に有効にされた ``immediate mode'' (イミーディエイトモード) があ り、読み込むデータがあるとき、返ります。data は、 利用可能なバイトの数を含んでいます。 EVFILT_WRITE 識別子として記述子を取り、記述子に書き込むことが可能 なときはいつでも返ります。ソケット、パイプと FIFO に ついて、data は、書き込みバッファの残りの空間の合計を 含んでいます。フィルタは、読み込み側が切断するとき、 EV_EOF を設定し、FIFO の場合に、これは、EV_CLEAR の使 用によってクリアされます。このフィルタは、vnode また は BPF デバイスをサポートしていないことに注意してくだ さい。 ソケットについて、最低点 (low water mark) とソケット エラーの扱いは、EVFILT_READ の場合と同じです。 EVFILT_AIO このフィルタのためのイベントは、kevent() で直接登録さ れませんが、それは、aio_read() のような非同期の I/O システムコールを通してスケジュールされるとき、非同期 の I/O 要求の aio_sigevent メンバを通して登録されま す。フィルタは、aio_error() と同じ条件の下で返りま す。このフィルタの詳細については、sigevent(3) と aio(4) を参照してください。 EVFILT_VNODE 識別子としてのファイル記述子と fflags を監視するイベ ントを取り、1 つ以上の要求されたイベントが記述子で生 じるとき、返ります。監視するイベントは、次の通りです: NOTE_ATTRIB 記述子によって参照されるファイル は、変更された属性がありました。 NOTE_CLOSE 監視されたファイルを参照している ファイル記述子は、クローズされま した。クローズされたファイル記述 子は、書き込みアクセスがありませ んでした。 NOTE_CLOSE_WRITE 監視されたファイルを参照している ファイル記述子は、クローズされま した。クローズされたファイル記述 子には、書き込みアクセスがありま した。 NOTE_CLOSE と同様に、この注は、 ファイルが unmount(2) または revoke(2) によって強制的にクロー ズされるとき、活性化されません。 代わりに、NOTE_REVOKE は、そのよ うなイベントのために送られます。 NOTE_DELETE unlink() システムコールは、記述 子によって参照されるファイルで呼 び出されます。 NOTE_EXTEND 通常のファイルについて、記述子に よって参照されるファイルが拡張さ れました。 ディレクトリについて、ディレクト リエントリが名前を変更する操作の 結果として、追加されるか、または 削除されたことを報告します。 NOTE_EXTEND イベントは、名前が ディレクトリの内側で変更されると き、報告されません。 NOTE_LINK 変更されたファイルのリンクカウン ト。特に、NOTE_LINK イベントは、 サブディレクトリが作成されたか、 または記述子によって参照された ディレクトリの内側で削除されたな ら、報告されます。 NOTE_OPEN 記述子によって参照されたファイル は、オープンされました。 NOTE_READ 記述子によって参照されたファイル で、読み込みが起こりました。 NOTE_RENAME 記述子によって参照されるファイル の名前が変更された。 NOTE_REVOKE ファイルへのアクセスが、 revoke(2) によって無効にされる か、または基本的なファイルシステ ムがアンマウントされました。 NOTE_WRITE 記述子によって参照されたファイル で書き込みが起こりました。 返り時に、fflags は、フィルタをトリガしたイベントを含 んでいます。 EVFILT_PROC 識別子として監視するプロセス ID と fflags を監視する イベントを取り、プロセスが 1 つ以上の要求されたイベン トを実行するとき、返ります。プロセスが通常、別のプロ セスを見ることができるなら、それにイベントをアタッチ することができます。監視するイベントは、次の通りです: NOTE_EXIT プロセスは、終了しました。終了ス テータスは、data に格納されます。 NOTE_FORK プロセスは、fork() を呼び出しまし た。 NOTE_EXEC プロセスは、execve(2) または同様の 呼び出しによって新しいプロセスを実 行しました。 NOTE_TRACK fork() 呼び出しに渡ってプロセスをた どります。親プロセスは、オリジナル のイベントとして、同じ fflags を使 用して、子プロセスをモニタするため に新しい kevent を登録します。子プ ロセスは、fflags の NOTE_CHILD 設定 があるイベントと data の親 PID にシ グナルを送ります。 (通常リソースの制限のために) 親プロ セスが新しい kevent の登録に失敗す るなら、fflags の NOTE_TRACKERR 設 定があるイベントにシグナルを送り、 子プロセスは、NOTE_CHILD イベントに シグナルを送りません。 返り時に、fflags は、フィルタをトリガしたイベントを含 んでいます。 EVFILT_PROCDESC fflags のために観察する識別子とイベントとしてモニタす る pdfork(2) によって作成されたプロセス記述子を取り、 関連するプロセスが要求されたイベントの 1 つ以上を実行 するとき、返ります。モニタするイベントは、次の通りで す: NOTE_EXIT プロセスは、終了しました。終了ステータ スは、data に格納されます。 返り時に、fflags は、フィルタをトリガするイベントを含 んでいます。 EVFILT_SIGNAL 識別子として監視するシグナル番号を取り、与えられたシ グナルがプロセスに配信されるとき、返ります。これは、 signal() と sigaction() 機能と共存し、より低い優先順 位があります。無視されるなら、フィルタによって記録さ れない、SIGCHLD シグナルを除いて、たとえシグナルが SIG_IGN とマークされていたとしても、フィルタは、プロ セスにシグナルを配信するすべての試みを記録します。イ ベント通知は、通常のシグナル配信処理の後に起こりま す。data は、kevent() への最後の呼び出し以後、シグナ ルが生じた回数を返します。このフィルタは、内部で EV_CLEAR フラグを自動的に設定します。 EVFILT_TIMER ident によって識別される任意のタイマを確立します。タ イマを追加するとき、data は、タイムアウト期間を指定し ます。タイマは、EV_ONESHOT が指定されなければ、周期的 です。返り時に、data は、kevent() への最後の呼び出し 以後、タイムアウトが満了した回数を含んでいます。この フィルタは、内部で EV_CLEAR フラグを自動的に設定しま す。 NOTE_SECONDS data は、数単位です。 NOTE_MSECONDS data は、ミリ秒単位です。 NOTE_USECONDS data は、マイクロ秒単位です。 NOTE_NSECONDS data は、ナノ秒単位です。 fflags が設定されないなら、デフォルトは、ミリ秒です。 返り時に、fflags は、フィルタをトリガしたイベントを含 んでいます。 既存のタイマが再追加されるなら、既存のタイマは、(前の タイマの期限切れのあらゆる配信されていないレコードを 放棄して) 効果的にキャンセルされ、data と fflags に含 まれている新しいパラメータを使用して再スタートしま す。 kern.kq_calloutmax sysctl によって制御されるタイマの 数に関してシステム全体の制限があります。 EVFILT_USER あらゆるカーネルのメカニズムに関連していないが、ユー ザレベルのコードによってトリガされる ident によって識 別されるユーザイベントを確立します。fflags の下位の 24 ビットは、ユーザ定義フラグのために使用され、次を使 用して操作されます: NOTE_FFNOP 入力 fflags を無視します。 NOTE_FFAND fflags をビット単位の論理積 (AND) します。 NOTE_FFOR fflags をビット単位の論理和 (OR) します。 NOTE_FFCOPY fflags をコピーします。 NOTE_FFCTRLMASK fflags のためのマスクを制御しま す。 NOTE_FFLAGSMASK fflags のためのユーザ定義フラグの マスク。 ユーザのイベントは、次で出力のためにトリガされます: NOTE_TRIGGER イベントは、トリガされます。 返り時に、fflags は、下位 24 ビットにユーザ定義のフラ グを含んでいます。 取り消しの振る舞い nevents が 0 でないなら、すなわち、関数が、潜在的にブロックされているな ら、呼び出しは、取り消しポイントです。そうでなければ、すなわち nevents が 0 であるなら、呼び出しは、取り消し可能ではありません。取り消しは、あらゆ る変更が kqueue に行われる前のみか、または呼び出しがブロックされ、キュー への変更が要求されなかったときのみ、起こるかもしれません。 戻り値 kqueue() システムコールは、新しいカーネルのイベントキューを作成し、ファイ ル記述子を返します。カーネルのイベントキューの作成でエラーがあったなら、 -1 の値が返され、errno が設定されます。 kevent() システムコールは、nevents によって与えられた値まで、eventlist に 置かれたイベントの数を返します。エラーが changelist の要素を処理する間に 生じて、eventlist に十分な空間があるなら、イベントは、flags に EV_ERROR が設定され、data にシステムエラーが設定された eventlist に置かれます。そ うでなければ、-1 が返され、errno は、エラー状態を示す値に設定されます。時 間の制限が満了するなら、kevent() は、0 を返します。 使用例 #include <sys/types.h> #include <sys/event.h> #include <sys/time.h> #include <err.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> int main(int argc, char **argv) { struct kevent event; /* 監視したいイベント */ struct kevent tevent; /* トリガされたイベント */ int kq, fd, ret; if (argc != 2) err(EXIT_FAILURE, "Usage: %s path\n", argv[0]); fd = open(argv[1], O_RDONLY); if (fd == -1) err(EXIT_FAILURE, "Failed to open '%s'", argv[1]); /* kqueue を作成します. */ kq = kqueue(); if (kq == -1) err(EXIT_FAILURE, "kqueue() failed"); /* kevent 構造体を初期化します. */ EV_SET(&event, fd, EVFILT_VNODE, EV_ADD | EV_CLEAR, NOTE_WRITE, 0, NULL); /* kqueue へのイベントをアタッチします. */ ret = kevent(kq, &event, 1, NULL, 0, NULL); if (ret == -1) err(EXIT_FAILURE, "kevent register"); if (event.flags & EV_ERROR) errx(EXIT_FAILURE, "Event error: %s", strerror(event.data)); for (;;) { /* 何かが起こるまでスリープします. */ ret = kevent(kq, NULL, 0, &tevent, 1, NULL); if (ret == -1) { err(EXIT_FAILURE, "kevent wait"); } else if (ret > 0) { printf("Something was written in '%s'\n", argv[1]); } } } エラー kqueue() システムコールは、次の場合に失敗します: [ENOMEM] カーネルがカーネルキューのための十分なメモリを割り付け ることに失敗しました。 [ENOMEM] カレントユーザのための RLIMIT_KQUEUES rlimit (getrlimit(2)) を参照) が超過しました。 [EMFILE] プロセスごとの記述子テーブルが、満杯です。 [ENFILE] システムファイルテーブルが、満杯です。 kevent() システムコールは、次の場合に失敗します: [EACCES] プロセスには、フィルタを登録するためのパーミッションが ありません。 [EFAULT] kevent 構造体を読み込むか、または書き込みでエラーがあ りました。 [EBADF] 指定された記述子が無効です。 [EINTR] タイムアウトが満了する前に、そして、あらゆるイベントが 返りの kqueue に置かれる前に、シグナルが配信されまし た。 [EINTR] 取り消し要求が、スレッドに配信されたけれども、まだ処理 されていません。 [EINVAL] 指定された時間の制限またはフィルタが無効です。 [ENOENT] 修正されるか、または削除されるイベントが、見つかりませ ん。 [ENOMEM] イベントを登録するためにメモリが利用可能でなかったか、 またはタイマの特別な場合に、タイマの最大数が超過しまし た。この最大値は、kern.kq_calloutmax sysctl によって設 定可能です。 [ESRCH] アタッチする指定されたプロセスが存在しません。 kevent() 呼び出しが EINTR エラーで失敗するとき、changelist のすべての変更 は、適用されます。 関連項目 aio_error(2), aio_read(2), aio_return(2), poll(2), read(2), select(2), sigaction(2), write(2), pthread_setcancelstate(3), signal(3) 歴史 kqueue() と kevent() システムコールは、FreeBSD 4.1 ではじめて登場しまし た。 作者 kqueue() システムと、このマニュアルページは、Jonathan Lemon <jlemon@FreeBSD.org> によって書かれました。 バグ timeout 値は、24 時間に制限されています。より長いタイムアウトは、黙って 24 時間として解釈し直されます。 FreeBSD 11.4 April 21, 2020 FreeBSD 11.4