@@ -58,20 +58,25 @@ pub mod rustrt {
5858 pub extern {
5959 unsafe fn rust_get_argc ( ) -> c_int ;
6060 unsafe fn rust_get_argv ( ) -> * * c_char ;
61- unsafe fn rust_getcwd ( ) -> ~str ;
6261 unsafe fn rust_path_is_dir ( path : * libc:: c_char ) -> c_int ;
6362 unsafe fn rust_path_exists ( path : * libc:: c_char ) -> c_int ;
64- unsafe fn rust_list_files2 ( & & path: ~str ) -> ~[ ~str ] ;
6563 unsafe fn rust_process_wait ( handle : c_int ) -> c_int ;
6664 unsafe fn rust_set_exit_status ( code : libc:: intptr_t ) ;
6765 }
6866}
6967
7068pub const TMPBUF_SZ : uint = 1000 u;
69+ const BUF_BYTES : uint = 2048 u;
7170
7271pub fn getcwd ( ) -> Path {
72+ let buf = [ 0 as libc:: c_char , ..BUF_BYTES ] ;
7373 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 ] ) )
7580 }
7681}
7782
@@ -164,20 +169,68 @@ fn with_env_lock<T>(f: &fn() -> T) -> T {
164169}
165170
166171pub fn env ( ) -> ~[ ( ~str , ~str ) ] {
167- extern {
168- unsafe fn rust_env_pairs ( ) -> ~[ ~str ] ;
169- }
170-
171172 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 ) ] {
173219 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 ) ;
177226 pairs. push ( ( copy vs[ 0 ] , copy vs[ 1 ] ) ) ;
178227 }
179228 pairs
180229 }
230+ do with_env_lock {
231+ let unparsed_environ = get_env_pairs ( ) ;
232+ env_convert ( unparsed_environ)
233+ }
181234 }
182235}
183236
@@ -615,13 +668,97 @@ pub fn make_dir(p: &Path, mode: c_int) -> bool {
615668#[ allow( non_implicitly_copyable_typarams) ]
616669pub fn list_dir( p : & Path ) -> ~[ ~str ] {
617670 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+ }
621707 #[ 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| {
625762 *filename != ~" . " && *filename != ~" .."
626763 }
627764 }
@@ -1274,9 +1411,8 @@ mod tests {
12741411 setenv(~" USERPROFILE ", ~" /home/PaloAlto ");
12751412 fail_unless!(os::homedir() == Some(Path(" /home/MountainView ")));
12761413
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});
12801416 }
12811417
12821418 #[test]
0 commit comments