root/tools/testing/selftests/cgroup/wait_inotify.c
// SPDX-License-Identifier: GPL-2.0
/*
 * Wait until an inotify event on the given cgroup file.
 */
#include <linux/limits.h>
#include <sys/inotify.h>
#include <sys/mman.h>
#include <sys/ptrace.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

static const char usage[] = "Usage: %s [-v] <cgroup_file>\n";
static char *file;
static int verbose;

static inline void fail_message(char *msg)
{
        fprintf(stderr, msg, file);
        exit(1);
}

int main(int argc, char *argv[])
{
        char *cmd = argv[0];
        int c, fd;
        struct pollfd fds = { .events = POLLIN, };

        while ((c = getopt(argc, argv, "v")) != -1) {
                switch (c) {
                case 'v':
                        verbose++;
                        break;
                }
                argv++, argc--;
        }

        if (argc != 2) {
                fprintf(stderr, usage, cmd);
                return -1;
        }
        file = argv[1];
        fd = open(file, O_RDONLY);
        if (fd < 0)
                fail_message("Cgroup file %s not found!\n");
        close(fd);

        fd = inotify_init();
        if (fd < 0)
                fail_message("inotify_init() fails on %s!\n");
        if (inotify_add_watch(fd, file, IN_MODIFY) < 0)
                fail_message("inotify_add_watch() fails on %s!\n");
        fds.fd = fd;

        /*
         * poll waiting loop
         */
        for (;;) {
                int ret = poll(&fds, 1, 10000);

                if (ret < 0) {
                        if (errno == EINTR)
                                continue;
                        perror("poll");
                        exit(1);
                }
                if ((ret > 0) && (fds.revents & POLLIN))
                        break;
        }
        if (verbose) {
                struct inotify_event events[10];
                long len;

                usleep(1000);
                len = read(fd, events, sizeof(events));
                printf("Number of events read = %ld\n",
                        len/sizeof(struct inotify_event));
        }
        close(fd);
        return 0;
}