118 lines
2.7 KiB
D
118 lines
2.7 KiB
D
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;
|
||
}
|
||
}
|