@@ -13,12 +13,9 @@ use filetime::{set_file_times, FileTime};
1313use std:: error:: Error ;
1414use std:: fmt:: { Debug , Display } ;
1515use std:: fs;
16- #[ cfg( not( unix) ) ]
1716use std:: fs:: File ;
1817use std:: os:: unix:: fs:: MetadataExt ;
1918#[ cfg( unix) ]
20- use std:: os:: unix:: fs:: OpenOptionsExt ;
21- #[ cfg( unix) ]
2219use std:: os:: unix:: prelude:: OsStrExt ;
2320use std:: path:: { Path , PathBuf , MAIN_SEPARATOR } ;
2421use std:: process;
@@ -753,52 +750,27 @@ fn perform_backup(to: &Path, b: &Behavior) -> UResult<Option<PathBuf>> {
753750fn copy_file ( from : & Path , to : & Path ) -> UResult < ( ) > {
754751 // fs::copy fails if destination is a invalid symlink.
755752 // so lets just remove all existing files at destination before copy.
756- let remove_destination = || {
757- if let Err ( e) = fs:: remove_file ( to) {
758- if e. kind ( ) != std:: io:: ErrorKind :: NotFound {
759- show_error ! (
760- "Failed to remove existing file {}. Error: {:?}" ,
761- to. display( ) ,
762- e
763- ) ;
764- }
753+ if let Err ( e) = fs:: remove_file ( to) {
754+ if e. kind ( ) != std:: io:: ErrorKind :: NotFound {
755+ show_error ! (
756+ "Failed to remove existing file {}. Error: {:?}" ,
757+ to. display( ) ,
758+ e
759+ ) ;
765760 }
766- } ;
767- remove_destination ( ) ;
768-
769- // create the destination file first. Using safer mode on unix to avoid
770- // potential unsafe mode between time-of-creation and time-of-chmod.
771- #[ cfg( unix) ]
772- let creation = fs:: OpenOptions :: new ( )
773- . write ( true )
774- . create_new ( true )
775- . mode ( 0o600 )
776- . open ( to) ;
777- #[ cfg( not( unix) ) ]
778- let creation = File :: create ( to) ;
779-
780- if let Err ( e) = creation {
781- show_error ! (
782- "Failed to create destination file {}. Error: {:?}" ,
783- to. display( ) ,
784- e
785- ) ;
786- return Err ( InstallError :: InstallFailed ( from. to_path_buf ( ) , to. to_path_buf ( ) , e) . into ( ) ) ;
787761 }
788762
789- // drop the file to close the fd of creation
790- drop ( creation) ;
791-
792- /* workaround a limitation of fs::copy: skip copy if source is /dev/null
793- * https://github.com/rust-lang/rust/issues/79390
794- */
795- if from. as_os_str ( ) != "/dev/null" {
796- if let Err ( err) = fs:: copy ( from, to) {
797- remove_destination ( ) ;
763+ if from. as_os_str ( ) == "/dev/null" {
764+ /* workaround a limitation of fs::copy
765+ * https://github.com/rust-lang/rust/issues/79390
766+ */
767+ if let Err ( err) = File :: create ( to) {
798768 return Err (
799769 InstallError :: InstallFailed ( from. to_path_buf ( ) , to. to_path_buf ( ) , err) . into ( ) ,
800770 ) ;
801771 }
772+ } else if let Err ( err) = fs:: copy ( from, to) {
773+ return Err ( InstallError :: InstallFailed ( from. to_path_buf ( ) , to. to_path_buf ( ) , err) . into ( ) ) ;
802774 }
803775 Ok ( ( ) )
804776}
0 commit comments