Subject: bin/28717: Wouldn't it be nice if progress(1) could print to stderr?
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: Seebs <seebs@guild.plethora.net>
List: netbsd-bugs
Date: 12/19/2004 22:15:01
>Number:         28717
>Category:       bin
>Synopsis:       progress(1) should be able to print to stderr
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sun Dec 19 22:15:00 +0000 2004
>Originator:     Seebs
>Release:        NetBSD 2.99.11
>Organization:
Consulting, computers, web hosting, and shell access: http://www.plethora.net/
>Environment:
System: NetBSD guild.plethora.net 2.99.11 NetBSD 2.99.11 (GUILD) #1: Sat Dec 18 00:01:30 CST 2004 seebs@guild.plethora.net:/usr/src/sys/arch/i386/compile/GUILD i386
Architecture: i386
Machine: i386
>Description:
Consider a command like
	tar cf - . | bzip2 -1c | ssh user@host "cat > file.tbz"

It might be useful to have a progress bar:
	tar cf - . | bzip2 -1c | progress ssh user@host "cat > file.tbz"

Of course, if you haven't compressed the data, you don't know how much to
expect.  The obvious solution is to run progress on bzip2:
	tar cf - . | progress bzip2 -1c | ssh user@host "cat > file.tbz"

... But this doesn't work, because the output of progress is mixed into the
bzip2 stream.  Oops.

>How-To-Repeat:
	Make backups, try to get a progress report.

>Fix:
	My solution was to add a flag, '-e', to print the messages to stderr.
	Thanks to the convenient design of progressbar.c, this is a very easy
	patch.

Index: progress.1
===================================================================
RCS file: /cvsroot/src/usr.bin/progress/progress.1,v
retrieving revision 1.9
diff -c -r1.9 progress.1
*** progress.1	3 Apr 2004 06:19:22 -0000	1.9
--- progress.1	19 Dec 2004 22:08:26 -0000
***************
*** 38,44 ****
  .Nd feed input to a command, displaying a progress bar
  .Sh SYNOPSIS
  .Nm
! .Op Fl z
  .Op Fl f Ar file
  .Op Fl l Ar length
  .Op Fl p Ar prefix
--- 38,44 ----
  .Nd feed input to a command, displaying a progress bar
  .Sh SYNOPSIS
  .Nm
! .Op Fl ez
  .Op Fl f Ar file
  .Op Fl l Ar length
  .Op Fl p Ar prefix
***************
*** 65,70 ****
--- 65,72 ----
  .Pp
  The options are as follows:
  .Bl -tag -width XlXlengthXX
+ .It Fl e
+ Display progress to standard error instead of standard output.
  .It Fl f Ar file
  Read from the specified
  .Ar file
Index: progress.c
===================================================================
RCS file: /cvsroot/src/usr.bin/progress/progress.c,v
retrieving revision 1.9
diff -c -r1.9 progress.c
*** progress.c	3 Apr 2004 06:19:22 -0000	1.9
--- progress.c	19 Dec 2004 22:08:26 -0000
***************
*** 73,79 ****
  usage(void)
  {
  	fprintf(stderr,
! 	    "usage: %s [-z] [-f file] [-l length] [-p prefix] cmd [args...]\n",
  	    getprogname());
  	exit(1);
  }
--- 73,79 ----
  usage(void)
  {
  	fprintf(stderr,
! 	    "usage: %s [-ez] [-f file] [-l length] [-p prefix] cmd [args...]\n",
  	    getprogname());
  	exit(1);
  }
***************
*** 86,92 ****
  	char *infile = NULL;
  	pid_t pid = 0, gzippid = 0;
  	int ch, fd, outpipe[2], waitstat;
! 	int lflag = 0, zflag = 0;
  	ssize_t nr, nw, off;
  	struct stat statb;
  	struct ttysize ts;
--- 86,92 ----
  	char *infile = NULL;
  	pid_t pid = 0, gzippid = 0;
  	int ch, fd, outpipe[2], waitstat;
! 	int eflag = 0, lflag = 0, zflag = 0;
  	ssize_t nr, nw, off;
  	struct stat statb;
  	struct ttysize ts;
***************
*** 98,105 ****
  	filesize = 0;
  	prefix=NULL;
  
! 	while ((ch = getopt(argc, argv, "f:l:p:z")) != -1)
  		switch (ch) {
  		case 'f':
  			infile = optarg;
  			break;
--- 98,108 ----
  	filesize = 0;
  	prefix=NULL;
  
! 	while ((ch = getopt(argc, argv, "ef:l:p:z")) != -1)
  		switch (ch) {
+ 		case 'e':
+ 			eflag++;
+ 			break;
  		case 'f':
  			infile = optarg;
  			break;
***************
*** 183,189 ****
  	/* Initialize progressbar.c's global state */
  	bytes = 0;
  	progress = 1;
! 	ttyout = stdout;
  
  	if (ioctl(fileno(ttyout), TIOCGSIZE, &ts) == -1) {
  		ttywidth = 80;
--- 186,192 ----
  	/* Initialize progressbar.c's global state */
  	bytes = 0;
  	progress = 1;
! 	ttyout = eflag ? stderr : stdout;
  
  	if (ioctl(fileno(ttyout), TIOCGSIZE, &ts) == -1) {
  		ttywidth = 80;