@@ -11,6 +11,7 @@ use crate::ptr;
11
11
use crate :: slice;
12
12
use crate :: sync:: Arc ;
13
13
use crate :: sys:: handle:: Handle ;
14
+ use crate :: sys:: path:: NativePath ;
14
15
use crate :: sys:: time:: SystemTime ;
15
16
use crate :: sys:: { c, cvt, Align8 } ;
16
17
use crate :: sys_common:: { AsInner , FromInner , IntoInner } ;
@@ -19,6 +20,60 @@ use crate::thread;
19
20
use super :: { api, to_u16s, IoResult } ;
20
21
use crate :: sys:: path:: maybe_verbatim;
21
22
23
+ /// The crate-public interface
24
+ pub ( crate ) mod fs_imp {
25
+ use crate :: io;
26
+ use crate :: path:: AsPath ;
27
+ use crate :: path:: PathBuf ;
28
+ use crate :: sys:: fs;
29
+ pub ( crate ) use crate :: sys:: fs:: {
30
+ DirBuilder , DirEntry , File , FileAttr , FilePermissions , FileTimes , FileType , OpenOptions ,
31
+ ReadDir ,
32
+ } ;
33
+ pub ( crate ) fn remove_file < P : AsPath > ( path : P ) -> io:: Result < ( ) > {
34
+ path. with_path ( fs:: unlink)
35
+ }
36
+ pub ( crate ) fn symlink_metadata < P : AsPath > ( path : P ) -> io:: Result < FileAttr > {
37
+ path. with_native_path ( fs:: lstat)
38
+ }
39
+ pub ( crate ) fn metadata < P : AsPath > ( path : P ) -> io:: Result < FileAttr > {
40
+ path. with_native_path ( fs:: stat)
41
+ }
42
+ pub ( crate ) fn rename < P : AsPath , Q : AsPath > ( from : P , to : Q ) -> io:: Result < ( ) > {
43
+ from. with_path ( |from| to. with_path ( |to| fs:: rename ( from, to) ) )
44
+ }
45
+ pub ( crate ) fn hard_link < P : AsPath , Q : AsPath > ( original : P , link : Q ) -> io:: Result < ( ) > {
46
+ original. with_path ( |original| link. with_path ( |link| fs:: link ( original, link) ) )
47
+ }
48
+ pub ( crate ) fn soft_link < P : AsPath , Q : AsPath > ( original : P , link : Q ) -> io:: Result < ( ) > {
49
+ original. with_path ( |original| link. with_path ( |link| fs:: symlink ( original, link) ) )
50
+ }
51
+ pub ( crate ) fn remove_dir < P : AsPath > ( path : P ) -> io:: Result < ( ) > {
52
+ path. with_path ( fs:: rmdir)
53
+ }
54
+ pub ( crate ) fn read_dir < P : AsPath > ( path : P ) -> io:: Result < ReadDir > {
55
+ path. with_path ( fs:: readdir)
56
+ }
57
+ pub ( crate ) fn set_permissions < P : AsPath > ( path : P , perms : FilePermissions ) -> io:: Result < ( ) > {
58
+ path. with_path ( |path| fs:: set_perm ( path, perms) )
59
+ }
60
+ pub ( crate ) fn copy < P : AsPath , Q : AsPath > ( from : P , to : Q ) -> io:: Result < u64 > {
61
+ from. with_path ( |from| to. with_path ( |to| fs:: copy ( from, to) ) )
62
+ }
63
+ pub ( crate ) fn canonicalize < P : AsPath > ( path : P ) -> io:: Result < PathBuf > {
64
+ path. with_native_path ( fs:: canonicalize)
65
+ }
66
+ pub ( crate ) fn remove_dir_all < P : AsPath > ( path : P ) -> io:: Result < ( ) > {
67
+ path. with_native_path ( fs:: remove_dir_all)
68
+ }
69
+ pub ( crate ) fn read_link < P : AsPath > ( path : P ) -> io:: Result < PathBuf > {
70
+ path. with_native_path ( fs:: readlink)
71
+ }
72
+ pub ( crate ) fn try_exists < P : AsPath > ( path : P ) -> io:: Result < bool > {
73
+ path. with_native_path ( fs:: try_exists)
74
+ }
75
+ }
76
+
22
77
pub struct File {
23
78
handle : Handle ,
24
79
}
@@ -294,8 +349,7 @@ impl OpenOptions {
294
349
}
295
350
296
351
impl File {
297
- pub fn open ( path : & Path , opts : & OpenOptions ) -> io:: Result < File > {
298
- let path = maybe_verbatim ( path) ?;
352
+ pub fn open_native ( path : & NativePath , opts : & OpenOptions ) -> io:: Result < File > {
299
353
let creation = opts. get_creation_mode ( ) ?;
300
354
let handle = unsafe {
301
355
c:: CreateFileW (
@@ -1132,16 +1186,16 @@ pub fn rmdir(p: &Path) -> io::Result<()> {
1132
1186
}
1133
1187
1134
1188
/// Open a file or directory without following symlinks.
1135
- fn open_link ( path : & Path , access_mode : u32 ) -> io:: Result < File > {
1189
+ fn open_link ( path : & NativePath , access_mode : u32 ) -> io:: Result < File > {
1136
1190
let mut opts = OpenOptions :: new ( ) ;
1137
1191
opts. access_mode ( access_mode) ;
1138
1192
// `FILE_FLAG_BACKUP_SEMANTICS` allows opening directories.
1139
1193
// `FILE_FLAG_OPEN_REPARSE_POINT` opens a link instead of its target.
1140
1194
opts. custom_flags ( c:: FILE_FLAG_BACKUP_SEMANTICS | c:: FILE_FLAG_OPEN_REPARSE_POINT ) ;
1141
- File :: open ( path, & opts)
1195
+ File :: open_native ( path, & opts)
1142
1196
}
1143
1197
1144
- pub fn remove_dir_all ( path : & Path ) -> io:: Result < ( ) > {
1198
+ pub fn remove_dir_all ( path : & NativePath ) -> io:: Result < ( ) > {
1145
1199
let file = open_link ( path, c:: DELETE | c:: FILE_LIST_DIRECTORY ) ?;
1146
1200
1147
1201
// Test if the file is not a directory or a symlink to a directory.
@@ -1241,14 +1295,14 @@ fn remove_dir_all_iterative(f: &File, delete: fn(&File) -> io::Result<()>) -> io
1241
1295
Ok ( ( ) )
1242
1296
}
1243
1297
1244
- pub fn readlink ( path : & Path ) -> io:: Result < PathBuf > {
1298
+ pub fn readlink ( path : & NativePath ) -> io:: Result < PathBuf > {
1245
1299
// Open the link with no access mode, instead of generic read.
1246
1300
// By default FILE_LIST_DIRECTORY is denied for the junction "C:\Documents and Settings", so
1247
1301
// this is needed for a common case.
1248
1302
let mut opts = OpenOptions :: new ( ) ;
1249
1303
opts. access_mode ( 0 ) ;
1250
1304
opts. custom_flags ( c:: FILE_FLAG_OPEN_REPARSE_POINT | c:: FILE_FLAG_BACKUP_SEMANTICS ) ;
1251
- let file = File :: open ( path, & opts) ?;
1305
+ let file = File :: open_native ( path, & opts) ?;
1252
1306
file. readlink ( )
1253
1307
}
1254
1308
@@ -1301,7 +1355,7 @@ pub fn link(_original: &Path, _link: &Path) -> io::Result<()> {
1301
1355
) ) ;
1302
1356
}
1303
1357
1304
- pub fn stat ( path : & Path ) -> io:: Result < FileAttr > {
1358
+ pub fn stat ( path : & NativePath ) -> io:: Result < FileAttr > {
1305
1359
match metadata ( path, ReparsePoint :: Follow ) {
1306
1360
Err ( err) if err. raw_os_error ( ) == Some ( c:: ERROR_CANT_ACCESS_FILE as i32 ) => {
1307
1361
if let Ok ( attrs) = lstat ( path) {
@@ -1315,7 +1369,7 @@ pub fn stat(path: &Path) -> io::Result<FileAttr> {
1315
1369
}
1316
1370
}
1317
1371
1318
- pub fn lstat ( path : & Path ) -> io:: Result < FileAttr > {
1372
+ pub fn lstat ( path : & NativePath ) -> io:: Result < FileAttr > {
1319
1373
metadata ( path, ReparsePoint :: Open )
1320
1374
}
1321
1375
@@ -1331,7 +1385,7 @@ impl ReparsePoint {
1331
1385
}
1332
1386
}
1333
1387
1334
- fn metadata ( path : & Path , reparse : ReparsePoint ) -> io:: Result < FileAttr > {
1388
+ fn metadata ( path : & NativePath , reparse : ReparsePoint ) -> io:: Result < FileAttr > {
1335
1389
let mut opts = OpenOptions :: new ( ) ;
1336
1390
// No read or write permissions are necessary
1337
1391
opts. access_mode ( 0 ) ;
@@ -1340,7 +1394,7 @@ fn metadata(path: &Path, reparse: ReparsePoint) -> io::Result<FileAttr> {
1340
1394
// Attempt to open the file normally.
1341
1395
// If that fails with `ERROR_SHARING_VIOLATION` then retry using `FindFirstFileW`.
1342
1396
// If the fallback fails for any reason we return the original error.
1343
- match File :: open ( path, & opts) {
1397
+ match File :: open_native ( path, & opts) {
1344
1398
Ok ( file) => file. file_attr ( ) ,
1345
1399
Err ( e)
1346
1400
if [ Some ( c:: ERROR_SHARING_VIOLATION as _ ) , Some ( c:: ERROR_ACCESS_DENIED as _ ) ]
@@ -1353,8 +1407,6 @@ fn metadata(path: &Path, reparse: ReparsePoint) -> io::Result<FileAttr> {
1353
1407
// However, there are special system files, such as
1354
1408
// `C:\hiberfil.sys`, that are locked in a way that denies even that.
1355
1409
unsafe {
1356
- let path = maybe_verbatim ( path) ?;
1357
-
1358
1410
// `FindFirstFileW` accepts wildcard file names.
1359
1411
// Fortunately wildcards are not valid file names and
1360
1412
// `ERROR_SHARING_VIOLATION` means the file exists (but is locked)
@@ -1403,13 +1455,13 @@ fn get_path(f: &File) -> io::Result<PathBuf> {
1403
1455
)
1404
1456
}
1405
1457
1406
- pub fn canonicalize ( p : & Path ) -> io:: Result < PathBuf > {
1458
+ pub fn canonicalize ( p : & NativePath ) -> io:: Result < PathBuf > {
1407
1459
let mut opts = OpenOptions :: new ( ) ;
1408
1460
// No read or write permissions are necessary
1409
1461
opts. access_mode ( 0 ) ;
1410
1462
// This flag is so we can open directories too
1411
1463
opts. custom_flags ( c:: FILE_FLAG_BACKUP_SEMANTICS ) ;
1412
- let f = File :: open ( p, & opts) ?;
1464
+ let f = File :: open_native ( p, & opts) ?;
1413
1465
get_path ( & f)
1414
1466
}
1415
1467
@@ -1467,7 +1519,7 @@ fn symlink_junction_inner(original: &Path, junction: &Path) -> io::Result<()> {
1467
1519
let mut opts = OpenOptions :: new ( ) ;
1468
1520
opts. write ( true ) ;
1469
1521
opts. custom_flags ( c:: FILE_FLAG_OPEN_REPARSE_POINT | c:: FILE_FLAG_BACKUP_SEMANTICS ) ;
1470
- let f = File :: open ( junction, & opts) ?;
1522
+ let f = File :: open_native ( & maybe_verbatim ( junction) ? , & opts) ?;
1471
1523
let h = f. as_inner ( ) . as_raw_handle ( ) ;
1472
1524
unsafe {
1473
1525
let mut data =
@@ -1525,14 +1577,14 @@ fn symlink_junction_inner(original: &Path, junction: &Path) -> io::Result<()> {
1525
1577
}
1526
1578
1527
1579
// Try to see if a file exists but, unlike `exists`, report I/O errors.
1528
- pub fn try_exists ( path : & Path ) -> io:: Result < bool > {
1580
+ pub fn try_exists ( path : & NativePath ) -> io:: Result < bool > {
1529
1581
// Open the file to ensure any symlinks are followed to their target.
1530
1582
let mut opts = OpenOptions :: new ( ) ;
1531
1583
// No read, write, etc access rights are needed.
1532
1584
opts. access_mode ( 0 ) ;
1533
1585
// Backup semantics enables opening directories as well as files.
1534
1586
opts. custom_flags ( c:: FILE_FLAG_BACKUP_SEMANTICS ) ;
1535
- match File :: open ( path, & opts) {
1587
+ match File :: open_native ( path, & opts) {
1536
1588
Err ( e) => match e. kind ( ) {
1537
1589
// The file definitely does not exist
1538
1590
io:: ErrorKind :: NotFound => Ok ( false ) ,
0 commit comments