diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2016-11-12 11:20:47 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2016-11-12 11:27:08 +0200 |
commit | 3a283cfe9f8f1f127e8dc5597a5ea1d249985a54 (patch) | |
tree | 8ab8a8e269cda67d7b767ed9b676cc17728b2e6a | |
parent | ca9399d4ee7a0cb5183385979f083af13da4fecd (diff) | |
download | tar-3a283cfe9f8f1f127e8dc5597a5ea1d249985a54.tar.gz |
Fix the --add-file option.
* src/common.h (name_more_files): New proto.
(files_from_option): Remove.
* src/names.c (name_more_files): New file.
(names_options): Fix declaration of the
add-file option.
(names_parse_opt): Handle --add-file.
* src/tar.c (struct tar_args): Remove the input_files member.
Change all uses: use name_more_files() instead.
* tests/Makefile.am: Add new test.
* tests/add-file.at: New testcase.
* tests/testsuite.at: Add new test.
-rw-r--r-- | src/common.h | 4 | ||||
-rw-r--r-- | src/names.c | 24 | ||||
-rw-r--r-- | src/tar.c | 16 | ||||
-rw-r--r-- | tests/Makefile.am | 3 | ||||
-rw-r--r-- | tests/add-file.at | 67 | ||||
-rw-r--r-- | tests/testsuite.at | 1 |
6 files changed, 92 insertions, 23 deletions
diff --git a/src/common.h b/src/common.h index 50c34cc7..6fdb6225 100644 --- a/src/common.h +++ b/src/common.h @@ -414,9 +414,6 @@ GLOBAL bool show_transformed_names_option; timestamps from archives with an unusual member order. It is automatically set for incremental archives. */ GLOBAL bool delay_directory_restore_option; - -/* When set, tar will not refuse to create empty archives */ -GLOBAL bool files_from_option; /* Declarations for each module. */ @@ -738,6 +735,7 @@ void uid_to_uname (uid_t uid, char **uname); int uname_to_uid (char const *uname, uid_t *puid); void name_init (void); +bool name_more_files (void); void name_add_name (const char *name); void name_term (void); const char *name_next (int change_dirs); diff --git a/src/names.c b/src/names.c index 219aa77a..1a946566 100644 --- a/src/names.c +++ b/src/names.c @@ -32,7 +32,8 @@ static void name_add_file (const char *name); enum { - EXCLUDE_BACKUPS_OPTION = 256, + ADD_FILE_OPTION = 256, + EXCLUDE_BACKUPS_OPTION, EXCLUDE_CACHES_OPTION, EXCLUDE_CACHES_UNDER_OPTION, EXCLUDE_CACHES_ALL_OPTION, @@ -67,7 +68,7 @@ static struct argp_option names_options[] = { {NULL, 0, NULL, 0, N_("Local file name selection:"), GRID }, - {"add-file", ARGP_KEY_ARG, N_("FILE"), 0, + {"add-file", ADD_FILE_OPTION, N_("FILE"), 0, N_("add given FILE to the archive (useful if its name starts with a dash)"), GRID+1 }, {"directory", 'C', N_("DIR"), 0, N_("change to directory DIR"), GRID+1 }, @@ -190,10 +191,10 @@ names_parse_opt (int key, char *arg, struct argp_state *state) case 'T': name_add_file (arg); - /* Indicate we've been given -T option. This is for backward - compatibility only, so that `tar cfT archive /dev/null will - succeed */ - files_from_option = true; + break; + + case ADD_FILE_OPTION: + name_add_name (arg); break; default: @@ -651,8 +652,8 @@ struct name_elt /* A name_array element. */ } v; }; -static struct name_elt *name_head; /* store a list of names */ -size_t name_count; /* how many of the entries are names? */ +static struct name_elt *name_head;/* store a list of names */ +size_t name_count; /* how many of the entries are file names? */ static struct name_elt * name_elt_alloc (void) @@ -784,6 +785,12 @@ name_list_advance (void) } } +/* Return true if there are names or options in the list */ +bool +name_more_files (void) +{ + return name_count > 0; +} /* Add to name_array the file NAME with fnmatch options MATFLAGS */ void @@ -823,6 +830,7 @@ name_add_file (const char *name) ep->v.file.name = name; ep->v.file.line = 0; ep->v.file.fp = NULL; + name_count++; } /* Names from external name file. */ @@ -813,7 +813,6 @@ struct tar_args /* Variables used during option parsing */ bool pax_option; /* True if --pax-option was given */ char const *backup_suffix_string; /* --suffix option argument */ char const *version_control_string; /* --backup option argument */ - bool input_files; /* True if some input files where given */ int compress_autodetect; /* True if compression autodetection should be attempted when creating archives */ }; @@ -1322,7 +1321,6 @@ parse_opt (int key, char *arg, struct argp_state *state) case ARGP_KEY_ARG: /* File name or non-parsed option, because of ARGP_IN_ORDER */ name_add_name (arg); - args->input_files = true; break; case 'A': @@ -2179,7 +2177,7 @@ more_options (int argc, char **argv, struct option_locus *loc) args.loc = loc; if (argp_parse (&argp, argc, argv, ARGP_IN_ORDER|ARGP_NO_EXIT, &idx, &args)) abort (); /* shouldn't happen */ - if (loc->source == OPTS_ENVIRON && args.input_files) + if (loc->source == OPTS_ENVIRON && name_more_files ()) USAGE_ERROR ((0, 0, _("non-option arguments in %s"), loc->name)); } @@ -2221,7 +2219,6 @@ decode_options (int argc, char **argv) args.pax_option = false; args.backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); args.version_control_string = 0; - args.input_files = false; args.compress_autodetect = false; subcommand_option = UNKNOWN_SUBCOMMAND; @@ -2340,10 +2337,7 @@ decode_options (int argc, char **argv) /* Handle operands after any "--" argument. */ for (; idx < argc; idx++) - { - name_add_name (argv[idx]); - args.input_files = true; - } + name_add_name (argv[idx]); /* Derive option values and check option consistency. */ @@ -2365,7 +2359,7 @@ decode_options (int argc, char **argv) if (occurrence_option) { - if (!args.input_files) + if (!name_more_files ()) USAGE_ERROR ((0, 0, _("--occurrence is meaningless without a file list"))); if (!IS_SUBCOMMAND_CLASS (SUBCL_OCCUR)) @@ -2569,7 +2563,7 @@ decode_options (int argc, char **argv) { /* --test-label is silent if the user has specified the label name to compare against. */ - if (!args.input_files) + if (!name_more_files ()) verbose_option++; } else if (utc_option) @@ -2598,7 +2592,7 @@ decode_options (int argc, char **argv) switch (subcommand_option) { case CREATE_SUBCOMMAND: - if (!args.input_files && !files_from_option) + if (!name_more_files ()) USAGE_ERROR ((0, 0, _("Cowardly refusing to create an empty archive"))); if (args.compress_autodetect && archive_names diff --git a/tests/Makefile.am b/tests/Makefile.am index 127d90b6..502a37c0 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -42,6 +42,7 @@ $(srcdir)/package.m4: $(top_srcdir)/configure.ac ## ------------ ## TESTSUITE_AT = \ + testsuite.at\ T-cd.at\ T-dir00.at\ T-dir01.at\ @@ -54,7 +55,7 @@ TESTSUITE_AT = \ T-nonl.at\ T-mult.at\ T-nest.at\ - testsuite.at\ + add-file.at\ append.at\ append01.at\ append02.at\ diff --git a/tests/add-file.at b/tests/add-file.at new file mode 100644 index 00000000..97003ff8 --- /dev/null +++ b/tests/add-file.at @@ -0,0 +1,67 @@ +# Process this file with autom4te to create testsuite. -*- Autotest -*- +# +# Test suite for GNU tar. +# Copyright 2016 Free Software Foundation, Inc. +# +# This file is part of GNU tar. +# +# GNU tar is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# GNU tar is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +AT_SETUP([The --add-file option]) +AT_KEYWORDS([add-file]) + +# Version 1.29 would give "tar: Cowardly refusing to create an empty archive" +# if only --add-file arguments were used, and would give "tar: unhandled +# positional option 0" when handling the --add-file if at least one file was +# also given normally. +# +# Reported by: James Clarke <jrtc27@jrtc27.com> +# References: <20161112000246.77013-1-jrtc27@jrtc27.com>, +# http://lists.gnu.org/archive/html/bug-tar/2016-11/msg00013.html + +AT_TAR_CHECK([ +genfile --file -File +genfile --file foo +genfile --file bar + +echo 1: +tar -cvf arc.tar --add-file foo --add-file -File + +echo 2: +tar -cvf arc.tar foo --add-file -File bar + + +AT_DATA([input],[foo +--add-file=-File +bar +]) + +echo 3: +tar -cvf arc.tar -T input +], +[0], +[1: +foo +-File +2: +foo +-File +bar +3: +foo +-File +bar +]) + +AT_CLEANUP diff --git a/tests/testsuite.at b/tests/testsuite.at index 52e42eb2..cb6a0c31 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -218,6 +218,7 @@ AT_BANNER([Positional options]) m4_include([positional01.at]) m4_include([positional02.at]) m4_include([positional03.at]) +m4_include([add-file.at]) AT_BANNER([The -T option]) m4_include([T-mult.at]) |