From: Ian Jackson Date: Thu, 21 Feb 2013 18:35:54 +0000 (+0000) Subject: New --progress option X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=8aef45fa67f12cb231aa431595ab0408fc6a8b50;p=vbig.git New --progress option This saves on boredom. Signed-off-by: Ian Jackson --- diff --git a/vbig.1 b/vbig.1 index 7d59b0a..a057ea9 100644 --- a/vbig.1 +++ b/vbig.1 @@ -35,7 +35,7 @@ specified file or device until the device is full, read the data back to check that everything written was properly stored, and report the device's size. Ideally, if you have privilege to do so, you would also specify \fB-f\fR (to flush the operating system disk -cache between the write and read). +cache between the write and read). Also you probably want \fB-p\fR. .PP \fBPATH\fR can refer to an ordinary file on a mounted file system, which vbig will create or truncate as necessary, or a block device. @@ -87,6 +87,9 @@ by the equivalent \fB--create\fR call. Flush cached data after creating the file or before verifying it. On some platforms, only root can use this option. .TP +.B --progress\fR, \fB-p +Show the progress (in bytes) on stdout. +.TP .B --entire\fR, \fB-e When writing, keep going until the device is full (No space left on device). When reading, keep going until the end of the file diff --git a/vbig.cc b/vbig.cc index d2cc1a2..c0f6cb6 100644 --- a/vbig.cc +++ b/vbig.cc @@ -41,6 +41,7 @@ const struct option opts[] = { { "create", no_argument, 0, 'c' }, { "flush", no_argument, 0, 'f' }, { "entire", no_argument, 0, 'e' }, + { "progress", no_argument, 0, 'p' }, { "help", no_argument, 0, 'h' }, { "version", no_argument, 0, 'V' }, { 0, 0, 0, 0 }, @@ -61,6 +62,7 @@ static void help(void) { " --create, -c Create PATH with psuedo-random contents\n" " --flush, -f Flush cache\n" " --entire, -e Write until full; read until EOF\n" + " --progress, -p Show progress as we go\n" " --help, -h Display usage message\n" " --version, -V Display version string\n"); } @@ -72,9 +74,12 @@ enum mode_type { BOTH }; +static void clearprogress(); + // Report an error and exit static void fatal(int errno_value, const char *fmt, ...) { va_list ap; + clearprogress(); fprintf(stderr, "ERROR: "); va_start(ap, fmt); vfprintf(stderr, fmt, ap); @@ -123,13 +128,14 @@ static const char *seedpath; static const char *path; static bool entireopt = false; static bool flush = false; +static bool progress = false; static long long size; int main(int argc, char **argv) { mode_type mode = BOTH; int n; char *ep; - while((n = getopt_long(argc, argv, "+s:S:L:vcefhV", opts, 0)) >= 0) { + while((n = getopt_long(argc, argv, "+s:S:L:vcepfhV", opts, 0)) >= 0) { switch(n) { case 's': seed = optarg; seedlen = strlen(optarg); break; case 'S': seedpath = optarg; break; @@ -141,6 +147,7 @@ int main(int argc, char **argv) { case 'v': mode = VERIFY; break; case 'c': mode = CREATE; break; case 'e': entireopt = true; break; + case 'p': progress = true; break; case 'f': flush = true; break; case 'h': help(); exit(0); case 'V': puts(VERSION); exit(0); @@ -224,6 +231,37 @@ int main(int argc, char **argv) { return 0; } +static void flushstdout() { + if(ferror(stdout) || fflush(stdout)) + fatal(errno, "flush stdout"); +} + +static void clearprogress() { + if (!progress) return; + printf(" %-10s %*s \r", "", sizeof(long long)*4, ""); + flushstdout(); +} + +static void showprogress(long long amount, const char *show) { + if (!progress) return; + + static int counter; + if (counter++ < 1000) return; + counter = 0; + + int triples = sizeof(amount); + char rawbuf[triples*3 + 1]; + char outbuf[triples*4 + 1]; + snprintf(rawbuf, sizeof(rawbuf), "% *lld", sizeof(rawbuf)-1, amount); + for (int i=0; i> 20, done >> 30, show); - if(ferror(stdout) || fflush(stdout)) - fatal(errno, "flush stdout"); + flushstdout(); } return done; }