Subject: re: bin/33207: progress(1) w/ stdin: useless progress bar
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org,>
From: Hubert Feyrer <hubert@feyrer.de>
List: netbsd-bugs
Date: 04/07/2006 02:15:04
The following reply was made to PR bin/33207; it has been noted by GNATS.

From: Hubert Feyrer <hubert@feyrer.de>
To: matthew green <mrg@eterna.com.au>
Cc: gnats-bugs@netbsd.org, Hubert Feyrer <hubert@feyrer.de>,
	gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Subject: re: bin/33207: progress(1) w/ stdin: useless progress bar 
Date: Fri, 7 Apr 2006 04:11:32 +0200 (CEST)

 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) {