@@ -15,7 +15,7 @@ use libc::{c_int, c_void};
1515use libc;
1616use std:: c_str:: CString ;
1717use std:: mem;
18- use std:: os:: win32:: { as_utf16_p , fill_utf16_buf_and_decode} ;
18+ use std:: os:: win32:: fill_utf16_buf_and_decode;
1919use std:: ptr;
2020use std:: rt:: rtio;
2121use std:: rt:: rtio:: IoResult ;
@@ -253,6 +253,17 @@ impl Drop for Inner {
253253 }
254254}
255255
256+ pub fn to_utf16 ( s : & CString ) -> IoResult < Vec < u16 > > {
257+ match s. as_str ( ) {
258+ Some ( s) => Ok ( s. to_utf16 ( ) . append_one ( 0 ) ) ,
259+ None => Err ( IoError {
260+ code : libc:: ERROR_INVALID_NAME as uint ,
261+ extra : 0 ,
262+ detail : Some ( "valid unicode input required" . to_str ( ) ) ,
263+ } )
264+ }
265+ }
266+
256267pub fn open ( path : & CString , fm : rtio:: FileMode , fa : rtio:: FileAccess )
257268 -> IoResult < FileDesc > {
258269 // Flags passed to open_osfhandle
@@ -299,15 +310,16 @@ pub fn open(path: &CString, fm: rtio::FileMode, fa: rtio::FileAccess)
299310 // Compat with unix, this allows opening directories (see libuv)
300311 dwFlagsAndAttributes |= libc:: FILE_FLAG_BACKUP_SEMANTICS ;
301312
302- let handle = as_utf16_p ( path. as_str ( ) . unwrap ( ) , |buf| unsafe {
303- libc:: CreateFileW ( buf,
313+ let path = try!( to_utf16 ( path) ) ;
314+ let handle = unsafe {
315+ libc:: CreateFileW ( path. as_ptr ( ) ,
304316 dwDesiredAccess,
305317 dwShareMode,
306318 ptr:: mut_null ( ) ,
307319 dwCreationDisposition,
308320 dwFlagsAndAttributes,
309321 ptr:: mut_null ( ) )
310- } ) ;
322+ } ;
311323 if handle == libc:: INVALID_HANDLE_VALUE as libc:: HANDLE {
312324 Err ( super :: last_error ( ) )
313325 } else {
@@ -324,11 +336,10 @@ pub fn open(path: &CString, fm: rtio::FileMode, fa: rtio::FileAccess)
324336}
325337
326338pub fn mkdir ( p : & CString , _mode : uint ) -> IoResult < ( ) > {
339+ let p = try!( to_utf16 ( p) ) ;
327340 super :: mkerr_winbool ( unsafe {
328341 // FIXME: turn mode into something useful? #2623
329- as_utf16_p ( p. as_str ( ) . unwrap ( ) , |buf| {
330- libc:: CreateDirectoryW ( buf, ptr:: mut_null ( ) )
331- } )
342+ libc:: CreateDirectoryW ( p. as_ptr ( ) , ptr:: mut_null ( ) )
332343 } )
333344}
334345
@@ -351,9 +362,11 @@ pub fn readdir(p: &CString) -> IoResult<Vec<CString>> {
351362 let star = Path :: new ( unsafe {
352363 CString :: new ( p. with_ref ( |p| p) , false )
353364 } ) . join ( "*" ) ;
354- as_utf16_p ( star. as_str ( ) . unwrap ( ) , |path_ptr| unsafe {
365+ let path = try!( to_utf16 ( & star. to_c_str ( ) ) ) ;
366+
367+ unsafe {
355368 let wfd_ptr = malloc_raw ( rust_list_dir_wfd_size ( ) as uint ) ;
356- let find_handle = libc:: FindFirstFileW ( path_ptr , wfd_ptr as libc:: HANDLE ) ;
369+ let find_handle = libc:: FindFirstFileW ( path . as_ptr ( ) , wfd_ptr as libc:: HANDLE ) ;
357370 if find_handle as libc:: c_int != libc:: INVALID_HANDLE_VALUE {
358371 let mut paths = vec ! ( ) ;
359372 let mut more_files = 1 as libc:: c_int ;
@@ -377,37 +390,35 @@ pub fn readdir(p: &CString) -> IoResult<Vec<CString>> {
377390 } else {
378391 Err ( super :: last_error ( ) )
379392 }
380- } )
393+ }
381394}
382395
383396pub fn unlink ( p : & CString ) -> IoResult < ( ) > {
397+ let p = try!( to_utf16 ( p) ) ;
384398 super :: mkerr_winbool ( unsafe {
385- as_utf16_p ( p. as_str ( ) . unwrap ( ) , |buf| {
386- libc:: DeleteFileW ( buf)
387- } )
399+ libc:: DeleteFileW ( p. as_ptr ( ) )
388400 } )
389401}
390402
391403pub fn rename ( old : & CString , new : & CString ) -> IoResult < ( ) > {
404+ let old = try!( to_utf16 ( old) ) ;
405+ let new = try!( to_utf16 ( new) ) ;
392406 super :: mkerr_winbool ( unsafe {
393- as_utf16_p ( old. as_str ( ) . unwrap ( ) , |old| {
394- as_utf16_p ( new. as_str ( ) . unwrap ( ) , |new| {
395- libc:: MoveFileExW ( old, new, libc:: MOVEFILE_REPLACE_EXISTING )
396- } )
397- } )
407+ libc:: MoveFileExW ( old. as_ptr ( ) , new. as_ptr ( ) ,
408+ libc:: MOVEFILE_REPLACE_EXISTING )
398409 } )
399410}
400411
401412pub fn chmod ( p : & CString , mode : uint ) -> IoResult < ( ) > {
402- super :: mkerr_libc ( as_utf16_p ( p. as_str ( ) . unwrap ( ) , |p| unsafe {
403- libc:: wchmod ( p, mode as libc:: c_int )
404- } ) )
413+ let p = try!( to_utf16 ( p) ) ;
414+ super :: mkerr_libc ( unsafe {
415+ libc:: wchmod ( p. as_ptr ( ) , mode. bits ( ) as libc:: c_int )
416+ } )
405417}
406418
407419pub fn rmdir ( p : & CString ) -> IoResult < ( ) > {
408- super :: mkerr_libc ( as_utf16_p ( p. as_str ( ) . unwrap ( ) , |p| unsafe {
409- libc:: wrmdir ( p)
410- } ) )
420+ let p = try!( to_utf16 ( p) ) ;
421+ super :: mkerr_libc ( unsafe { libc:: wrmdir ( p. as_ptr ( ) ) } )
411422}
412423
413424pub fn chown ( _p : & CString , _uid : int , _gid : int ) -> IoResult < ( ) > {
@@ -418,16 +429,15 @@ pub fn chown(_p: &CString, _uid: int, _gid: int) -> IoResult<()> {
418429pub fn readlink ( p : & CString ) -> IoResult < CString > {
419430 // FIXME: I have a feeling that this reads intermediate symlinks as well.
420431 use io:: c:: compat:: kernel32:: GetFinalPathNameByHandleW ;
432+ let p = try!( to_utf16 ( p) ) ;
421433 let handle = unsafe {
422- as_utf16_p ( p. as_str ( ) . unwrap ( ) , |p| {
423- libc:: CreateFileW ( p,
424- libc:: GENERIC_READ ,
425- libc:: FILE_SHARE_READ ,
426- ptr:: mut_null ( ) ,
427- libc:: OPEN_EXISTING ,
428- libc:: FILE_ATTRIBUTE_NORMAL ,
429- ptr:: mut_null ( ) )
430- } )
434+ libc:: CreateFileW ( p. as_ptr ( ) ,
435+ libc:: GENERIC_READ ,
436+ libc:: FILE_SHARE_READ ,
437+ ptr:: mut_null ( ) ,
438+ libc:: OPEN_EXISTING ,
439+ libc:: FILE_ATTRIBUTE_NORMAL ,
440+ ptr:: mut_null ( ) )
431441 } ;
432442 if handle as int == libc:: INVALID_HANDLE_VALUE as int {
433443 return Err ( super :: last_error ( ) )
@@ -453,19 +463,19 @@ pub fn readlink(p: &CString) -> IoResult<CString> {
453463
454464pub fn symlink ( src : & CString , dst : & CString ) -> IoResult < ( ) > {
455465 use io:: c:: compat:: kernel32:: CreateSymbolicLinkW ;
456- super :: mkerr_winbool ( as_utf16_p ( src. as_str ( ) . unwrap ( ) , |src| {
457- as_utf16_p ( dst . as_str ( ) . unwrap ( ) , |dst| {
458- unsafe { CreateSymbolicLinkW ( dst , src , 0 ) }
459- } ) as libc:: BOOL
460- } ) )
466+ let src = try! ( to_utf16 ( src) ) ;
467+ let dst = try! ( to_utf16 ( dst ) ) ;
468+ super :: mkerr_winbool ( unsafe {
469+ CreateSymbolicLinkW ( dst . as_ptr ( ) , src . as_ptr ( ) , 0 ) as libc:: BOOL
470+ } )
461471}
462472
463473pub fn link ( src : & CString , dst : & CString ) -> IoResult < ( ) > {
464- super :: mkerr_winbool ( as_utf16_p ( src. as_str ( ) . unwrap ( ) , |src| {
465- as_utf16_p ( dst . as_str ( ) . unwrap ( ) , |dst| {
466- unsafe { libc :: CreateHardLinkW ( dst , src , ptr :: mut_null ( ) ) }
467- } )
468- } ) )
474+ let src = try! ( to_utf16 ( src) ) ;
475+ let dst = try! ( to_utf16 ( dst ) ) ;
476+ super :: mkerr_winbool ( unsafe {
477+ libc :: CreateHardLinkW ( dst . as_ptr ( ) , src . as_ptr ( ) , ptr :: mut_null ( ) )
478+ } )
469479}
470480
471481fn mkstat ( stat : & libc:: stat ) -> rtio:: FileStat {
@@ -491,12 +501,11 @@ fn mkstat(stat: &libc::stat) -> rtio::FileStat {
491501
492502pub fn stat ( p : & CString ) -> IoResult < rtio:: FileStat > {
493503 let mut stat: libc:: stat = unsafe { mem:: zeroed ( ) } ;
494- as_utf16_p ( p. as_str ( ) . unwrap ( ) , |up| {
495- match unsafe { libc:: wstat ( up, & mut stat) } {
496- 0 => Ok ( mkstat ( & stat) ) ,
497- _ => Err ( super :: last_error ( ) ) ,
498- }
499- } )
504+ let p = try!( to_utf16 ( p) ) ;
505+ match unsafe { libc:: wstat ( p. as_ptr ( ) , & mut stat) } {
506+ 0 => Ok ( mkstat ( & stat) ) ,
507+ _ => Err ( super :: last_error ( ) ) ,
508+ }
500509}
501510
502511pub fn lstat ( _p : & CString ) -> IoResult < rtio:: FileStat > {
@@ -509,7 +518,8 @@ pub fn utime(p: &CString, atime: u64, mtime: u64) -> IoResult<()> {
509518 actime : ( atime / 1000 ) as libc:: time64_t ,
510519 modtime : ( mtime / 1000 ) as libc:: time64_t ,
511520 } ;
512- super :: mkerr_libc ( as_utf16_p ( p. as_str ( ) . unwrap ( ) , |p| unsafe {
513- libc:: wutime ( p, & buf)
514- } ) )
521+ let p = try!( to_utf16 ( p) ) ;
522+ super :: mkerr_libc ( unsafe {
523+ libc:: wutime ( p. as_ptr ( ) , & buf)
524+ } )
515525}
0 commit comments