mirror of
https://https.git.savannah.gnu.org/git/tar.git
synced 2026-01-26 16:09:29 +00:00
checkpoint actions: further improvements.
* NEWS: Update. * doc/tar.texi: Update. * src/buffer.c (print_stats): Avoid use of additional string buffer. Allow for text to be NULL. Call gettext if it is not. (format_total_stats): Don't use gettext when calling print_stats. * src/checkpoint.c (def_format): Change default format. (format_checkpoint_string): Implement optional arguments for T conversion. (finish_checkpoint_actions): Rename to checkpoint_flush_actions, make extern. All uses changed. * src/common.h (checkpoint_flush_actions): New proto. * src/tar.c (main): Set error_hook
This commit is contained in:
parent
717a07e208
commit
eb7e2aa933
21
NEWS
21
NEWS
@ -1,4 +1,4 @@
|
||||
GNU tar NEWS - User visible changes. 2014-01-21
|
||||
GNU tar NEWS - User visible changes. 2014-01-22
|
||||
Please send GNU tar bug reports to <bug-tar@gnu.org>
|
||||
|
||||
|
||||
@ -11,14 +11,19 @@ total number of bytes transferred at each checkpoint.
|
||||
|
||||
* Extended checkpoint format specification.
|
||||
|
||||
New conversion specifiers are implemented:
|
||||
New conversion specifiers are implemented. Some of them take
|
||||
optional arguments, supplied in curly braces between the percent
|
||||
sign and the specifier letter.
|
||||
|
||||
%d - output number of seconds since tar started
|
||||
%T - output I/O totals
|
||||
%{FMT}t - output current local time using FMT as strftime(3) format
|
||||
If {FMT} is omitted, use %c
|
||||
%{N}* - pad output with spaces to the Nth column, or to the
|
||||
current screen width, if {N} is not given.
|
||||
%d - output number of seconds since tar started
|
||||
%{r,w,d}T - output I/O totals; optional arguments supply prefixes
|
||||
to be used before number of bytes read, written and
|
||||
deleted, correspondingly.
|
||||
%{FMT}t - output current local time using FMT as strftime(3) format
|
||||
If {FMT} is omitted, use %c
|
||||
%{N}* - pad output with spaces to the Nth column, or to the
|
||||
current screen width, if {N} is not given.
|
||||
%c - a shortcut for "%{%Y-%m-%d %H:%M:%S}t: %ds, %{read,wrote}T%*\r"
|
||||
|
||||
|
||||
version 1.27.1 - Sergey Poznyakoff, 2013-11-17
|
||||
|
||||
24
doc/tar.texi
24
doc/tar.texi
@ -3975,7 +3975,10 @@ tar: Hit write checkpoint #20
|
||||
tar: Hit write checkpoint #30
|
||||
@end smallexample
|
||||
|
||||
The complete list of available format specifiers follows:
|
||||
The complete list of available format specifiers follows. Some of
|
||||
them can take optional arguments. These arguments, if given, are
|
||||
supplied in curly braces between the percent sign and the specifier
|
||||
letter.
|
||||
|
||||
@table @samp
|
||||
@item %s
|
||||
@ -3984,17 +3987,18 @@ Print type of the checkpoint (@samp{write} or @samp{read}).
|
||||
@item %u
|
||||
Print number of the checkpoint.
|
||||
|
||||
@item %T
|
||||
@item %@{r,w,d@}T
|
||||
Print number of bytes transferred so far and approximate transfer
|
||||
speed. The number is preceded by @samp{W:}, when writing and by
|
||||
@samp{R:} when reading. If @command{tar} is performing delete
|
||||
operation (@pxref{delete}), three numbers are printed: number of bytes
|
||||
read, written and deleted, each of them prefixed by @samp{R:},
|
||||
@samp{W:} and @samp{D:} correspondingy. For example:
|
||||
speed. Optional arguments supply prefixes to be used before number
|
||||
of bytes read, written and deleted, correspondingly. If absent,
|
||||
they default to @samp{R}. @samp{W}, @samp{D}. Any or all of them can
|
||||
be omitted, so, that e.g. @samp{%@{@}T} means to print corresponding
|
||||
statistics without any prefixes. Any surplus arguments, if present,
|
||||
are silently ignored.
|
||||
|
||||
@example
|
||||
$ @kbd{tar --delete -f f.tar --checkpoint-action=echo="#%u: %T" main.c}
|
||||
tar: #1: R: 0 (0B, ?/s),W: 0 (0B, ?/s),D: 0
|
||||
tar: #1: R: 0 (0B, 0B/s),W: 0 (0B, 0B/s),D: 0
|
||||
tar: #2: R: 10240 (10KiB, 19MiB/s),W: 0 (0B, 0B/s),D: 10240
|
||||
@end example
|
||||
|
||||
@ -4012,6 +4016,10 @@ for the current locale.
|
||||
Pad output with spaces to the @var{n}th column. If the
|
||||
@samp{@{@var{n}@}} part is omitted, the current screen width
|
||||
is assumed.
|
||||
|
||||
@item %@var{c}
|
||||
This is a shortcut for @samp{%@{%Y-%m-%d %H:%M:%S@}t: %ds, %@{read,wrote@}T%*\r},
|
||||
intended mainly for use with @samp{ttyout} action (see below).
|
||||
@end table
|
||||
|
||||
Aside from format expansion, the message string is subject to
|
||||
|
||||
33
src/buffer.c
33
src/buffer.c
@ -492,20 +492,20 @@ open_compressed_archive (void)
|
||||
static int
|
||||
print_stats (FILE *fp, const char *text, tarlong numbytes)
|
||||
{
|
||||
char bytes[sizeof (tarlong) * CHAR_BIT];
|
||||
char abbr[LONGEST_HUMAN_READABLE + 1];
|
||||
char rate[LONGEST_HUMAN_READABLE + 1];
|
||||
|
||||
int n = 0;
|
||||
|
||||
int human_opts = human_autoscale | human_base_1024 | human_SI | human_B;
|
||||
|
||||
sprintf (bytes, TARLONG_FORMAT, numbytes);
|
||||
|
||||
return fprintf (fp, "%s: %s (%s, %s/s)",
|
||||
text, bytes,
|
||||
human_readable (numbytes, abbr, human_opts, 1, 1),
|
||||
(0 < duration && numbytes / duration < (uintmax_t) -1
|
||||
? human_readable (numbytes / duration, rate, human_opts, 1, 1)
|
||||
: "?"));
|
||||
if (text && text[0])
|
||||
n += fprintf (fp, "%s: ", gettext (text));
|
||||
return n + fprintf (fp, TARLONG_FORMAT " (%s, %s/s)",
|
||||
numbytes,
|
||||
human_readable (numbytes, abbr, human_opts, 1, 1),
|
||||
(0 < duration && numbytes / duration < (uintmax_t) -1
|
||||
? human_readable (numbytes / duration, rate, human_opts, 1, 1)
|
||||
: "?"));
|
||||
}
|
||||
|
||||
/* Format totals to file FP. FORMATS is an array of strings to output
|
||||
@ -524,27 +524,28 @@ format_total_stats (FILE *fp, const char **formats, int eor, int eol)
|
||||
case CAT_SUBCOMMAND:
|
||||
case UPDATE_SUBCOMMAND:
|
||||
case APPEND_SUBCOMMAND:
|
||||
n = print_stats (fp, _(formats[TF_WRITE]),
|
||||
n = print_stats (fp, formats[TF_WRITE],
|
||||
prev_written + bytes_written);
|
||||
break;
|
||||
|
||||
case DELETE_SUBCOMMAND:
|
||||
{
|
||||
char buf[UINTMAX_STRSIZE_BOUND];
|
||||
n = print_stats (fp, _(formats[TF_READ]),
|
||||
n = print_stats (fp, formats[TF_READ],
|
||||
records_read * record_size);
|
||||
|
||||
fputc (eor, fp);
|
||||
n++;
|
||||
|
||||
n += print_stats (fp, _(formats[TF_WRITE]),
|
||||
n += print_stats (fp, formats[TF_WRITE],
|
||||
prev_written + bytes_written);
|
||||
|
||||
fputc (eor, fp);
|
||||
n++;
|
||||
|
||||
n += fprintf (fp, "%s: %s",
|
||||
_(formats[TF_DELETED]),
|
||||
|
||||
if (formats[TF_DELETED] && formats[TF_DELETED][0])
|
||||
n += fprintf (fp, "%s: ", gettext (formats[TF_DELETED]));
|
||||
n += fprintf (fp, "%s",
|
||||
STRINGIFY_BIGINT ((records_read - records_skipped)
|
||||
* record_size
|
||||
- (prev_written + bytes_written), buf));
|
||||
|
||||
@ -185,7 +185,8 @@ getarg (const char *input, const char ** endp, char **argbuf, size_t *arglen)
|
||||
|
||||
static int tty_cleanup;
|
||||
|
||||
static const char *def_format = "%s: %t: %T%*\r";
|
||||
static const char *def_format =
|
||||
"%{%Y-%m-%d %H:%M:%S}t: %ds, %{read,wrote}T%*\r";
|
||||
|
||||
static int
|
||||
format_checkpoint_string (FILE *fp, size_t len,
|
||||
@ -254,8 +255,33 @@ format_checkpoint_string (FILE *fp, size_t len,
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
compute_duration ();
|
||||
len += format_total_stats (fp, checkpoint_total_format, ',', 0);
|
||||
{
|
||||
const char **fmt = checkpoint_total_format, *fmtbuf[3];
|
||||
struct wordsplit ws;
|
||||
compute_duration ();
|
||||
|
||||
if (arg)
|
||||
{
|
||||
ws.ws_delim = ",";
|
||||
if (wordsplit (arg, &ws, WRDSF_NOVAR | WRDSF_NOCMD |
|
||||
WRDSF_QUOTE | WRDSF_DELIM))
|
||||
ERROR ((0, 0, _("cannot split string '%s': %s"),
|
||||
arg, wordsplit_strerror (&ws)));
|
||||
else
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ws.ws_wordc; i++)
|
||||
fmtbuf[i] = ws.ws_wordv[i];
|
||||
for (; i < 3; i++)
|
||||
fmtbuf[i] = NULL;
|
||||
fmt = fmtbuf;
|
||||
}
|
||||
}
|
||||
len += format_total_stats (fp, fmt, ',', 0);
|
||||
if (arg)
|
||||
wordsplit_free (&ws);
|
||||
}
|
||||
break;
|
||||
|
||||
case 't':
|
||||
@ -362,11 +388,11 @@ run_checkpoint_actions (bool do_write)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
finish_checkpoint_actions (void)
|
||||
void
|
||||
checkpoint_flush_actions (void)
|
||||
{
|
||||
struct checkpoint_action *p;
|
||||
|
||||
|
||||
for (p = checkpoint_action; p; p = p->next)
|
||||
{
|
||||
switch (p->opcode)
|
||||
@ -378,14 +404,13 @@ finish_checkpoint_actions (void)
|
||||
while (w--)
|
||||
fputc (' ', tty);
|
||||
fputc ('\r', tty);
|
||||
fflush (tty);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* nothing */;
|
||||
}
|
||||
}
|
||||
if (tty)
|
||||
fclose (tty);
|
||||
}
|
||||
|
||||
void
|
||||
@ -399,5 +424,9 @@ void
|
||||
checkpoint_finish (void)
|
||||
{
|
||||
if (checkpoint_option)
|
||||
finish_checkpoint_actions ();
|
||||
{
|
||||
checkpoint_flush_actions ();
|
||||
if (tty)
|
||||
fclose (tty);
|
||||
}
|
||||
}
|
||||
|
||||
@ -862,6 +862,7 @@ void checkpoint_compile_action (const char *str);
|
||||
void checkpoint_finish_compile (void);
|
||||
void checkpoint_run (bool do_write);
|
||||
void checkpoint_finish (void);
|
||||
void checkpoint_flush_actions (void);
|
||||
|
||||
/* Module warning.c */
|
||||
#define WARN_ALONE_ZERO_BLOCK 0x00000001
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user