diff --git a/bin/dd/Makefile b/bin/dd/Makefile index 2a9ff1f788f7..9088112536dd 100644 --- a/bin/dd/Makefile +++ b/bin/dd/Makefile @@ -6,6 +6,7 @@ PACKAGE=runtime PROG= dd SRCS= args.c conv.c conv_tab.c dd.c misc.c position.c +LIBADD= util # # Test the character conversion functions. We have to be explicit about diff --git a/bin/dd/dd.c b/bin/dd/dd.c index 358d2c06190c..a37a3072bcff 100644 --- a/bin/dd/dd.c +++ b/bin/dd/dd.c @@ -95,6 +95,8 @@ volatile sig_atomic_t need_progress; int main(int argc __unused, char *argv[]) { + struct itimerval itv = { { 1, 0 }, { 1, 0 } }; /* SIGALARM every second, if needed */ + (void)setlocale(LC_CTYPE, ""); jcl(argv); setup(); @@ -104,7 +106,10 @@ main(int argc __unused, char *argv[]) err(1, "unable to enter capability mode"); (void)signal(SIGINFO, siginfo_handler); - (void)signal(SIGALRM, sigalrm_handler); + if (ddflags & C_PROGRESS) { + (void)signal(SIGALRM, sigalarm_handler); + setitimer(ITIMER_REAL, &itv, NULL); + } (void)signal(SIGINT, terminate); atexit(summary); @@ -284,14 +289,6 @@ 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"); } @@ -469,12 +466,10 @@ dd_in(void) in.dbp += in.dbrcnt; (*cfunc)(); - if (need_summary) { + if (need_summary) summary(); - } - if (need_progress) { + if (need_progress) progress(); - } } } diff --git a/bin/dd/extern.h b/bin/dd/extern.h index ca80a87f1621..f471048a189b 100644 --- a/bin/dd/extern.h +++ b/bin/dd/extern.h @@ -45,10 +45,11 @@ void jcl(char **); void pos_in(void); void pos_out(void); double secs_elapsed(void); +void progress(void); void summary(void); void progress(void); +void sigalarm_handler(int); void siginfo_handler(int); -void sigalrm_handler(int); void terminate(int); void unblock(void); void unblock_close(void); diff --git a/bin/dd/misc.c b/bin/dd/misc.c index e778f275fcef..dfe83fd1ef9a 100644 --- a/bin/dd/misc.c +++ b/bin/dd/misc.c @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -56,8 +57,6 @@ __FBSDID("$FreeBSD$"); #include "dd.h" #include "extern.h" -static int need_newline; - double secs_elapsed(void) { @@ -85,7 +84,7 @@ summary(void) if (ddflags & C_NOINFO) return; - if (need_newline && !need_summary) + if (ddflags & C_PROGRESS) fprintf(stderr, "\n"); secs = secs_elapsed(); @@ -110,22 +109,25 @@ summary(void) void progress(void) { + static int outlen; + char si[4 + 1 + 2 + 1]; /* 123 NUL */ + char iec[4 + 1 + 2 + 1]; /* 123 NUL */ + char persec[4 + 1 + 2 + 1]; /* 123 NUL */ + char *buf; 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; + humanize_number(si, sizeof(si), (int64_t)st.bytes, "B", HN_AUTOSCALE, + HN_DECIMAL | HN_DIVISOR_1000); + humanize_number(iec, sizeof(iec), (int64_t)st.bytes, "B", HN_AUTOSCALE, + HN_DECIMAL | HN_IEC_PREFIXES); + humanize_number(persec, sizeof(iec), (int64_t)(st.bytes / secs), "B", + HN_AUTOSCALE, HN_DECIMAL | HN_DIVISOR_1000); + asprintf(&buf, " %'ju bytes (%s, %s) transferred %.3fs, %s/s", + (uintmax_t)st.bytes, si, iec, secs, persec); + outlen = fprintf(stderr, "%-*s\r", outlen, buf); + fflush(stderr); + free(buf); need_progress = 0; } @@ -139,7 +141,7 @@ siginfo_handler(int signo __unused) /* ARGSUSED */ void -sigalrm_handler(int signo __unused) +sigalarm_handler(int signo __unused) { need_progress = 1; diff --git a/bin/dd/position.c b/bin/dd/position.c index 0bd8edcda1e9..21a100cd3b24 100644 --- a/bin/dd/position.c +++ b/bin/dd/position.c @@ -125,6 +125,8 @@ pos_in(void) --cnt; if (need_summary) summary(); + if (need_progress) + progress(); continue; }