1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Wait until an inotify event on the given cgroup file. 4 */ 5 #include <linux/limits.h> 6 #include <sys/inotify.h> 7 #include <sys/mman.h> 8 #include <sys/ptrace.h> 9 #include <sys/stat.h> 10 #include <sys/types.h> 11 #include <errno.h> 12 #include <fcntl.h> 13 #include <poll.h> 14 #include <stdio.h> 15 #include <stdlib.h> 16 #include <string.h> 17 #include <unistd.h> 18 19 static const char usage[] = "Usage: %s [-v] <cgroup_file>\n"; 20 static char *file; 21 static int verbose; 22 23 static inline void fail_message(char *msg) 24 { 25 fprintf(stderr, msg, file); 26 exit(1); 27 } 28 29 int main(int argc, char *argv[]) 30 { 31 char *cmd = argv[0]; 32 int c, fd; 33 struct pollfd fds = { .events = POLLIN, }; 34 35 while ((c = getopt(argc, argv, "v")) != -1) { 36 switch (c) { 37 case 'v': 38 verbose++; 39 break; 40 } 41 argv++, argc--; 42 } 43 44 if (argc != 2) { 45 fprintf(stderr, usage, cmd); 46 return -1; 47 } 48 file = argv[1]; 49 fd = open(file, O_RDONLY); 50 if (fd < 0) 51 fail_message("Cgroup file %s not found!\n"); 52 close(fd); 53 54 fd = inotify_init(); 55 if (fd < 0) 56 fail_message("inotify_init() fails on %s!\n"); 57 if (inotify_add_watch(fd, file, IN_MODIFY) < 0) 58 fail_message("inotify_add_watch() fails on %s!\n"); 59 fds.fd = fd; 60 61 /* 62 * poll waiting loop 63 */ 64 for (;;) { 65 int ret = poll(&fds, 1, 10000); 66 67 if (ret < 0) { 68 if (errno == EINTR) 69 continue; 70 perror("poll"); 71 exit(1); 72 } 73 if ((ret > 0) && (fds.revents & POLLIN)) 74 break; 75 } 76 if (verbose) { 77 struct inotify_event events[10]; 78 long len; 79 80 usleep(1000); 81 len = read(fd, events, sizeof(events)); 82 printf("Number of events read = %ld\n", 83 len/sizeof(struct inotify_event)); 84 } 85 close(fd); 86 return 0; 87 } 88