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!