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
19static const char usage[] = "Usage: %s [-v] <cgroup_file>\n";
20static char *file;
21static int verbose;
22
23static inline void fail_message(char *msg)
24{
25	fprintf(stderr, msg, file);
26	exit(1);
27}
28
29int 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