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

Arj*_*Rao 6 c unix linux

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

现在,使用这些东西之一的程序如下.你取一个整数(比如event_notifier),用inotify_init()把它变成一个inotify描述符,就像这样

event_notifier=inotify_init();
Run Code Online (Sandbox Code Playgroud)

现在,假设我想要监视多个目录上的事件.然后,我将在这些目录上为此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);
Run Code Online (Sandbox Code Playgroud)

现在,我可以在多个目录上添加监视.这些调用中的每一个都返回一个"监视描述符"(上面的wd1,wd2,wd3 ... wdn).每当任何目录中发生事件时,inotify系统都会向inotify文件描述符event_notifier发送一个事件以及与该特定"监视目录"对应的监视描述符(wd1,wd2 ... wdn).

当一个事件进来时,我可以读取一个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  
}
Run Code Online (Sandbox Code Playgroud)

要阅读事件,您只需这样做

read(event_notifier, buffer, sizeof(buffer))
struct inotify_event* event;
event=(struct inotify_event*)buffer; //Assuming only one event will occur
Run Code Online (Sandbox Code Playgroud)

我有兴趣找出通知来自哪个目录.但是当我使用stat()监视描述符时,它什么都没给我

struct stat fileinfo;
fstat(event->wd, &fileinfo);
printf("\n Size of file is %l",fileinfo_st.size);
Run Code Online (Sandbox Code Playgroud)

即使/ 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);
Run Code Online (Sandbox Code Playgroud)

我有两个问题:

1)什么是指向描述符的确切位置?到底有什么好处呢 ?
2)如何判断通知来自哪个目录

hek*_*mgl 2

手表描述符到底指向什么?到底有什么好处呢 ?

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

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

cat  /proc/sys/fs/inotify/max_user_watches
Run Code Online (Sandbox Code Playgroud)

如果您出于任何原因需要超过此值,您可以使用以下方法设置该值:

sudo sysctl -w fs.inotify.max_user_watches=XXXXXX
Run Code Online (Sandbox Code Playgroud)

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

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