Obsolete the --use-compress-program by the --filter-program option (same sematics). Add new option --compress-program.
Use '--compres-program'-like API by the -Z, but also by -z, -J, --lzop and --lzma options. Use '--filter-program'-like interface by -j and --lzip. See also: <http://lists.gnu.org/archive/html/bug-tar/2013-02/msg00025.html> <http://lists.gnu.org/archive/html/bug-tar/2013-04/msg00006.html> <https://bugzilla.redhat.com/show_bug.cgi?id=759371> * src/common.h (compress_like_api): New global. * src/tar.c (argp_option): Add --compress-program and --filter-program options, obsolete --use-compress-program option. (COMPRESS_PROGRAM_OPTION): New option in enum. (tar_help_filter): Set 'compress_like_api' global for proper compressors, handle new COMPRESS_PROGRAM_OPTION. * src/system.c (sys_wait_for_child): Warn only when child process exited with 2 and uses 'compress_like_api'. * doc/tar.texi: Document all changes. * NEWS: Document. --- NEWS | 17 +++++++++++++++++ doc/tar.texi | 32 ++++++++++++++++++++++++-------- src/common.h | 3 +++ src/system.c | 12 +++++++++--- src/tar.c | 22 ++++++++++++++++++++-- 5 files changed, 73 insertions(+), 13 deletions(-) diff --git a/NEWS b/NEWS index 3108798..7bba8e6 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,23 @@ version 1.26.90 (Git) * Bug fixes +** tar now successes when the compressor "warns" by exit status 2 + +New options --filter-program and --compress-program were added. The +option --filter-program replaces the old --use-compress-program (which +is now still working, but is obsoleted and removed from manual to not +confuse users). That means that program passed as an argument to +--filter-program, apart from others requirements, must return zero +exit status if successed, otherwise failed. The --compress-program +option is similar to --filter-program, but accepts also the child's +exit value 2 as a correct (but warning) exit status. + +The default 'xz', 'gzip', 'compress', 'lzop' and 'lzma' compressors +(used by -J, -z, -Z, --lzop and --lzma options) are now by default +used by the --compress-program API; and compressors 'bzip2' and 'lzip' +(used by -j and --lzip options) are used with more "vanilla" +--filter-program API. + ** Sparse files with large data When creating a PAX-format archive, tar no longer arbitrarily restricts diff --git a/doc/tar.texi b/doc/tar.texi index 480fe89..e300b54 100644 --- a/doc/tar.texi +++ b/doc/tar.texi @@ -3412,12 +3412,13 @@ system before extracting it from the archive. @xref{Unlink First}. Enable unquoting input file or member names (default). @xref{input name quoting}. -@opsummary{use-compress-program} -@item --use-compress-program=@var{prog} +@opsummary{filter-program} +@item --filter-program=@var{prog} @itemx -I=@var{prog} Instructs @command{tar} to access the archive through @var{prog}, which is -presumed to be a compression program of some sort. @xref{gzip}. +presumed to be a compression program of some sort. This option obsoletes the +old option @option{--use-compress-program}. @xref{gzip}. @opsummary{utc} @item --utc @@ -4284,7 +4285,7 @@ supply on the command line. One of such operations is checkpointing, described above (@pxref{checkpoint exec}). Another example of this feature is the @option{-I} option, which allows you to supply the program to use for compressing or decompressing the archive -(@pxref{use-compress-program}). +(@pxref{filter-program}). Whenever such operation is requested, @command{tar} first splits the supplied command into words much like the shell does. It then treats @@ -9053,9 +9054,9 @@ suffix. The following suffixes are recognized: @item @samp{.xz} @tab @command{xz} @end multitable -@anchor{use-compress-program} -@opindex use-compress-program -@item --use-compress-program=@var{command} +@anchor{filter-program} +@opindex filter-program +@item --filter-program=@var{command} @itemx -I=@var{command} Use external compression program @var{command}. Use this option if you are not happy with the compression program associated with the suffix @@ -9076,12 +9077,15 @@ standard input and produce uncompressed data on the standard output. The latter requirement means that you must not use the @option{-d} option as a part of the @var{command} itself. + +From the @GNUTAR{} point of view, any non-zero exit value of @var{command} is +taken as a fatal error. @end table @cindex gpg, using with tar @cindex gnupg, using with tar @cindex Using encrypted archives -The @option{--use-compress-program} option, in particular, lets you +The @option{--filter-program} option, in particular, lets you implement your own filters, not necessarily dealing with compression/decompression. For example, suppose you wish to implement PGP encryption on top of compression, using @command{gpg} (@pxref{Top, @@ -9152,6 +9156,18 @@ The above is based on the following discussion: the DLT compression mode, the data will actually get bigger and one will end up with less space on the tape. @end ignore +@table @option +@anchor{compress-program} +@opindex compress-program +@item --compress-program=@var{command} +This option has exactly the same semantics as the previous +@option{--filter-program} with one exception. When the @var{command} exits with +exit status 2, this is considered like as warning - not a fatal error. This +option was created to allow user to pass compressor having similar interface as +the @command{compress} has (exit status 2 warns that the "compressed" output +is bigger than uncompressed input). Other examples having such non-fatal exit +status are @command{xz}, @command{lzma}, @command{gzip} or @command{lzop}. +@end table @menu * lbzip2:: Using lbzip2 with @GNUTAR{}. diff --git a/src/common.h b/src/common.h index 4f7c19f..53790c3 100644 --- a/src/common.h +++ b/src/common.h @@ -145,6 +145,9 @@ GLOBAL unsigned checkpoint_option; /* Specified name of compression program, or "gzip" as implied by -z. */ GLOBAL const char *use_compress_program_option; +/* The exit value 2 of compression program is not fatal error */ +GLOBAL bool compress_like_api; + GLOBAL bool dereference_option; GLOBAL bool hard_dereference_option; diff --git a/src/system.c b/src/system.c index e1fd263..32bfd37 100644 --- a/src/system.c +++ b/src/system.c @@ -189,9 +189,15 @@ sys_wait_for_child (pid_t child_pid, bool eof) if (!(!eof && sig == SIGPIPE)) FATAL_ERROR ((0, 0, _("Child died with signal %d"), sig)); } - else if (WEXITSTATUS (wait_status) != 0) - FATAL_ERROR ((0, 0, _("Child returned status %d"), - WEXITSTATUS (wait_status))); + else if (WEXITSTATUS (wait_status) == 0) + return; + /* compress-like api just warns by exit status 2 */ + else if (WEXITSTATUS (wait_status) == 2 && compress_like_api) + WARN ((0, 0, _("%lu: Child '%s' exited with warning"), + (unsigned long) child_pid, use_compress_program_option)); + else + FATAL_ERROR ((0, 0, _("Child '%s' returned exit status %d"), + use_compress_program_option, WEXITSTATUS (wait_status))); } } diff --git a/src/tar.c b/src/tar.c index c29b4fa..a141b69 100644 --- a/src/tar.c +++ b/src/tar.c @@ -267,6 +267,7 @@ enum CHECK_DEVICE_OPTION, CHECKPOINT_OPTION, CHECKPOINT_ACTION_OPTION, + COMPRESS_PROGRAM_OPTION, DELAY_DIRECTORY_RESTORE_OPTION, HARD_DEREFERENCE_OPTION, DELETE_OPTION, @@ -657,8 +658,15 @@ static struct argp_option options[] = { {"no-auto-compress", NO_AUTO_COMPRESS_OPTION, 0, 0, N_("do not use archive suffix to determine the compression program"), GRID+1 }, - {"use-compress-program", 'I', N_("PROG"), 0, - N_("filter through PROG (must accept -d)"), GRID+1 }, + {"filter-program", 'I', N_("PROG"), 0, + N_("filter archive through PROG (PROG must accept -d)"), GRID+1 }, + {"use-compress-program", 0, N_("PROG"), OPTION_ALIAS | OPTION_HIDDEN, NULL, + GRID+1 }, + {"compress-program", COMPRESS_PROGRAM_OPTION, N_("PROG"), 0, + N_("filter archive through PROG having COMPRESS-like API, this is similar " + "to --filter-program except that the PROG's exit value 2 means just a " + "warning (PROG must accept -d option)"), + GRID+1 }, /* Note: docstrings for the options below are generated by tar_help_filter */ {"bzip2", 'j', 0, 0, NULL, GRID+1 }, {"gzip", 'z', 0, 0, NULL, GRID+1 }, @@ -1327,6 +1335,7 @@ tar_help_filter (int key, const char *text, void *input) case LZMA_OPTION: s = xasprintf (_("filter the archive through %s"), LZMA_PROGRAM); + compress_like_api = true; break; case 'J': @@ -1579,6 +1588,7 @@ parse_opt (int key, char *arg, struct argp_state *state) case 'J': set_use_compress_program_option (XZ_PROGRAM); + compress_like_api = true; break; case 'k': @@ -1636,6 +1646,7 @@ parse_opt (int key, char *arg, struct argp_state *state) case LZOP_OPTION: set_use_compress_program_option (LZOP_PROGRAM); + compress_like_api = true; break; case 'm': @@ -1797,10 +1808,12 @@ parse_opt (int key, char *arg, struct argp_state *state) case 'z': set_use_compress_program_option (GZIP_PROGRAM); + compress_like_api = true; break; case 'Z': set_use_compress_program_option (COMPRESS_PROGRAM); + compress_like_api = true; break; case ANCHORED_OPTION: @@ -2161,6 +2174,11 @@ parse_opt (int key, char *arg, struct argp_state *state) set_use_compress_program_option (arg); break; + case COMPRESS_PROGRAM_OPTION: + set_use_compress_program_option (arg); + compress_like_api = true; + break; + case VOLNO_FILE_OPTION: volno_file_option = arg; break; -- 1.8.1.4