@@ -15,7 +15,7 @@ use libc::{c_int, c_void};
15
15
use libc;
16
16
use std:: c_str:: CString ;
17
17
use 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;
19
19
use std:: ptr;
20
20
use std:: rt:: rtio;
21
21
use std:: rt:: rtio:: IoResult ;
@@ -253,6 +253,17 @@ impl Drop for Inner {
253
253
}
254
254
}
255
255
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
+
256
267
pub fn open ( path : & CString , fm : rtio:: FileMode , fa : rtio:: FileAccess )
257
268
-> IoResult < FileDesc > {
258
269
// Flags passed to open_osfhandle
@@ -299,15 +310,16 @@ pub fn open(path: &CString, fm: rtio::FileMode, fa: rtio::FileAccess)
299
310
// Compat with unix, this allows opening directories (see libuv)
300
311
dwFlagsAndAttributes |= libc:: FILE_FLAG_BACKUP_SEMANTICS ;
301
312
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 ( ) ,
304
316
dwDesiredAccess,
305
317
dwShareMode,
306
318
ptr:: mut_null ( ) ,
307
319
dwCreationDisposition,
308
320
dwFlagsAndAttributes,
309
321
ptr:: mut_null ( ) )
310
- } ) ;
322
+ } ;
311
323
if handle == libc:: INVALID_HANDLE_VALUE as libc:: HANDLE {
312
324
Err ( super :: last_error ( ) )
313
325
} else {
@@ -324,11 +336,10 @@ pub fn open(path: &CString, fm: rtio::FileMode, fa: rtio::FileAccess)
324
336
}
325
337
326
338
pub fn mkdir ( p : & CString , _mode : uint ) -> IoResult < ( ) > {
339
+ let p = try!( to_utf16 ( p) ) ;
327
340
super :: mkerr_winbool ( unsafe {
328
341
// 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 ( ) )
332
343
} )
333
344
}
334
345
@@ -351,9 +362,11 @@ pub fn readdir(p: &CString) -> IoResult<Vec<CString>> {
351
362
let star = Path :: new ( unsafe {
352
363
CString :: new ( p. with_ref ( |p| p) , false )
353
364
} ) . 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 {
355
368
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 ) ;
357
370
if find_handle as libc:: c_int != libc:: INVALID_HANDLE_VALUE {
358
371
let mut paths = vec ! ( ) ;
359
372
let mut more_files = 1 as libc:: c_int ;
@@ -377,37 +390,35 @@ pub fn readdir(p: &CString) -> IoResult<Vec<CString>> {
377
390
} else {
378
391
Err ( super :: last_error ( ) )
379
392
}
380
- } )
393
+ }
381
394
}
382
395
383
396
pub fn unlink ( p : & CString ) -> IoResult < ( ) > {
397
+ let p = try!( to_utf16 ( p) ) ;
384
398
super :: mkerr_winbool ( unsafe {
385
- as_utf16_p ( p. as_str ( ) . unwrap ( ) , |buf| {
386
- libc:: DeleteFileW ( buf)
387
- } )
399
+ libc:: DeleteFileW ( p. as_ptr ( ) )
388
400
} )
389
401
}
390
402
391
403
pub fn rename ( old : & CString , new : & CString ) -> IoResult < ( ) > {
404
+ let old = try!( to_utf16 ( old) ) ;
405
+ let new = try!( to_utf16 ( new) ) ;
392
406
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 )
398
409
} )
399
410
}
400
411
401
412
pub 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
+ } )
405
417
}
406
418
407
419
pub 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 ( ) ) } )
411
422
}
412
423
413
424
pub fn chown ( _p : & CString , _uid : int , _gid : int ) -> IoResult < ( ) > {
@@ -418,16 +429,15 @@ pub fn chown(_p: &CString, _uid: int, _gid: int) -> IoResult<()> {
418
429
pub fn readlink ( p : & CString ) -> IoResult < CString > {
419
430
// FIXME: I have a feeling that this reads intermediate symlinks as well.
420
431
use io:: c:: compat:: kernel32:: GetFinalPathNameByHandleW ;
432
+ let p = try!( to_utf16 ( p) ) ;
421
433
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 ( ) )
431
441
} ;
432
442
if handle as int == libc:: INVALID_HANDLE_VALUE as int {
433
443
return Err ( super :: last_error ( ) )
@@ -453,19 +463,19 @@ pub fn readlink(p: &CString) -> IoResult<CString> {
453
463
454
464
pub fn symlink ( src : & CString , dst : & CString ) -> IoResult < ( ) > {
455
465
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
+ } )
461
471
}
462
472
463
473
pub 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
+ } )
469
479
}
470
480
471
481
fn mkstat ( stat : & libc:: stat ) -> rtio:: FileStat {
@@ -491,12 +501,11 @@ fn mkstat(stat: &libc::stat) -> rtio::FileStat {
491
501
492
502
pub fn stat ( p : & CString ) -> IoResult < rtio:: FileStat > {
493
503
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
+ }
500
509
}
501
510
502
511
pub fn lstat ( _p : & CString ) -> IoResult < rtio:: FileStat > {
@@ -509,7 +518,8 @@ pub fn utime(p: &CString, atime: u64, mtime: u64) -> IoResult<()> {
509
518
actime : ( atime / 1000 ) as libc:: time64_t ,
510
519
modtime : ( mtime / 1000 ) as libc:: time64_t ,
511
520
} ;
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
+ } )
515
525
}
0 commit comments