将 read 与 inotify 一起使用
我一直在研究inotify调用,但是当涉及到读取接口时我仍然有点不稳定。这些是我能找到的关于如何使用 read(2) 正确与 inotify 交互的最相关资源:
- http://www.ibm.com/developerworks/linux/library/l-ubuntu-inotify/index.html
- http://www.linuxjournal.com/article/8478
他们都以相同的方式实现它,他们首先定义以下大小:
#define EVENT_SIZE ( sizeof (struct inotify_event) )
#define BUF_LEN ( 1024 * ( EVENT_SIZE + 16 )
然后他们使用它们以这种方式:
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;
}
现在,我们知道 name 是 struct inotify_event 的一部分,并且它具有可变长度。那么,buffer中的最后一个inotify_event不能被截断吗?
假设有 1023 个 16 字节路径的 inotify_events 和 1 个 32 字节路径的 inotify_events。那会发生什么?后期会被截断吗?或者内核会发现它不适合缓冲区并完全保留它吗?
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;
}
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?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
基本用法
根据inotify(7),你可以使用FIONREAD ioctl来了解有多少数据可供使用。被读取并相应地调整缓冲区大小。这里有一些(非常粗略的)代码可以实现这一点:
更强大的用法
inotify-tools 提供了更高级别的接口通知。您可以使用它而不是访问 inotify,或者您可以查看它如何实现 inotifytools_next_events 来安全可靠地读取所有可用事件。
部分事件和截断
为了回答您有关截断的问题,我认为如果给定的缓冲区对于所有事件来说都太小,内核将不会返回部分 inotify_event 或截断 inotify_event 。 inotify(7) 联机帮助页中的以下段落表明了这一点:
正如 inotifytools.c 中的以下评论一样:
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:
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.
Partial events and truncation
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:
As do the following comments from inotifytools.c: