@@ -22,25 +22,17 @@ use io;
2222use iter;
2323use libc:: { self , c_int, c_char, c_void} ;
2424use mem;
25- use ptr;
2625use path:: { self , PathBuf } ;
26+ use ptr;
2727use slice;
2828use str;
2929use sys:: c;
3030use sys:: fd;
3131use vec;
3232
33- const BUF_BYTES : usize = 2048 ;
33+ const GETCWD_BUF_BYTES : usize = 2048 ;
3434const TMPBUF_SZ : usize = 128 ;
3535
36- fn bytes2path ( b : & [ u8 ] ) -> PathBuf {
37- PathBuf :: from ( <OsStr as OsStrExt >:: from_bytes ( b) )
38- }
39-
40- fn os2path ( os : OsString ) -> PathBuf {
41- bytes2path ( os. as_bytes ( ) )
42- }
43-
4436/// Returns the platform-specific value of errno
4537pub fn errno ( ) -> i32 {
4638 #[ cfg( any( target_os = "macos" ,
@@ -102,12 +94,24 @@ pub fn error_string(errno: i32) -> String {
10294}
10395
10496pub fn getcwd ( ) -> io:: Result < PathBuf > {
105- let mut buf = [ 0 as c_char ; BUF_BYTES ] ;
106- unsafe {
107- if libc:: getcwd ( buf. as_mut_ptr ( ) , buf. len ( ) as libc:: size_t ) . is_null ( ) {
108- Err ( io:: Error :: last_os_error ( ) )
109- } else {
110- Ok ( bytes2path ( CStr :: from_ptr ( buf. as_ptr ( ) ) . to_bytes ( ) ) )
97+ let mut buf = Vec :: new ( ) ;
98+ let mut n = GETCWD_BUF_BYTES ;
99+ loop {
100+ unsafe {
101+ buf. reserve ( n) ;
102+ let ptr = buf. as_mut_ptr ( ) as * mut libc:: c_char ;
103+ if !libc:: getcwd ( ptr, buf. capacity ( ) as libc:: size_t ) . is_null ( ) {
104+ let len = CStr :: from_ptr ( buf. as_ptr ( ) as * const libc:: c_char ) . to_bytes ( ) . len ( ) ;
105+ buf. set_len ( len) ;
106+ buf. shrink_to_fit ( ) ;
107+ return Ok ( PathBuf :: from ( OsString :: from_vec ( buf) ) ) ;
108+ } else {
109+ let error = io:: Error :: last_os_error ( ) ;
110+ if error. raw_os_error ( ) != Some ( libc:: ERANGE ) {
111+ return Err ( error) ;
112+ }
113+ }
114+ n *= 2 ;
111115 }
112116 }
113117}
@@ -129,11 +133,14 @@ pub struct SplitPaths<'a> {
129133}
130134
131135pub fn split_paths < ' a > ( unparsed : & ' a OsStr ) -> SplitPaths < ' a > {
136+ fn bytes_to_path ( b : & [ u8 ] ) -> PathBuf {
137+ PathBuf :: from ( <OsStr as OsStrExt >:: from_bytes ( b) )
138+ }
132139 fn is_colon ( b : & u8 ) -> bool { * b == b':' }
133140 let unparsed = unparsed. as_bytes ( ) ;
134141 SplitPaths {
135142 iter : unparsed. split ( is_colon as fn ( & u8 ) -> bool )
136- . map ( bytes2path as fn ( & ' a [ u8 ] ) -> PathBuf )
143+ . map ( bytes_to_path as fn ( & ' a [ u8 ] ) -> PathBuf )
137144 }
138145}
139146
@@ -444,7 +451,7 @@ pub fn page_size() -> usize {
444451}
445452
446453pub fn temp_dir ( ) -> PathBuf {
447- getenv ( "TMPDIR" . as_ref ( ) ) . map ( os2path ) . unwrap_or_else ( || {
454+ getenv ( "TMPDIR" . as_ref ( ) ) . map ( PathBuf :: from ) . unwrap_or_else ( || {
448455 if cfg ! ( target_os = "android" ) {
449456 PathBuf :: from ( "/data/local/tmp" )
450457 } else {
@@ -456,7 +463,7 @@ pub fn temp_dir() -> PathBuf {
456463pub fn home_dir ( ) -> Option < PathBuf > {
457464 return getenv ( "HOME" . as_ref ( ) ) . or_else ( || unsafe {
458465 fallback ( )
459- } ) . map ( os2path ) ;
466+ } ) . map ( PathBuf :: from ) ;
460467
461468 #[ cfg( any( target_os = "android" ,
462469 target_os = "ios" ) ) ]
0 commit comments