Mac OS X 上的 kqueues:奇怪的事件顺序

发布于 2024-12-18 11:22:56 字数 830 浏览 9 评论 0原文

我使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

极致的悲 2024-12-25 11:22:56

实际上发生的是 Vim 首先不会写入同一个文件
它可能会将其重命名为其他名称,然后创建另一个文件(链接)。
您可以通过执行以下操作来确认:

$ vim file -c wq

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

$ ls -i
30621217 file

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

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

只是不同。这意味着第二个文件实际上是另一个文件
(链接到另一个 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:

$ 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文