Untitled
#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; }
Leave a Comment