/* Watch a directory using inotify for files that have just been closed for
 * writing, and print their names.
 * Adam Sampson <ats@offog.org>
 */

#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/inotify.h>
#include <sys/select.h>
#include <unistd.h>

#define die(...) \
	do { \
		fprintf(stderr, "error: "); \
		fprintf(stderr, __VA_ARGS__); \
		fprintf(stderr, "\n"); \
		exit(1); \
	} while (false)

int main(int argc, char *argv[]) {
	int fd = inotify_init();
	if (fd == -1)
		die("inotify_init failed");

	const int flags = IN_CLOSE_WRITE;
	for (int i = 1; i < argc; i++) {
		if (inotify_add_watch(fd, argv[i], flags) == -1)
			die("inotify_add_watch failed: %s", argv[i]);
	}

	while (true) {
		fd_set rfds;
		FD_ZERO(&rfds);
		FD_SET(fd, &rfds);

		int rc = select(fd + 1, &rfds, NULL, NULL, NULL);
		if (rc == -1)
			die("select failed");

		char buf[4096];
		ssize_t count = read(fd, buf, sizeof buf);
		if (count == -1)
			die("read failed");

		const char *p = buf;
		while (p < buf + count) {
			struct inotify_event *ev = (struct inotify_event *) p;
			if (ev->len > 0) {
				printf("%s\n", ev->name);
				fflush(stdout);
			}

			p += sizeof(struct inotify_event) + ev->len;
		}
	}

	close(fd);
}
