@@ -22,25 +22,17 @@ use io;
22
22
use iter;
23
23
use libc:: { self , c_int, c_char, c_void} ;
24
24
use mem;
25
- use ptr;
26
25
use path:: { self , PathBuf } ;
26
+ use ptr;
27
27
use slice;
28
28
use str;
29
29
use sys:: c;
30
30
use sys:: fd;
31
31
use vec;
32
32
33
- const BUF_BYTES : usize = 2048 ;
33
+ const GETCWD_BUF_BYTES : usize = 2048 ;
34
34
const TMPBUF_SZ : usize = 128 ;
35
35
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
-
44
36
/// Returns the platform-specific value of errno
45
37
pub fn errno ( ) -> i32 {
46
38
#[ cfg( any( target_os = "macos" ,
@@ -102,12 +94,24 @@ pub fn error_string(errno: i32) -> String {
102
94
}
103
95
104
96
pub 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 ;
111
115
}
112
116
}
113
117
}
@@ -129,11 +133,14 @@ pub struct SplitPaths<'a> {
129
133
}
130
134
131
135
pub 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
+ }
132
139
fn is_colon ( b : & u8 ) -> bool { * b == b':' }
133
140
let unparsed = unparsed. as_bytes ( ) ;
134
141
SplitPaths {
135
142
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 )
137
144
}
138
145
}
139
146
@@ -444,7 +451,7 @@ pub fn page_size() -> usize {
444
451
}
445
452
446
453
pub 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 ( || {
448
455
if cfg ! ( target_os = "android" ) {
449
456
PathBuf :: from ( "/data/local/tmp" )
450
457
} else {
@@ -456,7 +463,7 @@ pub fn temp_dir() -> PathBuf {
456
463
pub fn home_dir ( ) -> Option < PathBuf > {
457
464
return getenv ( "HOME" . as_ref ( ) ) . or_else ( || unsafe {
458
465
fallback ( )
459
- } ) . map ( os2path ) ;
466
+ } ) . map ( PathBuf :: from ) ;
460
467
461
468
#[ cfg( any( target_os = "android" ,
462
469
target_os = "ios" ) ) ]
0 commit comments