From 461486ec4fad624152b466d9dd6d2b7c3dfcd8fd Mon Sep 17 00:00:00 2001 From: Andrew Wood Date: Sun, 16 Jul 2023 23:12:12 +0100 Subject: [PATCH] Added --bits option --- doc/ACKNOWLEDGEMENTS.md | 1 + doc/NEWS.md | 1 + doc/TODO.md | 1 - doc/quickref.1.in | 9 +++++++ src/include/options.h | 1 + src/include/pv-internal.h | 1 + src/include/pv.h | 1 + src/main/help.c | 2 ++ src/main/main.c | 1 + src/main/options.c | 8 +++++- src/pv/display.c | 54 +++++++++++++++++++++++++++++---------- src/pv/state.c | 5 ++++ 12 files changed, 70 insertions(+), 15 deletions(-) diff --git a/doc/ACKNOWLEDGEMENTS.md b/doc/ACKNOWLEDGEMENTS.md index 592d5a9..f17325a 100644 --- a/doc/ACKNOWLEDGEMENTS.md +++ b/doc/ACKNOWLEDGEMENTS.md @@ -80,5 +80,6 @@ is acknowledged and greatly appreciated: * [christoph-zededa](https://github.com/christoph-zededa) - provided OS X support for "`--watchfd`" * [Dave Beckett](https://github.com/dajobe) - added "`@filename`" syntax to "`--size`", and corrected an autoconf problem with stat64 on OS X * [Volodymyr Bychkovyak](https://github.com/vbychkoviak) - provided fix for rate limit behaviour with bursty traffic + * [Nick Black](https://nick-black.com) - added "`--bits`" option --- diff --git a/doc/NEWS.md b/doc/NEWS.md index 9a1d316..fbb02a2 100644 --- a/doc/NEWS.md +++ b/doc/NEWS.md @@ -7,6 +7,7 @@ UNRELEASED * fix: corrected elapsed time display to show as D:HH:MM:SS after 1 day, like the ETA does - corrects [GH#16 "Show days in same format in ETA as in elapsed time"](https://github.com/a-j-wood/pv/issues/16) * feature: the "`--size`" option now accepts "`@filename`" to use the size of another file (pull request [#57](https://github.com/a-j-wood/pv/pull/57) supplied by [Dave Beckett](https://github.com/dajobe)) * feature: the "`--watchfd`" option is now available on OS X (pull request [#60](https://github.com/a-j-wood/pv/pull/60) supplied by [christoph-zededa](https://github.com/christoph-zededa)) + * feature: new "`--bits`" option to show bit count instead of byte count (adapted from pull request [#63](https://github.com/a-j-wood/pv/pull/63) supplied by [Nick Black](https://nick-black.com)) * feature: new "`--average-rate-window`" option, to set the window over which the average rate is calculated, also used for ETA (modified from pull request [#65](https://github.com/a-j-wood/pv/pull/65) supplied by [lemonsqueeze](https://github.com/lemonsqueeze)) * feature: the "`--watchfd`" option will now show relative filenames, if they are under the current directory (pull request [#66](https://github.com/a-j-wood/pv/pull/66) supplied by [ikasty](https://github.com/ikasty)) * docs: moved all open issues into GitHub and updated the TODO list diff --git a/doc/TODO.md b/doc/TODO.md index d4975c5..bd96d63 100644 --- a/doc/TODO.md +++ b/doc/TODO.md @@ -25,7 +25,6 @@ Feature requests * ([GH#12](https://github.com/a-j-wood/pv/issues/12)) Allow multiple "`-d`" options (Linus Heckemann for multiple PID:FD; Jacek Wielemborek) * ([GH#15](https://github.com/a-j-wood/pv/issues/15)) Use Unicode for more granular progress bar (Alexander Petrossian) * ([GH#17](https://github.com/a-j-wood/pv/issues/17)) Allow "`-r`" with "`-l`" and "`-n`" to output lines/sec (Roland Kletzing) - * ([GH#21](https://github.com/a-j-wood/pv/issues/21)) Options to change the units in the rate display (Jeffrey Paul, John W. O'Brien, David Henderson) * ([GH#22](https://github.com/a-j-wood/pv/issues/22)) Options to skip input and seek on output (Jason A. Pfeil, Feb 2022) * ([GH#25](https://github.com/a-j-wood/pv/issues/25)) Normalise progress to 100% on overrun (Andrej Gantvorg) * ([GH#29](https://github.com/a-j-wood/pv/issues/29)) Option to enable *O_DIRECT* (Romain Kang, Jacek Wielemborek) diff --git a/doc/quickref.1.in b/doc/quickref.1.in index cee6ee4..5716e28 100644 --- a/doc/quickref.1.in +++ b/doc/quickref.1.in @@ -149,6 +149,10 @@ rate of data transfer (default: last 30s, see --average-rate-window). Turn the total byte counter on. This will display the total amount of data transferred so far. .TP +.B \-8, \-\-bits +Display the total bits instead of the total bytes. The output suffix will +be "b" instead of "B". +.TP .B \-T, \-\-buffer\-percent Turn on the transfer buffer percentage display. This will show the percentage of the transfer buffer in use - but see the caveat under @@ -489,6 +493,11 @@ Bytes transferred so far (or lines if .B \-l was specified). Equivalent to .BR \-b . +If +.B \-\-bits +was specified, +.B %b +shows the bits transferred so far, not bytes. .TP .B %T Percentage of the transfer buffer in use. Equivalent to diff --git a/src/include/options.h b/src/include/options.h index 08b7bc5..c0e6204 100644 --- a/src/include/options.h +++ b/src/include/options.h @@ -22,6 +22,7 @@ struct opts_s { /* structure describing run-time options */ bool rate; /* rate counter flag */ bool average_rate; /* average rate counter flag */ bool bytes; /* bytes transferred flag */ + bool bits; /* report transfer size in bits */ bool bufpercent; /* transfer buffer percentage flag */ unsigned int lastwritten; /* show N bytes last written */ bool force; /* force-if-not-terminal flag */ diff --git a/src/include/pv-internal.h b/src/include/pv-internal.h index d12e5c3..04d9d58 100644 --- a/src/include/pv-internal.h +++ b/src/include/pv-internal.h @@ -70,6 +70,7 @@ struct pvstate_s { bool numeric; /* numeric output only */ bool wait; /* wait for data before display */ bool linemode; /* count lines instead of bytes */ + bool bits; /* report bits instead of bytes */ bool null; /* lines are null-terminated */ bool no_op; /* do nothing other than pipe data */ unsigned int skip_errors; /* skip read errors counter */ diff --git a/src/include/pv.h b/src/include/pv.h index 853d769..8e5651f 100644 --- a/src/include/pv.h +++ b/src/include/pv.h @@ -78,6 +78,7 @@ extern void pv_state_numeric_set(pvstate_t, bool); extern void pv_state_wait_set(pvstate_t, bool); extern void pv_state_delay_start_set(pvstate_t, double); extern void pv_state_linemode_set(pvstate_t, bool); +extern void pv_state_bits_set(pvstate_t, bool); extern void pv_state_null_set(pvstate_t, bool); extern void pv_state_no_op_set(pvstate_t, bool); extern void pv_state_skip_errors_set(pvstate_t, unsigned int); diff --git a/src/main/help.c b/src/main/help.c index ee7f198..f4406d4 100644 --- a/src/main/help.c +++ b/src/main/help.c @@ -45,6 +45,8 @@ void display_help(void) ("compute average rate over past SEC seconds (default 30s)")}, {"-b", "--bytes", 0, N_("show number of bytes transferred")}, + {"-8", "--bits", 0, + N_("show number of bits transferred")}, {"-T", "--buffer-percent", 0, N_("show percentage of transfer buffer in use")}, {"-A", "--last-written", _("NUM"), diff --git a/src/main/main.c b/src/main/main.c index 328110b..6d675c4 100644 --- a/src/main/main.c +++ b/src/main/main.c @@ -195,6 +195,7 @@ int main(int argc, char **argv) pv_state_wait_set(state, opts->wait); pv_state_delay_start_set(state, opts->delay_start); pv_state_linemode_set(state, opts->linemode); + pv_state_bits_set(state, opts->bits); pv_state_null_set(state, opts->null); pv_state_skip_errors_set(state, opts->skip_errors); pv_state_stop_at_size_set(state, opts->stop_at_size); diff --git a/src/main/options.c b/src/main/options.c index 7994a14..b0e76e5 100644 --- a/src/main/options.c +++ b/src/main/options.c @@ -58,6 +58,7 @@ opts_t opts_parse(int argc, char **argv) {"rate", 0, NULL, (int) 'r'}, {"average-rate", 0, NULL, (int) 'a'}, {"bytes", 0, NULL, (int) 'b'}, + {"bits", 0, NULL, (int) '8'}, {"buffer-percent", 0, NULL, (int) 'T'}, {"last-written", 1, NULL, (int) 'A'}, {"force", 0, NULL, (int) 'f'}, @@ -88,7 +89,7 @@ opts_t opts_parse(int argc, char **argv) int option_index = 0; #endif char *short_options = - "hVpteIrabTA:fnqcWD:s:l0i:w:H:N:F:L:B:CESR:P:d:m:"; + "hVpteIrab8TA:fnqcWD:s:l0i:w:H:N:F:L:B:CESR:P:d:m:"; int c, numopts; unsigned int check_pid; int check_fd; @@ -234,6 +235,11 @@ opts_t opts_parse(int argc, char **argv) opts->bytes = true; numopts++; break; + case '8': + opts->bytes = true; + opts->bits = true; + numopts++; + break; case 'T': opts->bufpercent = true; numopts++; diff --git a/src/pv/display.c b/src/pv/display.c index af42ebd..abcf149 100644 --- a/src/pv/display.c +++ b/src/pv/display.c @@ -640,8 +640,15 @@ static char *pv__format(pvstate_t state, sprintf(numericprefix, "%.4Lf ", elapsed_sec); if ((state->components_used & PV_DISPLAY_BYTES) != 0) { - sprintf(state->display_buffer, "%.99s%lld\n", - numericprefix, total_bytes); + if (state->bits) { + sprintf(state->display_buffer, + "%.99s%lld\n", numericprefix, + 8 * total_bytes); + } else { + sprintf(state->display_buffer, + "%.99s%lld\n", numericprefix, + total_bytes); + } } else if (state->percentage > 100) { /* As mentioned above, we go 0-100, then 100-0. */ sprintf(state->display_buffer, "%.99s%ld\n", @@ -673,10 +680,17 @@ static char *pv__format(pvstate_t state, /* If we're showing bytes transferred, set up the display string. */ if ((state->components_used & PV_DISPLAY_BYTES) != 0) { - pv__sizestr(state->str_transferred, - sizeof(state->str_transferred), "%s", - (long double) total_bytes, "", _("B"), - state->linemode ? 0 : 1); + if (state->bits && !state->linemode) { + pv__sizestr(state->str_transferred, + sizeof(state->str_transferred), "%s", + (long double) total_bytes * 8, "", + _("b"), 1); + } else { + pv__sizestr(state->str_transferred, + sizeof(state->str_transferred), "%s", + (long double) total_bytes, "", _("B"), + state->linemode ? 0 : 1); + } } /* Transfer buffer percentage - set up the display string. */ @@ -722,17 +736,31 @@ static char *pv__format(pvstate_t state, /* Rate - set up the display string. */ if ((state->components_used & PV_DISPLAY_RATE) != 0) { - pv__sizestr(state->str_rate, sizeof(state->str_rate), - "[%s]", rate, _("/s"), _("B/s"), - state->linemode ? 0 : 1); + if (state->bits && !state->linemode) { + pv__sizestr(state->str_rate, + sizeof(state->str_rate), "[%s]", + 8 * rate, "", _("b/s"), 1); + } else { + pv__sizestr(state->str_rate, + sizeof(state->str_rate), "[%s]", rate, + _("/s"), _("B/s"), + state->linemode ? 0 : 1); + } } /* Average rate - set up the display string. */ if ((state->components_used & PV_DISPLAY_AVERAGERATE) != 0) { - pv__sizestr(state->str_average_rate, - sizeof(state->str_average_rate), "[%s]", - average_rate, _("/s"), _("B/s"), - state->linemode ? 0 : 1); + if (state->bits && !state->linemode) { + pv__sizestr(state->str_average_rate, + sizeof(state->str_average_rate), + "[%s]", 8 * average_rate, "", _("b/s"), + 1); + } else { + pv__sizestr(state->str_average_rate, + sizeof(state->str_average_rate), + "[%s]", average_rate, _("/s"), + _("B/s"), state->linemode ? 0 : 1); + } } /* Last output bytes - set up the display string. */ diff --git a/src/pv/state.c b/src/pv/state.c index 80e21d9..e55a941 100644 --- a/src/pv/state.c +++ b/src/pv/state.c @@ -174,6 +174,11 @@ void pv_state_linemode_set(pvstate_t state, bool val) state->linemode = val; }; +void pv_state_bits_set(pvstate_t state, bool bits) +{ + state->bits = bits; +}; + void pv_state_null_set(pvstate_t state, bool val) { state->null = val;