@@ -817,6 +817,13 @@ fn is_fifo(_filetype: fs::FileType) -> bool {
817817}
818818
819819#[ cfg( unix) ]
820+ /// Best-effort ownership preservation for `to` using `from_meta`.
821+ ///
822+ /// On Unix, this tries to set `uid`/`gid` on `to`. If `follow_symlinks` is
823+ /// true it uses `chown`, otherwise it uses `lchown` so the link itself (not its
824+ /// target) is updated. `chown`/`lchown` failures are non-fatal; permission
825+ /// errors are ignored, and other failures emit a warning because ownership
826+ /// preservation is optional.
820827fn try_preserve_ownership ( from_meta : & fs:: Metadata , to : & Path , follow_symlinks : bool ) {
821828 use std:: ffi:: CString ;
822829 use std:: os:: unix:: ffi:: OsStrExt as _;
@@ -829,22 +836,43 @@ fn try_preserve_ownership(from_meta: &fs::Metadata, to: &Path, follow_symlinks:
829836 return ;
830837 } ;
831838
832- unsafe {
839+ let result = unsafe {
833840 if follow_symlinks {
834- let _ = libc:: chown ( to_cstr. as_ptr ( ) , uid, gid) ;
841+ libc:: chown ( to_cstr. as_ptr ( ) , uid, gid)
835842 } else {
836- let _ = libc:: lchown ( to_cstr. as_ptr ( ) , uid, gid) ;
843+ libc:: lchown ( to_cstr. as_ptr ( ) , uid, gid)
844+ }
845+ } ;
846+ if result != 0 {
847+ let err = io:: Error :: last_os_error ( ) ;
848+ if err. kind ( ) != io:: ErrorKind :: PermissionDenied {
849+ eprintln ! (
850+ "mv: warning: failed to preserve ownership for {}: {err}" ,
851+ to. quote( )
852+ ) ;
837853 }
838854 }
839855}
840856
841857#[ cfg( unix) ]
858+ /// Best-effort permission preservation for `to` using `from_meta`.
859+ ///
860+ /// Only the mode bits are applied (`chmod` does not accept file type bits).
861+ /// Failures are non-fatal; permission errors are ignored, and other failures
862+ /// emit a warning because this is optional.
842863fn try_preserve_permissions ( from_meta : & fs:: Metadata , to : & Path ) {
843864 use std:: os:: unix:: fs:: { MetadataExt as _, PermissionsExt as _} ;
844865
845866 // Keep mode bits only (file type bits are not allowed in chmod).
846867 let mode = from_meta. mode ( ) & 0o7777 ;
847- let _ = fs:: set_permissions ( to, fs:: Permissions :: from_mode ( mode) ) ;
868+ if let Err ( err) = fs:: set_permissions ( to, fs:: Permissions :: from_mode ( mode) ) {
869+ if err. kind ( ) != io:: ErrorKind :: PermissionDenied {
870+ eprintln ! (
871+ "mv: warning: failed to preserve permissions for {}: {err}" ,
872+ to. quote( )
873+ ) ;
874+ }
875+ }
848876}
849877
850878#[ cfg( unix) ]
0 commit comments