Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C inotify api在报告一两次后停止工作_C_Select_File Descriptor_Inotify - Fatal编程技术网

C inotify api在报告一两次后停止工作

C inotify api在报告一两次后停止工作,c,select,file-descriptor,inotify,C,Select,File Descriptor,Inotify,我想测试inotify,所以从互联网上取了几个例子,对它进行了修改以了解各个方面,但失败了,因为它不能像我想的那样工作。首先,我试着查看一个目录,它运行得非常好 因此,我对该文件进行了一些修改,扩展了该示例,但它只能工作一次,并且在读取函数中被阻塞 #include <sys/inotify.h> #include <unistd.h> #include <stdio.h> #define EVENT_SIZE (sizeof (struct inotif

我想测试inotify,所以从互联网上取了几个例子,对它进行了修改以了解各个方面,但失败了,因为它不能像我想的那样工作。首先,我试着查看一个目录,它运行得非常好

因此,我对该文件进行了一些修改,扩展了该示例,但它只能工作一次,并且在读取函数中被阻塞

#include <sys/inotify.h>
#include <unistd.h>
#include <stdio.h>

#define EVENT_SIZE  (sizeof (struct inotify_event))
#define BUF_LEN        (16 * (EVENT_SIZE + 16))

int main()
{
    int fd;
    fd = inotify_init();
    if (fd < 0)
        perror("inotify_init()");
        int wd;
        wd = inotify_add_watch(fd, "target", IN_CLOSE_WRITE);
    if (wd < 0)
        perror("inotify_add_watch");

    char buf[BUF_LEN];
    int len;

    while(1) {

         len = read(fd, buf, BUF_LEN);

         printf("after read\n");

        if (len > 0)
        {
            int i = 0;
            while (i < len)
            {
                struct inotify_event *event;
                event = (struct inotify_event *) &buf[i];

                printf("wd=%d mask=%x cookie=%u len=%u\n",
                    event->wd, event->mask,
                    event->cookie, event->len);

                if (event->mask & IN_MODIFY)
                printf("file modified %s", event->name);

                if (event->len)
                printf("name=%s\n", event->name);

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

    }

    return 0;
}
#包括
#包括
#包括
#定义事件大小(sizeof(结构索引事件))
#定义基本事件(16*(事件大小+16))
int main()
{
int-fd;
fd=inotify_init();
如果(fd<0)
perror(“inotify_init()”);
int-wd;
wd=inotify\u add\u watch(fd,“目标”,在写入时关闭);
如果(wd<0)
佩罗(inotify_add_watch);
char buf[buf_LEN];
内伦;
而(1){
len=读取(fd,buf,buf_len);
printf(“读取后\n”);
如果(len>0)
{
int i=0;
而(我wd,事件->掩码,
事件->cookie,事件->len);
如果(事件->屏蔽和修改)
printf(“文件已修改%s”,事件->名称);
如果(事件->镜头)
printf(“名称=%s\n”,事件->名称);
i+=事件大小+事件->镜头;
}
}
}
返回0;
}
因此,我改为select(),但在这里,它只工作一次,报告两次,然后停止报告更改

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/inotify.h>

#define EVENT_SIZE  ( sizeof (struct inotify_event) )
#define BUF_LEN     ( 1024 * ( EVENT_SIZE + 16 ) )

int main( int argc, char **argv ) 
{
int length, i = 0;
int fd;
int wd;
char buffer[BUF_LEN];

struct timeval timeout;

fd = inotify_init();

if ( fd < 0 ) {
   perror( "inotify_init" );
}

wd = inotify_add_watch( fd, "target", 
                      IN_CLOSE_WRITE );
fd_set rfds,rfdss;
int ret;

/* zero-out the fd_set */
FD_ZERO (&rfds);
FD_ZERO (&rfdss);
FD_SET (fd, &rfds);

timeout.tv_sec = 5;    
timeout.tv_usec = 0;

while(1){
    printf("Before select\n");
    //rfds = rfdss;
    ret = select (fd + 1, &rfds, NULL, NULL, NULL);
    printf("After Select\n");
    timeout.tv_sec = 5;     
    timeout.tv_usec = 0; 
    if (ret < 0)
            perror ("select");
    else if (!ret){
    }
            /* timed out! */
    else if (FD_ISSET (fd, &rfds)){
            printf("file changed============\n");
            length = read( fd, buffer, BUF_LEN );
    }
}

  ( void ) inotify_rm_watch( fd, wd );
 ( void ) close( fd );

 exit( 0 );
}
#包括
#包括
#包括
#包括
#包括
#定义事件大小(sizeof(结构索引事件))
#定义基本长度(1024*(事件大小+16))
int main(int argc,字符**argv)
{
整数长度,i=0;
int-fd;
int-wd;
字符缓冲区[BUF_LEN];
结构timeval超时;
fd=inotify_init();
如果(fd<0){
perror(“inotify_init”);
}
wd=inotify\u add\u watch(fd,“目标”,
在(关闭)(写入);;
fd_设置RFD、rfdss;
int ret;
/*将fd_集归零*/
FD_ZERO(和RFD);
FD_ZERO(和rfdss);
FD_集(FD和RFD);
timeout.tv_sec=5;
timeout.tv_usec=0;
而(1){
printf(“选择前”\n);
//rfds=rfdss;
ret=select(fd+1,&rfds,NULL,NULL,NULL);
printf(“选择后”\n);
timeout.tv_sec=5;
timeout.tv_usec=0;
如果(ret<0)
佩罗(“选择”);
否则如果(!ret){
}
/*超时*/
否则如果(FD_ISSET(FD和RFD)){
printf(“文件更改====================\n”);
长度=读取(fd、缓冲区、BUF_LEN);
}
}
(无效)inotify_rm_手表(fd、wd);
(无效)关闭(fd);
出口(0);
}

一项研究表明,流行的编辑以不同的方式保存它

他们不是直接覆盖该文件,而是创建一个临时文件,然后用新的临时文件替换原始文件。因此,实际发生的情况是,您实际查看的文件不再存在,因此,将要进行的任何更改都不会反映回来

实际上遵循此方法的编辑器是(可能还有更多) 格迪,格尼,六

直接覆盖文件的编辑器是(可能还有更多) 纳米级


因此,即使代码是正确的,编辑器的异常行为也可能是有问题的

对于阻塞读取调用,请参阅:

您可能还希望从IN_CLOSE_WRITE切换到IN_ALL_事件,以确保您没有遗漏某些内容;可能需要删除:

最好的做法是监视包含感兴趣的文件而不是单个文件的目录,因为这样会减少内核中的资源消耗。它还允许您观察“原子”文件替换操作,其中写入程序在文件系统上创建临时文件(可能在同一目录中),写入临时文件,然后在末尾将其重命名(2)到原始文件的顶部


这种替换方式确保了文件的观察者只会注意到文件的完整内容,而不会注意到它的半书面版本。

这在我使用gedit时发生过。作为一种解决方法,我关闭了监视描述符(inotify_rm_watch),并在收到任何通知(读取返回)后关闭了inotify描述符(close)。我立即打开新的描述符再次监视该文件。不知何故,在gedit修改文件后,read()和inotify_rm_watch()返回errno different为零,但监视确实起作用。在文件上使用touch不会引发inotify问题,它只是gedit。