OSDN Git Service

Retire LDP man-pages repository
[linuxjm/LDP_man-pages.git] / draft / man7 / fanotify.7
diff --git a/draft/man7/fanotify.7 b/draft/man7/fanotify.7
deleted file mode 100644 (file)
index 85a1431..0000000
+++ /dev/null
@@ -1,528 +0,0 @@
-.\" Copyright (C) 2013, Heinrich Schuchardt <xypron.glpk@gmx.de>
-.\" and Copyright (C) 2014, Michael Kerrisk <mtk.manpages@gmail.com>
-.\"
-.\" %%%LICENSE_START(VERBATIM)
-.\" Permission is granted to make and distribute verbatim copies of this
-.\" manual provided the copyright notice and this permission notice are
-.\" preserved on all copies.
-.\"
-.\" Permission is granted to copy and distribute modified versions of
-.\" this manual under the conditions for verbatim copying, provided that
-.\" the entire resulting derived work is distributed under the terms of
-.\" a permission notice identical to this one.
-.\"
-.\" Since the Linux kernel and libraries are constantly changing, this
-.\" manual page may be incorrect or out-of-date.  The author(s) assume.
-.\" no responsibility for errors or omissions, or for damages resulting.
-.\" from the use of the information contained herein.  The author(s) may.
-.\" not have taken the same level of care in the production of this.
-.\" manual, which is licensed free of charge, as they might when working.
-.\" professionally.
-.\"
-.\" Formatted or processed versions of this manual, if unaccompanied by
-.\" the source, must acknowledge the copyright and authors of this work.
-.\" %%%LICENSE_END
-.\"*******************************************************************
-.\"
-.\" This file was generated with po4a. Translate the source file.
-.\"
-.\"*******************************************************************
-.TH FANOTIFY 7 2014\-12\-31 Linux "Linux Programmer's Manual"
-.SH 名前
-fanotify \- ファイルシステムイベントを監視する
-.SH 説明
-fanotify API はファイルシステムイベントの通知と横取り機能 (interception) を提供する。
-ユースケースとしては、ウイルススキャンや階層型ストレージの管理などがある。 現在のところ、限定的なイベントのみがサポートされている。 特に、作成
-(create)、削除 (delete)、移動 (move) イベントがサポートされていない (これらのイベントを通知する API の詳細については
-\fBinotify\fP(7) を参照)。
-
-\fBinotify\fP(7) API と比較して追加されている機能としては、 マウントされたファイルシステムの全オブジェクトを監視する機能、
-アクセス許可の判定を行う機能、 他のアプリケーションによるアクセスの前にファイルを読み出したり変更したりする機能がある。
-
-この API では以下のシステムコールを使用する: \fBfanotify_init\fP(2), \fBfanotify_mark\fP(2),
-\fBread\fP(2), \fBwrite\fP(2), \fBclose\fP(2)。
-.SS "fanotify_init(), fanotify_mark() と通知グループ"
-\fBfanotify_init\fP(2) システムコールは fanotify 通知グループを作成、初期化し、
-この通知グループを参照するファイルディスクリプターを返す。
-.PP
-fanotify 通知グループはカーネル内部のオブジェクトで、 イベントが作成されるファイル、 ディレクトリ、 マウントポイントのリストを保持する。
-.PP
-fanotify 通知グループの各エントリーには 2 つのビットマスクがある。 \fImark\fP マスクと \fIignore\fP マスクである。 mark
-マスクはどのファイル操作についてイベントを作成するかを定義する。 ignore マスクはどの操作についてイベントを作成しないかを定義する。 これらの 2
-種類のマスクがあることで、 マウントポイントやディレクトリに対してイベントの受信を mark しておきつつ、
-同時にそのマウントポイントやディレクトリ配下の特定のオブジェクトに対するイベントを無視する、 といったことができる。
-.PP
-\fBfanotify_mark\fP(2) システムコールは、ファイル、ディレクトリ、マウントを通知グループに追加し、 どのイベントを報告 (もしくは無視)
-するかを指定する。 また、このようなエントリーの削除、変更も行う。
-.PP
-ignore マスクの考えられる使用方法はファイルキャッシュに対してである。
-ファイルキャッシュに関して興味のあるイベントは、ファイルの変更とファイルのクローズである。 それゆえ、
-キャッシュされたディレクトリやマウントポイントは、 これらのイベントを受信するようにマークされる。
-ファイルが変更されたという最初のイベントを受信した後は、 対応するキャッシュエントリーは無効化される。 そのファイルがクローズされるまでは、
-このファイルに対する変更イベントは興味のない情報となる。 したがって、 変更イベントを ignore マスクに追加することができる。
-クローズイベントを受信すると、 変更イベントを ignore イベントから削除し、 ファイルキャッシュエントリーを更新することができる。
-.PP
-fanotify 通知グループのエントリーは、 ファイルやディレクトリでは inode 番号経由で参照され、 マウントではマウント ID
-経由で参照される。 ファイルやディレクトリの名前が変更されたり、移動されたりした場合も、 関連するエントリーはそのまま残る。
-ファイルやディレクトリが削除されたり、マウントがアンマウントされたりした場合には、 対応するエントリーは削除される。
-.SS イベントキュー
-通知グループにより監視されているファイルシステムオブジェクトでイベントが発生すると、 fanotify システムはイベントを生成し、
-そのイベントはキューにまとめられる。 これらのイベントは、 \fBfanotify_init\fP(2) が返した fanotify
-ファイルディスクリプターから (\fBread\fP(2) などを使って) 読み出すことができる。
-
-2 種類のイベントが生成される。 \fInotification\fP (通知) イベントと \fIpermission\fP (アクセス許可) イベントである。
-通知イベントは単なる情報通知であり、 イベントで渡されたファイルディスクリプターをクローズする場合 (下記参照) を除き、
-受信したアプリケーションでアクションを取る必要はない。 アクセス許可イベントは、
-受信したアプリケーションがファイルアクセスの許可を承認するかを判定する必要がある。 この場合、
-受信者はアクセスが許可されたか否かを決定する応答を書き込まなければならない。
-
-イベントは、 読み出されると、 fanotify グループのイベントキューから削除される。 読み出されたアクセス許可イベントは、 fanotify
-ファイルディスクリプターにアクセス許可の判定が書き込まれるか、 fanotify ファイルディスクリプターがクローズされるまで、 fanotify
-グループの内部のリストに保持される。
-.SS "fanotify イベントの読み出し"
-\fBfanotify_init\fP(2) が返したファイルディスクリプターに対する \fBread\fP(2) を呼び出しは、
-(\fBfanotify_init\fP(2) の呼び出しでフラグ \fBFAN_NONBLOCK\fP を指定しなかった場合)
-ファイルイベントが起こるか、呼び出しがシグナルによって割り込まれる (\fBsignal\fP(7) 参照) まで停止する。
-
-\fBread\fP(2) が成功すると、読み出しバッファーには以下の構造体が 1 つ以上格納される。
-
-.in +4n
-.nf
-struct fanotify_event_metadata {
-    __u32 event_len;
-    __u8 vers;
-    __u8 reserved;
-    __u16 metadata_len;
-    __aligned_u64 mask;
-    __s32 fd;
-    __s32 pid;
-};
-.fi
-.in
-.PP
-性能上の理由から、複数のイベントを一度の \fBread\fP(2) で取得できるように大きめのバッファーサイズ (例えば 4096 バイト)
-を使用することを推奨する。
-
-\fBread\fP(2) の返り値はバッファーに格納されたバイト数である。 エラーの場合は \-1 が返される (ただし、バグも参照)。
-
-\fIfanotify_event_metadata\fP 構造体のフィールドは以下のとおりである。
-.TP 
-\fIevent_len\fP
-これは、 このイベントのデータ長であり、バッファー内の次のイベントへのオフセットである。 現在の実装では、 \fIevent_len\fP の値は常に
-\fBFAN_EVENT_METADATA_LEN\fP である。 しかしながら、 API は将来可変長の構造体を返すことができるように設計されている。
-.TP 
-\fIvers\fP
-このフィールドには構造体のバージョン番号が入る。 実行時に返された構造体がコンパイル時の構造体と一致しているかを検査するには、 この値を
-\fBFANOTIFY_METADATA_VERSION\fP を比較すること。 一致しない場合、 アプリケーションはその fanotify
-ファイルディスクリプターを使用するのを諦めるべきである。
-.TP 
-\fIreserved\fP
-このフィールドは使用されない。
-.TP 
-\fImetadata_len\fP
-この構造体の長さである。 このフィールドは、 イベント種別単位のオプションヘッダーの実装を扱うために導入された。
-現在の実装ではこのようなオプションヘッダーは存在しない。
-.TP 
-\fImask\fP
-イベントを示すビットマスクである (下記参照)
-.TP 
-\fIfd\fP
-これはアクセスされたオブジェクトに対するオープンされたファイルディスクリプターである。 または、キューのオーバーフローが発生した場合には
-\fBFAN_NOFD\fP が入る。 ファイルディスクリプターは監視対象のファイルやディレクトリの内容にアクセスするのに使用できる。
-読み出したアプリケーションは責任を持ってこのファイルディスクリプターをクローズしなければならない。
-.IP
-\fBfanotify_init\fP(2) を呼び出す際、
-呼び出し元はこのファイルディスクリプターに対応するオープンファイル記述にセットされた様々なファイル状態フラグを (\fIevent_f_flags\fP
-引き数を使って) 指定することができる。 さらに、 (カーネル内部の) \fBFMODE_NONOTIFY\fP
-ファイル状態フラグがオープンファイル記述にセットされる。 このフラグは fanotify イベントの生成を抑制する。 したがって、 fanotify
-イベントの受信者がこのファイルディスクリプターを使って通知されたファイルやディレクトリにアクセスした際に、 これ以上イベントが作成されなくなる。
-.TP 
-\fIpid\fP
-これはイベントが発生する原因となったプロセス ID である。 fanotify イベントを監視しているプログラムは、 この PID を
-\fBgetpid\fP(2) が返す PID と比較することで、 イベントが監視しているプログラム自身から発生したかどうか、
-別のプロセスによるファイルアクセスにより発生したか、を判定できる。
-.PP
-\fImask\fP のビットマスクは、1 つのファイルシステムオブジェクトに対してどのイベントが発生したかを示す。
-監視対象のファイルシステムオブジェクトに複数のイベントが発生した場合は、 このマスクに複数のビットがセットされることがある。 特に、
-同じファイルシステムオブジェクトに対する連続するイベントが同じプロセスから生成された場合には、 一つのイベントにまとめられることがある。 例外として、
-2 つのアクセス許可イベントが一つのキューエントリーにまとめられることは決してない。
-.PP
-\fImask\fP でセットされている可能性のあるビットは以下のとおりである。
-.TP 
-\fBFAN_ACCESS\fP
-ファイルやディレクトリがアクセスされた (読み出しが行われた) (ただし、「バグ」の節も参照)。
-.TP 
-\fBFAN_OPEN\fP
-ファイルやディレクトリがオープンされた。
-.TP 
-\fBFAN_MODIFY\fP
-ファイルやディレクトリが変更された。
-.TP 
-\fBFAN_CLOSE_WRITE\fP
-書き込み用 (\fBO_WRONLY\fP か \fBO_RDWR\fP) にオープンされたファイルがクローズされた。
-.TP 
-\fBFAN_CLOSE_NOWRITE\fP
-読み出し用 (\fBO_RDONLY\fP) にオープンされたファイルがクローズされた。
-.TP 
-\fBFAN_Q_OVERFLOW\fP
-イベントキューが 16384 エントリーの上限を超過した。 この上限は \fBfanotify_init\fP(2) 呼び出し時に
-\fBFAN_UNLIMITED_QUEUE\fP フラグを指定することで上書きできる。
-.TP 
-\fBFAN_ACCESS_PERM\fP
-アプリケーションが例えば \fBread\fP(2) や \fBreaddir\fP(2) などを使ってファイルやディレクトリを読み出そうとした。
-このイベントを読み出したプログラムは、 そのファイルシステムオブジェクトへのアクセス許可を承認するかを判定し (下記で説明するとおり)
-応答を書き込まなければならない。
-.TP 
-\fBFAN_OPEN_PERM\fP
-アプリケーションがファイルやディレクトリをオープンしようとした。 このイベントを読み出したプログラムは、
-そのファイルシステムオブジェクトのオープンを承認するかを判定し (下記で説明するとおり) 応答を書き込まなければならない。
-.PP
-クローズイベントを確認するために以下のビットマスクを使うことができる。
-.TP 
-\fBFAN_CLOSE\fP
-ファイルがクローズされた。 以下の同義語である。
-
-    FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE
-.PP
-fanotify ファイルディスクリプターからの \fBread\fP(2) が返した fanotify
-イベントメタデータを含むバッファーに対して繰り返しを行うため、 以下のマクロが提供されている。
-.TP 
-\fBFAN_EVENT_OK(meta, len)\fP
-このマクロは、 バッファー \fImeta\fP の残りの長さ \fIlen\fP を、 メタデータ構造体の長さとバッファーの最初のメタデータ構造体の
-\fIevent_len\fP フィールドと比較して検査する。
-.TP 
-\fBFAN_EVENT_NEXT(meta, len)\fP
-このマクロは、 \fImeta\fP が指すメタデータ構造体の \fIevent_len\fP フィールドで示された長さを使って、 \fImeta\fP
-の次のメタデータ構造体のアドレスを計算する。 \fIlen\fP はバッファーに現在残っているメタデータのバイト数である。 このマクロは \fImeta\fP
-の次のメタデータ構造体へのポインターを返し、 スキップされたメタデータ構造体のバイト数だけ \fIlen\fP を減算する (つまり、 \fIlen\fP から
-\fImeta\->event_len\fP を引き算する)。
-.PP
-また、 以下のマクロも用意されている。
-.TP 
-\fBFAN_EVENT_METADATA_LEN\fP
-.\"
-このマクロは \fIfanotify_event_metadata\fP 構造体の (バイト単位の) サイズを返す。
-返される値はイベントメタデータの最小値である (現在のところ、これが唯一のサイズである)。
-.SS "fanotify ファイルディスクリプターのイベントを監視する"
-fanotify イベントが発生すると、 \fBepoll\fP(7), \fBpoll\fP(2), \fBselect\fP(2) に fanotify
-ファイルディスクリプターが渡された場合には、そのファイルディスクリプターが読み出し可能であると通知される。
-.SS アクセス許可イベントの取り扱い
-アクセス許可イベントでは、 アプリケーションは以下の形式の構造体を fanotify ファイルディスクリプターに \fBwrite\fP(2)
-しなければならない。
-
-.in +4n
-.nf
-struct fanotify_response {
-    __s32 fd;
-    __u32 response;
-};
-.fi
-.in
-.PP
-この構造体のフィールドは以下のとおりである。
-.TP 
-\fIfd\fP
-このフィールドは \fIfanotify_event_metadata\fP 構造体で返されたファイルディスクリプターである。
-.TP 
-\fIresponse\fP
-このフィールドはアクセス許可を承認するかどうかを示す。 値は、このファイル操作を許可する \fBFAN_ALLOW\fP か、 このファイル操作を拒否する
-\fBFAN_DENY\fP のいずれかでなければならない。
-.PP
-アクセスを拒否した場合、 アクセスを要求したアプリケーションは \fBEPERM\fP エラーを受け取ることになる。
-.SS "fanotify ファイルディスクリプターのクローズ"
-.PP
-fanotify 通知グループを参照するすべてのファイルディスクリプターがクローズされると、 fanotify グループは解放され、
-カーネルが再利用できるようにそのリソースは解放される。 \fBclose\fP(2) の際に、 処理中であったアクセス許可イベントには許可が設定される。
-.SS /proc/[pid]/fdinfo
-ファイル \fI/proc/[pid]/fdinfo/[fd]\fP には、 プロセス \fIpid\fP のファイルディスクリプター \fIfd\fP の
-fanotify マークに関する情報が格納される。 詳細はカーネルのソースファイル
-\fIDocumentation/filesystems/proc.txt\fP を参照。
-.SH エラー
-通常の \fBread\fP(2) のエラーに加え、 fanotify ファイルディスクリプターから読み出しを行った際に以下のエラーが発生することがある。
-.TP 
-\fBEINVAL\fP
-バッファーがイベントを保持するには小さすぎる。
-.TP 
-\fBEMFILE\fP
-オープンしたファイル数のプロセス毎の上限に達した。 \fBgetrlimit\fP(2) の \fBRLIMIT_NOFILE\fP の説明を参照。
-.TP 
-\fBENFILE\fP
-オープンされたファイル数のシステム全体の上限に達した。 \fBproc\fP(5) の \fI/proc/sys/fs/file\-max\fP を参照。
-.TP 
-\fBETXTBSY\fP
-\fBfanotify_init\fP(2) の呼び出し時に \fBO_RDWR\fP か \fBO_WRONLY\fP が \fIevent_f_flags\fP
-引き数に指定されており、 現在実行中の監視対象のファイルに対してイベントが発生した際に、 このエラーが \fBread\fP(2) から返される。
-.PP
-通常の \fBwrite\fP(2) のエラーに加え、 fanotify ファイルディスクリプターに書き込みを行った際に以下のエラーが発生することがある。
-.TP 
-\fBEINVAL\fP
-fanotify アクセス許可がカーネルの設定で有効になっていない。 応答構造体の \fIresponse\fP 値が無効である。
-.TP 
-\fBENOENT\fP
-応答構造体のファイルディスクリプター \fIfd\fP が無効である。 このエラーはアクセス許可イベントに対する応答がすでに書き込まれている際に発生する。
-.SH バージョン
-fanotify API は Linux カーネルのバージョン 2.6.36 で導入され、 バージョン 2.6.37 で有効にされた。 fdinfo
-のサポートはバージョン 3.8 で追加された。
-.SH 準拠
-fanotify API は Linux 独自のものである。
-.SH 注意
-fanotify API が利用できるのは、 カーネルが \fBCONFIG_FANOTIFY\fP 設定オプションを有効にして作成されている場合だけである。
-また、 fanotify アクセス許可の処理が利用できるのは \fBCONFIG_FANOTIFY_ACCESS_PERMISSIONS\fP
-設定オプションが有効になっている場合だけである。
-.SS 制限と警告
-fanotify が報告するのはユーザー空間プログラムがファイルシステム API 経由で行ったイベントだけである。 その結果、 fanotify
-ではネットワークファイルシステム上で発生したリモートイベントは捕捉できない。
-.PP
-inotify API は \fBmmap\fP(2), \fBmsync\fP(2), \fBmunmap\fP(2)
-により起こったファイルのアクセスと変更を報告しない。
-.PP
-ディレクトリのイベントは、ディレクトリ自身がオープン、読み出し、クローズされた場合にしか作成されない。
-マークされたディレクトリでの子要素の追加、削除、変更では、監視対象のディレクトリ自身へのイベントは作成されない。
-.PP
-fanotify のディレクトリの監視は再帰的ではない。 ディレクトリ内のサブディレクトリを監視するには、
-追加で監視用のマークを作成しなければならない。 (ただし、 fanotify API
-では、サブディレクトリが監視対象としてマークされているディレクトリに作成された際に検出する手段は提供されていない点に注意すること。)
-マウントの監視を使うことで、 ディレクトリツリー全体を監視することができる。
-.PP
-ベントキューはオーバーフローすることがある。 この場合、 イベントは失われる。
-.SH バグ
-Linux 3.17 時点では、 以下のバグが存在する。
-.IP * 3
-Linux では、ファイルシステムオブジェクトは複数のパスでアクセス可能である。 例えば、 ファイルシステムの一部は \fBmount\fP(8) の
-\fI\-\-bind\fP オプションを使って再マウントされることがある。 マークされたマウントの監視者は、
-同じマウントを使ったファイルオブジェクトについてのみイベント通知を受ける。 それ以外のイベントは通知されない。
-.IP *
-\fBfallocate\fP(2) の呼び出しでは fanotify イベントが作成されない。
-.IP *
-.\" FIXME . A patch was proposed.
-イベントが生成された際に、 そのファイルのファイルディスクリプターを渡す前に、 イベントを受信するプロセスのユーザー ID
-がそのファイルに対する読み出し/書き込み許可があるかの確認は行われない。 非特権ユーザーによって実行されたプログラムに \fBCAP_SYS_ADMIN\fP
-ケーパビリティーがセットされている場合には、 このことはセキュリティーリスクとなる。
-.IP *
-\fBread\fP(2) の呼び出しが fanotify キューから複数のイベントを処理している際に、 エラーが発生した場合、
-返り値はエラーが発生する前までにユーザー空間バッファーに正常にコピーされたイベントの合計長となる。 返り値は \-1 にならず、 \fIerrno\fP
-もセットされない。 したがって、 読み出しを行うアプリケーションではエラーを検出する方法はない。
-.SH 例
-以下のプログラムは fanotify API の使用法を示すものである。 コマンドライン引き数で渡されたマウントポイントを監視し、 種別が
-\fBFAN_PERM_OPEN\fP と \fBFAN_CLOSE_WRITE\fP のイベントを待つ。 アクセス許可イベントが発生には、
-\fBFAN_ALLOW\fP 応答を返す。
-.PP
-以下の出力例はファイル \fI/home/user/temp/notes\fP を編集した際に記録されたものである。 ファイルをオープンする前に
-\fBFAN_OPEN_PERM\fP イベントが発生している。 ファイルをクローズした後に \fBFAN_CLOSE_WRITE\fP イベントが発生している。
-エンターキーをユーザーが押すと、 このプログラムの実行は終了する。
-.SS 出力例
-.in +4n
-.nf
-# ./fanotify_example /home
-Press enter key to terminate.
-Listening for events.
-FAN_OPEN_PERM: File /home/user/temp/notes
-FAN_CLOSE_WRITE: File /home/user/temp/notes
-
-Listening for events stopped.
-.fi
-.in
-.SS プログラムソース
-.nf
-#define _GNU_SOURCE     /* O_LARGEFILE の定義を得るために必要 */
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <poll.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/fanotify.h>
-#include <unistd.h>
-
-/* ファイルディスクリプター 'fd' から読み出しできる全 fanotify イベントを読み出す */
-
-static void
-handle_events(int fd)
-{
-    const struct fanotify_event_metadata *metadata;
-    struct fanotify_event_metadata buf[200];
-    ssize_t len;
-    char path[PATH_MAX];
-    ssize_t path_len;
-    char procfd_path[PATH_MAX];
-    struct fanotify_response response;
-
-    /* fanotify ファイルディスクリプターからイベントが読み出せる間はループする */
-
-    for(;;) {
-
-        /* イベントを読み出す */
-
-        len = read(fd, (void *) &buf, sizeof(buf));
-        if (len == \-1 && errno != EAGAIN) {
-            perror("read");
-            exit(EXIT_FAILURE);
-        }
-
-        /* 読み出せるデータの最後に達しているかチェックする */
-
-        if (len <= 0)
-            break;
-
-        /* バッファーの最初のイベントを参照する */
-
-        metadata = buf;
-
-        /* バッファー内の全イベントを処理する */
-
-        while (FAN_EVENT_OK(metadata, len)) {
-
-            /* 実行時とコンパイル時の構造体が一致するか確認する */
-
-            if (metadata\->vers != FANOTIFY_METADATA_VERSION) {
-                fprintf(stderr,
-                        "Mismatch of fanotify metadata version.\en");
-                exit(EXIT_FAILURE);
-            }
-
-            /* metadata\->fd には、キューのオーバーフローを示す FAN_NOFD か、
-               ファイルディスクリプター (負でない整数) のいずれかが入っている。
-               ここではキューのオーバーフローは無視している。 */
-
-            if (metadata\->fd >= 0) {
-
-                /* オープン許可イベントを処理する */
-
-                if (metadata\->mask & FAN_OPEN_PERM) {
-                    printf("FAN_OPEN_PERM: ");
-
-                    /* ファイルのオープンを許可する */
-
-                    response.fd = metadata\->fd;
-                    response.response = FAN_ALLOW;
-                    write(fd, &response,
-                          sizeof(struct fanotify_response));
-                }
-
-                /* 書き込み可能ファイルのクローズイベントを処理する */
-
-                if (metadata\->mask & FAN_CLOSE_WRITE)
-                    printf("FAN_CLOSE_WRITE: ");
-
-                /* アクセスされたファイルのパス名を取得し表示する */
-
-                snprintf(procfd_path, sizeof(procfd_path),
-                         "/proc/self/fd/%d", metadata\->fd);
-                path_len = readlink(procfd_path, path,
-                                    sizeof(path) \- 1);
-                if (path_len == \-1) {
-                    perror("readlink");
-                    exit(EXIT_FAILURE);
-                }
-
-                path[path_len] = '\e0';
-                printf("File %s\en", path);
-
-                /* イベントのファイルディスクリプターをクローズする */
-
-                close(metadata\->fd);
-            }
-
-            /* 次のイベントに進む */
-
-            metadata = FAN_EVENT_NEXT(metadata, len);
-        }
-    }
-}
-
-int
-main(int argc, char *argv[])
-{
-    char buf;
-    int fd, poll_num;
-    nfds_t nfds;
-    struct pollfd fds[2];
-
-    /* マウントポイントが指定されたか確認する */
-
-    if (argc != 2) {
-        fprintf(stderr, "Usage: %s MOUNT\en", argv[0]);
-        exit(EXIT_FAILURE);
-    }
-
-    printf("Press enter key to terminate.\en");
-
-    /* fanotify API にアクセスするためのファイルディスクリプターを作成する */
-
-    fd = fanotify_init(FAN_CLOEXEC | FAN_CLASS_CONTENT | FAN_NONBLOCK,
-                       O_RDONLY | O_LARGEFILE);
-    if (fd == \-1) {
-        perror("fanotify_init");
-        exit(EXIT_FAILURE);
-    }
-
-    /* 指定されたマウントに対して以下を監視するようにマークを付ける:
-       \- ファイルのオープン前のアクセス許可イベント
-       \- 書き込み可能なファイルディスクリプターのクローズ後の
-         通知イベント */
-
-    if (fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_MOUNT,
-                      FAN_OPEN_PERM | FAN_CLOSE_WRITE, AT_FDCWD,
-                      argv[1]) == \-1) {
-        perror("fanotify_mark");
-        exit(EXIT_FAILURE);
-    }
-
-    /* ポーリングの準備 */
-
-    nfds = 2;
-
-    /* コンソールの入力 */
-
-    fds[0].fd = STDIN_FILENO;
-    fds[0].events = POLLIN;
-
-    /* fanotify の入力 */
-
-    fds[1].fd = fd;
-    fds[1].events = POLLIN;
-
-    /* イベントの発生を待つループ */
-
-    printf("Listening for events.\en");
-
-    while (1) {
-        poll_num = poll(fds, nfds, \-1);
-        if (poll_num == \-1) {
-            if (errno == EINTR)     /* シグナルに割り込まれた場合 */
-                continue;           /* poll() を再開する */
-
-            perror("poll");         /* 予期しないエラー */
-            exit(EXIT_FAILURE);
-        }
-
-        if (poll_num > 0) {
-            if (fds[0].revents & POLLIN) {
-
-                /* コンソールからの入力がある場合: 空の標準入力であれば終了 */
-
-                while (read(STDIN_FILENO, &buf, 1) > 0 && buf != '\en')
-                    continue;
-                break;
-            }
-
-            if (fds[1].revents & POLLIN) {
-
-                /* fanotify イベントがある場合 */
-
-                handle_events(fd);
-            }
-        }
-    }
-
-    printf("Listening for events stopped.\en");
-    exit(EXIT_SUCCESS);
-}
-.fi
-.SH 関連項目
-.ad l
-\fBfanotify_init\fP(2), \fBfanotify_mark\fP(2), \fBinotify\fP(7)
-.SH この文書について
-この man ページは Linux \fIman\-pages\fP プロジェクトのリリース 3.79 の一部
-である。プロジェクトの説明とバグ報告に関する情報は
-http://www.kernel.org/doc/man\-pages/ に書かれている。