@@ -20,7 +20,7 @@ use std::rt::rtio;
2020use std:: unstable:: intrinsics;
2121use std:: vec;
2222
23- use super :: IoResult ;
23+ use io :: { IoResult , retry } ;
2424
2525#[ cfg( windows) ] use std:: os:: win32:: { as_utf16_p, fill_utf16_buf_and_decode} ;
2626#[ cfg( windows) ] use std:: ptr;
@@ -143,8 +143,8 @@ impl rtio::RtioFileStream for FileDesc {
143143 overlap. OffsetHigh = ( offset >> 32 ) as libc:: DWORD ;
144144
145145 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) {
148148 0 => Err ( super :: last_error ( ) ) ,
149149 _ => Ok ( bytes_read as int )
150150 }
@@ -153,10 +153,10 @@ impl rtio::RtioFileStream for FileDesc {
153153
154154 #[ cfg( unix) ]
155155 fn os_pread ( fd : c_int , buf : * u8 , amt : uint , offset : u64 ) -> IoResult < int > {
156- match unsafe {
156+ match retry ( || unsafe {
157157 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+ } ) {
160160 -1 => Err ( super :: last_error ( ) ) ,
161161 n => Ok ( n as int )
162162 }
@@ -184,10 +184,10 @@ impl rtio::RtioFileStream for FileDesc {
184184
185185 #[ cfg( unix) ]
186186 fn os_pwrite ( fd : c_int , buf : * u8 , amt : uint , offset : u64 ) -> IoResult < ( ) > {
187- super :: mkerr_libc ( unsafe {
187+ super :: mkerr_libc ( retry ( || unsafe {
188188 libc:: pwrite ( fd, buf as * libc:: c_void , amt as libc:: size_t ,
189189 offset as libc:: off_t )
190- } as c_int )
190+ } as c_int ) )
191191 }
192192 }
193193 #[ cfg( windows) ]
@@ -240,7 +240,7 @@ impl rtio::RtioFileStream for FileDesc {
240240 }
241241 #[ cfg( unix) ]
242242 fn os_fsync ( fd : c_int ) -> IoResult < ( ) > {
243- super :: mkerr_libc ( unsafe { libc:: fsync ( fd) } )
243+ super :: mkerr_libc ( retry ( || unsafe { libc:: fsync ( fd) } ) )
244244 }
245245 }
246246 #[ cfg( windows) ]
@@ -255,9 +255,13 @@ impl rtio::RtioFileStream for FileDesc {
255255 unsafe { libc:: fcntl ( fd, libc:: F_FULLFSYNC ) }
256256 }
257257 #[ 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+ }
259261 #[ 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+ }
261265 }
262266
263267 #[ cfg( windows) ]
@@ -278,9 +282,9 @@ impl rtio::RtioFileStream for FileDesc {
278282 }
279283 #[ cfg( unix) ]
280284 fn truncate ( & mut self , offset : i64 ) -> Result < ( ) , IoError > {
281- super :: mkerr_libc ( unsafe {
285+ super :: mkerr_libc ( retry ( || unsafe {
282286 libc:: ftruncate ( self . fd , offset as libc:: off_t )
283- } )
287+ } ) )
284288 }
285289}
286290
@@ -311,9 +315,17 @@ impl rtio::RtioTTY for FileDesc {
311315
312316impl Drop for FileDesc {
313317 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.
315324 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+ }
317329 }
318330 }
319331}
@@ -336,7 +348,7 @@ impl CFile {
336348 }
337349
338350 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 ) } ) )
340352 }
341353}
342354
@@ -444,13 +456,13 @@ pub fn open(path: &CString, fm: io::FileMode, fa: io::FileAccess)
444456 #[ cfg( windows) ]
445457 fn os_open ( path : & CString , flags : c_int , mode : c_int ) -> c_int {
446458 as_utf16_p ( path. as_str ( ) . unwrap ( ) , |path| {
447- unsafe { libc:: wopen ( path, flags, mode) }
459+ retry ( || unsafe { libc:: wopen ( path, flags, mode) } )
448460 } )
449461 }
450462
451463 #[ cfg( unix) ]
452464 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) } )
454466 }
455467}
456468
@@ -469,9 +481,9 @@ pub fn mkdir(p: &CString, mode: io::FilePermission) -> IoResult<()> {
469481
470482 #[ cfg( unix) ]
471483 fn os_mkdir ( p : & CString , mode : c_int ) -> IoResult < ( ) > {
472- super :: mkerr_libc ( unsafe {
484+ super :: mkerr_libc ( retry ( || unsafe {
473485 libc:: mkdir ( p. with_ref ( |p| p) , mode as libc:: mode_t )
474- } )
486+ } ) )
475487 }
476488}
477489
@@ -582,7 +594,7 @@ pub fn unlink(p: &CString) -> IoResult<()> {
582594
583595 #[ cfg( unix) ]
584596 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) ) } ) )
586598 }
587599}
588600
@@ -602,9 +614,9 @@ pub fn rename(old: &CString, new: &CString) -> IoResult<()> {
602614
603615 #[ cfg( unix) ]
604616 fn os_rename ( old : & CString , new : & CString ) -> IoResult < ( ) > {
605- super :: mkerr_libc ( unsafe {
617+ super :: mkerr_libc ( retry ( || unsafe {
606618 libc:: rename ( old. with_ref ( |p| p) , new. with_ref ( |p| p) )
607- } )
619+ } ) )
608620 }
609621}
610622
@@ -614,13 +626,15 @@ pub fn chmod(p: &CString, mode: io::FilePermission) -> IoResult<()> {
614626 #[ cfg( windows) ]
615627 fn os_chmod ( p : & CString , mode : c_int ) -> c_int {
616628 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+ } ) )
618632 }
619633 }
620634
621635 #[ cfg( unix) ]
622636 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 ) } )
624638 }
625639}
626640
@@ -630,13 +644,15 @@ pub fn rmdir(p: &CString) -> IoResult<()> {
630644 #[ cfg( windows) ]
631645 fn os_rmdir ( p : & CString ) -> c_int {
632646 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+ } ) )
634650 }
635651 }
636652
637653 #[ cfg( unix) ]
638654 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) ) } )
640656 }
641657}
642658
@@ -649,10 +665,10 @@ pub fn chown(p: &CString, uid: int, gid: int) -> IoResult<()> {
649665
650666 #[ cfg( unix) ]
651667 fn os_chown ( p : & CString , uid : int , gid : int ) -> c_int {
652- unsafe {
668+ retry ( || unsafe {
653669 libc:: chown ( p. with_ref ( |p| p) , uid as libc:: uid_t ,
654670 gid as libc:: gid_t )
655- }
671+ } )
656672 }
657673}
658674
@@ -697,10 +713,10 @@ pub fn readlink(p: &CString) -> IoResult<Path> {
697713 len = 1024 ; // XXX: read PATH_MAX from C ffi?
698714 }
699715 let mut buf = vec:: with_capacity :: < u8 > ( len as uint ) ;
700- match unsafe {
716+ match retry ( || unsafe {
701717 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+ } ) {
704720 -1 => Err ( super :: last_error ( ) ) ,
705721 n => {
706722 assert ! ( n > 0 ) ;
@@ -725,9 +741,9 @@ pub fn symlink(src: &CString, dst: &CString) -> IoResult<()> {
725741
726742 #[ cfg( unix) ]
727743 fn os_symlink ( src : & CString , dst : & CString ) -> IoResult < ( ) > {
728- super :: mkerr_libc ( unsafe {
744+ super :: mkerr_libc ( retry ( || unsafe {
729745 libc:: symlink ( src. with_ref ( |p| p) , dst. with_ref ( |p| p) )
730- } )
746+ } ) )
731747 }
732748}
733749
@@ -745,9 +761,9 @@ pub fn link(src: &CString, dst: &CString) -> IoResult<()> {
745761
746762 #[ cfg( unix) ]
747763 fn os_link ( src : & CString , dst : & CString ) -> IoResult < ( ) > {
748- super :: mkerr_libc ( unsafe {
764+ super :: mkerr_libc ( retry ( || unsafe {
749765 libc:: link ( src. with_ref ( |p| p) , dst. with_ref ( |p| p) )
750- } )
766+ } ) )
751767 }
752768}
753769
@@ -842,7 +858,7 @@ pub fn stat(p: &CString) -> IoResult<io::FileStat> {
842858 fn os_stat ( p : & CString ) -> IoResult < io:: FileStat > {
843859 let mut stat: libc:: stat = unsafe { intrinsics:: uninit ( ) } ;
844860 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) } ) {
846862 0 => Ok ( mkstat ( & stat, p) ) ,
847863 _ => Err ( super :: last_error ( ) ) ,
848864 }
@@ -852,7 +868,7 @@ pub fn stat(p: &CString) -> IoResult<io::FileStat> {
852868 #[ cfg( unix) ]
853869 fn os_stat ( p : & CString ) -> IoResult < io:: FileStat > {
854870 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) } ) {
856872 0 => Ok ( mkstat ( & stat, p) ) ,
857873 _ => Err ( super :: last_error ( ) ) ,
858874 }
@@ -871,7 +887,7 @@ pub fn lstat(p: &CString) -> IoResult<io::FileStat> {
871887 #[ cfg( unix) ]
872888 fn os_lstat ( p : & CString ) -> IoResult < io:: FileStat > {
873889 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) } ) {
875891 0 => Ok ( mkstat ( & stat, p) ) ,
876892 _ => Err ( super :: last_error ( ) ) ,
877893 }
@@ -888,7 +904,9 @@ pub fn utime(p: &CString, atime: u64, mtime: u64) -> IoResult<()> {
888904 modtime : ( mtime / 1000 ) as libc:: time64_t ,
889905 } ;
890906 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+ } ) )
892910 }
893911 }
894912
@@ -898,7 +916,7 @@ pub fn utime(p: &CString, atime: u64, mtime: u64) -> IoResult<()> {
898916 actime : ( atime / 1000 ) as libc:: time_t ,
899917 modtime : ( mtime / 1000 ) as libc:: time_t ,
900918 } ;
901- unsafe { libc:: utime ( p. with_ref ( |p| p) , & buf) }
919+ retry ( || unsafe { libc:: utime ( p. with_ref ( |p| p) , & buf) } )
902920 }
903921}
904922
0 commit comments