dwatch/source/app.d
2025-08-22 22:09:19 +03:00

71 lines
5.4 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.

// Модуль app.d
// Это основное приложение, демонстрирующее использование обёртки fanotify_wrapper.
// Инициализирует fanotify, маркирует директорию /tmp/scripts для мониторинга событий (открытие, модификация и т.д.),
// затем в бесконечном цикле читает события и выводит информацию о них в консоль.
// Импорты: fanotify_wrapper - обёртка, std.stdio для вывода, std.file для readLink (хотя здесь не используется из-за режима),
// std.format для форматирования строк, core.sys.posix для констант.
import fanotify_wrapper; // Импорт обёртки для fanotify.
import std.stdio; // Импорт для writeln, writefln (вывод в консоль).
import std.file : readLink; // Импорт readLink для чтения симлинков (не используется здесь, но оставлено для возможного расширения).
import std.format : format; // Импорт format для форматирования строк (хотя здесь используется writefln напрямую).
import core.sys.posix.fcntl : AT_FDCWD; // Импорт AT_FDCWD для текущей директории.
import core.sys.posix.unistd : close; // Импорт close (не используется здесь, но для возможного расширения с fd).
// Функция main: точка входа приложения.
void main()
{
// Инициализация объекта Fanotify с флагами:
// FAN_CLASS_NOTIF - режим уведомлений (без контроля доступа),
// FAN_CLOEXEC - закрытие дескриптора при exec,
// FAN_REPORT_FID | FAN_REPORT_DIR_FID | FAN_REPORT_NAME - отчёт с FID (идентификатор файла) вместо fd, плюс имя файла.
// Это позволяет получать имя без реального fd (fd будет FAN_NOFD).
auto fan = new Fanotify(
FAN_CLASS_NOTIF | FAN_CLOEXEC | FAN_REPORT_FID | FAN_REPORT_DIR_FID | FAN_REPORT_NAME);
// Определение маски событий: битовая OR флагов для мониторинга.
// FAN_OPEN - открытие, FAN_MODIFY - модификация, FAN_CLOSE - закрытие (включает WRITE и NOWRITE),
// FAN_CREATE - создание, FAN_DELETE - удаление, FAN_EVENT_ON_CHILD - события в поддиректориях.
auto eventMask = FAN_OPEN | FAN_MODIFY | FAN_CLOSE | FAN_CREATE | FAN_DELETE | FAN_EVENT_ON_CHILD;
// Маркировка директории /tmp/scripts:
// FAN_MARK_ADD - добавить марку, FAN_MARK_ONLYDIR - только для директории (ошибка, если не директория).
// AT_FDCWD - базовая директория текущая, путь "/tmp/scripts".
fan.mark(FAN_MARK_ADD | FAN_MARK_ONLYDIR, eventMask, AT_FDCWD, "/tmp/scripts");
writeln("Мониторинг запущен для /tmp/scripts..."); // Вывод сообщения о старте мониторинга.
// Бесконечный цикл: постоянно читает события и обрабатывает их.
while (true)
{
auto events = fan.readEvents(); // Чтение событий (блокирующее, ждёт до появления событий).
foreach (ref e; events) // Цикл по каждому событию в массиве.
{
// Определение пути: если name извлечено (из FAN_REPORT_NAME), использовать его; иначе "unknown".
// name - относительное имя файла/директории относительно маркированной.
string path = e.name.length ? e.name : "unknown"; // Используем извлечённое имя (относительное)
// Комментарий: в режиме с FAN_REPORT_FID fd = FAN_NOFD, так что нельзя использовать readLink("/proc/self/fd/" ~ to!string(e.eventFd)) для полного пути.
// fd теперь FAN_NOFD, так что пропускаем readLink/close
// Вывод общей информации о событии: маска в hex, PID, путь/имя.
writefln("Событие: mask=0x%x, pid=%d, name/path=%s", e.mask, e.pid, path);
// Проверки и вывод конкретных типов событий с использованием методов структуры.
if (e.isOpen) // Если открытие.
writeln(" - Открытие файла");
if (e.isModify) // Если модификация.
writeln(" - Модификация файла");
if (e.isCloseWrite) // Если закрытие после записи.
writeln(" - Закрытие после записи");
if (e.isCloseNoWrite) // Если закрытие без записи.
writeln(" - Закрытие без записи");
if (e.isCreate) // Если создание.
writeln(" - Создание файла/директории");
if (e.isDelete) // Если удаление.
writeln(" - Удаление файла/директории");
}
}
}