Добавлена функция определения имени процесса создающего события

This commit is contained in:
Alexander Zhirov 2025-08-29 01:27:33 +03:00
parent 1f78d8eb83
commit bc02ac8518
Signed by: alexander
GPG key ID: C8D8BE544A27C511

View file

@ -6,7 +6,7 @@ import depoll; // новый модуль для epoll
import core.sys.posix.fcntl : O_RDONLY, O_LARGEFILE; import core.sys.posix.fcntl : O_RDONLY, O_LARGEFILE;
import core.stdc.errno : errno; import core.stdc.errno : errno;
import core.stdc.string : strerror; import core.stdc.string : strerror;
import std.string : fromStringz, toStringz, join; import std.string : fromStringz, toStringz, join, strip;
import std.conv : to; import std.conv : to;
import std.stdio : writeln, writefln; import std.stdio : writeln, writefln;
import std.getopt; import std.getopt;
@ -18,6 +18,8 @@ import std.exception;
import std.path : baseName; import std.path : baseName;
import std.file : readText, exists, read;
/// Вернуть путь для fd из события PRE_CONTENT. /// Вернуть путь для fd из события PRE_CONTENT.
/// Может вернуть "(deleted)" или пустую строку, если объект без имени. /// Может вернуть "(deleted)" или пустую строку, если объект без имени.
string pathFromEventFd(int fd) string pathFromEventFd(int fd)
@ -35,6 +37,76 @@ string pathFromEventFd(int fd)
return cast(string) buf[0 .. n].idup; return cast(string) buf[0 .. n].idup;
} }
/// Возвращает "имя процесса" для события fanotify.
/// Приоритет: /proc/<pid>/comm → имя ссылки /proc/<pid>/exe → первый токен из cmdline.
/// Если всё сломалось — "pid:<pid>".
string eventProcessName(int pid)
{
// 1) /proc/<pid>/comm — самое точное короткое имя
const commPath = "/proc/" ~ pid.to!string ~ "/comm";
try
{
if (exists(commPath))
{
auto s = readText(commPath).strip; // там обычно одна строка с \n
if (s.length)
return s;
}
}
catch (Exception e)
{
}
// 2) /proc/<pid>/exe — полный путь к исполняемому файлу
try
{
char[4096] buf;
auto link = "/proc/" ~ pid.to!string ~ "/exe";
auto n = readlink(link.toStringz, buf.ptr, buf.length);
if (n > 0)
{
auto exePath = cast(string) buf[0 .. n].idup;
auto name = baseName(exePath);
if (name.length)
return name;
}
}
catch (Exception e)
{
}
// 3) /proc/<pid>/cmdline — первый NUL-разделённый аргумент
try
{
const cmdPath = "/proc/" ~ pid.to!string ~ "/cmdline";
if (exists(cmdPath))
{
auto bytes = cast(const(ubyte)[]) read(cmdPath);
if (bytes.length)
{
// до первого \0
size_t i = 0;
for (; i < bytes.length && bytes[i] != 0; ++i)
{
}
auto first = cast(string) bytes[0 .. i].idup;
if (first.length)
{
auto name = baseName(first);
if (name.length)
return name;
}
}
}
}
catch (Exception e)
{
}
// fallback
return "pid:" ~ pid.to!string;
}
// Удобная печать маски (для живых логов) // Удобная печать маски (для живых логов)
string maskToStr(uint64_t m) string maskToStr(uint64_t m)
{ {
@ -204,6 +276,9 @@ void main(string[] args)
foreach (ev; events) foreach (ev; events)
{ {
auto pname = eventProcessName(ev.pid);
writeln("pid = ", ev.pid, "\tproc = ", pname, "\tmask = ", maskToStr(ev.mask));
if (tag == TAG_PRE && (ev.isOpenPerm || ev.isAccessPerm)) if (tag == TAG_PRE && (ev.isOpenPerm || ev.isAccessPerm))
{ {
string path = pathFromEventFd(ev.eventFd); string path = pathFromEventFd(ev.eventFd);
@ -214,11 +289,11 @@ void main(string[] args)
} }
// Лог // Лог
writefln("[%s] pid=%s mask=%s name=%s", // writefln("[%s] pid=%s mask=%s name=%s",
(tag == TAG_PRE) ? "PRE" : "NOTIF", // (tag == TAG_PRE) ? "PRE" : "NOTIF",
ev.pid.to!string, // ev.pid.to!string,
maskToStr(ev.mask), // maskToStr(ev.mask),
ev.name.length ? ev.name : "(unknown)"); // ev.name.length ? ev.name : "(unknown)");
// --- ВЕТКА РЕШЕНИЯ ДЛЯ PERM-СОБЫТИЙ --- // --- ВЕТКА РЕШЕНИЯ ДЛЯ PERM-СОБЫТИЙ ---
// if (tag == TAG_PRE && // if (tag == TAG_PRE &&