Question

I monitor a file for changes in a separate thread using kqueues/ kevent(2). (I monitor a Python file for reparsing)

I subscribe as following:

EV_SET(&file_change, pyFileP, EVFILT_VNODE,
       EV_ADD | EV_CLEAR,
       NOTE_DELETE |  NOTE_WRITE | NOTE_EXTEND | 
               NOTE_ATTRIB | NOTE_LINK | NOTE_RENAME | NOTE_REVOKE,
       0, 0);

When I write to the file "/tmp/somefile.py" using Vim, I get two separate kevents: The flags of these events (event.fflags) are:

NOTE_RENAME

and

NOTE_DELETE | NOTE_LINK

I never get a "NOTE_WRITE" event! This seems to have something to do with the way Vim writes these files, since if I do

echo "sometext" >> /tmp/somefile.py

I do get the:

NOTE_WRITE|NOTE_EXTEND

event.

Odd, eh? I haven't checked the Vim source code but it must do something strange, or does it simply use user level functions that are implemented that way?

I wasn't really expecting this. Is this a known problem, I just have to check for all events possible, or is there a known interface that really checks if a file has been written?

Was it helpful?

Solution

What is actually happening is that Vim won't write over the same file, first it probably renames it to something else and then creates another file (link). You can confirm that by doing something like:

$ vim file -c wq

This will open a file and write it. Now check the inode:

$ ls -i
30621217 file

Write the file with Vim again and re-check the inode:

$ vim file -c wq
$ ls -i
30621226 file

It's just different. That means the second file is actually another file (linked to another inode) with the same name, and the old one was unlinked.

Many editors do that. I can't confirm why exactly Vim takes this approach. Maybe for safety: if you first rename the file and something goes wrong while writing the new file, you still have the old one. If you start writing over a file and a problem occurs (even with memory) you'll probably loose part of it. Maybe.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top