@@ -58,20 +58,25 @@ pub mod rustrt {
58
58
pub extern {
59
59
unsafe fn rust_get_argc ( ) -> c_int ;
60
60
unsafe fn rust_get_argv ( ) -> * * c_char ;
61
- unsafe fn rust_getcwd ( ) -> ~str ;
62
61
unsafe fn rust_path_is_dir ( path : * libc:: c_char ) -> c_int ;
63
62
unsafe fn rust_path_exists ( path : * libc:: c_char ) -> c_int ;
64
- unsafe fn rust_list_files2 ( & & path: ~str ) -> ~[ ~str ] ;
65
63
unsafe fn rust_process_wait ( handle : c_int ) -> c_int ;
66
64
unsafe fn rust_set_exit_status ( code : libc:: intptr_t ) ;
67
65
}
68
66
}
69
67
70
68
pub const TMPBUF_SZ : uint = 1000 u;
69
+ const BUF_BYTES : uint = 2048 u;
71
70
72
71
pub fn getcwd ( ) -> Path {
72
+ let buf = [ 0 as libc:: c_char , ..BUF_BYTES ] ;
73
73
unsafe {
74
- Path ( rustrt:: rust_getcwd ( ) )
74
+ if ( 0 as * libc:: c_char == libc:: getcwd (
75
+ & buf[ 0 ] ,
76
+ BUF_BYTES as libc:: size_t ) ) {
77
+ fail ! ( ) ;
78
+ }
79
+ Path ( str:: raw:: from_c_str ( & buf[ 0 ] ) )
75
80
}
76
81
}
77
82
@@ -164,20 +169,68 @@ fn with_env_lock<T>(f: &fn() -> T) -> T {
164
169
}
165
170
166
171
pub fn env ( ) -> ~[ ( ~str , ~str ) ] {
167
- extern {
168
- unsafe fn rust_env_pairs ( ) -> ~[ ~str ] ;
169
- }
170
-
171
172
unsafe {
172
- do with_env_lock {
173
+ #[ cfg( windows) ]
174
+ unsafe fn get_env_pairs ( ) -> ~[ ~str ] {
175
+ use libc:: types:: os:: arch:: extra:: LPTCH ;
176
+ use libc:: funcs:: extra:: kernel32:: {
177
+ GetEnvironmentStringsA ,
178
+ FreeEnvironmentStringsA
179
+ } ;
180
+ let ch = GetEnvironmentStringsA ( ) ;
181
+ if ( ch as uint == 0 ) {
182
+ fail ! ( fmt!( "os::env() failure getting env string from OS: %s" ,
183
+ os:: last_os_error( ) ) ) ;
184
+ }
185
+ let mut curr_ptr: uint = ch as uint ;
186
+ let mut result = ~[ ] ;
187
+ while ( * ( curr_ptr as * libc:: c_char ) != 0 as libc:: c_char ) {
188
+ let env_pair = str:: raw:: from_c_str (
189
+ curr_ptr as * libc:: c_char ) ;
190
+ result. push ( env_pair) ;
191
+ curr_ptr +=
192
+ libc:: strlen ( curr_ptr as * libc:: c_char ) as uint
193
+ + 1 ;
194
+ }
195
+ FreeEnvironmentStringsA ( ch) ;
196
+ result
197
+ }
198
+ #[ cfg( unix) ]
199
+ unsafe fn get_env_pairs ( ) -> ~[ ~str ] {
200
+ extern mod rustrt {
201
+ unsafe fn rust_env_pairs ( ) -> * * libc:: c_char ;
202
+ }
203
+ let environ = rustrt:: rust_env_pairs ( ) ;
204
+ if ( environ as uint == 0 ) {
205
+ fail ! ( fmt!( "os::env() failure getting env string from OS: %s" ,
206
+ os:: last_os_error( ) ) ) ;
207
+ }
208
+ let mut result = ~[ ] ;
209
+ ptr:: array_each ( environ, |e| {
210
+ let env_pair = str:: raw:: from_c_str ( e) ;
211
+ log ( debug, fmt ! ( "get_env_pairs: %s" ,
212
+ env_pair) ) ;
213
+ result. push ( env_pair) ;
214
+ } ) ;
215
+ result
216
+ }
217
+
218
+ fn env_convert ( input : ~[ ~str ] ) -> ~[ ( ~str , ~str ) ] {
173
219
let mut pairs = ~[ ] ;
174
- for vec:: each( rust_env_pairs( ) ) |p| {
175
- let vs = str:: splitn_char ( * p, '=' , 1 u) ;
176
- fail_unless ! ( vec:: len( vs) == 2 u) ;
220
+ for input. each |p| {
221
+ let vs = str:: splitn_char ( * p, '=' , 1 ) ;
222
+ log ( debug,
223
+ fmt ! ( "splitting: len: %u" ,
224
+ vs. len( ) ) ) ;
225
+ fail_unless ! ( vs. len( ) == 2 ) ;
177
226
pairs. push ( ( copy vs[ 0 ] , copy vs[ 1 ] ) ) ;
178
227
}
179
228
pairs
180
229
}
230
+ do with_env_lock {
231
+ let unparsed_environ = get_env_pairs ( ) ;
232
+ env_convert ( unparsed_environ)
233
+ }
181
234
}
182
235
}
183
236
@@ -615,13 +668,97 @@ pub fn make_dir(p: &Path, mode: c_int) -> bool {
615
668
#[ allow( non_implicitly_copyable_typarams) ]
616
669
pub fn list_dir( p : & Path ) -> ~[ ~str ] {
617
670
unsafe {
618
- #[ cfg( unix) ]
619
- fn star ( p : & Path ) -> Path { copy * p }
620
-
671
+ #[ cfg( target_os = "linux" ) ]
672
+ #[ cfg( target_os = "android" ) ]
673
+ #[ cfg( target_os = "freebsd" ) ]
674
+ #[ cfg( target_os = "macos" ) ]
675
+ unsafe fn get_list ( p : & Path ) -> ~[ ~str ] {
676
+ use libc:: { DIR , dirent_t} ;
677
+ use libc:: { opendir, readdir, closedir} ;
678
+ extern mod rustrt {
679
+ unsafe fn rust_list_dir_val ( ptr : * dirent_t )
680
+ -> * libc:: c_char ;
681
+ }
682
+ let input = p. to_str ( ) ;
683
+ let mut strings = ~[ ] ;
684
+ let input_ptr = :: cast:: transmute ( & input[ 0 ] ) ;
685
+ log ( debug, "os::list_dir -- BEFORE OPENDIR" ) ;
686
+ let dir_ptr = opendir ( input_ptr) ;
687
+ if ( dir_ptr as uint != 0 ) {
688
+ log ( debug, "os::list_dir -- opendir() SUCCESS" ) ;
689
+ let mut entry_ptr = readdir ( dir_ptr) ;
690
+ while ( entry_ptr as uint != 0 ) {
691
+ strings. push (
692
+ str:: raw:: from_c_str (
693
+ rustrt:: rust_list_dir_val (
694
+ entry_ptr) ) ) ;
695
+ entry_ptr = readdir ( dir_ptr) ;
696
+ }
697
+ closedir ( dir_ptr) ;
698
+ }
699
+ else {
700
+ log ( debug, "os::list_dir -- opendir() FAILURE" ) ;
701
+ }
702
+ log ( debug,
703
+ fmt ! ( "os::list_dir -- AFTER -- #: %?" ,
704
+ strings. len( ) ) ) ;
705
+ strings
706
+ }
621
707
#[ cfg( windows) ]
622
- fn star ( p : & Path ) -> Path { p. push ( "*" ) }
623
-
624
- do rustrt:: rust_list_files2 ( star ( p) . to_str ( ) ) . filtered |filename| {
708
+ unsafe fn get_list( p : & Path ) -> ~[ ~str ] {
709
+ use libc:: types:: os:: arch:: extra:: { LPCTSTR , HANDLE , BOOL } ;
710
+ use libc:: consts:: os:: extra:: INVALID_HANDLE_VALUE ;
711
+ use libc:: wcslen;
712
+ use libc:: funcs:: extra:: kernel32:: {
713
+ FindFirstFileW ,
714
+ FindNextFileW ,
715
+ FindClose ,
716
+ } ;
717
+ use os:: win32:: {
718
+ as_utf16_p
719
+ } ;
720
+ use unstable:: exchange_alloc:: { malloc_raw, free_raw} ;
721
+ #[ nolink]
722
+ extern mod rustrt {
723
+ unsafe fn rust_list_dir_wfd_size ( ) -> libc:: size_t ;
724
+ unsafe fn rust_list_dir_wfd_fp_buf ( wfd : * libc:: c_void )
725
+ -> * u16 ;
726
+ }
727
+ fn star ( p : & Path ) -> Path { p. push ( "*" ) }
728
+ do as_utf16_p( star ( p) . to_str ( ) ) |path_ptr| {
729
+ let mut strings = ~[ ] ;
730
+ let wfd_ptr = malloc_raw (
731
+ rustrt:: rust_list_dir_wfd_size ( ) as uint ) ;
732
+ let find_handle =
733
+ FindFirstFileW (
734
+ path_ptr,
735
+ :: cast:: transmute ( wfd_ptr) ) ;
736
+ if find_handle as int != INVALID_HANDLE_VALUE {
737
+ let mut more_files = 1 as libc:: c_int ;
738
+ while more_files != 0 {
739
+ let fp_buf = rustrt:: rust_list_dir_wfd_fp_buf (
740
+ wfd_ptr) ;
741
+ if fp_buf as uint == 0 {
742
+ fail ! ( ~"os:: list_dir( ) failure: "+
743
+ ~" got null ptr from wfd");
744
+ }
745
+ else {
746
+ let fp_vec = vec::from_buf(
747
+ fp_buf, wcslen(fp_buf) as uint);
748
+ let fp_str = str::from_utf16(fp_vec);
749
+ strings.push(fp_str);
750
+ }
751
+ more_files = FindNextFileW(
752
+ find_handle,
753
+ ::cast::transmute(wfd_ptr));
754
+ }
755
+ FindClose(find_handle);
756
+ free_raw(wfd_ptr);
757
+ }
758
+ strings
759
+ }
760
+ }
761
+ do get_list(p).filtered |filename| {
625
762
*filename != ~" . " && *filename != ~" .."
626
763
}
627
764
}
@@ -1274,9 +1411,8 @@ mod tests {
1274
1411
setenv(~" USERPROFILE ", ~" /home/PaloAlto ");
1275
1412
fail_unless!(os::homedir() == Some(Path(" /home/MountainView ")));
1276
1413
1277
- option::iter(&oldhome, |s| setenv(~" HOME ", *s));
1278
- option::iter(&olduserprofile,
1279
- |s| setenv(~" USERPROFILE ", *s));
1414
+ oldhome.each(|s| {setenv(~" HOME ", *s);true});
1415
+ olduserprofile.each(|s| {setenv(~" USERPROFILE ", *s);true});
1280
1416
}
1281
1417
1282
1418
#[test]
0 commit comments