This adds a new option disp that can be set to "human" for a more human-
readable completion message.  This does not change the current behavior.

  $ dd if=/dev/zero of=/tmp/kthxbye bs=1337K count=42 disp=human
  42+0 records in
  42+0 records out
  57501696 bytes (54.8MB) transferred in 0.161 seconds (340MB/s)

  $ dd if=/dev/zero of=/tmp/kthxbye bs=1337K count=42
  42+0 records in
  42+0 records out
  57501696 bytes transferred in 0.138 secs (415847262 bytes/sec)

You can add disp=legacy if you one day should decide to make disp=human
the default (yah).  Simple modification to scripts to keep them working.

I know you're all thrilled seeing yet another dd diff from me, but rest
assured; this is the last one ... for now ;-)

So, if anyone is interested:

Index: Makefile
===================================================================
RCS file: /cvs/src/bin/dd/Makefile,v
retrieving revision 1.5
diff -u -p -r1.5 Makefile
--- Makefile    29 May 1998 04:34:20 -0000      1.5
+++ Makefile    19 Oct 2011 18:50:31 -0000
@@ -2,5 +2,7 @@
 
 PROG=  dd
 SRCS=  args.c conv.c conv_tab.c dd.c misc.c position.c
+DPADD= ${LIBUTIL}
+LDADD= -lutil
 
 .include <bsd.prog.mk>
Index: args.c
===================================================================
RCS file: /cvs/src/bin/dd/args.c,v
retrieving revision 1.19
diff -u -p -r1.19 args.c
--- args.c      18 Oct 2011 09:37:35 -0000      1.19
+++ args.c      19 Oct 2011 18:50:31 -0000
@@ -53,6 +53,7 @@ static void   f_bs(char *);
 static void    f_cbs(char *);
 static void    f_conv(char *);
 static void    f_count(char *);
+static void    f_disp(char *);
 static void    f_files(char *);
 static void    f_ibs(char *);
 static void    f_if(char *);
@@ -72,6 +73,7 @@ static const struct arg {
        { "cbs",        f_cbs,          C_CBS,   C_CBS },
        { "conv",       f_conv,         0,       0 },
        { "count",      f_count,        C_COUNT, C_COUNT },
+       { "disp",       f_disp,         0,       0 },
        { "files",      f_files,        C_FILES, C_FILES },
        { "ibs",        f_ibs,          C_IBS,   C_BS|C_IBS },
        { "if",         f_if,           C_IF,    C_IF },
@@ -197,6 +199,14 @@ f_count(char *arg)
 
        if ((cpy_cnt = get_bsz(arg)) == 0)
                cpy_cnt = (size_t)-1;
+}
+
+static void
+f_disp(char *arg)
+{
+
+       if ((disp_human = !strcmp(arg, "human")) != 1)
+               errx(1, "%s: illegal value", "disp");
 }
 
 static void
Index: dd.1
===================================================================
RCS file: /cvs/src/bin/dd/dd.1,v
retrieving revision 1.25
diff -u -p -r1.25 dd.1
--- dd.1        18 Oct 2011 09:37:35 -0000      1.25
+++ dd.1        19 Oct 2011 18:50:31 -0000
@@ -137,6 +137,13 @@ Otherwise, input data is read and discar
 For pipes, the correct number of bytes is read.
 For all other devices, the correct number of blocks is read without
 distinguishing between a partial or complete block being read.
+.It Cm disp= Ns Ar s
+If
+.Ar s
+is
+.Sq human
+the completion message will be displayed in a more human-readable format
+using the appropriate size suffixes.
 .It Xo
 .Sm off
 .Cm conv= Ar value Oo ,
@@ -371,6 +378,9 @@ specification.
 .Pp
 The
 .Cm files
+operand,
+the
+.Cm disp
 operand,
 the conversions
 .Cm oldascii ,
Index: extern.h
===================================================================
RCS file: /cvs/src/bin/dd/extern.h,v
retrieving revision 1.7
diff -u -p -r1.7 extern.h
--- extern.h    25 Jun 2003 21:12:30 -0000      1.7
+++ extern.h    19 Oct 2011 18:50:31 -0000
@@ -57,6 +57,7 @@ extern STAT st;
 extern void (*cfunc)(void);
 extern size_t cpy_cnt;
 extern size_t cbsz;
+extern int disp_human;
 extern u_int ddflags;
 extern size_t files_cnt;
 extern const u_char *ctab;
Index: misc.c
===================================================================
RCS file: /cvs/src/bin/dd/misc.c,v
retrieving revision 1.16
diff -u -p -r1.16 misc.c
--- misc.c      27 Oct 2009 23:59:21 -0000      1.16
+++ misc.c      19 Oct 2011 18:50:31 -0000
@@ -45,10 +45,13 @@
 #include <errno.h>
 #include <time.h>
 #include <unistd.h>
+#include <util.h>
 
 #include "dd.h"
 #include "extern.h"
 
+int    disp_human;
+
 void
 summary(void)
 {
@@ -57,6 +60,7 @@ summary(void)
        struct iovec iov[4];
        double microsecs;
        int i = 0;
+       char sizebuf[FMT_SCALED_STRSIZE], ratebuf[FMT_SCALED_STRSIZE];
 
        (void)gettimeofday(&nowtv, (struct timezone *)NULL);
        timersub(&nowtv, &st.startv, &nowtv);
@@ -85,10 +89,25 @@ summary(void)
                iov[i].iov_base = buf[2];
                iov[i++].iov_len = strlen(buf[2]);
        }
-       (void)snprintf(buf[3], sizeof(buf[3]),
-           "%qd bytes transferred in %ld.%03ld secs (%0.0f bytes/sec)\n",
-           (long long)st.bytes, nowtv.tv_sec, nowtv.tv_usec / 1000,
-           ((double)st.bytes * 1000000) / microsecs);
+
+       if (disp_human) {
+               strlcpy(sizebuf, "?", sizeof sizebuf);
+               fmt_scaled(st.bytes, sizebuf);
+               sizebuf[strcspn(sizebuf, "B")] = '\0';
+
+               strlcpy(ratebuf, "?", sizeof ratebuf);
+               fmt_scaled(st.bytes * 1000000.0 / microsecs, ratebuf);
+               ratebuf[strcspn(ratebuf, "B")] = '\0';
+
+               snprintf(buf[3], sizeof(buf[3]), "%qd bytes (%sB) transferred "
+                   "in %ld.%03ld seconds (%sB/s)\n", (long long)st.bytes,
+                   sizebuf, nowtv.tv_sec, nowtv.tv_usec / 1000, ratebuf);
+       } else {
+               snprintf(buf[3], sizeof(buf[3]), "%qd bytes transferred in "
+                   "%ld.%03ld secs (%0.0f bytes/sec)\n", (long long)st.bytes,
+                   nowtv.tv_sec, nowtv.tv_usec / 1000,
+                   ((double)st.bytes * 1000000) / microsecs);
+       }
 
        iov[i].iov_base = buf[3];
        iov[i++].iov_len = strlen(buf[3]);

Reply via email to