Subject: re: bin/33207: progress(1) w/ stdin: useless progress bar
To: matthew green <mrg@eterna.com.au>
From: Hubert Feyrer <hubert@feyrer.de>
List: netbsd-bugs
Date: 04/07/2006 04:11:32
After some more guesswork, it seems the problem is not in the 
foregroundproc() function but really in what progress(1) thinks of as the 
size of the file: using stat(2) on a pipe seems to have very funny 
effects:

 	miyu% perl -e 'print "x" x 1' | stat -f %z
 	1
 	miyu% perl -e 'print "x" x 10' | stat -f %z
 	0
 	miyu% perl -e 'print "x" x 10' | stat -f %z
 	10
 	miyu% perl -e 'print "x" x 100' | stat -f %z
 	100
 	miyu% perl -e 'print "x" x 100' | stat -f %z
 	100
 	miyu% perl -e 'print "x" x 100' | stat -f %z
 	100
 	miyu% perl -e 'print "x" x 100' | stat -f %z
 	0

While I have _no_ idea why this is, I think it's safe to assume that 
trying to determining the size of what's coming from a pipe doesn't make 
sense, and this no progress bar should be printed at all.

The patch below makes this. Can you please review this?


  - Hubert

Index: progress.c
===================================================================
RCS file: /cvsroot/src/usr.bin/progress/progress.c,v
retrieving revision 1.11
diff -u -r1.11 progress.c
--- progress.c	12 Jan 2006 20:33:20 -0000	1.11
+++ progress.c	7 Apr 2006 02:06:44 -0000
@@ -132,8 +132,16 @@
  		err(1, "%s", infile);

  	/* stat() to get the filesize unless overridden, or -z */
-	if (!zflag && !lflag && (fstat(fd, &statb) == 0))
-		filesize = statb.st_size;
+	if (!zflag && !lflag && (fstat(fd, &statb) == 0)) {
+		if (S_ISFIFO(statb.st_mode)) {
+			/* stat(2) on pipe may return only the
+			 * first few bytes with more coming.
+			 * Don't trust!
+			 */
+		} else {
+			filesize = statb.st_size;
+		}
+	}

  	/* gzip -l the file if we have the name and -z is given */
  	if (zflag && !lflag && infile != NULL) {