Inotify : monitorer les actions effectuées dans un répertoire

Boris HUISGEN
Exemple en langage C pour détecter la création de sous-répertoires grâce à inotify :
#include <sys/inotify.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
int fd;
int wd;
void
sigint_handler(int signum)
{
    (void) signum;
    if (inotify_rm_watch(fd, wd))
    {
        perror("inotify_rm_watch");
        exit(EXIT_FAILURE);
    }
    if (close(fd) < 0)
    {
        perror("close");
        exit(EXIT_FAILURE);
    }
    exit(EXIT_SUCCESS);
}
int
is_directory(char *path)
{
    if (path == NULL)
        return -1;
    struct stat s;
    if (stat(path, &s) < 0)
    {
        perror("stat");
        return -1;
    }
    if (s.st_mode & S_IFDIR)
        return 1;
    return 0;
}
int
main(int argc, char* argv[])
{
    fd_set fds;
    size_t r;
    char buf[8192], buf2[8192];
    struct inotify_event *event;
    if (argc != 2)
    {
        fprintf(stderr, "usage: %s <DIR>\n", argv[0]);
        return EXIT_FAILURE;
    }
    fd = inotify_init();
    if (fd < 0)
    {
        perror("inotify_init");
        return EXIT_FAILURE;
    }
    wd = inotify_add_watch(fd, argv[1], IN_CREATE);
    if (wd < 0)
    {
        perror("inotify_add_watch");
        return EXIT_FAILURE;
    }
    printf("Directory watched: %s\n", argv[1]);
    signal(SIGINT, sigint_handler);
    while (1)
    {
        FD_ZERO(&fds);
        FD_SET(fd, &fds);
        if (select(fd + 1, &fds, NULL, NULL, 0) <= 0)
        {
            continue;
        }
        r = read(fd, buf, sizeof(buf));
        if (r <= 0)
        {
            perror("read");
            return EXIT_FAILURE;
        }
        event = (struct inotify_event *)buf;
        if (!(event->mask & IN_CREATE) || (event->len < 0))
            continue;
        snprintf(buf2, sizeof(buf2), "%s%s", argv[1], event->name);
        if (is_directory(buf2) < 0)
            continue;
        printf("New directory created %s\n", event->name);
    }
    return EXIT_FAILURE;
}