Index: head/bin/dd/Makefile =================================================================== --- head/bin/dd/Makefile +++ head/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 Index: head/bin/dd/dd.c =================================================================== --- head/bin/dd/dd.c +++ head/bin/dd/dd.c @@ -95,6 +95,8 @@ 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 @@ 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 @@ 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 @@ in.dbp += in.dbrcnt; (*cfunc)(); - if (need_summary) { + if (need_summary) summary(); - } - if (need_progress) { + if (need_progress) progress(); - } } } Index: head/bin/dd/extern.h =================================================================== --- head/bin/dd/extern.h +++ head/bin/dd/extern.h @@ -45,10 +45,11 @@ 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); Index: head/bin/dd/misc.c =================================================================== --- head/bin/dd/misc.c +++ head/bin/dd/misc.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -56,8 +57,6 @@ #include "dd.h" #include "extern.h" -static int need_newline; - double secs_elapsed(void) { @@ -85,7 +84,7 @@ if (ddflags & C_NOINFO) return; - if (need_newline && !need_summary) + if (ddflags & C_PROGRESS) fprintf(stderr, "\n"); secs = secs_elapsed(); @@ -110,22 +109,25 @@ 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 @@ /* ARGSUSED */ void -sigalrm_handler(int signo __unused) +sigalarm_handler(int signo __unused) { need_progress = 1; Index: head/bin/dd/position.c =================================================================== --- head/bin/dd/position.c +++ head/bin/dd/position.c @@ -125,6 +125,8 @@ --cnt; if (need_summary) summary(); + if (need_progress) + progress(); continue; }