diff --git a/THANKS b/THANKS index e87381f..6fa0a9e 100644 --- a/THANKS +++ b/THANKS @@ -131,6 +131,7 @@ David Nugent davidn@blaze.net.au David Shaw david.shaw@alcatel.com.au David Steiner dsteiner@ispa.uni-osnabrueck.de David Taylor taylor@think.com +Dawid dpc@dpc.pw Dean Gaudet dgaudet@watdragon.uwaterloo.ca Demizu Noritoshi nori-d@is.aist-nara.ac.jp Denis Excoffier denis.excoffier@free.fr diff --git a/src/extract.c b/src/extract.c index b622a2a..63e4d14 100644 --- a/src/extract.c +++ b/src/extract.c @@ -745,13 +745,13 @@ maybe_recoverable (char *file_name, bool regular, bool *interdir_made) in advance dramatically improves the following performance of reading and writing a file). If not restoring permissions, invert the INVERT_PERMISSIONS bits from the file's current permissions. TYPEFLAG specifies the type of the - file. FILE_CREATED indicates set_xattr has created the file */ + file. Returns non-zero when error occurs (while un-available xattrs is not + an error, rather no-op). Non-zero FILE_CREATED indicates set_xattr has + created the file. */ static int set_xattr (char const *file_name, struct tar_stat_info const *st, mode_t invert_permissions, char typeflag, int *file_created) { - int status = 0; - #ifdef HAVE_XATTRS bool interdir_made = false; @@ -759,17 +759,32 @@ set_xattr (char const *file_name, struct tar_stat_info const *st, { mode_t mode = current_stat_info.stat.st_mode & MODE_RWX & ~ current_umask; - do - status = mknodat (chdir_fd, file_name, mode ^ invert_permissions, 0); - while (status && maybe_recoverable ((char *)file_name, false, - &interdir_made)); + for (;;) + { + if (!mknodat (chdir_fd, file_name, mode ^ invert_permissions, 0)) + { + /* Successfully created file */ + xattrs_xattrs_set (st, file_name, typeflag, 0); + *file_created = 1; + return 0; + } - xattrs_xattrs_set (st, file_name, typeflag, 0); - *file_created = 1; + switch (maybe_recoverable ((char *)file_name, false, &interdir_made)) + { + case RECOVER_OK: + continue; + case RECOVER_NO: + skip_member (); + open_error (file_name); + return 1; + case RECOVER_SKIP: + return 0; + } + } } #endif - return(status); + return 0; } /* Fix the statuses of all directories whose statuses need fixing, and @@ -1089,11 +1104,7 @@ extract_file (char *file_name, int typeflag) int file_created = 0; if (set_xattr (file_name, ¤t_stat_info, invert_permissions, typeflag, &file_created)) - { - skip_member (); - open_error (file_name); - return 1; - } + return 1; while ((fd = open_output_file (file_name, typeflag, mode, file_created, ¤t_mode, diff --git a/tests/Makefile.am b/tests/Makefile.am index 2a70314..8e1ef8d 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -200,6 +200,7 @@ TESTSUITE_AT = \ xattr04.at\ xattr05.at\ xattr06.at\ + xattr07.at\ acls01.at\ acls02.at\ acls03.at\ diff --git a/tests/testsuite.at b/tests/testsuite.at index ebce9cc..3eb0eee 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -361,6 +361,7 @@ m4_include([xattr03.at]) m4_include([xattr04.at]) m4_include([xattr05.at]) m4_include([xattr06.at]) +m4_include([xattr07.at]) m4_include([acls01.at]) m4_include([acls02.at]) diff --git a/tests/xattr07.at b/tests/xattr07.at new file mode 100644 index 0000000..a834981 --- /dev/null +++ b/tests/xattr07.at @@ -0,0 +1,73 @@ +# Process this file with autom4te to create testsuite. -*- Autotest -*- +# +# Test suite for GNU tar. +# Copyright 2011, 2013-2014, 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 . +# +# Test description: +# Test that --keep-old-files doesn't change xattrs of already existing file. +# Per report: +# https://lists.gnu.org/archive/html/bug-tar/2016-10/msg00001.html + +AT_SETUP([xattrs: xattrs and --skip-old-files]) +AT_KEYWORDS([xattrs xattr07]) + +AT_TAR_CHECK([ +AT_XATTRS_PREREQ +mkdir dir +genfile --file dir/file +genfile --file dir/file2 + +setfattr -n user.test -v OurDirValue dir +setfattr -n user.test -v OurFileValue dir/file +setfattr -n user.test -v OurFileValue dir/file2 + +tar --xattrs -cf archive.tar dir + +setfattr -n user.test -v OurDirValue2 dir +setfattr -n user.test -v OurFileValue2 dir/file +setfattr -n user.test -v OurFileValue2 dir/file2 + +# Check that tar continues to file2 too! +tar --xattrs -xvf archive.tar --skip-old-files +tar --xattrs -xvf archive.tar --keep-old-files + +getfattr -h -d dir | grep -v -e '^#' -e ^$ +getfattr -h -d dir/file | grep -v -e '^#' -e ^$ +getfattr -h -d dir/file2 | grep -v -e '^#' -e ^$ +], +[0], +[dir/ +dir/file +dir/file2 +dir/ +dir/file +dir/file2 +user.test="OurDirValue2" +user.test="OurFileValue2" +user.test="OurFileValue2" +], [tar: dir: skipping existing file +tar: dir/file: skipping existing file +tar: dir/file: skipping existing file +tar: dir/file2: skipping existing file +tar: dir/file2: skipping existing file +tar: dir/file: Cannot open: File exists +tar: dir/file2: Cannot open: File exists +tar: Exiting with failure status due to previous errors +]) + +AT_CLEANUP From f2a7560718946e0920b55419f0953953bf824077 Mon Sep 17 00:00:00 2001 From: Pavel Raiskup Date: Mon, 28 Nov 2016 08:44:42 +0100 Subject: [PATCH] tests: more deterministic xattr07 * tests/xattr07.at: Define order of files within tested archive. --- tests/xattr07.at | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/xattr07.at b/tests/xattr07.at index a834981..47d54b8 100644 --- a/tests/xattr07.at +++ b/tests/xattr07.at @@ -36,7 +36,7 @@ setfattr -n user.test -v OurDirValue dir setfattr -n user.test -v OurFileValue dir/file setfattr -n user.test -v OurFileValue dir/file2 -tar --xattrs -cf archive.tar dir +tar --xattrs --no-recursion -cf archive.tar dir dir/file dir/file2 setfattr -n user.test -v OurDirValue2 dir setfattr -n user.test -v OurFileValue2 dir/file -- 2.13.5