admin管理员组

文章数量:1420228

I wanted to add an output of the path where something was changed, but I encountered a problem that the code processed all events as a directory event, which is why metadata->fd == -1, which is why I caught an error with /proc/self/fd/-1. I assume that the error is in the fanotify_mark or fanotify_init flags, but in my attempts to fix it I get fanotify_mark: Invalid argument. I don't know what the problem could be anymore.

#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/fanotify.h>
#include <unistd.h>
#include <string.h>

#define MONITOR_PATH "/home/user/Desktop/test"

void run() {
    const char *file_name;
    int fanotify_fd;
    char buffer[4096];
    ssize_t length;

    /* Initialize fanotify instance with specified flags:
       FAN_CLASS_NOTIF enables notification events.
       FAN_REPORT_FID requests the event metadata to include the file descriptor. */
    fanotify_fd = fanotify_init(FAN_CLASS_NOTIF | FAN_REPORT_FID, O_RDONLY | O_LARGEFILE);
    if (fanotify_fd == -1) {
        perror("fanotify_init");
        exit(EXIT_FAILURE);
    }

    /* Add watch on the specified path with specified event types:
       FAN_OPEN, FAN_MODIFY, FAN_CREATE, FAN_DELETE, FAN_CLOSE_WRITE. */
    if (fanotify_mark(fanotify_fd, FAN_MARK_ADD,
                          FAN_OPEN | FAN_MODIFY | FAN_CREATE | FAN_DELETE | FAN_CLOSE_WRITE, 
                          AT_FDCWD, MONITOR_PATH) == -1) {
        perror("fanotify_mark");
        exit(EXIT_FAILURE);
    }

    printf("Monitoring file system events in '%s'. Press Ctrl+C to stop.\n", MONITOR_PATH);

    /* Setup poll to wait for events on the fanotify file descriptor */
    struct pollfd fds[] = {{fanotify_fd, POLLIN, 0}};

    while (1) {
        /* Poll the fanotify file descriptor for events */
        int ret = poll(fds, 1, -1);
        if (ret == -1) {
            perror("poll failed");
            break;
        }

        /* If an event is ready to be read, process it */
        if (fds[0].revents & POLLIN) {
            length = read(fanotify_fd, buffer, sizeof(buffer));
            if (length == -1) {
                if (errno == EINTR) continue;  // If interrupted, retry
                perror("read failed");
                break;
            }

            /* Process each fanotify event in the buffer */
            struct fanotify_event_metadata *metadata = (struct fanotify_event_metadata *)buffer;

            /* Loop through events in the buffer */
            for (metadata = (struct fanotify_event_metadata*) buffer; FAN_EVENT_OK(metadata, length); metadata=FAN_EVENT_NEXT(metadata,length)) {
                struct fanotify_event_info_fid *fid = (struct fanotify_event_info_fid*)(metadata + 1);
                struct file_handle *file_handle = (struct file_handle *) fid->handle;

                /* Determine the file name based on the event information type */
                if (fid->hdr.info_type == FAN_EVENT_INFO_TYPE_FID || fid->hdr.info_type == FAN_EVENT_INFO_TYPE_DFID) {
                    file_name = NULL;  // No file name in this case
                } else if (fid->hdr.info_type == FAN_EVENT_INFO_TYPE_DFID_NAME) {
                    file_name = file_handle->f_handle + file_handle->handle_bytes;
                } else {
                    fprintf(stderr, "Received unexpected event info type.\n");
                    exit(EXIT_FAILURE);
                }

                /* Process the event based on the event mask */
                if (metadata->mask & FAN_MODIFY) {
                    printf(" - Event: File modified\n");
                } 
                if (metadata->mask & FAN_CREATE) {
                    printf(" - Event: File created\n");
                } 
                if (metadata->mask & FAN_DELETE) {
                    printf(" - Event: File deleted\n");
                } 
                if (metadata->mask & FAN_CLOSE_WRITE) {
                    printf(" - Event: File closed after writing\n");
                }
            }
        }
    }

    /* Close the fanotify file descriptor */
    if (close(fanotify_fd) == -1) {
        perror("Error closing fanotify file descriptor");
    }
}

There was also a problem that it reads changing a file as creating it, but it seems to me that this is a problem with how vim and nano work Thanks in advance!

本文标签: cMy fanotify monitor thinks all events have descriptor 1Stack Overflow