Добавлен вывод через библиотеку sdiff

This commit is contained in:
Alexander Zhirov 2025-09-01 18:10:28 +03:00
parent aa214dcf96
commit 7f54a56ef5
Signed by: alexander
GPG key ID: C8D8BE544A27C511
2 changed files with 66 additions and 5 deletions

View file

@ -10,7 +10,7 @@ import core.sys.posix.sys.stat : fstat, stat_t;
import core.stdc.errno : errno, EINTR;
import core.stdc.string : strerror;
import std.stdio : writeln, writefln, stderr;
import std.file : isDir, readText, exists;
import std.file : isDir, readText, exists, read;
import std.string : strip, splitLines, startsWith, toStringz, fromStringz, split;
import std.conv : to;
import std.exception : enforce;
@ -147,6 +147,8 @@ struct Session
uint uid; // LOGINUID из /proc/PID/loginuid
string filePathOpen; // путь, снятый на PERM
bool changed; // был CLOSE_WRITE
const(ubyte)[] fileBytesSource;
const(ubyte)[] fileBytesDiff;
}
__gshared Session[DevIno] gMap; // (pid,dev,ino) -> Session
@ -184,12 +186,28 @@ ulong dirMask()
FAN_OPEN | FAN_CLOSE_WRITE;
}
ubyte[] readAllFromFd(int fd)
{
import std.array : appender;
ubyte[16_384] buf; // 16 KiB буфер
auto output = appender!(ubyte[]);
for (;;)
{
auto n = read(fd, buf.ptr, buf.length);
if (n <= 0)
break;
output.put(buf[0 .. n]);
}
return output.data;
}
/// ---- обработчики ----
void onOpenPerm(FanotifyEvent ev, Epoll ep)
{
const pid = ev.pid;
auto procName = readProcComm(pid);
auto ids = readProcIds(pid); // <-- ruid + loginuid
auto ids = readProcIds(pid);
DevIno key;
if (!getDevIno(ev.eventFd, key, pid))
@ -200,13 +218,26 @@ void onOpenPerm(FanotifyEvent ev, Epoll ep)
auto path = readlinkFdPath(ev.eventFd);
const(ubyte)[] content;
try
{
if (path.length)
{
content = readAllFromFd(ev.eventFd);
}
}
catch (Exception e)
{
content = [];
}
if (auto ps = key in gMap)
{
// уже есть
}
else
{
gMap[key] = Session(procName, ids.ruid, ids.uid, path, false);
gMap[key] = Session(procName, ids.ruid, ids.uid, path, false, content);
}
if (!(pid in gPidfdByPid))
@ -214,7 +245,7 @@ void onOpenPerm(FanotifyEvent ev, Epoll ep)
int pfd = -1;
try
{
pfd = pidfd_open(pid, 0); // на твоей системе так ок
pfd = pidfd_open(pid, 0);
if (pfd < 0)
writeln("pidfd_open failed: ", strerror(errno).fromStringz);
}
@ -244,7 +275,27 @@ void onCloseWrite(FanotifyEvent ev)
if (!getDevIno(ev.eventFd, key, ev.pid))
return;
if (auto ps = key in gMap)
{
ps.changed = true;
import sdiff;
const(ubyte)[] content;
try
{
if (ps.filePathOpen.length)
content = readAllFromFd(ev.eventFd);
}
catch (Exception e)
{
content = [];
}
auto dataSource = new MMFile(ps.fileBytesSource);
auto dataChange = new MMFile(content);
ps.fileBytesDiff = dataSource.diff(dataChange).slice();
}
}
void flushAndClearForPid(int pid, Epoll ep)
@ -256,7 +307,10 @@ void flushAndClearForPid(int pid, Epoll ep)
continue;
auto s = gMap[k];
if (s.changed)
{
logChange(s.procName, s.filePathOpen, s.uid, s.ruid);
writeln(cast(string)s.fileBytesDiff);
}
gMap.remove(k);
}
if (auto p = pid in gPidfdByPid)