shithub: hx

Download patch

ref: b383d5d9832dbf81d6f8825b7cdfeea3d95fb696
parent: a46b80aaca77143cc957ff7de2ddf272d877f3d9
author: Sigrid Haflínudóttir <[email protected]>
date: Sat Dec 28 08:52:48 EST 2019

print whatever was read as soon as possible

--- a/README.md
+++ b/README.md
@@ -18,4 +18,5 @@
 
 # Notes
 
-`echo blah | hx` won't print anything, use `echo blah | hx /dev/stdin` instead.
+ * `echo blah | hx` won't print anything, use `echo blah | hx /dev/stdin` instead.
+ * hx will print data as soon as it is available (if used on pipes), without buffering.
--- a/hx.c
+++ b/hx.c
@@ -8,6 +8,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/select.h>
+#include <sys/time.h>
 #include <unistd.h>
 
 enum
@@ -35,7 +37,9 @@
 	ssize_t sz, i;
 	char s[65536], c;
 	unsigned char line[16];
-	int wroff, off, eof, wrlen, lineoff, r;
+	fd_set set;
+	struct timeval timeout;
+	int wroff, off, eof, lineoff, r;
 
 #ifdef __linux__
 	readahead(fd, 0, Bufsz);
@@ -46,18 +50,6 @@
 	eof = 0;
 	for (addr = 0; eof == 0 && (sz = read(fd, buf, Bufsz)) > 0;) {
 		for (i = 0; i < sz; ) {
-			if (off >= (int)sizeof(s)-Linesz) {
-				wrlen = off - (off % Linesz);
-				for (wroff = 0; wroff < wrlen; wroff += r) {
-					if ((r = write(1, s+wroff, wrlen-wroff)) < 0) {
-						sz = -1;
-						break;
-					}
-				}
-				memmove(s, s+wrlen, off-wrlen);
-				off -= wrlen;
-			}
-
 			if (lineoff == 0) {
 				s[off++] = b2h[((addr>>55) & 0x1fe)];
 				s[off++] = b2h[((addr>>55) & 0x1fe)+1];
@@ -103,11 +95,32 @@
 				s[off++] = '\n';
 				lineoff = 0;
 			}
+
+			if (off >= (int)sizeof(s)-Linesz) {
+writes:
+				for (wroff = 0; wroff < off; wroff += r) {
+					if ((r = write(1, s+wroff, off-wroff)) < 0) {
+						sz = -1;
+						break;
+					}
+				}
+				off = 0;
+			}
 		}
+		if (sz == 0)
+			continue;
 
 #ifdef __linux__
 		readahead(fd, addr, Bufsz);
 #endif
+		FD_ZERO(&set);
+		FD_SET(fd, &set);
+		timeout.tv_sec = 0;
+		timeout.tv_usec = 1000;
+		if (select(fd+1, &set, NULL, NULL, &timeout) == 0) {
+			sz = 0;
+			goto writes;
+		}
 	}
 
 	if (sz >= 0) {