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