如何解决与 read() 系统调用混淆
我对获取 inotify 事件的 read()
调用感到非常困惑。
代码如下:
#define EVENT_SIZE sizeof(inotify_event)
int fd = inotify_init();
int wd = inotify_add_watch(fd,dir,IN_MODIFY);
void* p = malloc(sizeof(EVENT_SIZE));
read(wd,p,(EVENT_SIZE + 10));
{wd = 0,mask = 0,cookie = 0,len = 0,name = 0x558f05d002d0 ""}
现在,当我将最后一行更改为 read(fd,(EVENT_SIZE + 16));
时,我在 gdb 中得到的输出是:
{wd = 1,mask = 2,len = 16,name = 0x5625cdd422d0 ".a.txt.swp"}
第一季度。为什么我没有收到溢出错误,因为在这两种情况下,我写入的内容都超过了分配的缓冲区 p
?
第 2 季度。如果没有错误,那么我的第一个程序也应该可以运行,因为我的文件名小于 10,但它不起作用,并且只能处理 16。我在这里缺少什么?
编译器 - g++ 9.3.0
操作系统 - ubuntu 20.04
谢谢。
解决方法
- 在数组边界之外写入的行为是未定义。此外,
read
读取最多给定的字节数。 - ???
第一季度
-
如果您的进程尝试访问不属于它的内存地址,则会出现段错误。
-
malloc - “通常,malloc() 从堆分配内存,并根据需要调整堆的大小,使用 sbrk(2)。”
-
sbrk - “sbrk() 将程序的数据空间增加字节。”
从 1.、2. 和 3. 开始:(可能)还有空间可供您写入,但分配的内存后的数据(如果有)肯定已损坏!
第二季度
阅读 inotify 的文档。
inotify_event 结构体的字段含义:
mask 包含描述发生的事件的位(见下文)。
和
len 字段计算 name 中的所有字节,包括空字节;因此,每个 inotify_event 结构的长度为 sizeof(struct inotify_event)+len
。
和
name 字段仅在为监视目录中的文件返回事件时出现;它标识了监视目录中的文件名。此文件名以空字符结尾,并且可能包含更多空字节 ('\0') 以将后续读取对齐到合适的地址边界。
和
当提供给 read(2) 的缓冲区太小而无法返回有关下一个事件的信息时的行为取决于内核版本:在 2.6.21 之前的内核中,read(2) 返回 0;从内核 2.6.21 开始,read(2) 失败并显示错误 EINVAL。指定大小为 sizeof(struct inotify_event) + NAME_MAX + 1
的缓冲区足以读取至少一个事件。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。