@@ -51,14 +51,40 @@ fn rm_rf(path: &Path) {
51
51
}
52
52
Ok ( metadata) => {
53
53
if metadata. file_type ( ) . is_file ( ) || metadata. file_type ( ) . is_symlink ( ) {
54
- do_op ( path, "remove file" , |p| fs:: remove_file ( p) ) ;
54
+ do_op ( path, "remove file" , |p| {
55
+ fs:: remove_file ( p) . or_else ( |e| {
56
+ // Work around the fact that we cannot
57
+ // delete an executable while it runs on Windows.
58
+ #[ cfg( windows) ]
59
+ if e. kind ( ) == std:: io:: ErrorKind :: PermissionDenied
60
+ && p. file_name ( ) . and_then ( std:: ffi:: OsStr :: to_str)
61
+ == Some ( "bootstrap.exe" )
62
+ {
63
+ eprintln ! ( "warning: failed to delete '{}'." , p. display( ) ) ;
64
+ return Ok ( ( ) ) ;
65
+ }
66
+ Err ( e)
67
+ } )
68
+ } ) ;
55
69
return ;
56
70
}
57
71
58
72
for file in t ! ( fs:: read_dir( path) ) {
59
73
rm_rf ( & t ! ( file) . path ( ) ) ;
60
74
}
61
- do_op ( path, "remove dir" , |p| fs:: remove_dir ( p) ) ;
75
+ do_op ( path, "remove dir" , |p| {
76
+ fs:: remove_dir ( p) . or_else ( |e| {
77
+ // Check for dir not empty on Windows
78
+ #[ cfg( windows) ]
79
+ if matches ! ( e. kind( ) , std:: io:: ErrorKind :: Other )
80
+ && e. raw_os_error ( ) == Some ( 145 )
81
+ {
82
+ return Ok ( ( ) ) ;
83
+ }
84
+
85
+ Err ( e)
86
+ } )
87
+ } ) ;
62
88
}
63
89
} ;
64
90
}
@@ -73,12 +99,18 @@ where
73
99
// As a result, we have some special logic to remove readonly files on windows.
74
100
// This is also the reason that we can't use things like fs::remove_dir_all().
75
101
Err ( ref e) if cfg ! ( windows) && e. kind ( ) == ErrorKind :: PermissionDenied => {
76
- let mut p = t ! ( path. symlink_metadata( ) ) . permissions ( ) ;
102
+ let m = t ! ( path. symlink_metadata( ) ) ;
103
+ let mut p = m. permissions ( ) ;
77
104
p. set_readonly ( false ) ;
78
105
t ! ( fs:: set_permissions( path, p) ) ;
79
106
f ( path) . unwrap_or_else ( |e| {
107
+ // Delete symlinked directories on Windows
108
+ #[ cfg( windows) ]
109
+ if m. file_type ( ) . is_symlink ( ) && path. is_dir ( ) && fs:: remove_dir ( path) . is_ok ( ) {
110
+ return ;
111
+ }
80
112
panic ! ( "failed to {} {}: {}" , desc, path. display( ) , e) ;
81
- } )
113
+ } ) ;
82
114
}
83
115
Err ( e) => {
84
116
panic ! ( "failed to {} {}: {}" , desc, path. display( ) , e) ;
0 commit comments