You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用inotify_add_watch监控目录时read()调用失败,返回errno 22

inotify监控目录时read()返回errno 22的问题排查与解决

你在使用inotify_add_watch()监控目录时遇到read()调用失败并返回errno 22(对应EINVAL,无效参数),但监控单个文件时IN_MODIFY事件能正常工作。结合你提供的代码,主要有几个明确的错误导致了这个问题:

  • 变量拼写错误:read()调用里的file_d是笔误,应该是你定义好的file_fd。这个错误会让read()拿到一个未定义的垃圾文件描述符,直接触发EINVAL错误。
  • print函数误用:C语言里没有print()函数,要改成printf()。
  • 缓冲区大小不足:监控目录时,inotify_event结构体末尾会携带变长的name字段(记录触发事件的文件名),直接用sizeof(struct inotify_event)作为read()的缓冲区大小,会导致无法容纳完整的事件数据,后续也可能引发错误。正确做法是分配一个足够大的缓冲区,比如sizeof(struct inotify_event) + NAME_MAX + 1,确保能装下完整事件。

修复后的代码如下:

#define FILE_DIR "/etc/folder"
#define FILENAME "/etc/folder/file"

#include <stdio.h>
#include <unistd.h>
#include <sys/inotify.h>
#include <errno.h>
#include <string.h>
#include <limits.h> // 引入NAME_MAX的定义

// 定义足够大的缓冲区,容纳inotify_event结构体和最长文件名
char buf[sizeof(struct inotify_event) + NAME_MAX + 1];

void notify()
{
    int file_fd = -1;
    int file_wd = -1;
    ssize_t readRet = -1;

    file_fd = inotify_init();
    if (-1 == file_fd) {
        perror("inotify_init failed");
        return;
    }

    file_wd = inotify_add_watch(file_fd, FILE_DIR, IN_CREATE | IN_DELETE);
    if (-1 == file_wd) {
        perror("inotify_add_watch failed");
        close(file_fd);
        return;
    }

    // 使用足够大的缓冲区读取事件
    readRet = read(file_fd, buf, sizeof(buf));
    if (-1 == readRet) {
        printf("Error %d: %s\n", errno, strerror(errno));
        close(file_fd);
        return;
    } else {
        printf("Read ok, %zd bytes read\n", readRet);
        // 解析并输出事件信息
        struct inotify_event *ev = (struct inotify_event *)buf;
        if (ev->mask & IN_CREATE) {
            printf("File created: %s\n", ev->len ? ev->name : "unknown");
        } else if (ev->mask & IN_DELETE) {
            printf("File deleted: %s\n", ev->len ? ev->name : "unknown");
        }
    }

    // 清理资源
    inotify_rm_watch(file_fd, file_wd);
    close(file_fd);
}

额外提醒:要确保你对/etc/folder目录有读权限,inotify_add_watch()需要目标目录的读权限才能正常工作。如果目录不存在或权限不足,inotify_add_watch()会直接失败,但你当前的问题核心还是代码里的拼写错误和缓冲区问题。

内容的提问来源于stack exchange,提问作者dhon2407

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 18:45:43