--- ../../coreutils/src/dd.c 2007-02-10 22:48:16.000000000 +0100 +++ dd.c 2007-02-13 23:22:57.000000000 +0100 @@ -126,6 +126,33 @@ enum STATUS_NOXFER = 01 }; +enum Display_mode +{ + /* Generate the default, standards-conforming, style of output: + $ dd if=/dev/zero of=/dev/null count=10 + 10+0 records in + 10+0 records out */ + DISP_DEFAULT, + + /* Generate no such output. + $ dd if=/dev/zero of=/dev/null count=10 display=quiet + $ */ + DISP_QUIET, + + /* Generate more readable output: + $ dd if=/dev/zero of=/dev/null count=10 display=human + 5.0K+0 bytes in + 5.0K+0 bytes out + You can also specify the display block size: + $ dd if=/dev/zero of=/dev/null count=10 display=human dbs=1 + 5120+0 bytes in + 5120+0 bytes out */ + DISP_HUMAN_READABLE +}; + +/* This is aimed to choose diplay type */ +static enum Display_mode display_mode = DISP_DEFAULT; + /* The name this program was run with. */ char *program_name; @@ -229,6 +256,12 @@ static sig_atomic_t volatile info_signal /* A longest symbol in the struct symbol_values tables below. */ #define LONGEST_SYMBOL "fdatasync" +/* Human-readable options for output. */ +static int human_output_opts; + +/* The units to use when printing sizes. */ +static uintmax_t display_block_size; + /* A symbol and the corresponding integer value. */ struct symbol_value { @@ -424,8 +457,21 @@ Copy a file, converting and formatting a seek=BLOCKS skip BLOCKS obs-sized blocks at start of output\n\ skip=BLOCKS skip BLOCKS ibs-sized blocks at start of input\n\ status=noxfer suppress transfer statistics\n\ + display=MODE uses display mode according to MODE\n\ + dbs=SIZE uses SIZE-byte blocks to display statistics\n\ +"), stdout); + fputs (_("\ +MODE may be:\n\ + quiet do not display statistics\n\ + human display statistics in a human readable format\n\ +\n\ +SIZE may be:\n\ + human prints all sizes in human readable format (e.g. 1K, 234M)\n\ + si likewise, but uses powers of 1000 instead of 1024\n\ + BYTES likewise, but use powers of BYTES\n\ "), stdout); fputs (_("\ ++\n\ \n\ BLOCKS and BYTES may be followed by the following multiplicative suffixes:\n\ xM M, c 1, w 2, b 512, kB 1000, K 1024, MB 1000*1000, M 1024*1024,\n\ @@ -530,6 +576,37 @@ multiple_bits_set (int i) return (i & (i - 1)) != 0; } +static void +print_human_stats (void) +{ + char display_buf[5][MAX (LONGEST_HUMAN_READABLE + 1, + INT_BUFSIZE_BOUND (uintmax_t))]; + + fprintf (stderr, _("%s+%s bytes in\n"), + human_readable (r_full, display_buf[0], human_output_opts, + input_blocksize, display_block_size), + human_readable (r_partial, display_buf[1], human_output_opts, + input_blocksize, display_block_size)); + + fprintf (stderr, _("%s+%s bytes out\n"), + human_readable (w_full, display_buf[2], human_output_opts, + output_blocksize , display_block_size), + human_readable (w_partial, display_buf[3], human_output_opts, + output_blocksize, display_block_size)); + + if (0 < r_truncate) + { + fprintf (stderr, "%s %s\n", + human_readable (r_truncate, display_buf[4], + human_output_opts, output_blocksize, + display_block_size), + (r_truncate == 1 + ? _("truncated record") + : _("truncated records"))); + } +} + + /* Print transfer statistics. */ static void @@ -537,25 +614,29 @@ print_stats (void) { xtime_t now = gethrxtime (); char hbuf[LONGEST_HUMAN_READABLE + 1]; - int human_opts = - (human_autoscale | human_round_to_nearest - | human_space_before_unit | human_SI | human_B); + double delta_s; char const *bytes_per_second; - fprintf (stderr, - _("%"PRIuMAX"+%"PRIuMAX" records in\n" - "%"PRIuMAX"+%"PRIuMAX" records out\n"), - r_full, r_partial, w_full, w_partial); - - if (r_truncate != 0) - fprintf (stderr, - ngettext ("%"PRIuMAX" truncated record\n", - "%"PRIuMAX" truncated records\n", - select_plural (r_truncate)), - r_truncate); + if (display_mode == DISP_HUMAN_READABLE) + { + print_human_stats (); + } + else if (display_mode == DISP_DEFAULT) + { + fprintf (stderr, + _("%"PRIuMAX"+%"PRIuMAX" records in\n" + "%"PRIuMAX"+%"PRIuMAX" records out\n"), + r_full, r_partial, w_full, w_partial); - if (status_flags & STATUS_NOXFER) + if (r_truncate != 0) + fprintf (stderr, + ngettext ("%"PRIuMAX" truncated record\n", + "%"PRIuMAX" truncated records\n", + select_plural (r_truncate)), + r_truncate); + } + if ((status_flags & STATUS_NOXFER) | display_mode == DISP_QUIET) return; /* Use integer arithmetic to compute the transfer rate, @@ -566,7 +647,7 @@ print_stats (void) "%"PRIuMAX" bytes (%s) copied", select_plural (w_bytes)), w_bytes, - human_readable (w_bytes, hbuf, human_opts, 1, 1)); + human_readable (w_bytes, hbuf, human_output_opts, 1, 1)); if (start_time < now) { @@ -574,7 +655,7 @@ print_stats (void) uintmax_t delta_xtime = now; delta_xtime -= start_time; delta_s = delta_xtime / XTIME_PRECISIONe0; - bytes_per_second = human_readable (w_bytes, hbuf, human_opts, + bytes_per_second = human_readable (w_bytes, hbuf, human_output_opts, XTIME_PRECISION, delta_xtime); } else @@ -904,6 +985,26 @@ scanargs (int argc, char **argv) else if (STREQ (name, "status")) status_flags |= parse_symbols (val, statuses, N_("invalid status flag: %s")); + else if (STREQ (name, "display")) /* select display mode */ + { + if (STREQ (val, "human")) + { + display_mode = DISP_HUMAN_READABLE; + human_output_opts = human_autoscale | human_SI | human_base_1024; + display_block_size = 1; + } + else if (STREQ (val, "quiet")) + { + display_mode = DISP_QUIET; + } + else + { + error (0, 0, _("unrecognized display= argument %s"), quote (val)); + usage (EXIT_FAILURE); + } + } + else if (STREQ (name, "dbs")) /* select display block size */ + human_output_opts = human_options (val, true, &display_block_size); else { bool invalid = false; @@ -1650,6 +1751,13 @@ main (int argc, char **argv) if (getopt_long (argc, argv, "", NULL, NULL) != -1) usage (EXIT_FAILURE); + if (getenv ("DD_DISPLAY_BLOCK_SIZE")) + human_output_opts = human_options (getenv ("DD_DISPLAY_BLOCK_SIZE"), + false, &display_block_size); + else + human_output_opts = (human_autoscale | human_round_to_nearest + | human_space_before_unit | human_SI | human_B); + /* Initialize translation table to identity translation. */ for (i = 0; i < 256; i++) trans_table[i] = i;