我正在Linux上使用inotify子系统在D中编写文件监视器来进行事件通知.我已经在下面写了一些代码而且我差不多了,但是我有一个问题,即被监视的文件被切换为忽略,并且不再为它提出任何事件.
看起来这个人有类似的问题,但那里没有答案:Inotify vim修改
请考虑以下代码:
/**
* Imports.
*/
import core.sys.posix.unistd;
import core.sys.posix.sys.select;
import inotify;
import std.stdio;
/**
* Main.
*/
void main(string[] arguments)
{
immutable int EVENT_BUF_LEN = (1024 * (inotify_event.sizeof + 16));
auto inotifyInstance = inotify_init();
if (inotifyInstance >= 0)
{
string watchedFile = "/home/gary/Desktop/test.txt";
char[EVENT_BUF_LEN] buffer;
void* pointer;
auto watchDescriptor = inotify_add_watch(inotifyInstance, cast(char*)watchedFile, IN_ALL_EVENTS);
while (true)
{
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(inotifyInstance, &rfds);
timeval timeout;
timeout.tv_sec = 5;
timeout.tv_usec = 0;
if (select(FD_SETSIZE, &rfds, null, null, &timeout))
{
auto inotifyResult = read(inotifyInstance, buffer.ptr, buffer.length);
for (pointer = buffer.ptr; pointer < buffer.ptr + inotifyResult; )
{
inotify_event* event = cast(inotify_event*)pointer;
if (event.mask & IN_ACCESS)
{
writeln("IN_ACCESS");
}
if (event.mask & IN_MODIFY)
{
writeln("IN_MODIFY");
}
if (event.mask & IN_ATTRIB)
{
writeln("IN_ATTRIB");
}
if (event.mask & IN_CLOSE_WRITE)
{
writeln("IN_CLOSE_WRITE");
}
if (event.mask & IN_CLOSE_NOWRITE)
{
writeln("IN_CLOSE_NOWRITE");
}
if (event.mask & IN_OPEN)
{
writeln("IN_OPEN");
}
if (event.mask & IN_MOVED_FROM)
{
writeln("IN_MOVED_FROM");
}
if (event.mask & IN_MOVED_TO)
{
writeln("IN_MOVED_TO");
}
if (event.mask & IN_CREATE)
{
writeln("IN_CREATE");
}
if (event.mask & IN_DELETE)
{
writeln("IN_DELETE");
}
if (event.mask & IN_DELETE_SELF)
{
writeln("IN_DELETE_SELF");
}
if (event.mask & IN_MOVE_SELF)
{
writeln("IN_MOVE_SELF");
}
if (event.mask & IN_UMOUNT)
{
writeln("IN_UMOUNT");
}
if (event.mask & IN_Q_OVERFLOW)
{
writeln("IN_Q_OVERFLOW");
}
if (event.mask & IN_IGNORED)
{
writeln("IN_IGNORED");
}
if (event.mask & IN_CLOSE)
{
writeln("IN_CLOSE");
}
if (event.mask & IN_MOVE)
{
writeln("IN_MOVE");
}
if (event.mask & IN_ONLYDIR)
{
writeln("IN_ONLYDIR");
}
if (event.mask & IN_DONT_FOLLOW)
{
writeln("IN_DONT_FOLLOW");
}
if (event.mask & IN_EXCL_UNLINK)
{
writeln("IN_EXCL_UNLINK");
}
if (event.mask & IN_MASK_ADD)
{
writeln("IN_MASK_ADD");
}
writefln("wd: %s - mask: 0x%08x - cookie: %s - len: %s", event.wd, event.mask, event.cookie, event.len);
pointer += inotify_event.sizeof + event.len;
}
}
}
inotify_rm_watch(inotifyInstance, watchDescriptor);
close(inotifyInstance);
}
}
Run Code Online (Sandbox Code Playgroud)
如果我执行以下操作,我会得到以下结果:
触摸〜/ Desktop/test.txt
IN_OPEN
wd:1 - 掩码:0x00000020 - cookie:0 - len:0
IN_IGNORED
wd:1 - 掩码:0x00008000 - cookie:0 - len:0
回声"玛丽有一只小羊羔." >>〜/ Desktop/test.txt
IN_OPEN
wd:1 - 掩码:0x00000020 - cookie:0 - len:0
IN_IGNORED
wd:1 - 掩码:0x00008000 - cookie:0 - len:0
在Vim中打开,修改和:wq
IN_OPEN
wd:1 - 掩码:0x00000020 - cookie:0 - len:0
IN_IGNORED
wd:1 - 掩码:0x00008000 - cookie:0 - len:0
这里似乎没有任何工作,触发打开事件后文件被忽略.
如果我改变代码并更改IN_ALL_EVENTS标志(检查所有事件)并使用IN_MODIFY,我得到以下内容:
触摸〜/ Desktop/test.txt
没有结果.
回声"玛丽有一只小羊羔." >>〜/ Desktop/test.txt
IN_MODIFY wd:1 - mask:0x00000002 - cookie:0 - len:0
在Vim中打开,修改和:wq
IN_IGNORED wd:1 - mask:0x00008000 - cookie:0 - len:0
只有第2点似乎正常工作.
我在这里做错了什么想法以及有关更改代码以正确获取文件的所有修改事件的任何想法?
经过一些阅读后,我对代码进行了一些修改,似乎已经解决了问题.附加到文件会引发一个IN_MODIFY很好的事件.Touch提出了一个IN_ATTRIB我们可以视为修改的东西.VIM(和其他编辑)提高IN_ATTRIB,IN_DELETE_SELF并IN_MOVE_SELF提高最终的事件之前IN_IGNORED,所以我可以处理这些现在我知道了.如果我遇到一个IN_IGNORED事件,我会重新初始化inotify.
/**
* Imports.
*/
import core.sys.posix.unistd;
import core.sys.posix.sys.select;
import inotify;
import std.stdio;
/**
* Main.
*/
void main(string[] arguments)
{
immutable int EVENT_BUFFER_LENGTH = (inotify_event.sizeof + 16) * 1024;
immutable uint NOTIFICATION_FLAGS = IN_MODIFY | IN_ATTRIB | IN_DELETE_SELF | IN_MOVE_SELF | IN_IGNORED;
auto inotifyInstance = inotify_init();
if (inotifyInstance >= 0)
{
string watchedFile = "/home/gary/Desktop/test.txt";
char[EVENT_BUFFER_LENGTH] eventBuffer;
void* eventPointer;
auto watchDescriptor = inotify_add_watch(inotifyInstance, cast(char*)watchedFile, NOTIFICATION_FLAGS);
while (true)
{
fd_set fileDescriptorSet;
FD_ZERO(&fileDescriptorSet);
FD_SET(inotifyInstance, &fileDescriptorSet);
timeval timeout;
timeout.tv_sec = 5;
timeout.tv_usec = 0;
if (select(FD_SETSIZE, &fileDescriptorSet, null, null, &timeout))
{
auto bytesRead = read(inotifyInstance, eventBuffer.ptr, eventBuffer.length);
for (eventPointer = eventBuffer.ptr; eventPointer < eventBuffer.ptr + bytesRead; null)
{
inotify_event* event = cast(inotify_event*)eventPointer;
if (event.mask & IN_MODIFY || event.mask & IN_ATTRIB)
{
writeln("Modified");
}
if (event.mask & IN_DELETE_SELF || event.mask & IN_MOVE_SELF || event.mask & IN_IGNORED)
{
writeln("Modified");
inotify_rm_watch(inotifyInstance, watchDescriptor);
close(inotifyInstance);
inotifyInstance = inotify_init();
watchDescriptor = inotify_add_watch(inotifyInstance, cast(char*)watchedFile, NOTIFICATION_FLAGS);
}
eventPointer += inotify_event.sizeof + event.len;
}
}
}
inotify_rm_watch(inotifyInstance, watchDescriptor);
close(inotifyInstance);
}
}
Run Code Online (Sandbox Code Playgroud)