1
+ mod ospathbuf;
2
+
1
3
use crate :: os:: unix:: prelude:: * ;
2
4
3
5
use crate :: ffi:: { CStr , CString , OsStr , OsString } ;
@@ -50,6 +52,8 @@ use libc::{
50
52
51
53
pub use crate :: sys_common:: fs:: { remove_dir_all, try_exists} ;
52
54
55
+ pub use ospathbuf:: OsPathBuf ;
56
+
53
57
pub struct File ( FileDesc ) ;
54
58
55
59
// FIXME: This should be available on Linux with all `target_env`.
@@ -729,8 +733,8 @@ impl OpenOptions {
729
733
730
734
impl File {
731
735
pub fn open ( path : & Path , opts : & OpenOptions ) -> io:: Result < File > {
732
- let path = cstr ( path) ?;
733
- File :: open_c ( & path, opts)
736
+ let path = OsPathBuf :: new ( path) ?;
737
+ File :: open_c ( & path, opts) . map_err ( |e| e . with_path ( path ) )
734
738
}
735
739
736
740
pub fn open_c ( path : & CStr , opts : & OpenOptions ) -> io:: Result < File > {
@@ -898,8 +902,8 @@ impl DirBuilder {
898
902
}
899
903
900
904
pub fn mkdir ( & self , p : & Path ) -> io:: Result < ( ) > {
901
- let p = cstr ( p) ?;
902
- cvt ( unsafe { libc:: mkdir ( p. as_ptr ( ) , self . mode ) } ) ?;
905
+ let p = OsPathBuf :: new ( p) ?;
906
+ cvt ( unsafe { libc:: mkdir ( p. as_ptr ( ) , self . mode ) } ) . map_err ( |e| e . with_path ( p ) ) ?;
903
907
Ok ( ( ) )
904
908
}
905
909
@@ -908,10 +912,6 @@ impl DirBuilder {
908
912
}
909
913
}
910
914
911
- fn cstr ( path : & Path ) -> io:: Result < CString > {
912
- Ok ( CString :: new ( path. as_os_str ( ) . as_bytes ( ) ) ?)
913
- }
914
-
915
915
impl FromInner < c_int > for File {
916
916
fn from_inner ( fd : c_int ) -> File {
917
917
File ( FileDesc :: new ( fd) )
@@ -998,11 +998,11 @@ impl fmt::Debug for File {
998
998
999
999
pub fn readdir ( p : & Path ) -> io:: Result < ReadDir > {
1000
1000
let root = p. to_path_buf ( ) ;
1001
- let p = cstr ( p) ?;
1001
+ let p = OsPathBuf :: new ( p) ?;
1002
1002
unsafe {
1003
1003
let ptr = libc:: opendir ( p. as_ptr ( ) ) ;
1004
1004
if ptr. is_null ( ) {
1005
- Err ( Error :: last_os_error ( ) )
1005
+ Err ( Error :: last_os_error ( ) . with_path ( p ) )
1006
1006
} else {
1007
1007
let inner = InnerReadDir { dirp : Dir ( ptr) , root } ;
1008
1008
Ok ( ReadDir {
@@ -1020,39 +1020,42 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
1020
1020
}
1021
1021
1022
1022
pub fn unlink ( p : & Path ) -> io:: Result < ( ) > {
1023
- let p = cstr ( p) ?;
1024
- cvt ( unsafe { libc:: unlink ( p. as_ptr ( ) ) } ) ?;
1023
+ let p = OsPathBuf :: new ( p) ?;
1024
+ cvt ( unsafe { libc:: unlink ( p. as_ptr ( ) ) } ) . map_err ( |e| e . with_path ( p ) ) ?;
1025
1025
Ok ( ( ) )
1026
1026
}
1027
1027
1028
1028
pub fn rename ( old : & Path , new : & Path ) -> io:: Result < ( ) > {
1029
- let old = cstr ( old) ?;
1030
- let new = cstr ( new) ?;
1029
+ let old = OsPathBuf :: new ( old) ?;
1030
+ let new = OsPathBuf :: new ( new) ?;
1031
1031
cvt ( unsafe { libc:: rename ( old. as_ptr ( ) , new. as_ptr ( ) ) } ) ?;
1032
1032
Ok ( ( ) )
1033
1033
}
1034
1034
1035
1035
pub fn set_perm ( p : & Path , perm : FilePermissions ) -> io:: Result < ( ) > {
1036
- let p = cstr ( p) ?;
1037
- cvt_r ( || unsafe { libc:: chmod ( p. as_ptr ( ) , perm. mode ) } ) ?;
1036
+ let p = OsPathBuf :: new ( p) ?;
1037
+ cvt_r ( || unsafe { libc:: chmod ( p. as_ptr ( ) , perm. mode ) } ) . map_err ( |e| e . with_path ( p ) ) ?;
1038
1038
Ok ( ( ) )
1039
1039
}
1040
1040
1041
1041
pub fn rmdir ( p : & Path ) -> io:: Result < ( ) > {
1042
- let p = cstr ( p) ?;
1043
- cvt ( unsafe { libc:: rmdir ( p. as_ptr ( ) ) } ) ?;
1042
+ let p = OsPathBuf :: new ( p) ?;
1043
+ cvt ( unsafe { libc:: rmdir ( p. as_ptr ( ) ) } ) . map_err ( |e| e . with_path ( p ) ) ?;
1044
1044
Ok ( ( ) )
1045
1045
}
1046
1046
1047
1047
pub fn readlink ( p : & Path ) -> io:: Result < PathBuf > {
1048
- let c_path = cstr ( p) ?;
1049
- let p = c_path. as_ptr ( ) ;
1048
+ let p = OsPathBuf :: new ( p) ?;
1050
1049
1051
1050
let mut buf = Vec :: with_capacity ( 256 ) ;
1052
1051
1053
1052
loop {
1054
- let buf_read =
1055
- cvt ( unsafe { libc:: readlink ( p, buf. as_mut_ptr ( ) as * mut _ , buf. capacity ( ) ) } ) ? as usize ;
1053
+ let buf_read = match cvt ( unsafe {
1054
+ libc:: readlink ( p. as_ptr ( ) , buf. as_mut_ptr ( ) as * mut _ , buf. capacity ( ) )
1055
+ } ) {
1056
+ Ok ( r) => r as usize ,
1057
+ Err ( e) => return Err ( e. with_path ( p) ) ,
1058
+ } ;
1056
1059
1057
1060
unsafe {
1058
1061
buf. set_len ( buf_read) ;
@@ -1072,15 +1075,15 @@ pub fn readlink(p: &Path) -> io::Result<PathBuf> {
1072
1075
}
1073
1076
1074
1077
pub fn symlink ( original : & Path , link : & Path ) -> io:: Result < ( ) > {
1075
- let original = cstr ( original) ?;
1076
- let link = cstr ( link) ?;
1078
+ let original = OsPathBuf :: new ( original) ?;
1079
+ let link = OsPathBuf :: new ( link) ?;
1077
1080
cvt ( unsafe { libc:: symlink ( original. as_ptr ( ) , link. as_ptr ( ) ) } ) ?;
1078
1081
Ok ( ( ) )
1079
1082
}
1080
1083
1081
1084
pub fn link ( original : & Path , link : & Path ) -> io:: Result < ( ) > {
1082
- let original = cstr ( original) ?;
1083
- let link = cstr ( link) ?;
1085
+ let original = OsPathBuf :: new ( original) ?;
1086
+ let link = OsPathBuf :: new ( link) ?;
1084
1087
cfg_if:: cfg_if! {
1085
1088
if #[ cfg( any( target_os = "vxworks" , target_os = "redox" , target_os = "android" ) ) ] {
1086
1089
// VxWorks, Redox, and old versions of Android lack `linkat`, so use
@@ -1099,7 +1102,7 @@ pub fn link(original: &Path, link: &Path) -> io::Result<()> {
1099
1102
}
1100
1103
1101
1104
pub fn stat ( p : & Path ) -> io:: Result < FileAttr > {
1102
- let p = cstr ( p) ?;
1105
+ let p = OsPathBuf :: new ( p) ?;
1103
1106
1104
1107
cfg_has_statx ! {
1105
1108
if let Some ( ret) = unsafe { try_statx(
@@ -1108,17 +1111,17 @@ pub fn stat(p: &Path) -> io::Result<FileAttr> {
1108
1111
libc:: AT_STATX_SYNC_AS_STAT ,
1109
1112
libc:: STATX_ALL ,
1110
1113
) } {
1111
- return ret;
1114
+ return ret. map_err ( |e| e . with_path ( p ) ) ;
1112
1115
}
1113
1116
}
1114
1117
1115
1118
let mut stat: stat64 = unsafe { mem:: zeroed ( ) } ;
1116
- cvt ( unsafe { stat64 ( p. as_ptr ( ) , & mut stat) } ) ?;
1119
+ cvt ( unsafe { stat64 ( p. as_ptr ( ) , & mut stat) } ) . map_err ( |e| e . with_path ( p ) ) ?;
1117
1120
Ok ( FileAttr :: from_stat64 ( stat) )
1118
1121
}
1119
1122
1120
1123
pub fn lstat ( p : & Path ) -> io:: Result < FileAttr > {
1121
- let p = cstr ( p) ?;
1124
+ let p = OsPathBuf :: new ( p) ?;
1122
1125
1123
1126
cfg_has_statx ! {
1124
1127
if let Some ( ret) = unsafe { try_statx(
@@ -1127,12 +1130,12 @@ pub fn lstat(p: &Path) -> io::Result<FileAttr> {
1127
1130
libc:: AT_SYMLINK_NOFOLLOW | libc:: AT_STATX_SYNC_AS_STAT ,
1128
1131
libc:: STATX_ALL ,
1129
1132
) } {
1130
- return ret;
1133
+ return ret. map_err ( |e| e . with_path ( p ) ) ;
1131
1134
}
1132
1135
}
1133
1136
1134
1137
let mut stat: stat64 = unsafe { mem:: zeroed ( ) } ;
1135
- cvt ( unsafe { lstat64 ( p. as_ptr ( ) , & mut stat) } ) ?;
1138
+ cvt ( unsafe { lstat64 ( p. as_ptr ( ) , & mut stat) } ) . map_err ( |e| e . with_path ( p ) ) ?;
1136
1139
Ok ( FileAttr :: from_stat64 ( stat) )
1137
1140
}
1138
1141
@@ -1284,7 +1287,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
1284
1287
// Opportunistically attempt to create a copy-on-write clone of `from`
1285
1288
// using `fclonefileat`.
1286
1289
if HAS_FCLONEFILEAT . load ( Ordering :: Relaxed ) {
1287
- let to = cstr ( to) ?;
1290
+ let to = OsPathBuf :: new ( to) ?;
1288
1291
let clonefile_result =
1289
1292
cvt ( unsafe { fclonefileat ( reader. as_raw_fd ( ) , libc:: AT_FDCWD , to. as_ptr ( ) , 0 ) } ) ;
1290
1293
match clonefile_result {
@@ -1331,7 +1334,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
1331
1334
1332
1335
#[ cfg( not( any( target_os = "fuchsia" , target_os = "vxworks" ) ) ) ]
1333
1336
pub fn chroot ( dir : & Path ) -> io:: Result < ( ) > {
1334
- let dir = cstr ( dir) ?;
1335
- cvt ( unsafe { libc:: chroot ( dir. as_ptr ( ) ) } ) ?;
1337
+ let dir = OsPathBuf :: new ( dir) ?;
1338
+ cvt ( unsafe { libc:: chroot ( dir. as_ptr ( ) ) } ) . map_err ( |e| e . with_path ( dir ) ) ?;
1336
1339
Ok ( ( ) )
1337
1340
}
0 commit comments