syscall: skip unsupported symlink chmod (#1148)

This commit is contained in:
Zen Dodd authored and GitHub committed 2026-11-06 20:51:34 +10:00
1 parent a6b31adfa4
commit ea645201fe
2 files changed
+43

No files matched your search

+2
View File
@@ -1806,6 +1806,8 @@ int do_chmod(const char *path, mode_t mode)
code = 1;
# elif defined AT_FDCWD && defined AT_SYMLINK_NOFOLLOW
code = fchmodat(AT_FDCWD, path, mode & CHMOD_BITS, AT_SYMLINK_NOFOLLOW);
if (code < 0 && (errno == ENOTSUP || errno == EOPNOTSUPP || errno == ENOSYS))
code = 1;
# else
code = 1;
# endif
+41
View File
@@ -0,0 +1,41 @@
#!/usr/bin/env python3
import os
import stat
import struct
from rsyncfns import SCRATCHDIR, makepath, run_rsync, test_fail
source = SCRATCHDIR / 'source'
destination = SCRATCHDIR / 'destination'
makepath(source)
makepath(destination)
target = destination / 'target'
target.write_text('target contents\n')
target.chmod(0o640)
links = [('link', 'target'), ('dangling', 'missing')]
for name, link in links:
os.symlink(link, source / name)
batch = SCRATCHDIR / 'symlinks.batch'
run_rsync('-rlp', '--checksum-seed=1', f'--only-write-batch={batch}',
f'{source}/', f'{destination}/')
# Supply BSD-style link modes without relying on the source filesystem
mode = stat.S_IMODE((source / 'link').lstat().st_mode)
wanted = 0o400 if mode != 0o400 else 0o755
encoded_mode = struct.pack('<I', 0o120000 | mode)
data = batch.read_bytes()
if data.count(encoded_mode) != 1:
test_fail('expected one shared symlink mode in the batch')
batch.write_bytes(data.replace(encoded_mode, struct.pack('<I', 0o120000 | wanted)))
for _ in range(2):
run_rsync('-rlp', f'--read-batch={batch}', f'{destination}/')
for name, link in links:
if not (destination / name).is_symlink() or os.readlink(destination / name) != link:
test_fail(f'{name}: symlink was not preserved')
if stat.S_IMODE(target.stat().st_mode) != 0o640 or target.read_text() != 'target contents\n':
test_fail('symlink chmod changed the target')
if (destination / 'missing').exists():
test_fail('dangling symlink target was created')