* src/common.h (must_be_dot_or_slash): New decl.
* src/extract.c (mark_after_links): New function, taking code
that used to be in create_placeholder_file.
(create_placeholder_file): Use it.
(delay_set_stat): Always delay setting status for . and /.
* src/misc.c (must_be_dot_or_slash): Now extern.
* tests/extrac12.at: New file.
* tests/Makefile.am (TESTSUITE_AT): Add it.
* tests/testsuite.at: Likewise.
enum { TIMESPEC_STRSIZE_BOUND =
UINTMAX_STRSIZE_BOUND + LOG10_BILLION + sizeof "-." - 1 };
+bool must_be_dot_or_slash (char const *);
+
enum remove_option
{
ORDINARY_REMOVE_OPTION,
fd, current_mode, current_mode_mask, typeflag, atflag);
}
+/* For each entry H in the leading prefix of entries in HEAD that do
+ not have after_links marked, mark H and fill in its dev and ino
+ members. Assume HEAD && ! HEAD->after_links. */
+static void
+mark_after_links (struct delayed_set_stat *head)
+{
+ struct delayed_set_stat *h = head;
+
+ do
+ {
+ struct stat st;
+ h->after_links = 1;
+
+ if (stat (h->file_name, &st) != 0)
+ stat_error (h->file_name);
+ else
+ {
+ h->dev = st.st_dev;
+ h->ino = st.st_ino;
+ }
+ }
+ while ((h = h->next) && ! h->after_links);
+}
+
/* Remember to restore stat attributes (owner, group, mode and times)
for the directory FILE_NAME, using information given in *ST,
once we stop extracting files into that directory.
data->change_dir = chdir_current;
strcpy (data->file_name, file_name);
delayed_set_stat_head = data;
+ if (must_be_dot_or_slash (file_name))
+ mark_after_links (data);
}
/* Update the delayed_set_stat info for an intermediate directory
&& strncmp (file_name, h->file_name, h->file_name_len) == 0
&& ISSLASH (file_name[h->file_name_len])
&& (last_component (file_name) == file_name + h->file_name_len + 1))
- {
- do
- {
- h->after_links = 1;
-
- if (stat (h->file_name, &st) != 0)
- stat_error (h->file_name);
- else
- {
- h->dev = st.st_dev;
- h->ino = st.st_ino;
- }
- }
- while ((h = h->next) && ! h->after_links);
- }
+ mark_after_links (h);
return 0;
}
static char *after_backup_name;
/* Return 1 if FILE_NAME is obviously "." or "/". */
-static bool
+bool
must_be_dot_or_slash (char const *file_name)
{
file_name += FILE_SYSTEM_PREFIX_LEN (file_name);
extrac09.at\
extrac10.at\
extrac11.at\
+ extrac12.at\
filerem01.at\
filerem02.at\
gzip.at\
--- /dev/null
+# Process this file with autom4te to create testsuite. -*- Autotest -*-
+
+# Test suite for GNU tar.
+# Copyright (C) 2010 Free Software Foundation, Inc.
+
+# This program 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, or (at your option)
+# any later version.
+
+# This program 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/>.
+
+# written by Paul Eggert
+
+# Check that 'tar' extracts permissions on the working directory last.
+
+AT_SETUP([extract dot permissions])
+AT_KEYWORDS([extract extrac12])
+
+AT_TAR_CHECK([
+mkdir src dst
+echo file1 >src/file1
+echo file2 >src/file2
+chmod a-w src
+
+tar --no-recursion -cf archive.tar -C src . ./file1 file2 &&
+tar -xf archive.tar -C dst &&
+cmp src/file1 dst/file1 &&
+cmp src/file2 dst/file2
+],
+[0],[],[],[],[],[gnu])
+
+AT_CLEANUP
m4_include([extrac09.at])
m4_include([extrac10.at])
m4_include([extrac11.at])
+m4_include([extrac12.at])
m4_include([label01.at])
m4_include([label02.at])