@@ -511,11 +511,16 @@ pub fn remove(files: &[&OsStr], options: &Options) -> bool {
511511 } else {
512512 None
513513 } ;
514- #[ cfg( not( unix) ) ]
515- let parent_dev_id = None ;
516514
517515 if metadata. is_dir ( ) {
518- handle_dir ( file, options, progress_bar. as_ref ( ) , parent_dev_id)
516+ #[ cfg( unix) ]
517+ {
518+ handle_dir ( file, options, progress_bar. as_ref ( ) , parent_dev_id)
519+ }
520+ #[ cfg( not( unix) ) ]
521+ {
522+ handle_dir ( file, options, progress_bar. as_ref ( ) )
523+ }
519524 } else if is_symlink_dir ( & metadata) {
520525 remove_dir ( file, options, progress_bar. as_ref ( ) )
521526 } else {
@@ -604,21 +609,103 @@ fn is_writable(_path: &Path) -> bool {
604609 true
605610}
606611
612+ #[ cfg( unix) ]
613+ fn should_skip_different_device (
614+ parent_dev_id : Option < u64 > ,
615+ metadata : & Metadata ,
616+ options : & Options ,
617+ path : & Path ,
618+ ) -> bool {
619+ if let Some ( parent_dev_id) = parent_dev_id {
620+ if metadata. dev ( ) != parent_dev_id {
621+ show_error ! (
622+ "{}" ,
623+ RmError :: SkippingDirectoryOnDifferentDevice ( path. as_os_str( ) . to_os_string( ) )
624+ ) ;
625+ if options. preserve_root_all {
626+ show_error ! ( "{}" , RmError :: PreserveRootAllInEffect ) ;
627+ }
628+ return true ;
629+ }
630+ }
631+ false
632+ }
633+
634+ #[ cfg( not( unix) ) ]
635+ fn should_skip_different_device (
636+ _parent_dev_id : Option < u64 > ,
637+ _metadata : & Metadata ,
638+ _options : & Options ,
639+ _path : & Path ,
640+ ) -> bool {
641+ false
642+ }
643+
644+ #[ cfg( unix) ]
645+ fn compute_next_parent_dev_id ( options : & Options , metadata : & Metadata ) -> Option < u64 > {
646+ if options. one_fs || options. preserve_root_all {
647+ Some ( metadata. dev ( ) )
648+ } else {
649+ None
650+ }
651+ }
652+
653+ #[ cfg( not( unix) ) ]
654+ fn compute_next_parent_dev_id ( _options : & Options , _metadata : & Metadata ) -> Option < u64 > {
655+ None
656+ }
657+
658+ #[ cfg( unix) ]
659+ fn remove_dir_recursive (
660+ path : & Path ,
661+ options : & Options ,
662+ progress_bar : Option < & ProgressBar > ,
663+ parent_dev_id : Option < u64 > ,
664+ ) -> bool {
665+ remove_dir_recursive_impl ( path, options, progress_bar, parent_dev_id)
666+ }
667+
668+ #[ cfg( not( unix) ) ]
669+ fn remove_dir_recursive (
670+ path : & Path ,
671+ options : & Options ,
672+ progress_bar : Option < & ProgressBar > ,
673+ ) -> bool {
674+ remove_dir_recursive_impl ( path, options, progress_bar, None )
675+ }
676+
677+ #[ cfg( unix) ]
678+ fn remove_dir_recursive_with_parent (
679+ path : & Path ,
680+ options : & Options ,
681+ progress_bar : Option < & ProgressBar > ,
682+ parent_dev_id : Option < u64 > ,
683+ ) -> bool {
684+ remove_dir_recursive ( path, options, progress_bar, parent_dev_id)
685+ }
686+
687+ #[ cfg( not( unix) ) ]
688+ fn remove_dir_recursive_with_parent (
689+ path : & Path ,
690+ options : & Options ,
691+ progress_bar : Option < & ProgressBar > ,
692+ _parent_dev_id : Option < u64 > ,
693+ ) -> bool {
694+ remove_dir_recursive ( path, options, progress_bar)
695+ }
696+
607697/// Recursively remove the directory tree rooted at the given path.
608698///
609699/// If `path` is a file or a symbolic link, just remove it. If it is a
610700/// directory, remove all of its entries recursively and then remove the
611701/// directory itself. In case of an error, print the error message to
612702/// `stderr` and return `true`. If there were no errors, return `false`.
613- fn remove_dir_recursive (
703+ fn remove_dir_recursive_impl (
614704 path : & Path ,
615705 options : & Options ,
616706 progress_bar : Option < & ProgressBar > ,
617- _parent_dev_id : Option < u64 > ,
707+ parent_dev_id : Option < u64 > ,
618708) -> bool {
619- #[ cfg( unix) ]
620- let parent_dev_id = _parent_dev_id;
621-
622709 let metadata = match path. symlink_metadata ( ) {
623710 Ok ( metadata) => metadata,
624711 Err ( e) => return show_removal_error ( e, path) ,
@@ -644,28 +731,11 @@ fn remove_dir_recursive(
644731 }
645732
646733 // Base case 3: this is a directory on a different device
647- #[ cfg( unix) ]
648- if let Some ( parent_dev_id) = parent_dev_id {
649- if metadata. dev ( ) != parent_dev_id {
650- show_error ! (
651- "{}" ,
652- RmError :: SkippingDirectoryOnDifferentDevice ( path. as_os_str( ) . to_os_string( ) )
653- ) ;
654- if options. preserve_root_all {
655- show_error ! ( "{}" , RmError :: PreserveRootAllInEffect ) ;
656- }
657- return true ;
658- }
734+ if should_skip_different_device ( parent_dev_id, & metadata, options, path) {
735+ return true ;
659736 }
660737
661- #[ cfg( unix) ]
662- let next_parent_dev_id = if options. one_fs || options. preserve_root_all {
663- Some ( metadata. dev ( ) )
664- } else {
665- None
666- } ;
667- #[ cfg( not( unix) ) ]
668- let next_parent_dev_id = None ;
738+ let next_parent_dev_id = compute_next_parent_dev_id ( options, & metadata) ;
669739
670740 // Use secure traversal on Linux for all recursive directory removals
671741 #[ cfg( target_os = "linux" ) ]
@@ -703,7 +773,7 @@ fn remove_dir_recursive(
703773 match entry {
704774 Err ( _) => error = true ,
705775 Ok ( entry) => {
706- let child_error = remove_dir_recursive (
776+ let child_error = remove_dir_recursive_impl (
707777 & entry. path ( ) ,
708778 options,
709779 progress_bar,
@@ -750,11 +820,26 @@ fn remove_dir_recursive(
750820 }
751821}
752822
823+ #[ cfg( unix) ]
753824fn handle_dir (
754825 path : & Path ,
755826 options : & Options ,
756827 progress_bar : Option < & ProgressBar > ,
757828 parent_dev_id : Option < u64 > ,
829+ ) -> bool {
830+ handle_dir_impl ( path, options, progress_bar, parent_dev_id)
831+ }
832+
833+ #[ cfg( not( unix) ) ]
834+ fn handle_dir ( path : & Path , options : & Options , progress_bar : Option < & ProgressBar > ) -> bool {
835+ handle_dir_impl ( path, options, progress_bar, None )
836+ }
837+
838+ fn handle_dir_impl (
839+ path : & Path ,
840+ options : & Options ,
841+ progress_bar : Option < & ProgressBar > ,
842+ parent_dev_id : Option < u64 > ,
758843) -> bool {
759844 let mut had_err = false ;
760845
@@ -769,7 +854,7 @@ fn handle_dir(
769854
770855 let is_root = path. has_root ( ) && path. parent ( ) . is_none ( ) ;
771856 if options. recursive && ( !is_root || !options. preserve_root ) {
772- had_err = remove_dir_recursive ( path, options, progress_bar, parent_dev_id) ;
857+ had_err = remove_dir_recursive_with_parent ( path, options, progress_bar, parent_dev_id) ;
773858 } else if options. dir && ( !is_root || !options. preserve_root ) {
774859 had_err = remove_dir ( path, options, progress_bar) . bitor ( had_err) ;
775860 } else if options. recursive {
0 commit comments