2011-11-28 25 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