Untitled

 avatar
unknown
plain_text
2 months ago
3.8 kB
2
Indexable
#include <sys/inotify.h>
#include <unistd.h>
#include <iostream>
#include <set>
#include <sstream>
#include <string>
#include <cstdio>

#define BUF_LEN (10 * (sizeof(struct inotify_event) + NAME_MAX + 1))

std::set<std::string> read_file_pids(const std::string &file_path) {
    std::set<std::string> pid_set;
    FILE *file = popen(("cat " + file_path).c_str(), "r"); // Use popen to execute `cat` and read the file content
    if (!file) {
        perror("popen");
        return pid_set;
    }

    char buffer[1024];
    while (fgets(buffer, sizeof(buffer), file) != nullptr) {
        std::string pid(buffer);
        pid.erase(pid.find_last_not_of(" \n\r\t") + 1); // Trim whitespace and newlines
        if (!pid.empty()) {
            pid_set.insert(pid);
        }
    }

    if (pclose(file) == -1) {
        perror("pclose");
    }

    return pid_set;
}

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::set<std::string> previous_pids;

    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::set<std::string> current_pids = read_file_pids(file_path);

                if (current_pids.empty()) {
                    std::cerr << "Failed to read file: " << file_path << std::endl;
                    break;
                }

                std::cout << "File modified!" << std::endl;

                // Compute differences
                std::set<std::string> added_pids, removed_pids;

                // Find added PIDs
                for (const auto &pid : current_pids) {
                    if (previous_pids.find(pid) == previous_pids.end()) {
                        added_pids.insert(pid);
                    }
                }

                // Find removed PIDs
                for (const auto &pid : previous_pids) {
                    if (current_pids.find(pid) == current_pids.end()) {
                        removed_pids.insert(pid);
                    }
                }

                // Display differences
                if (!added_pids.empty()) {
                    std::cout << "Added PIDs:\n";
                    for (const auto &pid : added_pids) {
                        std::cout << pid << std::endl;
                    }
                }

                if (!removed_pids.empty()) {
                    std::cout << "Removed PIDs:\n";
                    for (const auto &pid : removed_pids) {
                        std::cout << pid << std::endl;
                    }
                }

                previous_pids = std::move(current_pids);
            }

            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