「inotify」の版間の差分
提供: セキュリティ
行56: | 行56: | ||
int r = -1; | int r = -1; | ||
char buffer [INOTIFY_BUFFER_SIZE] = { 0 }; | char buffer [INOTIFY_BUFFER_SIZE] = { 0 }; | ||
− | struct inotify_event *event_ptr; | + | struct inotify_event *event_ptr = NULL; |
r = read (fd, buffer, INOTIFY_BUFFER_SIZE); | r = read (fd, buffer, INOTIFY_BUFFER_SIZE); | ||
行79: | 行79: | ||
main (int argc, char *argv[]) | main (int argc, char *argv[]) | ||
{ | { | ||
− | |||
int inotify_fd = Inotify_init(); | int inotify_fd = Inotify_init(); | ||
if (inotify_fd < 0) { | if (inotify_fd < 0) { |
2013年10月5日 (土) 17:26時点における版
inotify とは、Linux の ファイルシステム のイベントを監視するための仕組みです。FreeBSD における kevent/kqueue といえます。
読み方
- inotify
- あいのーてぃふぁい
概要
inotify は、Linuxカーネル 2.6.13 で、組み込まれました。 ファイルシステムのイベント監視は、ファイルマネージャーやセキュリティのツールなどに必要不可欠です。inotify は、1つのファイル記述子を開くことで、1つ以上のファイルやディレクトリのオープン、クローズ、移動・名前の変更、削除、作成、属性の変更などのイベントを指定して監視できます。 イベント監視に select や poll を使用できます。 inotify は、再帰的に監視できません。サブディレクトリの監視には、サブディレクトリを inotify_add_watch() で追加する必要があります。
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> #include <linux/limits.h> #define INOTIFY_BUFFER_SIZE ((sizeof(struct inotify_event) + NAME_MAX + 1) * 4096) 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 = NULL; 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 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