NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

bin/56134: patch: add feedback to tee(1)



>Number:         56134
>Category:       bin
>Synopsis:       patch: add feedback to tee(1)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Thu Apr 29 19:45:00 +0000 2021
>Originator:     jklowden%schemamania.org@localhost
>Release:        NetBSD 7.0
>Organization:
	
>Environment:
	
	
System: NetBSD oak.schemamania.org 7.0 NetBSD 7.0 (GENERIC.201509250726Z) amd64
Architecture: x86_64
Machine: amd64
>Description:
	tee came back without waving flags
>How-To-Repeat:
	$ find /usr/bin | ./tee -v | wc 
	682617.19 KB/s (7,689 bytes in 0.000011 seconds)
	     486     486    7689

>Fix:
	The attached patch adds a -v option to tee(1) to produce a "progress"
	line on stderr as shown above. 

	The patch also updates tee.1 to document the flag.  Since I
	had to add time.h and sys/time.h, I took the opportunity to
	sort the include files, too.

	I made this change to have a simple way to measure network
	throughput using pax and ssh to copy files.

diff -u orig/tee.1 ./tee.1
--- orig/tee.1	2003-08-07 07:16:07.000000000 -0400
+++ ./tee.1	2021-04-29 15:02:35.175783950 -0400
@@ -40,7 +40,7 @@
 .Nd pipe fitting
 .Sh SYNOPSIS
 .Nm
-.Op Fl ai
+.Op Fl aiv
 .Op Ar file ...
 .Sh DESCRIPTION
 The
@@ -58,6 +58,9 @@
 Ignore the
 .Dv SIGINT
 signal.
+.It Fl v
+Write a feedback message to standard error with the data rate, bytes
+transferred, and seconds elapsed.`
 .El
 .Pp
 The following operands are available:

diff -u orig/tee.c ./tee.c
--- orig/tee.c	2013-03-06 06:44:11.000000000 -0500
+++ ./tee.c	2021-04-29 15:14:03.574540090 -0400
@@ -42,17 +42,19 @@
 __RCSID("$NetBSD: tee.c,v 1.11 2013/03/06 11:44:11 yamt Exp $");
 #endif
 
-#include <sys/types.h>
 #include <sys/stat.h>
-#include <signal.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <err.h>
 #include <errno.h>
 #include <fcntl.h>
-#include <unistd.h>
+#include <locale.h>
+#include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <locale.h>
-#include <err.h>
+#include <time.h>
+#include <unistd.h>
 
 typedef struct _list {
 	struct _list *next;
@@ -64,6 +66,31 @@
 void	add(int, const char *);
 int	main(int, char **);
 
+void
+feedback (const struct timeval * then, ssize_t rval)
+{
+	static int erc;
+	static ssize_t nbyte;
+	static struct timezone tz = { 0, 0 };
+	struct timeval now;
+	double elapsed, bps;
+	
+	if (erc) return;
+	if (!then) return;
+
+	nbyte += rval;
+	
+	if ((erc = gettimeofday(&now, &tz)) == -1) 
+		err(1, "gettimeofday");
+
+	elapsed = difftime(now.tv_sec, then->tv_sec);
+	elapsed += (now.tv_usec - then->tv_usec) * 1e-6;
+	bps = nbyte/elapsed;
+
+	fprintf(stderr, "\r%.2f KB/s (%'zu bytes in %f seconds)",
+		bps/1024, nbyte, elapsed);
+}
+
 int
 main(int argc, char *argv[])
 {
@@ -72,12 +99,14 @@
 	int fd;
 	int append, ch, exitval;
 	char *buf;
+	struct timeval tv, *then = NULL;
+	struct timezone tz = { 0, 0 };
 #define	BSIZE (8 * 1024)
 
 	setlocale(LC_ALL, "");
 
 	append = 0;
-	while ((ch = getopt(argc, argv, "ai")) != -1)
+	while ((ch = getopt(argc, argv, "aiv")) != -1)
 		switch((char)ch) {
 		case 'a':
 			append = 1;
@@ -85,9 +114,14 @@
 		case 'i':
 			(void)signal(SIGINT, SIG_IGN);
 			break;
+		case 'v':
+			if (-1 == gettimeofday(&tv, &tz)) 
+				err(1, "gettimeofday");
+			then = &tv;
+			break;
 		case '?':
 		default:
-			(void)fprintf(stderr, "usage: tee [-ai] [file ...]\n");
+			(void)fprintf(stderr, "usage: tee [-aiv] [file ...]\n");
 			exit(1);
 		}
 	argv += optind;
@@ -106,7 +140,8 @@
 		} else
 			add(fd, *argv);
 
-	while ((rval = read(STDIN_FILENO, buf, BSIZE)) > 0)
+	while ((rval = read(STDIN_FILENO, buf, BSIZE)) > 0) {
+		feedback(then, rval);
 		for (p = head; p; p = p->next) {
 			const char *bp = buf;
 			size_t n = rval;
@@ -121,6 +156,7 @@
 				bp += wval;
 			} while (n -= wval);
 		}
+	}
 	if (rval < 0) {
 		warn("read");
 		exitval = 1;
@@ -133,6 +169,7 @@
 		}
 	}
 
+	if (then) fprintf(stderr, "\n");
 	exit(exitval);
 }
 

>Unformatted:
 	
 	


Home | Main Index | Thread Index | Old Index