@@ -12,13 +12,13 @@ use file_diff::diff;
12
12
use filetime:: { set_file_times, FileTime } ;
13
13
use std:: error:: Error ;
14
14
use std:: fmt:: { Debug , Display } ;
15
- use std:: fs;
16
15
use std:: fs:: File ;
17
16
use std:: os:: unix:: fs:: MetadataExt ;
18
17
#[ cfg( unix) ]
19
18
use std:: os:: unix:: prelude:: OsStrExt ;
20
19
use std:: path:: { Path , PathBuf , MAIN_SEPARATOR } ;
21
20
use std:: process;
21
+ use std:: { fs, io} ;
22
22
use uucore:: backup_control:: { self , BackupMode } ;
23
23
use uucore:: display:: Quotable ;
24
24
use uucore:: entries:: { grp2gid, usr2uid} ;
@@ -736,6 +736,18 @@ fn perform_backup(to: &Path, b: &Behavior) -> UResult<Option<PathBuf>> {
736
736
}
737
737
}
738
738
739
+ fn copy_file_source_not_dev_null ( from : & Path , to : & Path ) -> io:: Result < ( ) > {
740
+ let dest_meta_res = fs:: symlink_metadata ( to) ;
741
+ if let Ok ( dest_meta) = dest_meta_res {
742
+ if dest_meta. is_symlink ( ) {
743
+ // fs::copy fails if destination is a invalid symlink
744
+ // so lets just remove all symlinks at destination before copy
745
+ fs:: remove_file ( to) ?;
746
+ }
747
+ }
748
+ fs:: copy ( from, to) . map ( |_| ( ) )
749
+ }
750
+
739
751
/// Copy a file from one path to another.
740
752
///
741
753
/// # Parameters
@@ -757,8 +769,13 @@ fn copy_file(from: &Path, to: &Path) -> UResult<()> {
757
769
InstallError :: InstallFailed ( from. to_path_buf ( ) , to. to_path_buf ( ) , err) . into ( ) ,
758
770
) ;
759
771
}
760
- } else if let Err ( err) = fs:: copy ( from, to) {
761
- return Err ( InstallError :: InstallFailed ( from. to_path_buf ( ) , to. to_path_buf ( ) , err) . into ( ) ) ;
772
+ } else {
773
+ let result = copy_file_source_not_dev_null ( from, to) ;
774
+ if let Err ( err) = result {
775
+ return Err (
776
+ InstallError :: InstallFailed ( from. to_path_buf ( ) , to. to_path_buf ( ) , err) . into ( ) ,
777
+ ) ;
778
+ }
762
779
}
763
780
Ok ( ( ) )
764
781
}
0 commit comments