@@ -7,6 +7,8 @@ use std::time::{Duration, SystemTime};
7
7
use std:: { env, fs} ;
8
8
9
9
use crossbeam_utils:: atomic:: AtomicCell ;
10
+ #[ cfg( any( target_os = "linux" , target_os = "macos" , windows) ) ]
11
+ use filepath:: FilePath ;
10
12
use num_bigint:: BigInt ;
11
13
12
14
use super :: errno:: errors;
@@ -161,11 +163,25 @@ fn make_path<'a>(
161
163
vm : & VirtualMachine ,
162
164
path : & ' a PyPathLike ,
163
165
dir_fd : & DirFd ,
164
- ) -> PyResult < & ' a ffi:: OsStr > {
165
- if dir_fd. 0 . is_some ( ) {
166
- Err ( vm. new_os_error ( "dir_fd not supported yet" . to_owned ( ) ) )
167
- } else {
168
- Ok ( path. path . as_os_str ( ) )
166
+ ) -> PyResult < std:: borrow:: Cow < ' a , ffi:: OsStr > > {
167
+ let path = & path. path ;
168
+ if dir_fd. 0 . is_none ( ) || path. is_absolute ( ) {
169
+ return Ok ( path. as_os_str ( ) . into ( ) ) ;
170
+ }
171
+
172
+ cfg_if:: cfg_if! {
173
+ if #[ cfg( any( target_os = "linux" , target_os = "macos" , windows) ) ] {
174
+ let dir_path = match rust_file( dir_fd. 0 . unwrap( ) . into( ) ) . path( ) {
175
+ Ok ( dir_path) => dir_path,
176
+ Err ( _) => {
177
+ return Err ( vm. new_os_error( format!( "Cannot determine path of dir_fd: {:?}" , dir_fd. 0 ) ) ) ;
178
+ }
179
+ } ;
180
+ let p: PathBuf = vec![ dir_path, path. to_path_buf( ) ] . iter( ) . collect( ) ;
181
+ Ok ( p. into_os_string( ) . into( ) )
182
+ } else {
183
+ return Err ( vm. new_os_error( "dir_fd not supported on wasi yet" . to_owned( ) ) ) ;
184
+ }
169
185
}
170
186
}
171
187
@@ -349,7 +365,7 @@ mod _os {
349
365
vm : & VirtualMachine ,
350
366
) -> PyResult < i64 > {
351
367
let fname = make_path ( vm, & name, & dir_fd) ?;
352
- if osstr_contains_nul ( fname) {
368
+ if osstr_contains_nul ( & fname) {
353
369
return Err ( vm. new_value_error ( "embedded null character" . to_owned ( ) ) ) ;
354
370
}
355
371
@@ -504,14 +520,14 @@ mod _os {
504
520
fn remove ( path : PyPathLike , dir_fd : DirFd , vm : & VirtualMachine ) -> PyResult < ( ) > {
505
521
let path = make_path ( vm, & path, & dir_fd) ?;
506
522
let is_junction = cfg ! ( windows)
507
- && fs:: symlink_metadata ( path) . map_or ( false , |meta| {
523
+ && fs:: symlink_metadata ( & path) . map_or ( false , |meta| {
508
524
let ty = meta. file_type ( ) ;
509
525
ty. is_dir ( ) && ty. is_symlink ( )
510
526
} ) ;
511
527
let res = if is_junction {
512
- fs:: remove_dir ( path)
528
+ fs:: remove_dir ( & path)
513
529
} else {
514
- fs:: remove_file ( path)
530
+ fs:: remove_file ( & path)
515
531
} ;
516
532
res. map_err ( |err| err. into_pyexception ( vm) )
517
533
}
@@ -1221,7 +1237,7 @@ mod _os {
1221
1237
pub ( super ) fn support_funcs ( vm : & VirtualMachine ) -> Vec < SupportFunc > {
1222
1238
let mut supports = super :: platform:: support_funcs ( vm) ;
1223
1239
supports. extend ( vec ! [
1224
- SupportFunc :: new( vm, "open" , open, None , Some ( false ) , None ) ,
1240
+ SupportFunc :: new( vm, "open" , open, None , Some ( true ) , None ) ,
1225
1241
SupportFunc :: new(
1226
1242
vm,
1227
1243
"access" ,
@@ -1800,10 +1816,10 @@ mod posix {
1800
1816
let path = make_path ( vm, & path, & dir_fd) ?;
1801
1817
let body = move || {
1802
1818
use std:: os:: unix:: fs:: PermissionsExt ;
1803
- let meta = fs_metadata ( path, follow_symlinks. 0 ) ?;
1819
+ let meta = fs_metadata ( & path, follow_symlinks. 0 ) ?;
1804
1820
let mut permissions = meta. permissions ( ) ;
1805
1821
permissions. set_mode ( mode) ;
1806
- fs:: set_permissions ( path, permissions)
1822
+ fs:: set_permissions ( & path, permissions)
1807
1823
} ;
1808
1824
body ( ) . map_err ( |err| err. into_pyexception ( vm) )
1809
1825
}
@@ -2675,14 +2691,14 @@ mod nt {
2675
2691
const S_IWRITE : u32 = 128 ;
2676
2692
let path = make_path ( vm, & path, & dir_fd) ?;
2677
2693
let metadata = if follow_symlinks. 0 {
2678
- fs:: metadata ( path)
2694
+ fs:: metadata ( & path)
2679
2695
} else {
2680
- fs:: symlink_metadata ( path)
2696
+ fs:: symlink_metadata ( & path)
2681
2697
} ;
2682
2698
let meta = metadata. map_err ( |err| err. into_pyexception ( vm) ) ?;
2683
2699
let mut permissions = meta. permissions ( ) ;
2684
2700
permissions. set_readonly ( mode & S_IWRITE != 0 ) ;
2685
- fs:: set_permissions ( path, permissions) . map_err ( |err| err. into_pyexception ( vm) )
2701
+ fs:: set_permissions ( & path, permissions) . map_err ( |err| err. into_pyexception ( vm) )
2686
2702
}
2687
2703
2688
2704
// cwait is available on MSVC only (according to CPython)
0 commit comments