通过阅读inotify的 [英] Using read with inotify

查看:126
本文介绍了通过阅读inotify的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在研究inotify的电话,但我还是有点当涉及到读取界面片状。这是最相关的资源的开发,我能找到关于如何正确使用接口使用的inotify读取(2):

I have been studying inotify call, but I still a bit flaky when it comes to the read interface. These are the most relevant resourses I could find regarding how to properly interface with inotify using read(2):

  • http://www.ibm.com/developerworks/linux/library/l-ubuntu-inotify/index.html
  • http://www.linuxjournal.com/article/8478

他们都实现它以同样的方式,他们首先定义了以下尺寸:

They both implement it in the same way, they first define the following sizes:

#define EVENT_SIZE  ( sizeof (struct inotify_event) )
#define BUF_LEN     ( 1024 * ( EVENT_SIZE + 16 )

然后,他们以这种方式使用它们:

And then they use them in this manner:

length = read( fd, buffer, BUF_LEN );  

if ( length < 0 ) {
    perror( "read" );
}  

while ( i < length ) {
    struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ];
    /* some processing */
    i += EVENT_SIZE + event->len;
}

现在,我们知道的名字是结构inotify_event 的一部分,它有可变长度。所以,不能在缓冲区中的最后inotify_event被截断?

Now, we know name is part of struct inotify_event and that it has variable length. So, couldn't the last inotify_event in buffer be truncated?

假设有1023 inotify_events用的16个字节和一个具有32个字节的路径的路径。什么会怎样呢?请问后来被截断?或将内核看到,它不适合在缓冲区中,离开这一切完全?

Suppose there is 1023 inotify_events with a path of 16 bytes and one with a path of 32 bytes. What will happen then? Will the later truncated? Or will the kernel see that it won't fit in the buffer and leave it all altogether?

推荐答案

根据的inotify(7),您可以使用FIONREAD的ioctl来找出多少数据是可用要被读取,并相应地调整您缓冲器。下面是一些(很粗糙)code,可以做到这一点:

Basic usage

According to inotify(7), you can use the FIONREAD ioctl to find out how much data is available to be read and size your buffer accordingly. Here's some (very rough) code that can accomplish this:

unsigned int avail;
ioctl(inotify_fd, FIONREAD, &avail);

char buffer[avail];
read(fd, buffer, avail);

int offset = 0;
while (offset < avail) {
    struct inotify_event *event = (inotify_event*)(buffer + offset);

    // Insert logic here
    my_process_inotify_event(event);

    offset = offset + sizeof(inotify_event) + event->len;
}

更强大的使用

inotify工具提供了更高层次的接口inotify的。你可以用它代替的inotify访问的,或者你可以看看它是如何实现的inotifytools_next_events安全和稳健读取所有可用的事件。

More robust usage

inotify-tools provides a higher-level interface to inotify. You can use it instead of accessing inotify, or you can see how it implements inotifytools_next_events to safely and robustly read all available events.

在回答您有关截断的问题,我不认为内核永远不会返回部分inotify_event或截断的inotify_event如果有缓冲区的所有事件太小。从inotify的下列第(7)manpage建议是:

In response to your questions about truncation, I do not think that the kernel will ever return a partial inotify_event or truncate an inotify_event if the buffer given is too small for all events. The following paragraph from the inotify(7) manpage suggests this:

当缓冲区给阅读(2)太小,对未来事件取决于内核版本返回信息的行为:2.6.21之前的内核,阅读(2)返回0;因为内核2.6.21,读取(2)失败,出现错误EINVAL。

The behavior when the buffer given to read(2) is too small to return information about the next event depends on the kernel version: in kernels before 2.6.21, read(2) returns 0; since kernel 2.6.21, read(2) fails with the error EINVAL.

由于从做以下评论<一个href=\"http://inotify-tools.sourceforge.net/api/inotifytools_8c-source.html#l01038\">inotifytools.c:

// oh... no.  this can't be happening.  An incomplete event.
// Copy what we currently have into first element, call self to
// read remainder.
// oh, and they BETTER NOT overlap.
// Boy I hope this code works.
// But I think this can never happen due to how inotify is written.

这篇关于通过阅读inotify的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