File tree 4 files changed +32
-1
lines changed
4 files changed +32
-1
lines changed Original file line number Diff line number Diff line change @@ -332,6 +332,7 @@ dependencies = [
332
332
name = " build_helper"
333
333
version = " 0.1.0"
334
334
dependencies = [
335
+ " fastrand" ,
335
336
" serde" ,
336
337
" serde_derive" ,
337
338
]
Original file line number Diff line number Diff line change @@ -82,6 +82,7 @@ dependencies = [
82
82
name = " build_helper"
83
83
version = " 0.1.0"
84
84
dependencies = [
85
+ " fastrand" ,
85
86
" serde" ,
86
87
" serde_derive" ,
87
88
]
@@ -233,6 +234,12 @@ dependencies = [
233
234
" windows-sys 0.52.0" ,
234
235
]
235
236
237
+ [[package ]]
238
+ name = " fastrand"
239
+ version = " 2.3.0"
240
+ source = " registry+https://github.com/rust-lang/crates.io-index"
241
+ checksum = " 37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
242
+
236
243
[[package ]]
237
244
name = " fd-lock"
238
245
version = " 4.0.2"
Original file line number Diff line number Diff line change @@ -6,5 +6,6 @@ edition = "2021"
6
6
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7
7
8
8
[dependencies ]
9
+ fastrand = " 2.3.0"
9
10
serde = " 1"
10
11
serde_derive = " 1"
Original file line number Diff line number Diff line change 1
1
//! Misc filesystem related helpers for use by bootstrap and tools.
2
+ use std:: ffi:: { OsStr , OsString } ;
2
3
use std:: fs:: Metadata ;
3
4
use std:: path:: Path ;
4
5
use std:: { fs, io} ;
@@ -100,6 +101,27 @@ where
100
101
101
102
pub fn remove_and_create_dir_all < P : AsRef < Path > > ( path : P ) -> io:: Result < ( ) > {
102
103
let path = path. as_ref ( ) ;
103
- recursive_remove ( path) ?;
104
+
105
+ // Attempt to rename the directory in case removing fails.
106
+ // We allow either the rename to fail or the remove to fail but not both.
107
+ let rm_path = rand_name ( path. as_os_str ( ) ) ;
108
+ if fs:: rename ( path, & rm_path) . is_err ( ) {
109
+ // Rename failed, try to remove the original path
110
+ recursive_remove ( & path) ?;
111
+ } else {
112
+ // Rename succeeded, try to remove the renamed path
113
+ let _ = recursive_remove ( & rm_path) ;
114
+ }
104
115
fs:: create_dir_all ( path)
105
116
}
117
+
118
+ fn rand_name ( prefix : & OsStr ) -> OsString {
119
+ let mut name: OsString = prefix. into ( ) ;
120
+ name. push ( "-" ) ;
121
+ let rand_suffix = [ fastrand:: alphanumeric ( ) as u8 ; 8 ] ;
122
+ // SAFETY: `fastrand::alphanumeric` only returns valid ascii.
123
+ // Since an `OsStr` is a superset of UTF-8, ascii must be a valid `OsStr`.
124
+ let ascii = unsafe { OsStr :: from_encoded_bytes_unchecked ( & rand_suffix) } ;
125
+ name. push ( ascii) ;
126
+ name
127
+ }
You can’t perform that action at this time.
0 commit comments