diff options
-rw-r--r-- | doc/tar.texi | 25 | ||||
m--------- | paxutils | 0 | ||||
-rw-r--r-- | src/checkpoint.c | 57 | ||||
-rw-r--r-- | src/common.h | 2 | ||||
-rw-r--r-- | src/tar.c | 25 | ||||
-rw-r--r-- | tests/dirrem01.at | 5 | ||||
-rw-r--r-- | tests/dirrem02.at | 5 | ||||
-rw-r--r-- | tests/filerem01.at | 7 | ||||
-rw-r--r-- | tests/filerem02.at | 7 | ||||
-rw-r--r-- | tests/grow.at | 4 | ||||
-rw-r--r-- | tests/sptrcreat.at | 10 | ||||
-rw-r--r-- | tests/sptrdiff00.at | 5 | ||||
-rw-r--r-- | tests/sptrdiff01.at | 5 | ||||
-rw-r--r-- | tests/truncate.at | 10 |
14 files changed, 110 insertions, 57 deletions
diff --git a/doc/tar.texi b/doc/tar.texi index 1362216c..a81851b3 100644 --- a/doc/tar.texi +++ b/doc/tar.texi @@ -2553,6 +2553,12 @@ Wait for @var{time} seconds. @item ttyout=@var{string} Output @var{string} on the current console (@file{/dev/tty}). + +@item totals +Print statistics (see @pxref{totals}). + +@item wait=@var{signo} +Wait for signal @var{signo}. @end table Several @option{--checkpoint-action} options can be specified. The @@ -4452,6 +4458,25 @@ checkpoint: $ @kbd{tar -c --checkpoint=1000 --checkpoint-action=sleep=30} @end smallexample +@anchor{checkpoint wait} +@cindex @code{wait}, checkpoint action +The @code{wait=@var{signo}} action stops further execution until the +signal @var{signo} is delivered. Valid values for @var{signo} are: +@code{SIGHUP}, @code{SIGQUIT}, @code{SIGINT}, @code{SIGUSR1} and +@code{SIGUSR2}. The @samp{SIG} prefix is optional. For example: + +@example +$ @kbd{tar -c -f arc --checkpoint=1000 --checkpoint-action wait=USR1 .} +@end example + +In this example, @GNUTAR{} will stop archivation at each 1000th +checkpoint. wait until the @samp{SIGUSR1} signal is delivered, +and resume processing. + +This action is used by the @command{genfile} utility to perform +modifications on the input files upon hitting certain checkpoints +(@pxref{Exec Mode, genfile}). + @anchor{checkpoint exec} @cindex @code{exec}, checkpoint action Finally, the @code{exec} action executes a given external command. diff --git a/paxutils b/paxutils -Subproject 4ef7f9ab13bcf8483050c932110c88f7ae9c75a +Subproject 56939847bfa9dbfacb7aebd26f48ea8a64dd8b1 diff --git a/src/checkpoint.c b/src/checkpoint.c index 4c86b526..a8dc64a0 100644 --- a/src/checkpoint.c +++ b/src/checkpoint.c @@ -1,6 +1,6 @@ /* Checkpoint management for tar. - Copyright 2007, 2013-2014, 2016-2017 Free Software Foundation, Inc. + Copyright 2007, 2013-2014, 2016-2018 Free Software Foundation, Inc. This file is part of GNU tar. @@ -23,6 +23,7 @@ #include <sys/ioctl.h> #include <termios.h> #include "fprintftime.h" +#include <signal.h> enum checkpoint_opcode { @@ -32,7 +33,8 @@ enum checkpoint_opcode cop_ttyout, cop_sleep, cop_exec, - cop_totals + cop_totals, + cop_wait }; struct checkpoint_action @@ -43,6 +45,7 @@ struct checkpoint_action { time_t time; char *command; + int signal; } v; }; @@ -52,6 +55,16 @@ static unsigned checkpoint; /* List of checkpoint actions */ static struct checkpoint_action *checkpoint_action, *checkpoint_action_tail; +/* State of the checkpoint system */ +enum { + CHKP_INIT, /* Needs initialization */ + CHKP_COMPILE, /* Actions are being compiled */ + CHKP_RUN /* Actions are being run */ +}; +static int checkpoint_state; +/* Blocked signals */ +static sigset_t sigs; + static struct checkpoint_action * alloc_action (enum checkpoint_opcode opcode) { @@ -85,6 +98,12 @@ checkpoint_compile_action (const char *str) { struct checkpoint_action *act; + if (checkpoint_state == CHKP_INIT) + { + sigemptyset (&sigs); + checkpoint_state = CHKP_COMPILE; + } + if (strcmp (str, ".") == 0 || strcmp (str, "dot") == 0) alloc_action (cop_dot); else if (strcmp (str, "bell") == 0) @@ -117,6 +136,12 @@ checkpoint_compile_action (const char *str) } else if (strcmp (str, "totals") == 0) alloc_action (cop_totals); + else if (strncmp (str, "wait=", 5) == 0) + { + act = alloc_action (cop_wait); + act->v.signal = decode_signal (str + 5); + sigaddset (&sigs, act->v.signal); + } else FATAL_ERROR ((0, 0, _("%s: unknown checkpoint action"), str)); } @@ -124,15 +149,22 @@ checkpoint_compile_action (const char *str) void checkpoint_finish_compile (void) { - if (checkpoint_option) + if (checkpoint_state == CHKP_COMPILE) { - if (!checkpoint_action) - /* Provide a historical default */ - checkpoint_compile_action ("echo"); + sigprocmask (SIG_BLOCK, &sigs, NULL); + + if (checkpoint_option) + { + if (!checkpoint_action) + /* Provide a historical default */ + checkpoint_compile_action ("echo"); + } + else if (checkpoint_action) + /* Otherwise, set default checkpoint rate */ + checkpoint_option = DEFAULT_CHECKPOINT; + + checkpoint_state = CHKP_RUN; } - else if (checkpoint_action) - /* Otherwise, set default checkpoint rate */ - checkpoint_option = DEFAULT_CHECKPOINT; } static const char *checkpoint_total_format[] = { @@ -390,6 +422,13 @@ run_checkpoint_actions (bool do_write) case cop_totals: compute_duration (); print_total_stats (); + break; + + case cop_wait: + { + int n; + sigwait (&sigs, &n); + } } } } diff --git a/src/common.h b/src/common.h index 885169fb..a4f6052d 100644 --- a/src/common.h +++ b/src/common.h @@ -798,6 +798,8 @@ void set_exit_status (int val); void request_stdin (const char *option); +int decode_signal (const char *); + /* Where an option comes from: */ enum option_source { @@ -976,36 +976,37 @@ stat_on_signal (int signo) #endif } -static void -set_stat_signal (const char *name) +int +decode_signal (const char *name) { static struct sigtab { char const *name; int signo; } const sigtab[] = { - { "SIGUSR1", SIGUSR1 }, { "USR1", SIGUSR1 }, - { "SIGUSR2", SIGUSR2 }, { "USR2", SIGUSR2 }, - { "SIGHUP", SIGHUP }, { "HUP", SIGHUP }, - { "SIGINT", SIGINT }, { "INT", SIGINT }, - { "SIGQUIT", SIGQUIT }, { "QUIT", SIGQUIT } }; struct sigtab const *p; + char const *s = name; + if (strncmp (s, "SIG", 3) == 0) + s += 3; for (p = sigtab; p < sigtab + sizeof (sigtab) / sizeof (sigtab[0]); p++) - if (strcmp (p->name, name) == 0) - { - stat_on_signal (p->signo); - return; - } + if (strcmp (p->name, s) == 0) + return p->signo; FATAL_ERROR ((0, 0, _("Unknown signal name: %s"), name)); } +static void +set_stat_signal (const char *name) +{ + stat_on_signal (decode_signal (name)); +} + struct textual_date { diff --git a/tests/dirrem01.at b/tests/dirrem01.at index dabc206f..b82be02b 100644 --- a/tests/dirrem01.at +++ b/tests/dirrem01.at @@ -1,7 +1,7 @@ # Process this file with autom4te to create testsuite. -*- Autotest -*- # Test suite for GNU tar. -# Copyright 2017 Free Software Foundation, Inc. +# Copyright 2017-2018 Free Software Foundation, Inc. # This file is part of GNU tar. @@ -47,8 +47,7 @@ gnu) CPT=3;; esac genfile --run --checkpoint=$CPT --unlink dir/sub/file2 --unlink dir/sub -- \ - tar --blocking-factor=1 --checkpoint=1 --checkpoint-action='echo' \ - --checkpoint-action='sleep=1' -c -f archive.tar \ + tar --blocking-factor=1 -c -f archive.tar \ --listed-incremental db -v dir >/dev/null ], [1], diff --git a/tests/dirrem02.at b/tests/dirrem02.at index 924454f1..c28989e6 100644 --- a/tests/dirrem02.at +++ b/tests/dirrem02.at @@ -1,7 +1,7 @@ # Process this file with autom4te to create testsuite. -*- Autotest -*- # Test suite for GNU tar. -# Copyright 2017 Free Software Foundation, Inc. +# Copyright 2017-2018 Free Software Foundation, Inc. # This file is part of GNU tar. @@ -44,8 +44,7 @@ gnu) CPT=3;; esac genfile --run --checkpoint=$CPT --unlink dir/sub/file2 --unlink dir/sub -- \ - tar --blocking-factor=1 --checkpoint=1 --checkpoint-action='echo' \ - --checkpoint-action='sleep=1' -c -f archive.tar \ + tar --blocking-factor=1 -c -f archive.tar \ --listed-incremental db -v dir dir/sub >/dev/null ], [2], diff --git a/tests/filerem01.at b/tests/filerem01.at index bf020538..0440277d 100644 --- a/tests/filerem01.at +++ b/tests/filerem01.at @@ -1,7 +1,7 @@ # Process this file with autom4te to create testsuite. -*- Autotest -*- # Test suite for GNU tar. -# Copyright 2009, 2013-2014, 2016-2017 Free Software Foundation, Inc. +# Copyright 2009, 2013-2014, 2016-2018 Free Software Foundation, Inc. # This file is part of GNU tar. @@ -33,7 +33,7 @@ # http://lists.gnu.org/archive/html/bug-tar/2009-03/msg00000.html # -AT_SETUP([file removed as we read it (ca. 22 seconds)]) +AT_SETUP([file removed as we read it]) AT_KEYWORDS([create incremental listed filechange filerem filerem01]) AT_TAR_CHECK([ @@ -43,8 +43,7 @@ genfile --file dir/file1 genfile --file dir/sub/file2 genfile --run --checkpoint=3 --unlink dir/file1 -- \ - tar --blocking-factor=1 --checkpoint=1 --checkpoint-action='sleep=1' \ - --checkpoint-action='echo' -c -f archive.tar \ + tar --blocking-factor=1 -c -f archive.tar \ --listed-incremental db -v dir >/dev/null ], [1], diff --git a/tests/filerem02.at b/tests/filerem02.at index 5e6d1bef..34625d6d 100644 --- a/tests/filerem02.at +++ b/tests/filerem02.at @@ -1,7 +1,7 @@ # Process this file with autom4te to create testsuite. -*- Autotest -*- # Test suite for GNU tar. -# Copyright 2009, 2013-2014, 2016-2017 Free Software Foundation, Inc. +# Copyright 2009, 2013-2014, 2016-2018 Free Software Foundation, Inc. # This file is part of GNU tar. @@ -23,7 +23,7 @@ # file or directory disappears that is explicitly mentioned # in the command line. -AT_SETUP([toplevel file removed (ca. 24 seconds)]) +AT_SETUP([toplevel file removed]) AT_KEYWORDS([create incremental listed filechange filerem filerem02]) AT_TAR_CHECK([ @@ -35,8 +35,7 @@ mkdir dir2 genfile --file dir2/file1 genfile --run --checkpoint=3 --exec 'rm -rf dir2' -- \ - tar --blocking-factor=1 --checkpoint=1 --checkpoint-action='sleep=1' \ - --checkpoint-action='echo' -c -f archive.tar \ + tar --blocking-factor=1 -c -f archive.tar \ --listed-incremental db -v --warning=no-new-dir dir dir2 >/dev/null ], [2], diff --git a/tests/grow.at b/tests/grow.at index b04250db..a4a047bf 100644 --- a/tests/grow.at +++ b/tests/grow.at @@ -1,7 +1,7 @@ # Process this file with autom4te to create testsuite. -*- Autotest -*- # Test suite for GNU tar. -# Copyright 2006-2007, 2013-2014, 2016-2017 Free Software Foundation, +# Copyright 2006-2007, 2013-2014, 2016-2018 Free Software Foundation, # Inc. # This file is part of GNU tar. @@ -28,7 +28,7 @@ AT_KEYWORDS([grow filechange]) AT_TAR_CHECK([ genfile --file foo --length 50000k genfile --file baz -genfile --run --checkpoint 10 --length 1024 --append foo -- tar --checkpoint -vcf bar foo baz +genfile --run=10 --checkpoint 10 --length 1024 --append foo -- tar -vcf bar foo baz ], [1], [foo diff --git a/tests/sptrcreat.at b/tests/sptrcreat.at index 8e28f0e0..cfc9e3b0 100644 --- a/tests/sptrcreat.at +++ b/tests/sptrcreat.at @@ -38,21 +38,17 @@ genfile --sparse --block-size=1024 --file foo \ 0 ABCDEFGHIJ 1M ABCDEFGHIJ 10M ABCDEFGHIJ 200M ABCDEFGHIJ genfile --file baz genfile --run --checkpoint 3 --length 200m --truncate foo -- \ - tar --checkpoint=1 \ - --checkpoint-action=echo \ - --checkpoint-action=sleep=1 \ - --sparse -vcf bar foo baz + tar --sparse -vcf bar foo baz echo Exit status: $? echo separator genfile --file foo --seek 200m --length 11575296 --pattern=zeros -tar dvf bar], -[1], +tar dvf bar | sed '/foo: Mod time differs/d'], +[0], [foo baz Exit status: 1 separator foo -foo: Mod time differs baz ], [tar: foo: File shrank by 11575296 bytes; padding with zeros diff --git a/tests/sptrdiff00.at b/tests/sptrdiff00.at index c4105610..4a8cdc7b 100644 --- a/tests/sptrdiff00.at +++ b/tests/sptrdiff00.at @@ -35,10 +35,7 @@ echo creating tar --sparse -vcf bar foo baz echo comparing genfile --run --checkpoint 3 --length 200m --truncate foo -- \ - tar --checkpoint=1 \ - --checkpoint-action=echo='Write checkpoint %u' \ - --checkpoint-action=sleep=1 \ - --sparse -vdf bar + tar --sparse -vdf bar ], [1], [creating diff --git a/tests/sptrdiff01.at b/tests/sptrdiff01.at index 2da22679..53c716b7 100644 --- a/tests/sptrdiff01.at +++ b/tests/sptrdiff01.at @@ -35,10 +35,7 @@ echo creating tar --sparse -vcf bar foo baz echo comparing genfile --run --checkpoint 5 --length 221278210 --truncate foo -- \ - tar --checkpoint=1 \ - --checkpoint-action=echo='Write checkpoint %u' \ - --checkpoint-action=sleep=1 \ - --sparse -vdf bar + tar --sparse -vdf bar ], [1], [creating diff --git a/tests/truncate.at b/tests/truncate.at index a743e4b7..7bd1443d 100644 --- a/tests/truncate.at +++ b/tests/truncate.at @@ -1,7 +1,7 @@ # Process this file with autom4te to create testsuite. -*- Autotest -*- # Test suite for GNU tar. -# Copyright 2005, 2007, 2013-2014, 2016-2017 Free Software Foundation, +# Copyright 2005, 2007, 2013-2014, 2016-2018 Free Software Foundation, # Inc. # This file is part of GNU tar. @@ -33,18 +33,18 @@ AT_KEYWORDS([truncate filechange]) AT_TAR_CHECK([ genfile --file foo --length 200k genfile --file baz -genfile --run --checkpoint 10 --length 195k --truncate foo -- tar --checkpoint --checkpoint-action=echo --checkpoint-action=sleep=1 -vcf bar foo baz +genfile --run --checkpoint 10 --length 195k --truncate foo -- \ + tar -vcf bar foo baz echo Exit status: $? echo separator genfile --file foo --seek 195k --length 5k --pattern=zeros -tar dvf bar], -[1], +tar dvf bar|sed '/foo: Mod time differs/d'], +[0], [foo baz Exit status: 1 separator foo -foo: Mod time differs baz ], [tar: foo: File shrank by 5120 bytes; padding with zeros |