#define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #define MAX_EFD 100 struct event { char *path; char *args; }; int main(int argc, char **argv) { struct event events[MAX_EFD]; struct pollfd pollfds[MAX_EFD]; int n = 0; char line[PATH_MAX]; int ret; while (fgets(line, PATH_MAX, stdin)) { int event_control, cfd; char *args = strchrnul(line, ' '); if (n >= MAX_EFD) { fprintf(stderr, "Too many events registered\n"); } if (*args) *args++ = '\0'; events[n].path = malloc(strlen(line) + 1); assert(events[n].path); strcpy(events[n].path, line); args[strlen(args) - 1] = '\0'; events[n].args = malloc(strlen(args) + 1); assert(events[n].args); strcpy(events[n].args, args); cfd = open(events[n].path, O_RDONLY); if (cfd < 0) { fprintf(stderr, "Cannot open %s: %s\n", events[n].path, strerror(errno)); return 1; } pollfds[n].events = POLLIN; pollfds[n].fd = eventfd(0, 0); dirname(line); strcat(line, "/cgroup.event_control"); event_control = open(line, O_WRONLY); if (event_control < 0) { fprintf(stderr, "Cannot open %s: %s\n", line, strerror(errno)); return 1; } snprintf(line, PATH_MAX, "%d %d %s\n", pollfds[n].fd, cfd, events[n].args); if (write(event_control, line, strlen(line)) < 0) { fprintf(stderr, "Cannot write to cgroup.event_control: %s\n", strerror(errno)); return 1; } close(event_control); close(cfd); n++; } while((ret = poll(pollfds, n, -1)) != 0) { int i; if (ret < 0) { perror("poll()"); return 1; } for(i=0; (i < n) && ret; i++) { if (pollfds[i].revents & POLLIN) { printf("%s %s\n", events[i].path, events[i].args); if (read(pollfds[i].fd, line, 8) < 0) { perror("read()"); return 1; } ret--; } if (pollfds[i].revents & ~(POLLIN)) { printf("%s(%s): unexpected event: %08x\n", events[i].path, events[i].args, pollfds[i].revents); return 1; } } } return 0; }