inotify手册

API

1. inotify_init()
#include <sys/inotify.h>

int inotify_init(void);
        //Returns file desctiptor on success, or -1 on error.

inotify_init()会返回一个文件描述符,用于在后续操作中指代inotify实例。

2. inotify_add_watch()
#include <sys/inotify.h>

int inotify_add_watch(int fd, const char* pathname, uint32_t mask);
    // Returns watch descriptor on success, or -1 on error.

针对描述符fd所指代inotify实例的监控列表,inotify_add_watch()既可以追加新的监控项,也可以修改现有监控项。

  1. pathname
    1. 标识要创建或修改的监控项所对应的文件。
    2. 调用程序必须对该文件具有读权限。
    3. 调用inotify_add_watch()时,会对文件权限做一次性检测。只要监控项继续存在,即便文件权限被更改,调用程序依然可以收到通知。
  2. mask
    1. 掩码,针对pathname定义了要监控的事件。

如果先前未将pathname加入fd的监控列表,则inotify_add_watch()会在列表中创建一个新的监控项,并返回一个新的、非负的监控描述符,用来在后续操作中指代此监控项。对inotify实例来说,该监控描述符是唯一的。

如果先前已将pathname加入fd的监控列表,则会修改现有pathname监控项的掩码,并返回其监控描述符。(此描述符就是最初将pathname加入该监控列表的系统调用inotify_add_watch()所返回的监控描述符。)

3. inotify_rm_watch()

inotify_rm_watch()会从文件描述符fd所指代的 inotify实例中,删除由wd所定义的监控项。

#include <sys/inotify.h>

int inotify_rm_watch(int fd, uint32_t wd);
    // Returns 0 on success, or -1 on error.
  1. wd
    • 监控描述符,由之前的inotify_add_watch()调用返回。

删除监控项会为该描述符生成IN_IGNORED事件。稍后将讨论该事件。

inotify事件

使用inotify_add_watch()删除或修改监控项时,位掩码mask标示了pathname要监控的事件。

mask对应的事件位如下:

  • [ 待办 ]

读取inotify事件

将监控项在监控列表中登记后,应用程序可用read()从inotify文件描述符中读取事件,以判断发生了哪些事件。

如果没有事件发生,read()会一直阻塞,直到有事件产生(除非对该描述符设置O_NOBLOCK)。

事件的结构体如下:

struct inotify_event{
    int wd;     // Watch descriptor on which event occured
    uint32_t mask;  // Bits describing event that occured
    uint32_t cookie;    // Cookie for related events (for rename())
    uint32_t len;   // Size of 'name' field
    char name[];    // Optional null-terminated filename
};
  1. wd

    • 指明发生事件1是哪个监控描述符。
    • 该字段由之前对inotify_add_watch()的调用返回。
    • 当应用程序要监控同一inotify文件描述符下的多个文件和目录时,字段wd就派上用场。应用利用其所提供的线索来判定发生事件的特定文件或目录。(要做到这一点,应用程序必须维护专有数据结构,记录监控描述符与路径名之间的关系。)
  2. mask

    • 该字段会返回描述该事件的位掩码
      注意以下几点:
      1. 移除监控项时,会产生IN_IGNORED事件。起因可能由两个:其一,应用程序使用了inotify_rm_watch()系统调用显式移除监控项。其二,因监控对象被删除或其所驻留的文件系统遭卸载,致使内核隐式删除监控项。以IN_ONESHOT而建立的监控项因事件触发而自动移除时,不会产生IN_IGNORED事件。
      2. 如果事件的主体为路径,那么除去其他位以外,在mask中还会设置IN_ISDIR位。
      3. IN_UNMOUNT事件会通知应用程序包含受监控对象的文件系统已遭卸载。该事件发生后,还会产生包含IN_IGNORED置位的附加事件。
      4. 后续章节将介绍IN_Q_OVERFLOW,并讨论对排队inotify事件的限制。
  3. cookie

    • 该字段可以将相关事件联系在一起。目前,只有在对文件重命名时才会用到该字段。当这种情况发生时,系统会针对待重命名文件所在目录产生IN_MOVED_FROM事件,然后,还会针对重命名后文件的所在目录生成IN_MOVED_TO事件。(若前后目录相同,则会针对同一目录产生上述两个事件。)
    • 两个事件的cookie字段值相等,故而应用程序得以将它们关联起来。
  4. name

    • 当受监控目录中有文件发生事件时,name字段返回一个字符串,标识该文件,以空字符结尾。
    • 若受监控对象自身有事件发生,则不使用name字段,将len字段置为0。
  5. len

    • 标示实际分配给name字段的字节数。
    • 存储于name内的字符串结尾与下一个inotify_event结构的开始之间,可能会有额外的填充字节,孤儿len字段不可或缺。
    • 单个inotify_event事件的长度是sizeof(struct inotify_event) + len

