[hackers] [sbase] [PATCH 05/10] tail: Use getc and putc instead of concat

From: Michael Forney <mforney_AT_mforney.org>
Date: Sun, 4 Dec 2016 21:55:07 -0800

The FILE streams are buffered, so the end result is essentially the
same, except now lines are printed as they are read since we don't wait
until the entire buffer is filled.

This also fixes an issue where only part of the lines during the follow
were printed if they contained NUL bytes.
---
 tail.c | 22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/tail.c b/tail.c
index 711707f..ad97308 100644
--- a/tail.c
+++ b/tail.c
_AT_@ -20,6 +20,7 @@ dropinit(FILE *fp, const char *str, size_t n)
 	char *buf = NULL;
 	size_t size = 0, i = 1;
 	ssize_t len;
+	int c;
 
 	if (mode == 'n') {
 		while (i < n && (len = getline(&buf, &size, fp)) > 0)
_AT_@ -30,7 +31,10 @@ dropinit(FILE *fp, const char *str, size_t n)
 			i++;
 	}
 	free(buf);
-	concat(fp, str, stdout, "<stdout>");
+	while ((c = fgetc(fp)) != EOF) {
+		if (fputc(c, stdout) == EOF)
+			break;
+	}
 }
 
 static void
_AT_@ -88,9 +92,9 @@ main(int argc, char *argv[])
 {
 	struct stat st1, st2;
 	FILE *fp;
-	size_t tmpsize, n = 10;
-	int fflag = 0, ret = 0, newline = 0, many = 0;
-	char *numstr, *tmp;
+	size_t n = 10;
+	int fflag = 0, ret = 0, newline = 0, many = 0, c;
+	char *numstr;
 	void (*tail)(FILE *, const char *, size_t) = taketail;
 
 	ARGBEGIN {
_AT_@ -141,13 +145,13 @@ main(int argc, char *argv[])
 					ret = 1;
 				continue;
 			}
-			for (tmp = NULL, tmpsize = 0;;) {
-				while (getline(&tmp, &tmpsize, fp) > 0) {
-					fputs(tmp, stdout);
-					fflush(stdout);
+			for (;;) {
+				while ((c = fgetc(fp)) != EOF) {
+					if (fputc(c, stdout) == EOF)
+						eprintf("fputc <stdout>:");
 				}
 				if (ferror(fp))
-					eprintf("readline %s:", *argv);
+					eprintf("fgetc %s:", *argv);
 				clearerr(fp);
 				/* ignore error in case file was removed, we continue
 				 * tracking the existing open file descriptor */
-- 
2.11.0
Received on Mon Dec 05 2016 - 06:55:07 CET

This archive was generated by hypermail 2.3.0 : Mon Dec 05 2016 - 07:00:41 CET