gpt4 book ai didi

c - 读取 inotify 文件描述符会用二进制垃圾填充缓冲区

转载 作者:太空宇宙 更新时间:2023-11-04 11:17:33 26 4
gpt4 key购买 nike

我正在尝试 inotify,下面的代码片段是我认为可以很好地演示其功能的代码:

#include <sys/inotify.h>  /* inotify_init(), inotify_add_watch(), IN_* */
#include <stdlib.h> /* EXIT_SUCCESS, EXIT_FAILURE, malloc() */
#include <stdio.h> /* printf(), puts(), perror() */
#include <unistd.h> /* read() */
#include <sys/ioctl.h> /* ioctl, FIONREAD */
#define PTRY(expr) if((expr) == -1)
#define PGOTO(label, msg) do{\
perror(msg);\
goto label;\
} while(0)


int main(void) {

int fd;
PTRY(fd = inotify_init()) PGOTO(failure, "inotify_init");
PTRY(inotify_add_watch(fd, ".", IN_ALL_EVENTS)) PGOTO(failure, "inotify_add_watch");

while(1) {

unsigned int avail; /* We find out how large a buffer we need */
PTRY(ioctl(fd, FIONREAD, &avail)) PGOTO(failure, "ioctl");

char buffer[avail];
ssize_t count = read(fd, buffer, avail); /* We fill the buffer */
if(avail > 0 && count < avail) PGOTO(failure, "read");

printf("Avail: %d, Read: %d\n", (int)avail, (int)count);
if(avail > 0) puts("");

for(ssize_t i = 0; i < count; ) { /* For each event structure in the buffer */

struct inotify_event* event = (struct inotify_event*)buffer + i;
printf("Byte: %d - %d out of %d\n", (int)i, (int)(sizeof(struct inotify_event) + event->len), (int)count);

if(event->len > 0) { /* We print its contents */
printf("Name: %s\n", event->name);
} printf("Cookie: %d\n", event->cookie);

if(event->mask & IN_ACCESS) puts("IN_ACCESS");
if(event->mask & IN_ATTRIB) puts("IN_ATTRIB");
if(event->mask & IN_CLOSE_WRITE) puts("IN_CLOSE_WRITE");
if(event->mask & IN_CLOSE_NOWRITE) puts("IN_CLOSE_NOWRITE");
if(event->mask & IN_CREATE) puts("IN_CREATE");
if(event->mask & IN_DELETE) puts("IN_DELETE");
if(event->mask & IN_DELETE_SELF) puts("IN_DELETE_SELF");
if(event->mask & IN_MODIFY) puts("IN_MODIFY");
if(event->mask & IN_MOVE_SELF) puts("IN_MOVE_SELF");
if(event->mask & IN_MOVED_FROM) puts("IN_MOVED_FROM");
if(event->mask & IN_MOVED_TO) puts("IN_MOVED_TO");
if(event->mask & IN_OPEN) puts("IN_OPEN");
puts("");

i += sizeof(struct inotify_event) + event->len;

}

}

return EXIT_SUCCESS;

failure:
return EXIT_FAILURE;

}

但是,我从 read(2) 调用中收到了一些无关的记录,其中充满了二进制垃圾。附件是从 shell 调用 cat notifyTest.c 时程序的输出:

Avail: 0, Read: -1
Avail: 64, Read: 64

Byte: 0 - 32 out of 64
Name: notifyTest.c
Cookie: 0
IN_OPEN

Byte: 32 - 32783 out of 64
Name: ▒▒▒
Cookie: 1726459283
IN_ACCESS
IN_ATTRIB
IN_CLOSE_WRITE
IN_CLOSE_NOWRITE
IN_CREATE
IN_DELETE
IN_DELETE_SELF
IN_MODIFY
IN_MOVE_SELF
IN_MOVED_FROM
IN_MOVED_TO
IN_OPEN

Avail: 0, Read: -1
Avail: 32, Read: 32

Byte: 0 - 32 out of 32
Name: notifyTest.c
Cookie: 0
IN_CLOSE_NOWRITE

这可能会破坏代码,因为如果没有任何终止 ,进程将收到 SIGSEGV 信号并在读取 event->name 时被杀死\0' 静态分配缓冲区范围内的字符。

这可能是一个怪癖,还是我只是做错了什么?我的 uname -a 是:

Linux witiko-D830 3.8.0-32-generic #47-Ubuntu SMP Tue Oct 1 22:35:23 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

对于可能出错的任何指示,我将不胜感激。

最佳答案

你的问题在这一行:

 struct inotify_event* event = (struct inotify_event*)buffer + i;

该行将指针 buffer 转换为类型 struct inotify_event*,然后添加 i,这是在您的第二次迭代中, 是 32。然后将值增加 32 * sizeof(struct inotify_event)

修复方法是:

 struct inotify_event* event = (struct inotify_event*)(buffer + i);

关于c - 读取 inotify 文件描述符会用二进制垃圾填充缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20182170/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com