dd: speed measurement. optional.
No binary (build failed)
—
(log yok)
| @@ -127,7 +127,16 @@ config FEATURE_DD_SIGNAL_HANDLING | |
| $ dd if=/dev/zero of=/dev/null& | |
| $ pid=$! kill -USR1 $pid; sleep 1; kill $pid | |
| - | 10899206+0 records in 10899206+0 records out |
| + | 10899206+0 records in |
| + | 10899206+0 records out |
| + | |
| + | config FEATURE_DD_THIRD_STATUS_LINE |
| + | bool "Enable the third status line upon signal" |
| + | default n |
| + | depends on DD && FEATURE_DD_SIGNAL_HANDLING |
| + | help |
| + | Displays a coreutils-like third status line with transferred bytes, |
| + | elapsed time and speed. |
| config FEATURE_DD_IBS_OBS | |
| bool "Enable ibs, obs and conv options" | |
| @@ -34,6 +34,10 @@ static const struct suffix_mult dd_suffixes[] = { | |
| struct globals { | |
| off_t out_full, out_part, in_full, in_part; | |
| + | #if ENABLE_FEATURE_DD_THIRD_STATUS_LINE |
| + | unsigned long long total_bytes; |
| + | unsigned long long begin_time_us; |
| + | #endif |
| }; | |
| #define G (*(struct globals*)&bb_common_bufsiz1) | |
| #define INIT_G() do { \ | |
| @@ -44,11 +48,50 @@ struct globals { | |
| static void dd_output_status(int UNUSED_PARAM cur_signal) | |
| { | |
| + | #if ENABLE_FEATURE_DD_THIRD_STATUS_LINE |
| + | unsigned long long total; |
| + | unsigned long long diff_scaled; |
| + | unsigned long long diff_us = monotonic_us(); /* before fprintf */ |
| + | #endif |
| + | |
| /* Deliberately using %u, not %d */ | |
| fprintf(stderr, "%"OFF_FMT"u+%"OFF_FMT"u records in\n" | |
| "%"OFF_FMT"u+%"OFF_FMT"u records out\n", | |
| G.in_full, G.in_part, | |
| G.out_full, G.out_part); | |
| + | |
| + | #if ENABLE_FEATURE_DD_THIRD_STATUS_LINE |
| + | fprintf(stderr, "%llu bytes (%sB) copied, ", |
| + | G.total_bytes, |
| + | /* show fractional digit, use suffixes */ |
| + | make_human_readable_str(G.total_bytes, 1, 0) |
| + | ); |
| + | /* Corner cases: |
| + | * ./busybox dd </dev/null >/dev/null |
| + | * ./busybox dd bs=1M count=2000 </dev/zero >/dev/null |
| + | * (echo DONE) | ./busybox dd >/dev/null |
| + | * (sleep 1; echo DONE) | ./busybox dd >/dev/null |
| + | */ |
| + | diff_us -= G.begin_time_us; |
| + | /* We need to calculate "(total * 1M) / usec" without overflow. |
| + | * this would work too, but is bigger than integer code below. |
| + | * total = G.total_bytes * (double)(1024 * 1024) / (diff_us ? diff_us : 1); |
| + | */ |
| + | diff_scaled = diff_us; |
| + | total = G.total_bytes; |
| + | while (total > MAXINT(unsigned long long) / (1024 * 1024)) { |
| + | total >>= 1; |
| + | diff_scaled >>= 1; |
| + | } |
| + | total *= (1024 * 1024); |
| + | if (diff_scaled > 1) |
| + | total /= diff_scaled; |
| + | fprintf(stderr, "%f seconds, %sB/s\n", |
| + | diff_us / 1000000.0, |
| + | /* show fractional digit, use suffixes */ |
| + | make_human_readable_str(total, 1, 0) |
| + | ); |
| + | #endif |
| } | |
| static ssize_t full_write_or_warn(const void *buf, size_t len, | |
| @@ -70,13 +113,16 @@ static bool write_and_stats(const void *buf, size_t len, size_t obs, | |
| G.out_full++; | |
| else if (n) /* > 0 */ | |
| G.out_part++; | |
| + | #if ENABLE_FEATURE_DD_THIRD_STATUS_LINE |
| + | G.total_bytes += n; |
| + | #endif |
| return 0; | |
| } | |
| #if ENABLE_LFS | |
| - | #define XATOU_SFX xatoull_sfx |
| + | # define XATOU_SFX xatoull_sfx |
| #else | |
| - | #define XATOU_SFX xatoul_sfx |
| + | # define XATOU_SFX xatoul_sfx |
| #endif | |
| int dd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |
| @@ -157,10 +203,6 @@ int dd_main(int argc UNUSED_PARAM, char **argv) | |
| INIT_G(); | |
| //fflush(NULL); - is this needed because of NOEXEC? | |
| - | #if ENABLE_FEATURE_DD_SIGNAL_HANDLING |
| - | signal_SA_RESTART_empty_mask(SIGUSR1, dd_output_status); |
| - | #endif |
| - | |
| for (n = 1; argv[n]; n++) { | |
| int what; | |
| char *val; | |
| @@ -246,6 +288,14 @@ int dd_main(int argc UNUSED_PARAM, char **argv) | |
| flags |= FLAG_TWOBUFS; | |
| obuf = xmalloc(obs); | |
| } | |
| + | |
| + | #if ENABLE_FEATURE_DD_SIGNAL_HANDLING |
| + | signal_SA_RESTART_empty_mask(SIGUSR1, dd_output_status); |
| + | #endif |
| + | #if ENABLE_FEATURE_DD_THIRD_STATUS_LINE |
| + | G.begin_time_us = monotonic_us(); |
| + | #endif |
| + | |
| if (infile != NULL) | |
| xmove_fd(xopen(infile, O_RDONLY), ifd); | |
| else { | |