svn commit: trunk/busybox/coreutils

vda at busybox.net vda at busybox.net
Wed Jan 9 23:00:02 UTC 2008


Author: vda
Date: 2008-01-09 15:00:00 -0800 (Wed, 09 Jan 2008)
New Revision: 20836

Log:
tac: handle NULs properly. +145 bytes



Modified:
   trunk/busybox/coreutils/tac.c


Changeset:
Modified: trunk/busybox/coreutils/tac.c
===================================================================
--- trunk/busybox/coreutils/tac.c	2008-01-09 17:13:57 UTC (rev 20835)
+++ trunk/busybox/coreutils/tac.c	2008-01-09 23:00:00 UTC (rev 20836)
@@ -20,12 +20,17 @@
 
 /* This is a NOEXEC applet. Be very careful! */
 
+struct lstring {
+	int size;
+	char buf[];
+};
+
 int tac_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int tac_main(int argc, char **argv)
 {
 	char **name;
 	FILE *f;
-	char *line;
+	struct lstring *line = NULL;
 	llist_t *list = NULL;
 	int retval = EXIT_SUCCESS;
 
@@ -38,6 +43,8 @@
 		name++;
 
 	do {
+		int ch, i;
+
 		name--;
 		f = fopen_or_warn_stdin(*name);
 		if (f == NULL) {
@@ -45,14 +52,26 @@
 			continue;
 		}
 
-		errno = 0;
-		/* FIXME: NUL bytes are mishandled. */
-		while ((line = xmalloc_fgets(f)) != NULL)
-			llist_add_to(&list, line);
-
-		/* xmalloc_fgets uses getc and returns NULL on error or EOF. */
-		/* It sets errno to ENOENT on EOF, but fopen_or_warn_stdin would */
-		/* catch this error so we can filter it out here. */
+		errno = i = 0;
+		do {
+			ch = fgetc(f);
+			if (ch != EOF) {
+				if (!(i & 0x7f))
+					/* Grow on every 128th char */
+					line = xrealloc(line, i + 0x7f + sizeof(int) + 1);
+				line->buf[i++] = ch;
+			}
+			if ((ch == '\n' || ch == EOF) && i) {
+				line = xrealloc(line, i + sizeof(int));
+				line->size = i;
+				llist_add_to(&list, line);
+				line = NULL;
+				i = 0;
+			}
+		} while (ch != EOF);
+		/* fgetc sets errno to ENOENT on EOF, but     */
+		/* fopen_or_warn_stdin would catch this error */
+		/* so we can filter it out here.              */
 		if (errno && errno != ENOENT) {
 			bb_simple_perror_msg(*name);
 			retval = EXIT_FAILURE;
@@ -60,8 +79,13 @@
 	} while (name != argv);
 
 	while (list) {
-		printf("%s", list->data);
-		list = list->link;
+		line = (struct lstring *)list->data;
+		xwrite(STDOUT_FILENO, line->buf, line->size);
+		if (ENABLE_FEATURE_CLEAN_UP) {
+			free(llist_pop(&list));
+		} else {
+			list = list->link;
+		}
 	}
 
 	return retval;




More information about the busybox-cvs mailing list