inotify don't treat vim editting as a modification event

心不动则不痛 提交于 2020-06-08 11:54:55

问题


my example code below watches a file for being modified. let's say the file being wathched is foo.txt, and the binary name came out from the sample code is inotify. I did two test for the sample code.

test1:
1) ./inotify foo.txt
2) echo "hello" > foo.txt
then everything works fine,and "file modified" has been printed out.

test2:
1) ./infity foo.txt
2) vim foo.txt
3) edit somehow and save,but don't quit vim
the printed out line is unknown Mask 0x00008000, checked out the inotify header file found this event mask mean IN_CLOSE_WRITE.

from my point of view, "edit and save" just menas modify. but obvisously the inotify code has a different interpration for it. it's strange for me, can anyone help to explain the things behind?

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


int main(int argc, char **argv)
{
  int fdnotify = -1; 

  if (argc !=2) {
    fprintf(stderr, "usage: ./inotify dir_name\n");
    exit(1);
  }

  printf("argc is %d\n", argc);

  fdnotify = inotify_init();
  if (fdnotify < 0) {
    fprintf(stderr, "inotity_init failed: %s\n", strerror(errno));
  }

  int wd = inotify_add_watch(fdnotify, argv[1], IN_MODIFY);
  if (wd < 0) {
    fprintf(stderr, "inotify_add_watch failed: %s\n", strerror(errno));
  }

  while(1) {
    char buffer[4096];
    struct inotify_event *event = NULL;

    int len = read(fdnotify, buffer, sizeof(buffer));

    if (len < 0) {
      fprintf(stderr, "read error %s\n", strerror(errno));
    }   

    event = (struct inotify_event *) buffer;

    while(event != NULL) {
      if ((event->mask & IN_MODIFY)  ) { 
        printf("File modified %s\n", event->name);
      } else {
 printf("unknown Mask 0x%.8x\n", event->mask);
      }
      len -= sizeof(*event) + event->len;

      if (len > 0)
        event = ((void *) event) + sizeof(event) + event->len;
      else
        event = NULL;
    }
  }
}

回答1:


Vim is a program that does not directly save to the file while you save the file. It creates a temporary file usually named .filename.swp and only when you close vim this file gets renamed to filename. From the inotify's FAQ:

The IN_MODIFY event is emitted on a file content change (e.g. via the write() syscall) while IN_CLOSE_WRITE occurs on closing the changed file. It means each change operation causes one IN_MODIFY event (it may occur many times during manipulations with an open file) whereas IN_CLOSE_WRITE is emitted only once (on closing the file).

So the event you get actually makes sense. Lets say that you have a file called filename. When you open the file filename another file is created named .filename.swp. All modifications you perform on this file would, if monitored, generate a number of IN_MODIFY events. When you actually save, what ends up happening is, vim renames this file and closes it, thus generating the IN_CLOSE_WRITE event.




回答2:


I thought Mask 0x00008000 was IN_IGNORED According to inotify.h:

#define IN_CLOSE_WRITE   0x00000008 /* Writtable file was closed.  */
#define IN_IGNORED   0x00008000 /* File was ignored.  */

Is it posible that the event mask is an IN_IGNORED?



来源:https://stackoverflow.com/questions/13312794/inotify-dont-treat-vim-editting-as-a-modification-event

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!