@@ -57,6 +57,13 @@ pub(crate) fn get_flags(path: &Path) -> io::Result<Vec<String>> {
5757 Ok ( flag_names)
5858}
5959
60+ /// Sets file flags on macOS.
61+ ///
62+ /// Note: This implementation overwrites all existing flags rather than merging them,
63+ /// which matches libarchive/bsdtar behavior. libarchive uses `chflags()` directly on
64+ /// BSD systems which replaces all flags, while on Linux it uses ioctl to read current
65+ /// flags first and merge them. This cross-platform inconsistency exists in bsdtar itself.
66+ /// See: https://github.com/libarchive/libarchive/blob/master/libarchive/archive_write_disk_posix.c
6067#[ cfg( target_os = "macos" ) ]
6168pub ( crate ) fn set_flags ( path : & Path , flags : & [ String ] ) -> io:: Result < ( ) > {
6269 use std:: os:: unix:: ffi:: OsStrExt ;
@@ -152,6 +159,14 @@ pub(crate) fn get_flags(path: &Path) -> io::Result<Vec<String>> {
152159 Ok ( flag_names)
153160}
154161
162+ /// Sets file flags on Linux.
163+ ///
164+ /// Note: This implementation reads current flags first and merges them with new flags,
165+ /// which matches libarchive/bsdtar behavior on Linux. libarchive uses ioctl to read
166+ /// current flags (`FS_IOC_GETFLAGS`) then computes `newflags = (oldflags & ~clear) | set`
167+ /// before writing. This differs from BSD systems where `chflags()` overwrites all flags.
168+ /// This cross-platform inconsistency exists in bsdtar itself.
169+ /// See: https://github.com/libarchive/libarchive/blob/master/libarchive/archive_write_disk_posix.c
155170#[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
156171pub ( crate ) fn set_flags ( path : & Path , flags : & [ String ] ) -> io:: Result < ( ) > {
157172 use linux_flags:: * ;
@@ -256,6 +271,13 @@ pub(crate) fn get_flags(path: &Path) -> io::Result<Vec<String>> {
256271 Ok ( flag_names)
257272}
258273
274+ /// Sets file flags on FreeBSD.
275+ ///
276+ /// Note: This implementation overwrites all existing flags rather than merging them,
277+ /// which matches libarchive/bsdtar behavior. libarchive uses `chflags()` directly on
278+ /// BSD systems which replaces all flags, while on Linux it uses ioctl to read current
279+ /// flags first and merge them. This cross-platform inconsistency exists in bsdtar itself.
280+ /// See: https://github.com/libarchive/libarchive/blob/master/libarchive/archive_write_disk_posix.c
259281#[ cfg( target_os = "freebsd" ) ]
260282pub ( crate ) fn set_flags ( path : & Path , flags : & [ String ] ) -> io:: Result < ( ) > {
261283 use std:: os:: unix:: ffi:: OsStrExt ;
0 commit comments