C inotify在删除时无法响应

C inotify在删除时无法响应,c,inotify,C,Inotify,我有以下(粗略的)功能,它持续监视目录中的新文件和被删除的文件,记录这些更改。它正确地记录了所有新文件和目录,但似乎对删除的文件或目录没有任何反应 它似乎是read()调用,当文件被删除时,它不会像应该的那样返回,尽管对于正在创建的文件它会返回 函数被作为两个独立线程之一调用,尽管目前另一个线程什么都不做(只是一个空的无限循环作为占位符) void*watchfs(void*arg){ int infp,手表,长度,i; 字符缓冲区[EVENT_BUF_LEN]; 结构inotify_事件*事件

我有以下(粗略的)功能,它持续监视目录中的新文件和被删除的文件,记录这些更改。它正确地记录了所有新文件和目录,但似乎对删除的文件或目录没有任何反应

它似乎是
read()
调用,当文件被删除时,它不会像应该的那样返回,尽管对于正在创建的文件它会返回

函数被作为两个独立线程之一调用,尽管目前另一个线程什么都不做(只是一个空的无限循环作为占位符)

void*watchfs(void*arg){
int infp,手表,长度,i;
字符缓冲区[EVENT_BUF_LEN];
结构inotify_事件*事件;
如果((infp=inotify_init())<0){
致命(“inotify:无法初始化”);
}
watch=inotify_add_watch(infp、userdir、IN_CREATE | IN_DELETE);
对于(;;){
长度=读取(infp、缓冲区、事件长度);
如果(长度<0){
致命(“inotify:无法读取事件”);
}
i=0;
while(i镜头){
如果(事件->掩码和创建中){
if(事件->掩码和IN_ISDIR){
记录(日志文件系统,“创建新目录”);
}否则{
记录(日志文件系统,“创建新文件”);
}
}else if(事件->屏蔽和删除中){
if(事件->掩码和IN_ISDIR){
记录(日志文件系统,“目录已删除”);
}否则{
记录(日志文件系统,“文件已删除”);
}
}
}
i+=事件大小+事件->镜头;
}
}
inotify_rm_手表(infp,手表);
关闭(infp);
返回0;
}

终于弄明白了到底发生了什么。Linux,或者Gnome,实际上并不删除文件,只是简单地移动它们。即使一个文件被简单地重命名,它显然被移动到了某个地方,那么一个具有新名称的新文件也会从其他地方(某个地方的临时文件夹?)移动到该文件夹中。
rm
命令实际上删除了一个文件,我的代码按照预期将其注册为
IN_DELETE
事件。但是,删除Gnome中的文件或目录时,会将寄存器注册为
,然后将寄存器重命名为
,将
中移动到


我以为我已经检查过这是第一件事,但显然还不够好。

这是你的linux发行版(ubuntu?)和你的文件管理器在幕后扮演的角色。为了模拟windows回收站,他们设置了一个回收站文件夹,并将delete映射到mv命令。这些东西被移动到回收站并被压缩,而不是被删除。@SpencerRathbun Ubuntu,是的。这也是我得出的结论。虽然我不确定重命名过程中到底发生了什么。似乎在某个地方创建了一个具有新名称的副本,然后将具有旧名称的文件移动到垃圾箱,并将具有新名称的副本移动到实际的目标文件夹。在linux上,重命名和在同一目录中移动是一样的。因此,如果我有一个文件
/my/home/file
,并重命名为
/my/home/superfle
,它将注册为
移动/my/home/file到/my/home/superfle
。有两个活动,因为您可能有兴趣观看
/my/home/file
/my/home/superfle
。“移动到”事件链接到
文件
,而“从”事件链接到
超链接
。如果您只将事件移动到,那么观看
superfle
的程序将不会收到事件。@SpencerRathbun啊,这更有意义。我早该知道的。谢谢你的澄清没问题,直到我在一个旧的盒子上寻找重命名命令,我才弄明白。你找不到,因为他们没有。现代重命名命令仅在跨多个文件进行正则表达式重命名时才真正存在。对于单个重命名,mv就像一个符咒。
void* watchfs(void* arg) {
    int infp, watch, length, i ;
    char buffer[EVENT_BUF_LEN] ;
    struct inotify_event* event ;

    if ((infp = inotify_init()) < 0) {
        fatal("inotify: Could not initialize") ;
    }

    watch = inotify_add_watch(infp, userdir, IN_CREATE | IN_DELETE) ;

    for (;;) {
        length = read(infp, buffer, EVENT_BUF_LEN) ;
        if (length < 0) {
            fatal("inotify: Could not read events") ;
        }

        i = 0 ;
        while (i < length) {
            event = (struct inotify_event*) &buffer[i] ;

            if (event->len) {
                if (event->mask & IN_CREATE) {
                    if (event->mask & IN_ISDIR) {
                        record(LOG_FILESYS, "New directory created") ;
                    } else {
                        record(LOG_FILESYS, "New file created") ;
                    }
                } else if (event->mask & IN_DELETE) {
                    if (event->mask & IN_ISDIR) {
                        record(LOG_FILESYS, "Directory deleted") ;
                    } else {
                        record(LOG_FILESYS, "File deleted") ;
                    }
                }
            }

            i += EVENT_SIZE + event->len ;
        }
    }

    inotify_rm_watch(infp, watch) ;
    close(infp) ;

    return 0 ;
}