Author: kevans
Date: Wed Aug  8 21:37:02 2018
New Revision: 337505
URL: https://svnweb.freebsd.org/changeset/base/337505

Log:
  dd: add status=progress support
  
  This reports the current status on a single line every second, mirroring
  similar functionality in GNU dd, and carefully interacts with SIGINFO.
  
  PR:           229615
  Submitted by: Thomas Hurst <t...@hur.st> (modified for style(9) nits by me)
  MFC after:    1 week

Modified:
  head/bin/dd/args.c
  head/bin/dd/dd.1
  head/bin/dd/dd.c
  head/bin/dd/dd.h
  head/bin/dd/extern.h
  head/bin/dd/misc.c

Modified: head/bin/dd/args.c
==============================================================================
--- head/bin/dd/args.c  Wed Aug  8 21:21:28 2018        (r337504)
+++ head/bin/dd/args.c  Wed Aug  8 21:37:02 2018        (r337505)
@@ -306,6 +306,8 @@ f_status(char *arg)
                ddflags |= C_NOINFO;
        else if (strcmp(arg, "noxfer") == 0)
                ddflags |= C_NOXFER;
+       else if (strcmp(arg, "progress") == 0)
+               ddflags |= C_PROGRESS;
        else
                errx(1, "unknown status %s", arg);
 }

Modified: head/bin/dd/dd.1
==============================================================================
--- head/bin/dd/dd.1    Wed Aug  8 21:21:28 2018        (r337504)
+++ head/bin/dd/dd.1    Wed Aug  8 21:37:02 2018        (r337505)
@@ -32,7 +32,7 @@
 .\"     @(#)dd.1       8.2 (Berkeley) 1/13/94
 .\" $FreeBSD$
 .\"
-.Dd April 2, 2017
+.Dd August 8, 2018
 .Dt DD 1
 .Os
 .Sh NAME
@@ -164,12 +164,14 @@ bytes per second.
 Where
 .Cm value
 is one of the symbols from the following list.
-.Bl -tag -width "noxfer"
+.Bl -tag -width "progress"
 .It Cm noxfer
 Do not print the transfer statistics as the last line of status output.
 .It Cm none
 Do not print the status output.
 Error messages are shown; informational messages are not.
+.It Cm progress
+Print basic transfer statistics once per second.
 .El
 .It Cm conv Ns = Ns Ar value Ns Op , Ns Ar value ...
 Where

Modified: head/bin/dd/dd.c
==============================================================================
--- head/bin/dd/dd.c    Wed Aug  8 21:21:28 2018        (r337504)
+++ head/bin/dd/dd.c    Wed Aug  8 21:37:02 2018        (r337505)
@@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/disklabel.h>
 #include <sys/filio.h>
 #include <sys/mtio.h>
+#include <sys/time.h>
 
 #include <assert.h>
 #include <capsicum_helpers.h>
@@ -89,6 +90,7 @@ const u_char *ctab;           /* conversion table */
 char   fill_char;              /* Character to fill with if defined */
 size_t speed = 0;              /* maximum speed, in bytes per second */
 volatile sig_atomic_t need_summary;
+volatile sig_atomic_t need_progress;
 
 int
 main(int argc __unused, char *argv[])
@@ -102,6 +104,7 @@ main(int argc __unused, char *argv[])
                err(1, "unable to enter capability mode");
 
        (void)signal(SIGINFO, siginfo_handler);
+       (void)signal(SIGALRM, sigalrm_handler);
        (void)signal(SIGINT, terminate);
 
        atexit(summary);
@@ -281,6 +284,14 @@ setup(void)
                ctab = casetab;
        }
 
+       if ((ddflags & C_PROGRESS)) {
+               struct itimerval timer = {
+                       .it_interval = { .tv_sec = 1, .tv_usec = 0 },
+                       .it_value = { .tv_sec = 1, .tv_usec = 0 },
+               };
+               setitimer(ITIMER_REAL, &timer, NULL);
+       }
+
        if (clock_gettime(CLOCK_MONOTONIC, &st.start))
                err(1, "clock_gettime");
 }
@@ -460,6 +471,9 @@ dd_in(void)
                (*cfunc)();
                if (need_summary) {
                        summary();
+               }
+               if (need_progress) {
+                       progress();
                }
        }
 }

Modified: head/bin/dd/dd.h
==============================================================================
--- head/bin/dd/dd.h    Wed Aug  8 21:21:28 2018        (r337504)
+++ head/bin/dd/dd.h    Wed Aug  8 21:37:02 2018        (r337505)
@@ -100,5 +100,6 @@ typedef struct {
 #define        C_STATUS        0x08000000
 #define        C_NOXFER        0x10000000
 #define        C_NOINFO        0x20000000
+#define        C_PROGRESS      0x40000000
 
 #define        C_PARITY        (C_PAREVEN | C_PARODD | C_PARNONE | C_PARSET)

Modified: head/bin/dd/extern.h
==============================================================================
--- head/bin/dd/extern.h        Wed Aug  8 21:21:28 2018        (r337504)
+++ head/bin/dd/extern.h        Wed Aug  8 21:37:02 2018        (r337505)
@@ -46,7 +46,9 @@ void pos_in(void);
 void pos_out(void);
 double secs_elapsed(void);
 void summary(void);
+void progress(void);
 void siginfo_handler(int);
+void sigalrm_handler(int);
 void terminate(int);
 void unblock(void);
 void unblock_close(void);
@@ -66,3 +68,4 @@ extern const u_char a2ibm_32V[], a2ibm_POSIX[];
 extern u_char casetab[];
 extern char fill_char;
 extern volatile sig_atomic_t need_summary;
+extern volatile sig_atomic_t need_progress;

Modified: head/bin/dd/misc.c
==============================================================================
--- head/bin/dd/misc.c  Wed Aug  8 21:21:28 2018        (r337504)
+++ head/bin/dd/misc.c  Wed Aug  8 21:37:02 2018        (r337505)
@@ -56,6 +56,8 @@ __FBSDID("$FreeBSD$");
 #include "dd.h"
 #include "extern.h"
 
+static int need_newline;
+
 double
 secs_elapsed(void)
 {
@@ -83,6 +85,9 @@ summary(void)
        if (ddflags & C_NOINFO)
                return;
 
+       if (need_newline && !need_summary)
+               fprintf(stderr, "\n");
+
        secs = secs_elapsed();
 
        (void)fprintf(stderr,
@@ -102,12 +107,42 @@ summary(void)
        need_summary = 0;
 }
 
+void
+progress(void)
+{
+       double secs;
+       static int lastlen;
+       int len;
+
+       secs = secs_elapsed();
+       len = fprintf(stderr,
+           "\r%ju bytes transferred in %.0f secs (%.0f bytes/sec)",
+           st.bytes, secs, st.bytes / secs);
+
+       if (len > 0) {
+               if (len < lastlen)
+                       (void)fprintf(stderr, "%*s", len - lastlen, "");
+               lastlen = len;
+       }
+
+       need_newline = 1;
+       need_progress = 0;
+}
+
 /* ARGSUSED */
 void
 siginfo_handler(int signo __unused)
 {
 
        need_summary = 1;
+}
+
+/* ARGSUSED */
+void
+sigalrm_handler(int signo __unused)
+{
+
+       need_progress = 1;
 }
 
 /* ARGSUSED */
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to