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

Boris HUISGEN
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;
}
Boris HUISGEN
Boris HUISGEN
Blog owner
  • #c
  • #linux
  • #inotify