summary refs log tree commit diff
path: root/fq.c
diff options
context:
space:
mode:
authorChristian Neukirchen <chneukirchen@gmail.com>2015-08-05 14:56:17 +0200
committerChristian Neukirchen <chneukirchen@gmail.com>2015-08-05 14:56:17 +0200
commit97c224768f79c8f898f647cf409b16cc3d22a681 (patch)
treeda503adf29a872c503be9ffa8d2bdd2d89a4d523 /fq.c
parent774a8f2d098fa242c5bac528e51ca62fca0bd9a4 (diff)
downloadnq-97c224768f79c8f898f647cf409b16cc3d22a681.tar.gz
nq-97c224768f79c8f898f647cf409b16cc3d22a681.tar.xz
nq-97c224768f79c8f898f647cf409b16cc3d22a681.zip
reimplement fq in C.
Diffstat (limited to 'fq.c')
-rw-r--r--fq.c109
1 files changed, 109 insertions, 0 deletions
diff --git a/fq.c b/fq.c
new file mode 100644
index 0000000..f1323c6
--- /dev/null
+++ b/fq.c
@@ -0,0 +1,109 @@
+/*
+ * fq [FILES...] - follow output of nq jobs, quitting when they are done
+ *
+ * To the extent possible under law,
+ * Christian Neukirchen <chneukirchen@gmail.com>
+ * has waived all copyright and related or neighboring rights to this work.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef __linux__
+#define USE_INOTIFY
+#endif
+
+#ifdef USE_INOTIFY
+#include <sys/inotify.h>
+char ibuf[8192];
+#endif
+
+char buf[8192];
+
+int main(int argc, char *argv[])
+{
+	int i, fd;
+	off_t off, loff;
+	ssize_t rd;
+
+#ifdef USE_INOTIFY
+	int ifd, wd;
+#endif
+
+	if (argc < 2) {
+		/* little better than glob(3)... */
+                /* TODO: replace and enable rescanning of the dir... */
+		execl("/bin/sh", "sh", "-c", "fq ${NQDIR:+$NQDIR/},*", (char *) 0);
+		exit(111);
+	}
+
+#ifdef USE_INOTIFY
+	ifd = inotify_init();
+	if (ifd < 0)
+		exit(111);
+#endif
+
+	for (i = 1; i < argc; i++) {
+		fd = open(argv[i], O_RDONLY);
+		loff = 0;
+
+		write(1, "==> ", 4);
+		write(1, argv[i], strlen(argv[i]));
+		write(1, "\n", 1);
+
+#ifdef USE_INOTIFY
+		wd = inotify_add_watch(ifd, argv[i], IN_MODIFY|IN_CLOSE_WRITE);
+#endif
+
+		while (1) {
+			off = lseek(fd, 0, SEEK_END);
+
+			if (off < loff)
+				loff = off;               /* file truncated */
+
+			if (off == loff) {
+				if (flock(fd, LOCK_EX|LOCK_NB) == -1 &&
+				    errno == EWOULDBLOCK) {
+#ifdef USE_INOTIFY
+					/* any inotify event is good */
+					read(ifd, ibuf, sizeof ibuf);
+#else
+					/* poll for size change */
+					while (off == lseek(fd, 0, SEEK_END))
+						usleep(250000);
+#endif
+					continue;
+				} else {
+					flock(fd, LOCK_UN);
+					break;
+				}
+			}
+
+			if (off - loff > sizeof buf)
+				off = loff + sizeof buf;
+
+			rd = pread(fd, &buf, off - loff, loff);
+			write(1, buf, rd);
+
+			loff += rd;
+		}
+
+#ifdef USE_INOTIFY
+		inotify_rm_watch(ifd, wd);
+#endif
+		close(fd);
+	}
+
+#ifdef USE_INOTIFY
+	close(ifd);
+#endif
+	return 0;
+}