Untitled
unknown
plain_text
a year ago
3.9 kB
5
Indexable
#include <sys/inotify.h>
#include <unistd.h>
#include <iostream>
#include <vector>
#include <cstring>
#include <string>
#include <map>
#include <cstdio>
#define BUF_LEN (10 * (sizeof(struct inotify_event) + NAME_MAX + 1))
std::string read_file_with_popen(const std::string &file_path) {
std::string content;
FILE *file = popen(("cat " + file_path).c_str(), "r"); // Use popen to execute `cat` and read the file content
if (!file) {
perror("popen");
return content;
}
char buffer[1024];
while (fgets(buffer, sizeof(buffer), file) != nullptr) {
content += buffer;
}
if (pclose(file) == -1) {
perror("pclose");
}
return content;
}
void monitor_cgroup_procs(const std::string &file_path) {
int fd = inotify_init1(IN_NONBLOCK);
if (fd == -1) {
perror("inotify_init1");
return;
}
int wd = inotify_add_watch(fd, file_path.c_str(), IN_MODIFY | IN_CLOSE_WRITE);
if (wd == -1) {
perror("inotify_add_watch");
close(fd);
return;
}
std::cout << "Monitoring file: " << file_path << std::endl;
char buf[BUF_LEN];
std::string previous_content;
while (true) {
ssize_t len = read(fd, buf, BUF_LEN);
if (len == -1 && errno != EAGAIN) {
perror("read");
break;
}
if (len <= 0) {
continue;
}
for (char *ptr = buf; ptr < buf + len;) {
struct inotify_event *event = reinterpret_cast<struct inotify_event *>(ptr);
if (event->mask & IN_MODIFY || event->mask & IN_CLOSE_WRITE) {
std::string current_content = read_file_with_popen(file_path);
if (current_content.empty()) {
std::cerr << "Failed to read file: " << file_path << std::endl;
break;
}
// Calculate the difference
std::cout << "File modified!" << std::endl;
if (!previous_content.empty()) {
std::cout << "Previous content:\n" << previous_content << std::endl;
std::cout << "Current content:\n" << current_content << std::endl;
// Find changes (added/removed lines)
std::istringstream prev_stream(previous_content), curr_stream(current_content);
std::string line;
std::map<std::string, bool> prev_lines, curr_lines;
while (std::getline(prev_stream, line)) {
prev_lines[line] = true;
}
while (std::getline(curr_stream, line)) {
curr_lines[line] = true;
}
std::cout << "Added lines:\n";
for (const auto &entry : curr_lines) {
if (prev_lines.find(entry.first) == prev_lines.end()) {
std::cout << entry.first << std::endl;
}
}
std::cout << "Removed lines:\n";
for (const auto &entry : prev_lines) {
if (curr_lines.find(entry.first) == curr_lines.end()) {
std::cout << entry.first << std::endl;
}
}
}
previous_content = current_content;
}
ptr += sizeof(struct inotify_event) + event->len;
}
}
inotify_rm_watch(fd, wd);
close(fd);
}
int main(int argc, char *argv[]) {
if (argc != 2) {
std::cerr << "Usage: " << argv[0] << " <file_path>" << std::endl;
return 1;
}
std::string file_path = argv[1];
monitor_cgroup_procs(file_path);
return 0;
}
Editor is loading...
Leave a Comment