read(2)
以结构形式从某个文件描述符中提取数据。这样做的代码通常是这样的:
#include <unistd.h>
#include <sys/inotify.h>
int main() {
int inotify_fd = inotify_init();
inotify_add_watch(inotify_fd, "file_to_watch", IN_ALL_EVENTS);
char c[4096];
for(;;) {
ssize_t len = read(inotify_fd, c, sizeof(c));
struct inotify_event *s;
for(char* p = c; p < c + len; p += sizeof(struct inotify_event) + s->len) {
s = (struct inotify_event *)p;
}
}
}
当我用clang编译上面的代码时,我得到了一个警告:
inotify.c:13:15: warning: cast from 'char *' to 'struct inotify_event *' increases required alignment from 1 to 4 [-Wcast-align]
s = (struct inotify_event *)p;
^~~~~~~~~~~~~~~~~~~~~~~~~
#include <stdalign.h>
和
alignas(struct inotify_event)
,但毫无用处。
我想修正这个警告,而不仅仅是让它沉默。我该怎么做?
编辑:下面是关于inotify fd的read(2)是如何工作的,如
its man page
:
以下结构:
struct inotify_event {
int wd;
uint32_t mask;
uint32_t cookie;
uint32_t len;
char name[];
};
此文件名以空结尾,可能包括
地址边界。
len字段统计名称中的所有字节,包括null
字节;因此,每个inotify事件结构的长度
当给读取(2)的缓冲区太小而无法返回时的行为
在2.6.21之前的内核,read(2)返回0;在内核2.6.21之后,read(2)
失败,出现错误EINVAL。指定大小为的缓冲区
sizeof(struct inotify_event) + NAME_MAX + 1
将足以读取至少一个事件。
我无法读取部分结构,例如从固定大小的文件中单独读取名称。如果我没有指定一个足够大的缓冲区来读取整个结构,我就不会得到任何缓冲区。