@@ -1000,29 +1000,39 @@ mod _io {
10001000 vm : & VirtualMachine ,
10011001 ) -> PyResult < Option < usize > > {
10021002 let len = buf_range. len ( ) ;
1003- let res = if let Some ( buf) = buf {
1004- let mem_obj = PyMemoryView :: from_buffer_range ( buf, buf_range, vm) ?. to_pyobject ( vm) ;
10051003
1006- // TODO: loop if write() raises an interrupt
1007- vm. call_method ( self . raw . as_ref ( ) . unwrap ( ) , "write" , ( mem_obj, ) ) ?
1004+ // Prepare the memoryview; if using the internal buffer, stash it
1005+ // in write_buf so we can restore it after the write.
1006+ let ( mem_obj, write_buf) = if let Some ( buf) = buf {
1007+ let mem_obj =
1008+ PyMemoryView :: from_buffer_range ( buf, buf_range, vm) ?. into_ref ( & vm. ctx ) ;
1009+ ( mem_obj, None )
10081010 } else {
10091011 let v = core:: mem:: take ( & mut self . buffer ) ;
1010- let write_buf = VecBuffer :: from ( v) . into_ref ( & vm. ctx ) ;
1011- let mem_obj = PyMemoryView :: from_buffer_range (
1012- write_buf. clone ( ) . into_pybuffer ( true ) ,
1013- buf_range,
1014- vm,
1015- ) ?
1016- . into_ref ( & vm. ctx ) ;
1012+ let wb = VecBuffer :: from ( v) . into_ref ( & vm. ctx ) ;
1013+ let mem_obj =
1014+ PyMemoryView :: from_buffer_range ( wb. clone ( ) . into_pybuffer ( true ) , buf_range, vm) ?
1015+ . into_ref ( & vm. ctx ) ;
1016+ ( mem_obj, Some ( wb) )
1017+ } ;
10171018
1018- // TODO: loop if write() raises an interrupt
1019+ // Loop if write() raises EINTR (PEP 475)
1020+ let res = loop {
10191021 let res = vm. call_method ( self . raw . as_ref ( ) . unwrap ( ) , "write" , ( mem_obj. clone ( ) , ) ) ;
1022+ match trap_eintr ( res, vm) {
1023+ Ok ( Some ( val) ) => break Ok ( val) ,
1024+ Ok ( None ) => continue ,
1025+ Err ( e) => break Err ( e) ,
1026+ }
1027+ } ;
10201028
1029+ // Restore internal buffer if we borrowed it
1030+ if let Some ( wb) = write_buf {
10211031 mem_obj. release ( ) ;
1022- self . buffer = write_buf. take ( ) ;
1032+ self . buffer = wb. take ( ) ;
1033+ }
10231034
1024- res?
1025- } ;
1035+ let res = res?;
10261036
10271037 if vm. is_none ( & res) {
10281038 return Ok ( None ) ;
@@ -5737,11 +5747,18 @@ mod fileio {
57375747
57385748 let mut handle = zelf. get_fd ( vm) ?;
57395749
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) ) ,
5750+ // Loop on EINTR (PEP 475)
5751+ let len = loop {
5752+ match obj. with_ref ( |b| handle. write ( b) ) {
5753+ Ok ( n) => break n,
5754+ Err ( e) if e. raw_os_error ( ) == Some ( libc:: EINTR ) => {
5755+ vm. check_signals ( ) ?;
5756+ continue ;
5757+ }
5758+ // Non-blocking mode: return None if EAGAIN
5759+ Err ( e) if e. raw_os_error ( ) == Some ( libc:: EAGAIN ) => return Ok ( None ) ,
5760+ Err ( e) => return Err ( Self :: io_error ( zelf, e, vm) ) ,
5761+ }
57455762 } ;
57465763
57475764 //return number of bytes written
0 commit comments