Mac OS X 上的 kqueues:奇怪的事件顺序
我使用 kqueues/kevent(2) 在单独的线程中监视文件的更改。 (我监视一个Python文件以进行重新解析)
我订阅如下:
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);
当我使用Vim写入文件“/tmp/somefile.py”时,我得到两个单独的kevent: 这些事件的标志(event.fflags)是:
NOTE_RENAME
并且
NOTE_DELETE | NOTE_LINK
我从未收到“NOTE_WRITE”事件! 这似乎与 Vim 写入这些文件的方式有关,因为如果我这样做,
echo "sometext" >> /tmp/somefile.py
我确实会得到:
NOTE_WRITE|NOTE_EXTEND
事件。
奇怪,是吗?我还没有检查 Vim 源代码,但它一定做了一些奇怪的事情,或者它只是使用以这种方式实现的用户级函数?
我真的没想到会这样。这是一个已知问题,我只需要检查所有可能的事件,或者是否有一个已知的接口真正检查文件是否已被写入?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
实际上发生的是 Vim 首先不会写入同一个文件
它可能会将其重命名为其他名称,然后创建另一个文件(链接)。
您可以通过执行以下操作来确认:
这将打开一个文件并写入它。现在检查 inode:
再次用 Vim 写入文件并重新检查 inode:
只是不同。这意味着第二个文件实际上是另一个文件
(链接到另一个 inode)具有相同的名称,并且旧的已取消链接。
许多编辑都这样做。我无法确认 Vim 到底为什么采取这种方法。
也许为了安全:如果您首先重命名文件并且出现问题
在写入新文件时,您仍然拥有旧文件。如果你开始写作
在文件上并且出现问题(即使有内存)你可能会丢失部分
它的。 也许。
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:
This will open a file and write it. Now check the inode:
Write the file with Vim again and re-check the inode:
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.