Merge pull request #7243 from ThomasWaldmann/macos-resourcefork-mtime-master

extract: fix mtime when ResourceFork xattr is set (macOS specific)
This commit is contained in:
TW 2023-01-06 22:25:42 +01:00 committed by GitHub
commit daf890ebfa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 8 deletions

View file

@ -951,6 +951,15 @@ Duration: {0.duration}
except NotImplementedError:
if not symlink:
os.chmod(path, item.mode)
if not self.noacls:
acl_set(path, item, self.numeric_ids, fd=fd)
if not self.noxattrs and "xattrs" in item:
# chown removes Linux capabilities, so set the extended attributes at the end, after chown, since they include
# the Linux capabilities in the "security.capability" attribute.
warning = xattr.set_all(fd or path, item.xattrs, follow_symlinks=False)
if warning:
set_ec(EXIT_WARNING)
# set timestamps rather late
mtime = item.mtime
atime = item.atime if "atime" in item else mtime
if "birthtime" in item:
@ -973,14 +982,6 @@ Duration: {0.duration}
except OSError:
# some systems don't support calling utime on a symlink
pass
if not self.noacls:
acl_set(path, item, self.numeric_ids, fd=fd)
if not self.noxattrs and "xattrs" in item:
# chown removes Linux capabilities, so set the extended attributes at the end, after chown, since they include
# the Linux capabilities in the "security.capability" attribute.
warning = xattr.set_all(fd or path, item.xattrs, follow_symlinks=False)
if warning:
set_ec(EXIT_WARNING)
# bsdflags include the immutable flag and need to be set last:
if not self.noflags and "bsdflags" in item:
try:

View file

@ -488,6 +488,29 @@ class ArchiverTestCase(ArchiverTestCaseBase):
assert "when setting extended attribute user.attribute" in out
assert os.path.isfile(input_abspath)
@pytest.mark.skipif(not is_darwin, reason="only for macOS")
def test_extract_xattrs_resourcefork(self):
self.create_regular_file("file")
self.cmd(f"--repo={self.repository_location}", "rcreate", "-e" "none")
input_path = os.path.abspath("input/file")
xa_key, xa_value = b"com.apple.ResourceFork", b"whatshouldbehere" # issue #7234
xattr.setxattr(input_path.encode(), xa_key, xa_value)
birthtime_expected = os.stat(input_path).st_birthtime
mtime_expected = os.stat(input_path).st_mtime_ns
# atime_expected = os.stat(input_path).st_atime_ns
self.cmd(f"--repo={self.repository_location}", "create", "test", "input")
with changedir("output"):
self.cmd(f"--repo={self.repository_location}", "extract", "test")
extracted_path = os.path.abspath("input/file")
birthtime_extracted = os.stat(extracted_path).st_birthtime
mtime_extracted = os.stat(extracted_path).st_mtime_ns
# atime_extracted = os.stat(extracted_path).st_atime_ns
xa_value_extracted = xattr.getxattr(extracted_path.encode(), xa_key)
assert xa_value_extracted == xa_value
assert birthtime_extracted == birthtime_expected
assert mtime_extracted == mtime_expected
# assert atime_extracted == atime_expected # still broken, but not really important.
def test_overwrite(self):
self.create_regular_file("file1", size=1024 * 80)
self.create_regular_file("dir2/file2", size=1024 * 80)