了解inotify

当内核中文件系统发生变化时,inotiy会将监控的事件传递给用户,比如创建、删除、读、写等。
inotify的使用,创建一个文件描述符,添加一个或者监控器watch,然后使用read()方法,从文件描述符中获取事件
信息。read()是以堵塞的方式,进行读取时间信息的。

inotify C API

inotiy提供3个系统调用,可以用来构建各种的文件系统监控器

  1. int inotify_init(void);
    创建一个inotify的实例,成功返回文件描述符,错误返回 -1。

    inotify_init() initializes a new inotify instance and returns a file descriptor associated with a
    new inotify event queue.
  2. int inotify_add_watch(int fd, const char *pathname, uint32_t mask);
    inotiy_add_watch用来添加监控器。
    参数:fd 文件描述符
    pathname 是一个监控的目录
    mask 要监控多个事件,需要使用 | 进行分隔,mask 可以为IN_MODIFY N_ATTRIB N_ATTRIB IN_DELETE 等选项
  3. int inotify_rm_watch(int fd, int wd); 删除一个监控器

    此外还需要read()和close()系统调用。
    read读取的是输入流。从buffer中,按照 inotify_event类型进行去读数据。

    struct inotify_event {
    __s32 wd;
    __u32 mask;
    __u32 cookie;
    __u32 len;
    char name[0];
    };

    mask就是文件变化的类型,比如创建、删除等。
    name 存储的文件的名字

示例代码

#include <unistd.h>
#include <stdio.h>
#include <sys/inotify.h>
#include <string.h>
#include <errno.h>
/*Usage: inotify <dir> */

int read__inotify_fd(int fd)
{
    int res;
    char event_buf[1024];
    int event_size;
    int event_pos = 0;
    struct inotify_event *event;

    res = read(fd, event_buf, sizeof(event_buf));

    if(res < (int)sizeof(*event)) {
        if(errno == EINTR)
            return 0;
        printf("could not get event, %s\n", strerror(errno));
        return -1;
    }
    while(res >= (int)sizeof(*event)) {
        event = (struct inotify_event *)(event_buf + event_pos);


        if(event->len) {
            if(event->mask & IN_CREATE) {
                printf("create file: %s\n", event->name);
            } else {
                printf("delete file: %s\n", event->name);
            }
        }
        event_size = sizeof(*event) + event->len;
        res -= event_size;
        event_pos += event_size;
    }
    return 0;
}

int main(int argc, char **argv)
{
    int mINotifyFd;
    int result;

    if (argc != 2)
    {
        printf("Usage: %s <dir>\n", argv[0]);
        return -1;
    }

    mINotifyFd = inotify_init();

    result = inotify_add_watch(mINotifyFd, argv[1], IN_DELETE | IN_CREATE);


    while (1)
    {
        read_inotify_fd(mINotifyFd);
    }

    return 0;
}

总结

linux 内核提供inotify来监控文件的活动,在android系统的输入系统部门也是允许这个inotify,来监控/dev/inpu这个目录下的变化,同时在这部分还有设计到epoll。

参考文献

使用 inotify 监控文件系统的活动
韦东山android输入子系统部分的内容

Logo

更多推荐