dwatch/source/fanotify_wrapper.d

118 lines
2.7 KiB
D
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

module fanotify_wrapper;
public import fanotify;
import core.sys.posix.unistd : read, close, ssize_t;
import core.sys.posix.fcntl : O_RDONLY, O_RDWR, O_LARGEFILE, AT_FDCWD;
import std.exception : enforce;
import std.string : toStringz;
import std.conv : to;
import core.stdc.stdint; // uint64_t и т.п.
// Структура для представления события (упрощённая)
struct FanotifyEvent
{
fanotify_event_metadata meta;
@property uint64_t mask() const
{
return meta.mask;
}
@property int eventFd() const
{
return meta.fd;
}
@property int pid() const
{
return meta.pid;
}
// Проверка конкретных событий для удобства
bool isOpen() const
{
return (mask & FAN_OPEN) != 0;
}
bool isModify() const
{
return (mask & FAN_MODIFY) != 0;
}
bool isCloseWrite() const
{
return (mask & FAN_CLOSE_WRITE) != 0;
}
bool isCloseNoWrite() const
{
return (mask & FAN_CLOSE_NOWRITE) != 0;
}
bool isAccess() const
{
return (mask & FAN_ACCESS) != 0;
}
// Добавьте другие по необходимости
}
// Класс для работы с fanotify
class Fanotify
{
private int fd = -1;
this(uint initFlags, uint eventFFlags = O_RDONLY | O_LARGEFILE)
{
fd = fanotify_init(initFlags, eventFFlags);
enforce(fd >= 0, "Ошибка инициализации fanotify: " ~ to!string(fd));
}
~this()
{
if (fd >= 0)
{
close(fd);
fd = -1;
}
}
// Маркировка пути (директории или файла)
void mark(uint markFlags, uint64_t eventMask, int dirFd = AT_FDCWD, string path = null)
{
const(char)* cPath = path ? path.toStringz() : null;
int res = fanotify_mark(fd, markFlags, eventMask, dirFd, cPath);
enforce(res == 0, "Ошибка маркировки fanotify: " ~ to!string(res));
}
// Чтение событий (блокирующее или неблокирующее в зависимости от FAN_NONBLOCK)
FanotifyEvent[] readEvents(size_t bufferSize = 4096)
{
ubyte[] buffer = new ubyte[bufferSize];
ssize_t len = read(fd, buffer.ptr, buffer.length);
if (len <= 0)
{
return [];
}
FanotifyEvent[] events;
size_t offset = 0;
while (offset + FAN_EVENT_METADATA_LEN <= len)
{
auto meta = cast(fanotify_event_metadata*)(buffer.ptr + offset);
if (meta.event_len < FAN_EVENT_METADATA_LEN || offset + meta.event_len > len)
{
break;
}
events ~= FanotifyEvent(*meta);
offset += meta.event_len;
}
return events;
}
// Получение дескриптора для расширенного использования (если нужно)
@property int handle() const
{
return fd;
}
}