Improve error diagnostics
* src/names.c (file_list_name): New static function. (add_file_id): If a filelist is being read twice, print the names of the files that caused it. * tests/T-rec.at: New test case. * tests/Makefile.am: Add new file. * tests/testsuite.at: Include new file.
This commit is contained in:
26
src/names.c
26
src/names.c
@@ -340,29 +340,51 @@ struct file_id_list
|
|||||||
struct file_id_list *next;
|
struct file_id_list *next;
|
||||||
ino_t ino;
|
ino_t ino;
|
||||||
dev_t dev;
|
dev_t dev;
|
||||||
|
const char *from_file;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct file_id_list *file_id_list;
|
static struct file_id_list *file_id_list;
|
||||||
|
|
||||||
|
/* Return the name of the file from which the file names and options
|
||||||
|
are being read.
|
||||||
|
*/
|
||||||
|
static const char *
|
||||||
|
file_list_name ()
|
||||||
|
{
|
||||||
|
struct name_elt *elt;
|
||||||
|
|
||||||
|
for (elt = name_head; elt; elt = elt->next)
|
||||||
|
if (elt->type == NELT_FILE && elt->v.file.fp)
|
||||||
|
return elt->v.file.name;
|
||||||
|
return _("command line");
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
add_file_id (const char *filename)
|
add_file_id (const char *filename)
|
||||||
{
|
{
|
||||||
struct file_id_list *p;
|
struct file_id_list *p;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
const char *reading_from;
|
||||||
|
|
||||||
if (stat (filename, &st))
|
if (stat (filename, &st))
|
||||||
stat_fatal (filename);
|
stat_fatal (filename);
|
||||||
|
reading_from = file_list_name ();
|
||||||
for (p = file_id_list; p; p = p->next)
|
for (p = file_id_list; p; p = p->next)
|
||||||
if (p->ino == st.st_ino && p->dev == st.st_dev)
|
if (p->ino == st.st_ino && p->dev == st.st_dev)
|
||||||
{
|
{
|
||||||
ERROR ((0, 0, _("%s: file list already read"),
|
int oldc = set_char_quoting (NULL, ':', 1);
|
||||||
quotearg_colon (filename)));
|
ERROR ((0, 0,
|
||||||
|
_("%s: file list requested from %s already read from %s"),
|
||||||
|
quotearg_n (0, filename),
|
||||||
|
reading_from, p->from_file));
|
||||||
|
set_char_quoting (NULL, ':', oldc);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
p = xmalloc (sizeof *p);
|
p = xmalloc (sizeof *p);
|
||||||
p->next = file_id_list;
|
p->next = file_id_list;
|
||||||
p->ino = st.st_ino;
|
p->ino = st.st_ino;
|
||||||
p->dev = st.st_dev;
|
p->dev = st.st_dev;
|
||||||
|
p->from_file = reading_from;
|
||||||
file_id_list = p;
|
file_id_list = p;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ TESTSUITE_AT = \
|
|||||||
T-cd.at\
|
T-cd.at\
|
||||||
T-empty.at\
|
T-empty.at\
|
||||||
T-null.at\
|
T-null.at\
|
||||||
|
T-rec.at\
|
||||||
T-zfile.at\
|
T-zfile.at\
|
||||||
T-nonl.at\
|
T-nonl.at\
|
||||||
T-mult.at\
|
T-mult.at\
|
||||||
|
|||||||
46
tests/T-rec.at
Normal file
46
tests/T-rec.at
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||||
|
#
|
||||||
|
# Test suite for GNU tar.
|
||||||
|
# Copyright 2013 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([recursive file lists])
|
||||||
|
AT_KEYWORDS([files-from T-rec])
|
||||||
|
|
||||||
|
AT_TAR_CHECK([
|
||||||
|
>file1
|
||||||
|
>file2
|
||||||
|
AT_DATA([F1],[file1
|
||||||
|
-T F2
|
||||||
|
])
|
||||||
|
AT_DATA([F2],[file2
|
||||||
|
-T F1
|
||||||
|
])
|
||||||
|
tar cf archive -T F1
|
||||||
|
echo $?
|
||||||
|
tar tf archive
|
||||||
|
],
|
||||||
|
[0],
|
||||||
|
[2
|
||||||
|
file1
|
||||||
|
file2
|
||||||
|
],
|
||||||
|
[tar: F1: file list requested from F2 already read from command line
|
||||||
|
tar: Exiting with failure status due to previous errors
|
||||||
|
],[],[],[ustar])
|
||||||
|
|
||||||
|
AT_CLEANUP
|
||||||
@@ -199,6 +199,7 @@ m4_include([opcomp06.at])
|
|||||||
AT_BANNER([The -T option])
|
AT_BANNER([The -T option])
|
||||||
m4_include([T-mult.at])
|
m4_include([T-mult.at])
|
||||||
m4_include([T-nest.at])
|
m4_include([T-nest.at])
|
||||||
|
m4_include([T-rec.at])
|
||||||
m4_include([T-cd.at])
|
m4_include([T-cd.at])
|
||||||
m4_include([T-empty.at])
|
m4_include([T-empty.at])
|
||||||
m4_include([T-null.at])
|
m4_include([T-null.at])
|
||||||
|
|||||||
Reference in New Issue
Block a user