@@ -20,7 +20,7 @@ use std::rt::rtio;
20
20
use std:: unstable:: intrinsics;
21
21
use std:: vec;
22
22
23
- use super :: IoResult ;
23
+ use io :: { IoResult , retry } ;
24
24
25
25
#[ cfg( windows) ] use std:: os:: win32:: { as_utf16_p, fill_utf16_buf_and_decode} ;
26
26
#[ cfg( windows) ] use std:: ptr;
@@ -143,8 +143,8 @@ impl rtio::RtioFileStream for FileDesc {
143
143
overlap. OffsetHigh = ( offset >> 32 ) as libc:: DWORD ;
144
144
145
145
match libc:: ReadFile ( handle, buf as libc:: LPVOID ,
146
- amt as libc:: DWORD ,
147
- & mut bytes_read, & mut overlap) {
146
+ amt as libc:: DWORD ,
147
+ & mut bytes_read, & mut overlap) {
148
148
0 => Err ( super :: last_error ( ) ) ,
149
149
_ => Ok ( bytes_read as int )
150
150
}
@@ -153,10 +153,10 @@ impl rtio::RtioFileStream for FileDesc {
153
153
154
154
#[ cfg( unix) ]
155
155
fn os_pread ( fd : c_int , buf : * u8 , amt : uint , offset : u64 ) -> IoResult < int > {
156
- match unsafe {
156
+ match retry ( || unsafe {
157
157
libc:: pread ( fd, buf as * libc:: c_void , amt as libc:: size_t ,
158
- offset as libc:: off_t )
159
- } {
158
+ offset as libc:: off_t ) as libc :: c_int
159
+ } ) {
160
160
-1 => Err ( super :: last_error ( ) ) ,
161
161
n => Ok ( n as int )
162
162
}
@@ -184,10 +184,10 @@ impl rtio::RtioFileStream for FileDesc {
184
184
185
185
#[ cfg( unix) ]
186
186
fn os_pwrite ( fd : c_int , buf : * u8 , amt : uint , offset : u64 ) -> IoResult < ( ) > {
187
- super :: mkerr_libc ( unsafe {
187
+ super :: mkerr_libc ( retry ( || unsafe {
188
188
libc:: pwrite ( fd, buf as * libc:: c_void , amt as libc:: size_t ,
189
189
offset as libc:: off_t )
190
- } as c_int )
190
+ } as c_int ) )
191
191
}
192
192
}
193
193
#[ cfg( windows) ]
@@ -240,7 +240,7 @@ impl rtio::RtioFileStream for FileDesc {
240
240
}
241
241
#[ cfg( unix) ]
242
242
fn os_fsync ( fd : c_int ) -> IoResult < ( ) > {
243
- super :: mkerr_libc ( unsafe { libc:: fsync ( fd) } )
243
+ super :: mkerr_libc ( retry ( || unsafe { libc:: fsync ( fd) } ) )
244
244
}
245
245
}
246
246
#[ cfg( windows) ]
@@ -255,9 +255,13 @@ impl rtio::RtioFileStream for FileDesc {
255
255
unsafe { libc:: fcntl ( fd, libc:: F_FULLFSYNC ) }
256
256
}
257
257
#[ cfg( target_os = "linux" ) ]
258
- fn os_datasync ( fd : c_int ) -> c_int { unsafe { libc:: fdatasync ( fd) } }
258
+ fn os_datasync ( fd : c_int ) -> c_int {
259
+ retry ( || unsafe { libc:: fdatasync ( fd) } )
260
+ }
259
261
#[ cfg( not( target_os = "macos" ) , not( target_os = "linux" ) ) ]
260
- fn os_datasync ( fd : c_int ) -> c_int { unsafe { libc:: fsync ( fd) } }
262
+ fn os_datasync ( fd : c_int ) -> c_int {
263
+ retry ( || unsafe { libc:: fsync ( fd) } )
264
+ }
261
265
}
262
266
263
267
#[ cfg( windows) ]
@@ -278,9 +282,9 @@ impl rtio::RtioFileStream for FileDesc {
278
282
}
279
283
#[ cfg( unix) ]
280
284
fn truncate ( & mut self , offset : i64 ) -> Result < ( ) , IoError > {
281
- super :: mkerr_libc ( unsafe {
285
+ super :: mkerr_libc ( retry ( || unsafe {
282
286
libc:: ftruncate ( self . fd , offset as libc:: off_t )
283
- } )
287
+ } ) )
284
288
}
285
289
}
286
290
@@ -311,9 +315,17 @@ impl rtio::RtioTTY for FileDesc {
311
315
312
316
impl Drop for FileDesc {
313
317
fn drop ( & mut self ) {
314
- // closing stdio file handles makes no sense, so never do it
318
+ // closing stdio file handles makes no sense, so never do it. Also, note
319
+ // that errors are ignored when closing a file descriptor. The reason
320
+ // for this is that if an error occurs we don't actually know if the
321
+ // file descriptor was closed or not, and if we retried (for something
322
+ // like EINTR), we might close another valid file descriptor (opened
323
+ // after we closed ours.
315
324
if self . close_on_drop && self . fd > libc:: STDERR_FILENO {
316
- unsafe { libc:: close ( self . fd ) ; }
325
+ let n = unsafe { libc:: close ( self . fd ) } ;
326
+ if n != 0 {
327
+ warn ! ( "error {} when closing file descriptor {}" , n, self . fd) ;
328
+ }
317
329
}
318
330
}
319
331
}
@@ -336,7 +348,7 @@ impl CFile {
336
348
}
337
349
338
350
pub fn flush ( & mut self ) -> Result < ( ) , IoError > {
339
- super :: mkerr_libc ( unsafe { libc:: fflush ( self . file ) } )
351
+ super :: mkerr_libc ( retry ( || unsafe { libc:: fflush ( self . file ) } ) )
340
352
}
341
353
}
342
354
@@ -444,13 +456,13 @@ pub fn open(path: &CString, fm: io::FileMode, fa: io::FileAccess)
444
456
#[ cfg( windows) ]
445
457
fn os_open ( path : & CString , flags : c_int , mode : c_int ) -> c_int {
446
458
as_utf16_p ( path. as_str ( ) . unwrap ( ) , |path| {
447
- unsafe { libc:: wopen ( path, flags, mode) }
459
+ retry ( || unsafe { libc:: wopen ( path, flags, mode) } )
448
460
} )
449
461
}
450
462
451
463
#[ cfg( unix) ]
452
464
fn os_open ( path : & CString , flags : c_int , mode : c_int ) -> c_int {
453
- unsafe { libc:: open ( path. with_ref ( |p| p) , flags, mode) }
465
+ retry ( || unsafe { libc:: open ( path. with_ref ( |p| p) , flags, mode) } )
454
466
}
455
467
}
456
468
@@ -469,9 +481,9 @@ pub fn mkdir(p: &CString, mode: io::FilePermission) -> IoResult<()> {
469
481
470
482
#[ cfg( unix) ]
471
483
fn os_mkdir ( p : & CString , mode : c_int ) -> IoResult < ( ) > {
472
- super :: mkerr_libc ( unsafe {
484
+ super :: mkerr_libc ( retry ( || unsafe {
473
485
libc:: mkdir ( p. with_ref ( |p| p) , mode as libc:: mode_t )
474
- } )
486
+ } ) )
475
487
}
476
488
}
477
489
@@ -582,7 +594,7 @@ pub fn unlink(p: &CString) -> IoResult<()> {
582
594
583
595
#[ cfg( unix) ]
584
596
fn os_unlink ( p : & CString ) -> IoResult < ( ) > {
585
- super :: mkerr_libc ( unsafe { libc:: unlink ( p. with_ref ( |p| p) ) } )
597
+ super :: mkerr_libc ( retry ( || unsafe { libc:: unlink ( p. with_ref ( |p| p) ) } ) )
586
598
}
587
599
}
588
600
@@ -602,9 +614,9 @@ pub fn rename(old: &CString, new: &CString) -> IoResult<()> {
602
614
603
615
#[ cfg( unix) ]
604
616
fn os_rename ( old : & CString , new : & CString ) -> IoResult < ( ) > {
605
- super :: mkerr_libc ( unsafe {
617
+ super :: mkerr_libc ( retry ( || unsafe {
606
618
libc:: rename ( old. with_ref ( |p| p) , new. with_ref ( |p| p) )
607
- } )
619
+ } ) )
608
620
}
609
621
}
610
622
@@ -614,13 +626,15 @@ pub fn chmod(p: &CString, mode: io::FilePermission) -> IoResult<()> {
614
626
#[ cfg( windows) ]
615
627
fn os_chmod ( p : & CString , mode : c_int ) -> c_int {
616
628
unsafe {
617
- as_utf16_p ( p. as_str ( ) . unwrap ( ) , |p| libc:: wchmod ( p, mode) )
629
+ as_utf16_p ( p. as_str ( ) . unwrap ( ) , |p| retry ( || {
630
+ libc:: wchmod ( p, mode)
631
+ } ) )
618
632
}
619
633
}
620
634
621
635
#[ cfg( unix) ]
622
636
fn os_chmod ( p : & CString , mode : c_int ) -> c_int {
623
- unsafe { libc:: chmod ( p. with_ref ( |p| p) , mode as libc:: mode_t ) }
637
+ retry ( || unsafe { libc:: chmod ( p. with_ref ( |p| p) , mode as libc:: mode_t ) } )
624
638
}
625
639
}
626
640
@@ -630,13 +644,15 @@ pub fn rmdir(p: &CString) -> IoResult<()> {
630
644
#[ cfg( windows) ]
631
645
fn os_rmdir ( p : & CString ) -> c_int {
632
646
unsafe {
633
- as_utf16_p ( p. as_str ( ) . unwrap ( ) , |p| libc:: wrmdir ( p) )
647
+ as_utf16_p ( p. as_str ( ) . unwrap ( ) , |p| retry ( || {
648
+ libc:: wrmdir ( p)
649
+ } ) )
634
650
}
635
651
}
636
652
637
653
#[ cfg( unix) ]
638
654
fn os_rmdir ( p : & CString ) -> c_int {
639
- unsafe { libc:: rmdir ( p. with_ref ( |p| p) ) }
655
+ retry ( || unsafe { libc:: rmdir ( p. with_ref ( |p| p) ) } )
640
656
}
641
657
}
642
658
@@ -649,10 +665,10 @@ pub fn chown(p: &CString, uid: int, gid: int) -> IoResult<()> {
649
665
650
666
#[ cfg( unix) ]
651
667
fn os_chown ( p : & CString , uid : int , gid : int ) -> c_int {
652
- unsafe {
668
+ retry ( || unsafe {
653
669
libc:: chown ( p. with_ref ( |p| p) , uid as libc:: uid_t ,
654
670
gid as libc:: gid_t )
655
- }
671
+ } )
656
672
}
657
673
}
658
674
@@ -697,10 +713,10 @@ pub fn readlink(p: &CString) -> IoResult<Path> {
697
713
len = 1024 ; // XXX: read PATH_MAX from C ffi?
698
714
}
699
715
let mut buf = vec:: with_capacity :: < u8 > ( len as uint ) ;
700
- match unsafe {
716
+ match retry ( || unsafe {
701
717
libc:: readlink ( p, buf. as_ptr ( ) as * mut libc:: c_char ,
702
- len as libc:: size_t )
703
- } {
718
+ len as libc:: size_t ) as libc :: c_int
719
+ } ) {
704
720
-1 => Err ( super :: last_error ( ) ) ,
705
721
n => {
706
722
assert ! ( n > 0 ) ;
@@ -725,9 +741,9 @@ pub fn symlink(src: &CString, dst: &CString) -> IoResult<()> {
725
741
726
742
#[ cfg( unix) ]
727
743
fn os_symlink ( src : & CString , dst : & CString ) -> IoResult < ( ) > {
728
- super :: mkerr_libc ( unsafe {
744
+ super :: mkerr_libc ( retry ( || unsafe {
729
745
libc:: symlink ( src. with_ref ( |p| p) , dst. with_ref ( |p| p) )
730
- } )
746
+ } ) )
731
747
}
732
748
}
733
749
@@ -745,9 +761,9 @@ pub fn link(src: &CString, dst: &CString) -> IoResult<()> {
745
761
746
762
#[ cfg( unix) ]
747
763
fn os_link ( src : & CString , dst : & CString ) -> IoResult < ( ) > {
748
- super :: mkerr_libc ( unsafe {
764
+ super :: mkerr_libc ( retry ( || unsafe {
749
765
libc:: link ( src. with_ref ( |p| p) , dst. with_ref ( |p| p) )
750
- } )
766
+ } ) )
751
767
}
752
768
}
753
769
@@ -842,7 +858,7 @@ pub fn stat(p: &CString) -> IoResult<io::FileStat> {
842
858
fn os_stat ( p : & CString ) -> IoResult < io:: FileStat > {
843
859
let mut stat: libc:: stat = unsafe { intrinsics:: uninit ( ) } ;
844
860
as_utf16_p ( p. as_str ( ) . unwrap ( ) , |up| {
845
- match unsafe { libc:: wstat ( up, & mut stat) } {
861
+ match retry ( || unsafe { libc:: wstat ( up, & mut stat) } ) {
846
862
0 => Ok ( mkstat ( & stat, p) ) ,
847
863
_ => Err ( super :: last_error ( ) ) ,
848
864
}
@@ -852,7 +868,7 @@ pub fn stat(p: &CString) -> IoResult<io::FileStat> {
852
868
#[ cfg( unix) ]
853
869
fn os_stat ( p : & CString ) -> IoResult < io:: FileStat > {
854
870
let mut stat: libc:: stat = unsafe { intrinsics:: uninit ( ) } ;
855
- match unsafe { libc:: stat ( p. with_ref ( |p| p) , & mut stat) } {
871
+ match retry ( || unsafe { libc:: stat ( p. with_ref ( |p| p) , & mut stat) } ) {
856
872
0 => Ok ( mkstat ( & stat, p) ) ,
857
873
_ => Err ( super :: last_error ( ) ) ,
858
874
}
@@ -871,7 +887,7 @@ pub fn lstat(p: &CString) -> IoResult<io::FileStat> {
871
887
#[ cfg( unix) ]
872
888
fn os_lstat ( p : & CString ) -> IoResult < io:: FileStat > {
873
889
let mut stat: libc:: stat = unsafe { intrinsics:: uninit ( ) } ;
874
- match unsafe { libc:: lstat ( p. with_ref ( |p| p) , & mut stat) } {
890
+ match retry ( || unsafe { libc:: lstat ( p. with_ref ( |p| p) , & mut stat) } ) {
875
891
0 => Ok ( mkstat ( & stat, p) ) ,
876
892
_ => Err ( super :: last_error ( ) ) ,
877
893
}
@@ -888,7 +904,9 @@ pub fn utime(p: &CString, atime: u64, mtime: u64) -> IoResult<()> {
888
904
modtime : ( mtime / 1000 ) as libc:: time64_t ,
889
905
} ;
890
906
unsafe {
891
- as_utf16_p ( p. as_str ( ) . unwrap ( ) , |p| libc:: wutime ( p, & buf) )
907
+ as_utf16_p ( p. as_str ( ) . unwrap ( ) , |p| retry ( || {
908
+ libc:: wutime ( p, & buf)
909
+ } ) )
892
910
}
893
911
}
894
912
@@ -898,7 +916,7 @@ pub fn utime(p: &CString, atime: u64, mtime: u64) -> IoResult<()> {
898
916
actime : ( atime / 1000 ) as libc:: time_t ,
899
917
modtime : ( mtime / 1000 ) as libc:: time_t ,
900
918
} ;
901
- unsafe { libc:: utime ( p. with_ref ( |p| p) , & buf) }
919
+ retry ( || unsafe { libc:: utime ( p. with_ref ( |p| p) , & buf) } )
902
920
}
903
921
}
904
922
0 commit comments