@@ -1001,10 +1001,18 @@ mod _io {
10011001 ) -> PyResult < Option < usize > > {
10021002 let len = buf_range. len ( ) ;
10031003 let res = if let Some ( buf) = buf {
1004- let mem_obj = PyMemoryView :: from_buffer_range ( buf, buf_range, vm) ?. to_pyobject ( vm) ;
1004+ let mem_obj =
1005+ PyMemoryView :: from_buffer_range ( buf, buf_range, vm) ?. into_ref ( & vm. ctx ) ;
10051006
1006- // TODO: loop if write() raises an interrupt
1007- vm. call_method ( self . raw . as_ref ( ) . unwrap ( ) , "write" , ( mem_obj, ) ) ?
1007+ // Loop if write() raises EINTR (PEP 475)
1008+ loop {
1009+ let res =
1010+ vm. call_method ( self . raw . as_ref ( ) . unwrap ( ) , "write" , ( mem_obj. clone ( ) , ) ) ;
1011+ match trap_eintr ( res, vm) ? {
1012+ Some ( val) => break val,
1013+ None => continue ,
1014+ }
1015+ }
10081016 } else {
10091017 let v = core:: mem:: take ( & mut self . buffer ) ;
10101018 let write_buf = VecBuffer :: from ( v) . into_ref ( & vm. ctx ) ;
@@ -1015,8 +1023,16 @@ mod _io {
10151023 ) ?
10161024 . into_ref ( & vm. ctx ) ;
10171025
1018- // TODO: loop if write() raises an interrupt
1019- let res = vm. call_method ( self . raw . as_ref ( ) . unwrap ( ) , "write" , ( mem_obj. clone ( ) , ) ) ;
1026+ // Loop if write() raises EINTR (PEP 475)
1027+ let res = loop {
1028+ let res =
1029+ vm. call_method ( self . raw . as_ref ( ) . unwrap ( ) , "write" , ( mem_obj. clone ( ) , ) ) ;
1030+ match trap_eintr ( res, vm) {
1031+ Ok ( Some ( val) ) => break Ok ( val) ,
1032+ Ok ( None ) => continue ,
1033+ Err ( e) => break Err ( e) ,
1034+ }
1035+ } ;
10201036
10211037 mem_obj. release ( ) ;
10221038 self . buffer = write_buf. take ( ) ;
@@ -5737,11 +5753,18 @@ mod fileio {
57375753
57385754 let mut handle = zelf. get_fd ( vm) ?;
57395755
5740- let len = match obj. with_ref ( |b| handle. write ( b) ) {
5741- Ok ( n) => n,
5742- // Non-blocking mode: return None if EAGAIN
5743- Err ( e) if e. raw_os_error ( ) == Some ( libc:: EAGAIN ) => return Ok ( None ) ,
5744- Err ( e) => return Err ( Self :: io_error ( zelf, e, vm) ) ,
5756+ // Loop on EINTR (PEP 475)
5757+ let len = loop {
5758+ match obj. with_ref ( |b| handle. write ( b) ) {
5759+ Ok ( n) => break n,
5760+ Err ( e) if e. raw_os_error ( ) == Some ( libc:: EINTR ) => {
5761+ vm. check_signals ( ) ?;
5762+ continue ;
5763+ }
5764+ // Non-blocking mode: return None if EAGAIN
5765+ Err ( e) if e. raw_os_error ( ) == Some ( libc:: EAGAIN ) => return Ok ( None ) ,
5766+ Err ( e) => return Err ( Self :: io_error ( zelf, e, vm) ) ,
5767+ }
57455768 } ;
57465769
57475770 //return number of bytes written
0 commit comments