如果传递给read()的缓冲区过小,无法容纳一个inotify_event结构,那么read()调用将以失败告终,错误号为EINVAL。

只要保证缓冲区足够容纳至少一个事件,这个问题就可以完全规避:传给read()的缓冲区应至少为sizeof(struct inotify_event) + NAME_MAX + 1,其中NAME_MAX是文件名的最大长度,此外再加上终止空字符用的字节。

针对文件描述符fd调用ioctl(fd, FIONREAD, &numbytes),会返回其所指代的inotify实例中的当前可读字节数。

从inotify文件描述符中读取的事件形成了一个有序队列。打个比方,对文件重命名时,便可保证在IN_MOVED_TO事件之前能读取到IN_MOVED_FROM事件。

在事件队列的末尾追加一个新事件时,如果此新事件与队列当前尾部事件拥有相同的wd、mask、cookie和mask值,那么内核会将两者合并(以避免对新事件排队)。之所以这么做,是因为很多应用程序都并不关注同一时间的反复出现,而其丢弃多余的事件能降低内核维护事件队列所需的内存总量。然而,这也意味着使用inotify将无法可靠判定出周期性事件的发生次数或频率。

例子

检测文件创建和删除的。注意,inotify无法检测/proc/sys等伪文件。

#include <sys/inotify.h>
#include <err.h>
#include <unistd.h>
#include <limits.h>
#include <stdio.h>

typedef struct inotify_event inotify_event;

int main (void)
{
	const char dir[] = "/home/sixqaq";
	int fd_notify = inotify_init();
	if (inotify_add_watch (fd_notify, dir, IN_CREATE | IN_DELETE) == -1)
		err (-1, "inotify_add_watch() %d", __LINE__);
		
	char buf[sizeof (inotify_event) + NAME_MAX + 1];
	
	for (; ;) {
		ssize_t nread = read (fd_notify, buf, sizeof (buf));
		inotify_event *event = (inotify_event *) buf;
		
		if (event->mask & IN_CREATE)
			printf ("new file <%s> is created in <%s>\n", event->name, dir);
		else if (event->mask & IN_DELETE)
			printf ("file <%s> is removed\n", event->name);
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Inotify是一种文件系统变化通知机制,可以即刻反映文件或文件夹的增删等事件在用户空间中。它是Linux内核从2.6.13版本开始引入的一种强大的、细粒度的、异步的文件系统事件监控机制。通过Inotify,第三方软件可以监控文件系统中文件的各种变化情况,包括添加、删除、移动和修改等。使用Inotify可以检测单个文件的变化,也可以监控整个目录。当监控目录时,目录本身和目录下的内容都会成为监控的对象。可以使用select、poll、epoll等接口监听Inotify文件描述符的可读事件,当有事件发生时,程序可以及时处理。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Linux inotify](https://download.csdn.net/download/chenggong526214/8942667)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [linux - inotify](https://blog.csdn.net/iteye_12332/article/details/82511287)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [Linux Inotify详解和使用](https://blog.csdn.net/zhanglei_admin/article/details/97636301)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

barbyQAQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值