【问题标题】:Confused with read() system call对 read() 系统调用感到困惑
【发布时间】:2021-04-27 19:26:41
【问题描述】:

我对 read() 调用获取 inotify 事件感到非常困惑。

代码如下:

#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));

我的测试文件是a.txt。 在gdb中调试后的输出是:

{wd = 0, mask = 0, cookie = 0, len = 0, name = 0x558f05d002d0 ""}

现在,当我将最后一行更改为 read(fd, p, (EVENT_SIZE + 16)); 时,我在 gdb 中得到的输出是:

{wd = 1, mask = 2, cookie = 0, len = 16, name = 0x5625cdd422d0 ".a.txt.swp"}

第一季度。为什么我没有收到溢出错误,因为在这两种情况下,我写的都超过了分配的缓冲区p

第二季度。如果没有错误,那么我的第一个程序也应该可以工作,因为我的文件名小于 10,但它不起作用,它只适用于 16。我在这里缺少什么?

编译器 - g++ 9.3.0

操作系统-ubuntu 20.04

谢谢。

【问题讨论】:

    标签: c system inotify


    【解决方案1】:
    1. 在数组边界外写入的行为是未定义。此外,read 读取最多给定的字节数。
    2. ???

    【讨论】:

      【解决方案2】:

      第一季度

      1. 如果您的进程尝试访问不属于它的内存地址,则会出现段错误。

      2. malloc - “通常,malloc() 从堆中分配内存,并根据需要使用 sbrk(2) 调整堆的大小。”

      3. sbrk - “sbrk() 将程序的数据空间增加字节数。”

      从 1.、2. 和 3. 开始:(可能)还有空间可供您写入,但分配内存后的数据(如果有)肯定已损坏!

      第二季度

      阅读inotify 的文档。

      inotify_event 结构的字段含义:

      ma​​sk 包含描述所发生事件的位(见下文)。

      len 字段计算名称中的所有字节,包括空字节;因此每个 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 的缓冲区足以读取至少一个事件。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-08-31
        • 1970-01-01
        • 2016-11-16
        • 2021-11-28
        • 2018-03-05
        • 2012-03-01
        • 2023-03-25
        • 1970-01-01
        相关资源
        最近更新 更多