diff options
author | Joel Kronqvist <joel.kronqvist@iki.fi> | 2024-05-31 15:29:42 +0300 |
---|---|---|
committer | Joel Kronqvist <joel.kronqvist@iki.fi> | 2024-06-30 08:31:37 +0300 |
commit | 576b7a70dbf6c43651dc77db3a0104c019eed018 (patch) | |
tree | 6ca087eb2e3bd27d876ad2842d67cee2d7e09cbf | |
parent | 41de123de0453274fb2e5b2192548ce274ad8deb (diff) | |
download | stdu-576b7a70dbf6c43651dc77db3a0104c019eed018.tar.gz stdu-576b7a70dbf6c43651dc77db3a0104c019eed018.zip |
Added `--forward`work/1.1.0
-rw-r--r-- | README | 8 | ||||
-rw-r--r-- | config-parser.c | 76 | ||||
-rw-r--r-- | config-parser.h | 1 | ||||
-rw-r--r-- | stdu.1 | 28 | ||||
-rw-r--r-- | stdu.c | 39 |
5 files changed, 127 insertions, 25 deletions
@@ -1,6 +1,6 @@ -stdu README -=========== +stdu 1.1.0 README +================= `stdu` is a program for monitoring the amount of input data in real time. @@ -19,7 +19,8 @@ Install by either copying/symlinking `stdu` and `stdu.1` to the appropriate locations, or run `make install`. You can change the installation paths by modifying `BINPATH` and `MANPATH` in the -makefile. +makefile. You should run `makewhatis` on your +`MANPATH` after installation. Usage ----- @@ -27,3 +28,4 @@ Usage See the man page and help message: `stdu --help` `man stdu` + diff --git a/config-parser.c b/config-parser.c index ef67a8e..b09bbc2 100644 --- a/config-parser.c +++ b/config-parser.c @@ -14,10 +14,11 @@ Result parse_config(int argc, char* argv[]) { Result res; res.success = false; Config tmp; - tmp.precision = 0; - tmp.multiline = false; + tmp.forward = false; tmp.human_readable = false; tmp.help = false; + tmp.multiline = false; + tmp.precision = 0; size_t i = 1; char* argument; @@ -58,7 +59,9 @@ Result parse_config(int argc, char* argv[]) { size_t tacktacklen = 2; if (strncmp(argument, "--", tacktacklen) == 0) { argument += tacktacklen; - if (strcmp(argument, "help") == 0) { + if (strcmp(argument, "forward") == 0) { + tmp.forward = true; + } else if (strcmp(argument, "help") == 0) { tmp.help = true; } else if (strcmp(argument, "human-readable") == 0) { tmp.human_readable = true; @@ -111,6 +114,9 @@ Result parse_config(int argc, char* argv[]) { case 'm': tmp.multiline = true; break; + case 'o': + tmp.forward = true; + break; case 'p': next_is_precision = true; if (opt_i != arglen - 1) { @@ -185,6 +191,7 @@ Result parse_config(int argc, char* argv[]) { } Config* conf = malloc(sizeof(Config)); + conf->forward = tmp.forward; conf->help = tmp.help; conf->human_readable = tmp.human_readable; conf->multiline = tmp.multiline; @@ -245,28 +252,73 @@ char* test_precision_parsing() { } +char* test_forward_parsing() { + int argc = 2; + char* argv1[] = { "stdu", "--forward" }; + char* argv2[] = { "stdu", "-o" }; + Result res1 = parse_config(argc, argv1); + Result res2 = parse_config(argc, argv2); + Config* conf1 = (Config*) res1.result; + Config* conf2 = (Config*) res2.result; + + mt_assert_eq(res1.success, true); + mt_assert_eq(res2.success, true); + mt_assert_eq(conf1->forward, true); + mt_assert_eq(conf2->forward, true); + free(conf1); + free(conf2); + + return 0; +} + +char* test_help_parsing() { + int argc = 2; + char* argv1[] = { "stdu", "--help" }; + char* argv2[] = { "stdu", "-?" }; + Result res1 = parse_config(argc, argv1); + Result res2 = parse_config(argc, argv2); + Config* conf1 = (Config*) res1.result; + Config* conf2 = (Config*) res2.result; + + mt_assert_eq(res1.success, true); + mt_assert_eq(res2.success, true); + mt_assert_eq(conf1->help, true); + mt_assert_eq(conf2->help, true); + free(conf1); + free(conf2); + + return 0; +} + char* test_human_readability_parsing() { int argc = 2; - char* argv[] = { "stdu", "--human-readable" }; - Result res = parse_config(argc, argv); - Config* conf = (Config*) res.result; + char* argv1[] = { "stdu", "--human-readable" }; + char* argv2[] = { "stdu", "-h" }; + Result res1 = parse_config(argc, argv1); + Result res2 = parse_config(argc, argv2); + Config* conf1 = (Config*) res1.result; + Config* conf2 = (Config*) res2.result; - mt_assert_eq(res.success, true); - mt_assert_eq(conf->human_readable, true); - free(conf); + mt_assert_eq(res1.success, true); + mt_assert_eq(res2.success, true); + mt_assert_eq(conf1->human_readable, true); + mt_assert_eq(conf2->human_readable, true); + free(conf1); + free(conf2); return 0; } char* test_multioption_parsing() { int argc = 3; - char* argv[] = { "stdu", "-mh?p", "3"}; + char* argv[] = { "stdu", "-mho?p", "3"}; Result res = parse_config(argc, argv); Config* conf = (Config*) res.result; mt_assert_eq(res.success, true); mt_assert_eq(conf->help, true); mt_assert_eq(conf->human_readable, true); mt_assert_eq(conf->multiline, true); + mt_assert_eq(conf->forward, true); mt_assert_eq(conf->precision, 3); free(conf); @@ -275,7 +327,9 @@ char* test_multioption_parsing() { void parsing_tests() { mt_run_test(test_default_config); - mt_run_test(test_precision_parsing); + mt_run_test(test_forward_parsing); mt_run_test(test_human_readability_parsing); + mt_run_test(test_help_parsing); mt_run_test(test_multioption_parsing); + mt_run_test(test_precision_parsing); } diff --git a/config-parser.h b/config-parser.h index 3446826..a2988f0 100644 --- a/config-parser.h +++ b/config-parser.h @@ -1,5 +1,6 @@ struct Config { + bool forward; bool human_readable; bool help; bool multiline; @@ -1,16 +1,17 @@ -.Dd 2024-04-14 +.Dd 2024-05-31 .Dt STDU 1 .Sh NAME .Nm stdu .Nd monitor amount of data read from stdin .Sh SYNOPSIS .Nm stdu +.Op Fl Fl forward .Op Fl Fl help .Op Fl Fl human-readable .Op Fl Fl multiline .Op Fl Fl precision Ar n .Nm stdu -.Op Fl hm? +.Op Fl hmo? .Op Fl p Ar n .Sh DESCRIPTION .Nm @@ -23,6 +24,9 @@ in chunks) if \fB--precision\fR or \fB--human-readable\fR aren't specified, so specifying them is recommended. .Sh OPTIONS .Bl -tag -width 3n +.It Fl Fl forward | Fl o +Writes data read from STDIN to STDOUT and prints amount of read data +to STDERR instead of STDOUT. .It Fl Fl help | Fl ? Displays a help message. .It Fl Fl human-readable | Fl h @@ -43,9 +47,27 @@ may add trailing zeroes. .Sh EXAMPLES .Nm is useful as a progress bar replacement when transmitting large files. -.Bd -literal +.Bd -literal -offset indent nc -l 1234 | tee backup.tar.gz | stdu -p3 -h .Ed +.Bd -literal -offset indent +cat void-live-x86_64-musl-base.iso | stdu -ho > /dev/sdb1 +.Ed +.Sh CAVEATS +.Bd -literal -offset indent +cat void-live-x86_64-musl-base.iso | sudo tee /dev/sdb1 | stdu -p3 +.Ed + +Is not very informative because +.Nm +probably reads the data faster from +.Xr tee 1 +than /dev/sdb1 does. This is why +.Ar forward +has been implemented. .Sh "SEE ALSO" +.Xr dd 1 .Xr du 1 +.Xr progress 1 +.Xr pv 1 @@ -27,6 +27,8 @@ int main (int argc, char* argv[]) { Config* conf = (Config*) res.result; + FILE* progress_destination = conf->forward ? stderr : stdout; + if (conf->help) { printf( "Usage: stdu [-hm?] [-p n]\n\ @@ -34,6 +36,7 @@ Print amount of data piped to stdin.\n\ --help | -?: print this help message\n\ --human-readable | -h: output in a human readable format\n\ --multiline | -m: output with line breaks\n\ +--forward | -o: forward STDIN to STDOUT and print amount of transferred data to STDERR\n\ --precision n | -p n | -pn: output with n significant digits\n" ); return 0; @@ -89,12 +92,17 @@ Print amount of data piped to stdin.\n\ conf->precision ); if (res < 0) { - printf("\r%llu \ + fprintf( + progress_destination, + "\r%llu \ (error when getting prefix)%s", - bytes_read, endl); + bytes_read, + endl + ); continue; } - printf( + fprintf( + progress_destination, "\r%sB%*s", stdout_buffer, int_max(previous_line_strlen - res, 0), @@ -109,11 +117,16 @@ Print amount of data piped to stdin.\n\ bytes_read ); if (res < 0) { - printf("\r%llu \ + fprintf( + progress_destination, + "\r%llu \ (error when getting prefix)%s", - bytes_read, endl); + bytes_read, + endl + ); } - printf( + fprintf( + progress_destination, "\r%sB%*s", stdout_buffer, int_max(previous_line_strlen - res, 0), @@ -122,9 +135,14 @@ Print amount of data piped to stdin.\n\ previous_line_strlen = int_max(res, previous_line_strlen); } else { - printf("\r%llu%s", bytes_read, endl); + fprintf( + progress_destination, + "\r%llu%s", + bytes_read, + endl + ); } - if (fflush(stdout) == EOF) { + if (fflush(progress_destination) == EOF) { printf("\n"); perror("error during fflush"); return 1; @@ -148,6 +166,11 @@ Print amount of data piped to stdin.\n\ } bytes_read += new_read_bytes; + /* writing */ + if (conf->forward) { + printf("%s", buf); + } + /* resizing buffer and blocksize to read as much as possible * at once */ |