66// spell-checker:ignore (ToDO) srcpath targetpath EEXIST
77
88use clap:: { Arg , ArgAction , Command } ;
9- use std:: io:: { Write , stdout} ;
9+ use std:: io:: { ErrorKind , Write , stdout} ;
1010use uucore:: display:: Quotable ;
1111use uucore:: error:: { FromIo , UError , UResult } ;
1212use uucore:: fs:: { make_path_relative_to, paths_refer_to_same_file} ;
@@ -251,7 +251,7 @@ pub fn uu_app() -> Command {
251251
252252fn exec ( files : & [ PathBuf ] , settings : & Settings ) -> UResult < ( ) > {
253253 // Handle cases where we create links in a directory first.
254- if let Some ( ref target_path) = settings. target_dir {
254+ if let Some ( target_path) = & settings. target_dir {
255255 // 4th form: a directory is specified by -t.
256256 return link_files_in_dir ( files, target_path, settings) ;
257257 }
@@ -404,7 +404,7 @@ fn link(src: &Path, dst: &Path, settings: &Settings) -> UResult<()> {
404404 return Err ( LnError :: SameFile ( src. to_owned ( ) , dst. to_owned ( ) ) . into ( ) ) ;
405405 }
406406 }
407- if let Some ( ref p) = backup_path {
407+ if let Some ( p) = & backup_path {
408408 fs:: rename ( dst, p)
409409 . map_err_context ( || translate ! ( "ln-cannot-backup" , "file" => dst. quote( ) ) ) ?;
410410 }
@@ -432,7 +432,8 @@ fn link(src: &Path, dst: &Path, settings: &Settings) -> UResult<()> {
432432 return Err ( LnError :: SameFile ( src. to_owned ( ) , dst. to_owned ( ) ) . into ( ) ) ;
433433 }
434434 }
435- if fs:: remove_file ( dst) . is_ok ( ) { }
435+
436+ if settings. symbolic && fs:: remove_file ( dst) . is_ok ( ) { }
436437 // In case of error, don't do anything
437438 }
438439 }
@@ -449,25 +450,34 @@ fn link(src: &Path, dst: &Path, settings: &Settings) -> UResult<()> {
449450 } else {
450451 source. to_path_buf ( )
451452 } ;
452- if let Err ( e ) = fs:: hard_link ( & p, dst) {
453+ if let Err ( err ) = fs:: hard_link ( & p, dst) {
453454 if p. is_dir ( ) {
454455 return Err ( LnError :: FailedToCreateHardLinkDir ( source. to_path_buf ( ) ) . into ( ) ) ;
455456 }
456- return Err ( e) . map_err_context ( || {
457- translate ! ( "ln-failed-to-create-hard-link" , "source" => source. quote( ) , "dest" => dst. quote( ) )
458- } ) ;
457+ if settings. overwrite == OverwriteMode :: Force
458+ && err. kind ( ) == ErrorKind :: AlreadyExists
459+ {
460+ let _ = fs:: remove_file ( dst) ;
461+ // In case of error, don't do anything
462+ fs:: hard_link ( & p, dst) . map_err_context ( || {
463+ translate ! ( "ln-failed-to-create-hard-link" , "source" => source. quote( ) , "dest" => dst. quote( ) )
464+ } ) ?;
465+ } else {
466+ return Err ( err) . map_err_context ( || {
467+ translate ! ( "ln-failed-to-create-hard-link" , "source" => source. quote( ) , "dest" => dst. quote( ) )
468+ } ) ;
469+ }
459470 }
460471 Ok ( ( ) )
461472 }
462473 } ) ( ) ;
463474 if res. is_err ( ) {
464- if let Some ( ref p) = backup_path {
475+ if let Some ( p) = & backup_path {
465476 fs:: rename ( p, dst)
466477 . map_err_context ( || translate ! ( "ln-cannot-backup" , "file" => dst. quote( ) ) ) ?;
467478 }
468479 res?;
469480 }
470-
471481 if settings. verbose {
472482 let mut out = stdout ( ) ;
473483 write ! ( out, "{} -> {}" , dst. quote( ) , source. quote( ) ) ?;
0 commit comments