1111//! Blocking Windows-based file I/O
1212
1313use alloc:: arc:: Arc ;
14- use libc:: { c_int, c_void} ;
15- use libc;
14+ use libc:: { mod, c_int} ;
1615use std:: c_str:: CString ;
1716use std:: mem;
1817use std:: os:: windows:: fill_utf16_buf_and_decode;
1918use std:: ptr;
2019use std:: rt:: rtio;
2120use std:: rt:: rtio:: { IoResult , IoError } ;
2221use std:: str;
23- use std:: vec;
2422
2523pub type fd_t = libc:: c_int ;
2624
@@ -344,8 +342,6 @@ pub fn mkdir(p: &CString, _mode: uint) -> IoResult<()> {
344342}
345343
346344pub fn readdir ( p : & CString ) -> IoResult < Vec < CString > > {
347- use std:: rt:: libc_heap:: malloc_raw;
348-
349345 fn prune ( root : & CString , dirs : Vec < Path > ) -> Vec < CString > {
350346 let root = unsafe { CString :: new ( root. as_ptr ( ) , false ) } ;
351347 let root = Path :: new ( root) ;
@@ -355,38 +351,35 @@ pub fn readdir(p: &CString) -> IoResult<Vec<CString>> {
355351 } ) . map ( |path| root. join ( path) . to_c_str ( ) ) . collect ( )
356352 }
357353
358- extern {
359- fn rust_list_dir_wfd_size ( ) -> libc:: size_t ;
360- fn rust_list_dir_wfd_fp_buf ( wfd : * mut libc:: c_void ) -> * const u16 ;
361- }
362354 let star = Path :: new ( unsafe {
363355 CString :: new ( p. as_ptr ( ) , false )
364356 } ) . join ( "*" ) ;
365357 let path = try!( to_utf16 ( & star. to_c_str ( ) ) ) ;
366358
367359 unsafe {
368- let wfd_ptr = malloc_raw ( rust_list_dir_wfd_size ( ) as uint ) ;
369- let find_handle = libc:: FindFirstFileW ( path. as_ptr ( ) ,
370- wfd_ptr as libc:: HANDLE ) ;
360+ let mut wfd = mem:: zeroed ( ) ;
361+ let find_handle = libc:: FindFirstFileW ( path. as_ptr ( ) , & mut wfd) ;
371362 if find_handle != libc:: INVALID_HANDLE_VALUE {
372- let mut paths = vec ! ( ) ;
373- let mut more_files = 1 as libc:: c_int ;
363+ let mut paths = vec ! [ ] ;
364+ let mut more_files = 1 as libc:: BOOL ;
374365 while more_files != 0 {
375- let fp_buf = rust_list_dir_wfd_fp_buf ( wfd_ptr as * mut c_void ) ;
376- if fp_buf as uint == 0 {
377- fail ! ( "os::list_dir() failure: got null ptr from wfd" ) ;
378- } else {
379- let fp_vec = vec:: raw:: from_buf ( fp_buf, libc:: wcslen ( fp_buf) as uint ) ;
380- let fp_trimmed = str:: truncate_utf16_at_nul ( fp_vec. as_slice ( ) ) ;
381- let fp_str = String :: from_utf16 ( fp_trimmed)
382- . expect ( "rust_list_dir_wfd_fp_buf returned invalid UTF-16" ) ;
383- paths. push ( Path :: new ( fp_str) ) ;
366+ {
367+ let filename = str:: truncate_utf16_at_nul ( wfd. cFileName ) ;
368+ match String :: from_utf16 ( filename) {
369+ Some ( filename) => paths. push ( Path :: new ( filename) ) ,
370+ None => {
371+ assert ! ( libc:: FindClose ( find_handle) != 0 ) ;
372+ return Err ( IoError {
373+ code : super :: c:: ERROR_ILLEGAL_CHARACTER as uint ,
374+ extra : 0 ,
375+ detail : Some ( format ! ( "path was not valid UTF-16: {}" , filename) ) ,
376+ } )
377+ } , // FIXME #12056: Convert the UCS-2 to invalid utf-8 instead of erroring
378+ }
384379 }
385- more_files = libc:: FindNextFileW ( find_handle,
386- wfd_ptr as libc:: HANDLE ) ;
380+ more_files = libc:: FindNextFileW ( find_handle, & mut wfd) ;
387381 }
388382 assert ! ( libc:: FindClose ( find_handle) != 0 ) ;
389- libc:: free ( wfd_ptr as * mut c_void ) ;
390383 Ok ( prune ( p, paths) )
391384 } else {
392385 Err ( super :: last_error ( ) )
0 commit comments