| // 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; |
| } |