我目前正在使用inotify()系统来监控我的C代码中文件系统中某些目录的活动。
现在,使用其中一种方法的程序如下。你取一个整数(比如event_notifier),使用inotify_init()把它变成一个inotify描述符,就像这样
event_notifier=inotify_init();
现在,假设我想要监视多个目录上的事件。然后,我将在这些目录上为此event_notifier添加监视
wd1 = inotify_add_watch(event_notifier,"/../path..to..directory1/../",IN_ALL_EVENTS);
wd2 = inotify_add_watch(event_notifier,"/../path..to..directory2/../",IN_ALL_EVENTS);
wd3 = inotify_add_watch(event_notifier,"/../path..to..directory3/../",IN_ALL_EVENTS);
. . . .
wdn = inotify_add_watch(event_notifier,"/../path..to..directoryn/../",IN_ALL_EVENTS);
现在,我可以在多个目录上添加监视。这些调用中的每一个都返回一个&#34;监视描述符&#34; (上面的wd1,wd2,wd3 .. wdn)。每当任何目录中发生事件时,inotify系统都会向inotify文件描述符event_notifier发送一个事件以及与该特定&#34;监视目录相对应的监视描述符(wd1,wd2 ... wdn)&#34; < / p>
当一个事件进来时,我可以读取一个 struct inotify_event 数组的event_notifier。此inotify_event结构包含以下字段:
struct inotify_event
{
int wd; //Watch descriptor
...
uint32_t len; //Size of 'name' field
char name[]; //null terminated name
}
要阅读活动,您只需
read(event_notifier, buffer, sizeof(buffer))
struct inotify_event* event;
event=(struct inotify_event*)buffer; //Assuming only one event will occur
我有兴趣找出通知来自哪个目录。但是当我使用stat()监视描述符时,它什么也没给我什么
struct stat fileinfo;
fstat(event->wd, &fileinfo);
printf("\n Size of file is %l",fileinfo_st.size);
即使是/ proc / self / fd / event-&gt; fd上的readlink()也没有产生任何文件名。
char filename[25];
readlink("/proc/self/fd/event-wd",filename,sizeof(filename));
printf("\n The filename is %s",filename);
我有两个问题:
1)什么是指向描述符的确切位置? 有什么好处?
2)如何判断通知来自哪个目录?
答案 0 :(得分:1)
究竟是什么手表描述符?有什么好处?
监视描述符不是文件系统对象或文件描述符。它是inotify子系统用于将事件链接到监视的资源的资源描述符,并允许您在删除时指定某些监视。
您还应注意,可能的“开放”手表描述符的数量在系统上是有限的。您可以使用以下方式获取最大值:
cat /proc/sys/fs/inotify/max_user_watches
如果您因任何原因需要超过此值,可以使用以下方式设置值:
sudo sysctl -w fs.inotify.max_user_watches=XXXXXX
如何判断通知来自哪个目录?
仅使用inotify扩展,无法从事件结构中获取文件(目录)的完整路径。您的应用程序代码需要特殊的查找表,用于存储监视描述符和完整路径名之间的链接。我曾经在PHP中做过一次,因为我觉得我需要它。您可以查看Github上的代码。就像我说的,这是PHP,但它可能有助于理解我在做什么。 (inotify系统调用签名在PHP和C中是相同的)
答案 1 :(得分:0)
int
。因此,它无法指向任何东西。
内核维护一个结构数组(文件描述符表),其中包含进程文件的详细信息。文件描述符是该数组的索引。您的进程本身无法直接读取或写入文件描述符表。
wd1 = inotify_add_watch(
event_notifier,
"/../path..to..directory1/../",
IN_ALL_EVENTS
);