1+ mod ospathbuf;
2+
13use crate :: os:: unix:: prelude:: * ;
24
35use crate :: ffi:: { CStr , CString , OsStr , OsString } ;
@@ -50,6 +52,8 @@ use libc::{
5052
5153pub use crate :: sys_common:: fs:: { remove_dir_all, try_exists} ;
5254
55+ pub use ospathbuf:: OsPathBuf ;
56+
5357pub struct File ( FileDesc ) ;
5458
5559// FIXME: This should be available on Linux with all `target_env`.
@@ -729,8 +733,8 @@ impl OpenOptions {
729733
730734impl File {
731735 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 ) )
734738 }
735739
736740 pub fn open_c ( path : & CStr , opts : & OpenOptions ) -> io:: Result < File > {
@@ -898,8 +902,8 @@ impl DirBuilder {
898902 }
899903
900904 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 ) ) ?;
903907 Ok ( ( ) )
904908 }
905909
@@ -908,10 +912,6 @@ impl DirBuilder {
908912 }
909913}
910914
911- fn cstr ( path : & Path ) -> io:: Result < CString > {
912- Ok ( CString :: new ( path. as_os_str ( ) . as_bytes ( ) ) ?)
913- }
914-
915915impl FromInner < c_int > for File {
916916 fn from_inner ( fd : c_int ) -> File {
917917 File ( FileDesc :: new ( fd) )
@@ -998,11 +998,11 @@ impl fmt::Debug for File {
998998
999999pub fn readdir ( p : & Path ) -> io:: Result < ReadDir > {
10001000 let root = p. to_path_buf ( ) ;
1001- let p = cstr ( p) ?;
1001+ let p = OsPathBuf :: new ( p) ?;
10021002 unsafe {
10031003 let ptr = libc:: opendir ( p. as_ptr ( ) ) ;
10041004 if ptr. is_null ( ) {
1005- Err ( Error :: last_os_error ( ) )
1005+ Err ( Error :: last_os_error ( ) . with_path ( p ) )
10061006 } else {
10071007 let inner = InnerReadDir { dirp : Dir ( ptr) , root } ;
10081008 Ok ( ReadDir {
@@ -1020,39 +1020,42 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
10201020}
10211021
10221022pub 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 ) ) ?;
10251025 Ok ( ( ) )
10261026}
10271027
10281028pub 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) ?;
10311031 cvt ( unsafe { libc:: rename ( old. as_ptr ( ) , new. as_ptr ( ) ) } ) ?;
10321032 Ok ( ( ) )
10331033}
10341034
10351035pub 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 ) ) ?;
10381038 Ok ( ( ) )
10391039}
10401040
10411041pub 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 ) ) ?;
10441044 Ok ( ( ) )
10451045}
10461046
10471047pub 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) ?;
10501049
10511050 let mut buf = Vec :: with_capacity ( 256 ) ;
10521051
10531052 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+ } ;
10561059
10571060 unsafe {
10581061 buf. set_len ( buf_read) ;
@@ -1072,15 +1075,15 @@ pub fn readlink(p: &Path) -> io::Result<PathBuf> {
10721075}
10731076
10741077pub 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) ?;
10771080 cvt ( unsafe { libc:: symlink ( original. as_ptr ( ) , link. as_ptr ( ) ) } ) ?;
10781081 Ok ( ( ) )
10791082}
10801083
10811084pub 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) ?;
10841087 cfg_if:: cfg_if! {
10851088 if #[ cfg( any( target_os = "vxworks" , target_os = "redox" , target_os = "android" ) ) ] {
10861089 // VxWorks, Redox, and old versions of Android lack `linkat`, so use
@@ -1099,7 +1102,7 @@ pub fn link(original: &Path, link: &Path) -> io::Result<()> {
10991102}
11001103
11011104pub fn stat ( p : & Path ) -> io:: Result < FileAttr > {
1102- let p = cstr ( p) ?;
1105+ let p = OsPathBuf :: new ( p) ?;
11031106
11041107 cfg_has_statx ! {
11051108 if let Some ( ret) = unsafe { try_statx(
@@ -1108,17 +1111,17 @@ pub fn stat(p: &Path) -> io::Result<FileAttr> {
11081111 libc:: AT_STATX_SYNC_AS_STAT ,
11091112 libc:: STATX_ALL ,
11101113 ) } {
1111- return ret;
1114+ return ret. map_err ( |e| e . with_path ( p ) ) ;
11121115 }
11131116 }
11141117
11151118 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 ) ) ?;
11171120 Ok ( FileAttr :: from_stat64 ( stat) )
11181121}
11191122
11201123pub fn lstat ( p : & Path ) -> io:: Result < FileAttr > {
1121- let p = cstr ( p) ?;
1124+ let p = OsPathBuf :: new ( p) ?;
11221125
11231126 cfg_has_statx ! {
11241127 if let Some ( ret) = unsafe { try_statx(
@@ -1127,12 +1130,12 @@ pub fn lstat(p: &Path) -> io::Result<FileAttr> {
11271130 libc:: AT_SYMLINK_NOFOLLOW | libc:: AT_STATX_SYNC_AS_STAT ,
11281131 libc:: STATX_ALL ,
11291132 ) } {
1130- return ret;
1133+ return ret. map_err ( |e| e . with_path ( p ) ) ;
11311134 }
11321135 }
11331136
11341137 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 ) ) ?;
11361139 Ok ( FileAttr :: from_stat64 ( stat) )
11371140}
11381141
@@ -1284,7 +1287,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
12841287 // Opportunistically attempt to create a copy-on-write clone of `from`
12851288 // using `fclonefileat`.
12861289 if HAS_FCLONEFILEAT . load ( Ordering :: Relaxed ) {
1287- let to = cstr ( to) ?;
1290+ let to = OsPathBuf :: new ( to) ?;
12881291 let clonefile_result =
12891292 cvt ( unsafe { fclonefileat ( reader. as_raw_fd ( ) , libc:: AT_FDCWD , to. as_ptr ( ) , 0 ) } ) ;
12901293 match clonefile_result {
@@ -1331,7 +1334,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
13311334
13321335#[ cfg( not( any( target_os = "fuchsia" , target_os = "vxworks" ) ) ) ]
13331336pub 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 ) ) ?;
13361339 Ok ( ( ) )
13371340}
0 commit comments