「inotify」の版間の差分
提供: セキュリティ
行116: | 行116: | ||
== 関連項目 == | == 関連項目 == | ||
+ | * [[inotify-tools]] | ||
* [[Linuxカーネル]] | * [[Linuxカーネル]] | ||
* [[Linux]] | * [[Linux]] |
2013年10月5日 (土) 13:30時点における版
inotify とは、Linux の ファイルシステム のイベントを監視するための仕組みです。FreeBSD における kevent/kqueue といえます。
読み方
- inotify
- あいのーてぃふぁい
概要
inotify は、Linuxカーネル 2.6.13 で、組み込まれました。 ファイスシステムのイベント監視は、ファイルマネージャーやセキュリティのツールなどに必要不可欠です。inotify は、1つのファイル記述子を開くことで、1つ以上のファイルやディレクトリのオープン、クローズ、移動・名前の変更、削除、作成、属性の変更などのイベントを指定して監視できます。 イベント監視に select や poll を使用できます。
inotify 以前のdnotify では、ディレクトリごとにファイル記述子を開く必要があり、複数の監視対象が存在する場合、コストが大きく、シグナルハンドリングの扱いにくさも問題でした。また、dnotify では、変更を調べるために stat の情報を持ち続けて、比較しなければなりませんでした。
インストール
特にインストールするものはありません。
サンプルコード inotify.c
このプログラムは、一度だけ、イベントを拾って、終了します。 一回の read で取得できるイベントだけを取得します。 バッファサイズの上限を超える場合は、うまくハンドリングできないでしょう。
#include <stdio.h> #include <stdlib.h> #include <err.h> #include <errno.h> #include <unistd.h> #include <sys/types.h> #include <sys/inotify.h> #define INOTIFY_BUFFER_SIZE (4096 * 32) int Inotify_init (void) { int fd = inotify_init (); if (fd < 0) { perror ("inotify_init"); return (fd); } return (fd); } int Inotify_add_watch (int fd, const char *pathname, uint32_t mask) { int watch_fd = inotify_add_watch (fd, pathname, mask); if (watch_fd == -1) { warn ("can not add inotify:fd=%d, path=%s, mask=%u", fd, pathname, mask); } return (watch_fd); } int read_events (int fd) { int r = -1; char buffer [INOTIFY_BUFFER_SIZE] = { 0 }; struct inotify_event *event_ptr; r = read (fd, buffer, INOTIFY_BUFFER_SIZE); if (r <= 0) { return (r); } int offset = 0; while (offset < r) { event_ptr = (struct inotify_event *) & buffer [offset]; (void) printf ("name=%s\n", event_ptr->name); offset += sizeof (struct inotify_event) + event_ptr->len; } return r; } int main (int argc, char *argv[]) { int i; int inotify_fd = Inotify_init(); if (inotify_fd < 0) { errx (EXIT_FAILURE, "can not init inotify"); } long mask = IN_ALL_EVENTS; char *path1 = "/tmp"; int wd1 = Inotify_add_watch (inotify_fd, path1, mask); read_events (inotify_fd); exit (EXIT_SUCCESS); }
使い方
$ cc inotify.c
a.out を実行し、 /tmp のファイルを適当にいじります。
$ ./a.out
/tmp/b に追記してみました。
$ echo hoge >> /tmp/b
/tmp/b に追記したとき、3つのイベントが取得されました。
$ ./a.out name=b name=b name=b