struct inotify_event { int wd; /* Watch descriptor */ uint32_t mask; /* Mask of events */ uint32_t cookie; /* Unique cookie associating related events (for rename(2)) */ uint32_t len; /* Size of name field */ char name[]; /* Optional null-terminated name */ };
IN_ACCESS | 文件被访问 |
IN_ATTRIB | 文件属性发生变化 |
IN_CLOSE_WRITE | 以write方式打开文件并关闭 |
IN_CLOSE_NOWRITE | 以非write方式打开文件并关闭 |
IN_CREATE | 文件或目录被创建 |
IN_DELETE | 文件或目录被删除(被监测的文件夹A中B文件被删除) |
IN_DELETE_SELF | 被监测的文件或目录被删除(被监测的文件夹A被删除) |
IN_MODIFY | 文件被修改 |
IN_MOVE_SELF | 被监测的文件或目录移动 |
IN_MOVED_FROM | 文件移出被监测的目录 |
IN_MOVED_TO | 文件移入被监测的目录 |
IN_OPEN | 文件被打开 |
上述flag的集合 | |
IN_ALL_EVENTS | 以上所有flag的集合 |
IN_MOVE | IN_MOVED_TO|IN_MOVED_FROM |
IN_CLOSE | IN_CLOSE_WRITE|IN_CLOSE_NOWRITE |
不常用的flag | |
IN_DONT_FOLLOW | 不follow符号链接 (since 2.6.15) |
IN_EXCL_UNLINK | 当文件从监测目中unlink后,则不再报告该文件的相关event,比如监控/tmp使用 (since 2.6.36) |
IN_MASK_ADD | 追打MASK到被监测的pathname |
IN_ONESHOT | 只监测一次 |
IN_ONLYDIR | 只监测目录 |
IN_IGNORED | inotify_rm_watch,文件被删除或者文件系统被umount |
IN_ISDIR | 发生事件的是一个目录 |
IN_Q_OVERFLOW | Event队列溢出 |
IN_UNMOUNT | 文件系统unmount |
使用:inotify [文件或目录]
#include
#include
#include
#include
#include
#include
#include
#define ERROR(text) error(1, errno, "%s", text)
struct EventMask {
int flag;
const char *name;
};
int freadsome(void *dest, size_t remain, FILE *file)
{
char *offset = (char*)dest;
while (remain) {
int n = fread(offset, 1, remain, file);
if (n == 0) {
return -1;
}
remain -= n;
offset += n;
}
return 0;
}
//http://www.ibm.com/developerworks/cn/linux/l-inotify/
//http://www.jiangmiao.org/blog/2179.html
int main(int argc, char *argv[])
{
const char *target;
if (argc == 1) {
target = ".";
}
else {
target = argv[1];
}
struct EventMask event_masks[] = {
{ IN_ACCESS, "IN_ACCESS" },
{ IN_ATTRIB, "IN_ATTRIB" },
{ IN_CLOSE_WRITE, "IN_CLOSE_WRITE" },
{ IN_CLOSE_NOWRITE, "IN_CLOSE_NOWRITE" },
{ IN_CREATE, "IN_CREATE" },
{ IN_DELETE, "IN_DELETE" },
{ IN_DELETE_SELF, "IN_DELETE_SELF" },
{ IN_MODIFY, "IN_MODIFY" },
{ IN_MOVE_SELF, "IN_MOVE_SELF" },
{ IN_MOVED_FROM, "IN_MOVED_FROM" },
{ IN_MOVED_TO, "IN_MOVED_TO" },
{ IN_OPEN, "IN_OPEN" },
{ IN_DONT_FOLLOW, "IN_DONT_FOLLOW" },
//{ IN_EXCL_UNLINK, "IN_EXCL_UNLINK" },
{ IN_MASK_ADD, "IN_MASK_ADD" },
{ IN_ONESHOT, "IN_ONESHOT" },
{ IN_ONLYDIR, "IN_ONLYDIR" },
{ IN_IGNORED, "IN_IGNORED" },
{ IN_ISDIR, "IN_ISDIR" },
{ IN_Q_OVERFLOW, "IN_Q_OVERFLOW" },
{ IN_UNMOUNT, "IN_UNMOUNT" },
};
int monitor = inotify_init();
if (-1 == monitor) {
ERROR("monitor");
}
int watcher = inotify_add_watch(monitor, target, IN_ALL_EVENTS);
if (-1 == watcher) {
ERROR("inotify_add_watch error");
}
FILE *monitor_file = fdopen(monitor, "r");
char last_name[1024];
char name[1024];
/* event:inotify_event -> name:char[event.len] */
while (true) {
struct inotify_event event;
if (-1 == freadsome(&event, sizeof(event), monitor_file)) {
ERROR("freadsome error");
}
if (event.len) {
freadsome(name, event.len, monitor_file);
}
else {
sprintf(name, "FD: %d\n", event.wd);
}
if (strcmp(name, last_name) != 0) {
puts(name);
strcpy(last_name, name);
}
/* 显示event的mask的含义 */
int i = 0;
for (i = 0; i < sizeof(event_masks) / sizeof(struct EventMask); ++i) {
if (event.mask & event_masks[i].flag) {
printf("\t%s\n", event_masks[i].name);
}
}
}
return 0;
}
http://www.jiangmiao.org/blog/2179.html
http://www.ibm.com/developerworks/cn/linux/l-inotify/