From 717a07e208ced8ab10c59e70eada67c1a2e8afa2 Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Wed, 22 Jan 2014 07:28:02 +0200 Subject: [PATCH] Improve checkpoint interface. * src/buffer.c (format_total_stats): The format arg is const All uses updated. (default_total_format): const * src/checkpoint.c (tty, tty_cleanup): New static. (format_checkpoint_string): New "canned" format %c (checkpoint_finish): New function. * src/common.h (checkpoint_finish): New proto. * src/tar.c (main): Call checkpoint_finish.` --- src/buffer.c | 4 +-- src/checkpoint.c | 76 ++++++++++++++++++++++++++++++++++++++---------- src/common.h | 3 +- src/tar.c | 2 ++ 4 files changed, 66 insertions(+), 19 deletions(-) diff --git a/src/buffer.c b/src/buffer.c index 0f5c76e..648b6ba 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -514,7 +514,7 @@ print_stats (FILE *fp, const char *text, tarlong numbytes) from the archive), EOL is a delimiter to add at the end of the output line. */ int -format_total_stats (FILE *fp, char **formats, int eor, int eol) +format_total_stats (FILE *fp, const char **formats, int eor, int eol) { int n; @@ -569,7 +569,7 @@ format_total_stats (FILE *fp, char **formats, int eor, int eol) return n; } -char *default_total_format[] = { +const char *default_total_format[] = { N_("Total bytes read"), /* Amanda 2.4.1p1 looks for "Total bytes written: [0-9][0-9]*". */ N_("Total bytes written"), diff --git a/src/checkpoint.c b/src/checkpoint.c index 7637452..3c3ca78 100644 --- a/src/checkpoint.c +++ b/src/checkpoint.c @@ -134,14 +134,14 @@ checkpoint_finish_compile (void) checkpoint_option = DEFAULT_CHECKPOINT; } -static char *checkpoint_total_format[] = { +static const char *checkpoint_total_format[] = { "R", "W", "D" }; static int -getwidth(FILE *fp) +getwidth (FILE *fp) { struct winsize ws; @@ -183,16 +183,19 @@ getarg (const char *input, const char ** endp, char **argbuf, size_t *arglen) return NULL; } +static int tty_cleanup; -static void -format_checkpoint_string (FILE *fp, const char *input, bool do_write, +static const char *def_format = "%s: %t: %T%*\r"; + +static int +format_checkpoint_string (FILE *fp, size_t len, + const char *input, bool do_write, unsigned cpn) { const char *opstr = do_write ? gettext ("write") : gettext ("read"); char uintbuf[UINTMAX_STRSIZE_BOUND]; char *cps = STRINGIFY_BIGINT (cpn, uintbuf); const char *ip; - size_t len = 0; static char *argbuf = NULL; static size_t arglen = 0; @@ -231,6 +234,11 @@ format_checkpoint_string (FILE *fp, const char *input, bool do_write, } switch (*ip) { + case 'c': + len += format_checkpoint_string (fp, len, def_format, do_write, + cpn); + break; + case 'u': fputs (cps, fp); len += strlen (cps); @@ -254,7 +262,7 @@ format_checkpoint_string (FILE *fp, const char *input, bool do_write, { struct timeval tv; struct tm *tm; - char *fmt = arg ? arg : "%c"; + const char *fmt = arg ? arg : "%c"; gettimeofday (&tv, NULL); tm = localtime (&tv.tv_sec); @@ -282,19 +290,24 @@ format_checkpoint_string (FILE *fp, const char *input, bool do_write, { fputc (*ip, fp); if (*ip == '\r') - len = 0; + { + len = 0; + tty_cleanup = 1; + } else len++; } } fflush (fp); + return len; } +static FILE *tty = NULL; + static void run_checkpoint_actions (bool do_write) { struct checkpoint_action *p; - FILE *tty = NULL; for (p = checkpoint_action; p; p = p->next) { @@ -316,20 +329,20 @@ run_checkpoint_actions (bool do_write) break; case cop_echo: - fprintf (stderr, "%s: ", program_name); - format_checkpoint_string (stderr, p->v.command, do_write, checkpoint); - fputc ('\n', stderr); + { + int n = fprintf (stderr, "%s: ", program_name); + format_checkpoint_string (stderr, n, p->v.command, do_write, + checkpoint); + fputc ('\n', stderr); + } break; case cop_ttyout: if (!tty) tty = fopen ("/dev/tty", "w"); if (tty) - { - format_checkpoint_string (tty, p->v.command, do_write, - checkpoint); - fflush (tty); - } + format_checkpoint_string (tty, 0, p->v.command, do_write, + checkpoint); break; case cop_sleep: @@ -347,6 +360,30 @@ run_checkpoint_actions (bool do_write) print_total_stats (); } } +} + +static void +finish_checkpoint_actions (void) +{ + struct checkpoint_action *p; + + for (p = checkpoint_action; p; p = p->next) + { + switch (p->opcode) + { + case cop_ttyout: + if (tty && tty_cleanup) + { + int w = getwidth (tty); + while (w--) + fputc (' ', tty); + fputc ('\r', tty); + } + break; + default: + /* nothing */; + } + } if (tty) fclose (tty); } @@ -357,3 +394,10 @@ checkpoint_run (bool do_write) if (checkpoint_option && !(++checkpoint % checkpoint_option)) run_checkpoint_actions (do_write); } + +void +checkpoint_finish (void) +{ + if (checkpoint_option) + finish_checkpoint_actions (); +} diff --git a/src/common.h b/src/common.h index 28d6d61..81e21fa 100644 --- a/src/common.h +++ b/src/common.h @@ -447,7 +447,7 @@ void set_start_time (void); #define TF_READ 0 #define TF_WRITE 1 #define TF_DELETED 2 -int format_total_stats (FILE *fp, char **formats, int eor, int eol); +int format_total_stats (FILE *fp, const char **formats, int eor, int eol); void print_total_stats (void); void mv_begin_write (const char *file_name, off_t totsize, off_t sizeleft); @@ -861,6 +861,7 @@ void set_compression_program_by_suffix (const char *name, const char *defprog); void checkpoint_compile_action (const char *str); void checkpoint_finish_compile (void); void checkpoint_run (bool do_write); +void checkpoint_finish (void); /* Module warning.c */ #define WARN_ALONE_ZERO_BLOCK 0x00000001 diff --git a/src/tar.c b/src/tar.c index 6fb9277..59cde36 100644 --- a/src/tar.c +++ b/src/tar.c @@ -2696,6 +2696,8 @@ main (int argc, char **argv) test_archive_label (); } + checkpoint_finish (); + if (totals_option) print_total_stats (); -- 2.45.2