Добавлена функция определения имени процесса создающего события
This commit is contained in:
parent
1f78d8eb83
commit
bc02ac8518
1 changed files with 81 additions and 6 deletions
87
source/app.d
87
source/app.d
|
@ -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 &&
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue