svn commit: trunk/busybox/coreutils

vda at busybox.net vda at busybox.net
Tue Feb 19 00:38:12 UTC 2008


Author: vda
Date: 2008-02-18 16:38:10 -0800 (Mon, 18 Feb 2008)
New Revision: 21058

Log:
tail: fix "tail -c 20 /dev/huge_disk" (was taking ages)
tail: a few variables renamed
wc: tiny optimization.



Modified:
   trunk/busybox/coreutils/tail.c
   trunk/busybox/coreutils/wc.c


Changeset:
Modified: trunk/busybox/coreutils/tail.c
===================================================================
--- trunk/busybox/coreutils/tail.c	2008-02-18 23:24:46 UTC (rev 21057)
+++ trunk/busybox/coreutils/tail.c	2008-02-19 00:38:10 UTC (rev 21058)
@@ -74,7 +74,7 @@
 		p++;
 	else if (*p == '+') {
 		p++;
-		G.status = EXIT_FAILURE;
+		G.status = 1; /* mark that we saw "+" */
 	}
 	return xatou_sfx(p, tail_suffixes);
 }
@@ -92,7 +92,7 @@
 	char *tailbuf;
 	size_t tailbufsize;
 	int taillen = 0;
-	int newline = 0;
+	int newlines_seen = 0;
 	int nfiles, nread, nwrite, seen, i, opt;
 
 	int *fds;
@@ -128,12 +128,12 @@
 #endif
 	argc -= optind;
 	argv += optind;
-	from_top = G.status;
+	from_top = G.status; /* 1 if there was "-c +N" or "-n +N" */
+	G.status = EXIT_SUCCESS;
 
 	/* open all the files */
 	fds = xmalloc(sizeof(int) * (argc + 1));
 	nfiles = i = 0;
-	G.status = EXIT_SUCCESS;
 	if (argc == 0) {
 		struct stat statbuf;
 
@@ -155,39 +155,49 @@
 	if (!nfiles)
 		bb_error_msg_and_die("no files");
 
+	/* prepare the buffer */
 	tailbufsize = BUFSIZ;
-
-	/* tail the files */
 	if (!from_top && COUNT_BYTES) {
-		if (tailbufsize < count) {
+		if (tailbufsize < count + BUFSIZ) {
 			tailbufsize = count + BUFSIZ;
 		}
 	}
+	tailbuf = xmalloc(tailbufsize);
 
-	buf = tailbuf = xmalloc(tailbufsize);
-
+	/* tail the files */
 	fmt = header_fmt + 1;	/* Skip header leading newline on first output. */
 	i = 0;
 	do {
-		/* Be careful.  It would be possible to optimize the count-bytes
-		 * case if the file is seekable.  If you do though, remember that
-		 * starting file position may not be the beginning of the file.
-		 * Beware of backing up too far.  See example in wc.c.
-		 */
-		if (!(count | from_top) && lseek(fds[i], 0, SEEK_END) >= 0) {
-			continue;
-		}
+		off_t current;
 
 		if (nfiles > header_threshhold) {
 			tail_xprint_header(fmt, argv[i]);
 			fmt = header_fmt;
 		}
 
+		/* Optimizing count-bytes case if the file is seekable.
+		 * Beware of backing up too far.
+		 * Also we exclude files with size 0 (because of /proc/xxx) */
+		current = lseek(fds[i], 0, SEEK_END);
+		if (current > 0) {
+			if (!from_top) {
+				if (count == 0)
+					continue; /* showing zero lines is easy :) */
+				if (COUNT_BYTES) {
+					current -= count;
+					if (current < 0)
+						current = 0;
+					xlseek(fds[i], current, SEEK_SET);
+					bb_copyfd_size(fds[i], STDOUT_FILENO, count);
+					continue;
+				}
+			}
+		}
+
 		buf = tailbuf;
 		taillen = 0;
 		seen = 1;
-		newline = 0;
-
+		newlines_seen = 0;
 		while ((nread = tail_read(fds[i], buf, tailbufsize-taillen)) > 0) {
 			if (from_top) {
 				nwrite = nread;
@@ -215,34 +225,32 @@
 					}
 				} else {
 					int k = nread;
-					int nbuf = 0;
+					int newlines_in_buf = 0;
 
-					while (k) {
-						--k;
+					do { /* count '\n' in last read */
+						k--;
 						if (buf[k] == '\n') {
-							++nbuf;
+							newlines_in_buf++;
 						}
-					}
+					} while (k);
 
-					if (newline + nbuf < count) {
-						newline += nbuf;
+					if (newlines_seen + newlines_in_buf < count) {
+						newlines_seen += newlines_in_buf;
 						taillen += nread;
 					} else {
-						int extra = 0;
+						int extra = (buf[nread-1] != '\n');
 
-						if (buf[nread-1] != '\n')
-							extra = 1;
-						k = newline + nbuf + extra - count;
+						k = newlines_seen + newlines_in_buf + extra - count;
 						s = tailbuf;
 						while (k) {
 							if (*s == '\n') {
-								--k;
+								k--;
 							}
-							++s;
+							s++;
 						}
 						taillen += nread - (s - tailbuf);
 						memmove(tailbuf, s, taillen);
-						newline = count - extra;
+						newlines_seen = count - extra;
 					}
 					if (tailbufsize < taillen + BUFSIZ) {
 						tailbufsize = taillen + BUFSIZ;
@@ -251,13 +259,10 @@
 				}
 				buf = tailbuf + taillen;
 			}
-		}
-
+		} /* while (tail_read() > 0) */
 		if (!from_top) {
 			xwrite(STDOUT_FILENO, tailbuf, taillen);
 		}
-
-		taillen = 0;
 	} while (++i < nfiles);
 
 	buf = xrealloc(tailbuf, BUFSIZ);

Modified: trunk/busybox/coreutils/wc.c
===================================================================
--- trunk/busybox/coreutils/wc.c	2008-02-18 23:24:46 UTC (rev 21057)
+++ trunk/busybox/coreutils/wc.c	2008-02-19 00:38:10 UTC (rev 21058)
@@ -73,7 +73,7 @@
 {
 	FILE *fp;
 	const char *s, *arg;
-	const char *start_fmt = "%9"COUNT_FMT;
+	const char *start_fmt = " %9"COUNT_FMT + 1;
 	const char *fname_fmt = " %s\n";
 	COUNT_T *pcounts;
 	COUNT_T counts[4];




More information about the busybox-cvs mailing list