2011-11-28 56 views
1

我使用kqueues/kevent(2)监视文件以查找单独线程中的更改。 (我监视重新解析Python文件)Mac OS X上的kqueues:奇怪的事件顺序

我同意如下:

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); 

当我写文件 “/tmp/somefile.py” 使用Vim的,我得到两个不同的kevents: 这些事件的标志(event.fflags)是:

NOTE_RENAME 

NOTE_DELETE | NOTE_LINK 

我永远不会收到“NOTE_WRITE”事件! 这似乎有事情做用Vim写这些文件的方式,因为如果我这样做

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

我得到的:

NOTE_WRITE|NOTE_EXTEND 

事件。

奇怪的,呃?我没有检查Vim的源代码,但它必须做一些奇怪的事情,还是仅仅使用以这种方式实现的用户级功能?

我并没有真正期待这一点。这是一个已知的问题,我只需要检查所有可能的事件,或者是否有一个已知的接口来检查文件是否被写入?

回答

1

实际发生的事情是Vim不会写同一个文件,首先 它可能会将其重命名为其他文件,然后创建另一个文件(链接)。 可以确认,通过做这样的事情:

$ vim file -c wq 

这将打开一个文件,并把它写。现在检查的inode:

$ ls -i 
30621217 file 

再次写入用Vim的文件,并重新检查的inode:

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

这只是不同。这意味着第二个文件实际上是具有相同名称的另一个文件 (链接到另一个inode),而旧文件是未链接的。

许多编辑都这么做。我无法证实为什么Vim采用这种方法。 也许为了安全起见:如果您在写入新文件时首先重命名文件并出错 ,您仍旧拥有旧文件。如果您开始在文件上写入 并且发生问题(即使是在有内存的情况下),您可能会丢失它的部分 。 也许

+0

谢谢,这解释了它。但这有点问题。 – buddhabrot

+1

确实。但是,你必须听所有的事情吗?您可以注册NOTE_WRITE | NOTE_LINK和两种情况(真正的追加,如来自外壳的回声或新文件)都应该有效。 – sidyll

+0

是的,我猜这套活动是安全的。谢谢您的帮助。 – buddhabrot