C 手表描述符到底是什么?(Linux inotify子系统)

C 手表描述符到底是什么?(Linux inotify子系统),c,linux,unix,C,Linux,Unix,我目前正在使用inotify()系统在我的C代码中监视文件系统中某些目录的活动 现在,使用这些东西的步骤如下。取一个整数(比如event_notifier),使用inotify_init()将其转换为inotify描述符,如下所示 现在,假设我想监视多个目录上的事件。然后,我将通过这些目录将手表添加到此事件通知程序 wd1 = inotify_add_watch(event_notifier,"/../path..to..directory1/../",IN_ALL_EVENTS); wd2 =

我目前正在使用inotify()系统在我的C代码中监视文件系统中某些目录的活动

现在,使用这些东西的步骤如下。取一个整数(比如event_notifier),使用inotify_init()将其转换为inotify描述符,如下所示

现在,假设我想监视多个目录上的事件。然后,我将通过这些目录将手表添加到此事件通知程序

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);
现在,我可以在多个目录上添加手表。每个调用都返回一个“监视描述符”(上面的wd1、wd2、wd3..wdn)。每当任何目录中发生事件时,inotify系统都会向inotify文件描述符事件通知程序发送一个事件以及对应于该特定“监视目录”的监视描述符(wd1、wd2…wdn)

当事件进入时,我可以读取事件通知程序中的struct inotify\u events数组。此inotify_事件结构具有以下字段:

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
我想知道通知来自哪个目录。但是当我统计手表描述符时,它什么也没给我

struct stat fileinfo;
fstat(event->wd, &fileinfo);
printf("\n Size of file is %l",fileinfo_st.size);
甚至/proc/self/fd/event->fd上的readlink()也没有生成任何文件名

char filename[25]; 
readlink("/proc/self/fd/event-wd",filename,sizeof(filename));
printf("\n The filename is %s",filename);
我有两个问题:

1) 手表描述符的确切指向是什么它有什么好处?
2) 如何判断通知来自哪个目录

手表描述符的确切指向是什么?它有什么好处

监视描述符不是文件系统对象或文件描述符。它是inotify子系统用于将事件链接到监视的资源的资源描述符,并允许您在删除某些监视时指定它们

您还应该注意,系统上可能的“打开”手表描述符的数量是有限的。您可以使用以下方法获得最大值:

cat  /proc/sys/fs/inotify/max_user_watches
sudo sysctl -w fs.inotify.max_user_watches=XXXXXX
如果出于任何原因需要超过此值,可以使用以下方法设置该值:

cat  /proc/sys/fs/inotify/max_user_watches
sudo sysctl -w fs.inotify.max_user_watches=XXXXXX

我如何知道通知来自哪个目录

仅使用inotify扩展名无法从事件结构获取文件(目录)的完整路径。您的应用程序代码需要特殊的查找表来存储监视描述符和完整路径名之间的链接。我曾经在PHP中这样做过,因为我也觉得我需要这样做。你可以看看上面的代码。正如我所说,这是PHP,但它可能有助于理解我在做什么。(inotify系统调用签名在PHP和C中是相同的)

  • 手表描述符确切指向什么 文件描述符不是指针,而是
    int
    。因此,它不能指向任何东西。

    它有什么好处? 用于访问文件的文件描述符抽象指示符。对于inotify,它是对虚拟文件的引用


    内核维护一个结构数组(文件描述符表),其中包含进程文件的详细信息。文件描述符是该数组的索引。进程本身无法直接读取或写入文件描述符表

  • 如何判断通知来自哪个目录 应用程序负责将目录与句柄关联

    wd1 = inotify_add_watch(
       event_notifier,
       "/../path..to..directory1/../",
       IN_ALL_EVENTS
       );
    

    如果说“手表描述符唯一的好处(就其自身而言)是移除手表”,是否准确?他们需要移除手表,并将其链接到完整路径名:)(或任何元数据)是的。但我们必须做连接部分。但是,就其本身而言,它们只适用于拆卸手表。:)不是真的。如果没有它们,您就没有机会将事件链接到某个文件或元数据。由于inotify只提供basename,因此如果不同目录中有多个同名文件,您将不知道哪个文件已更改。