None means non-blocking failed
(
&mut self,
buf: Option<PyBuffer>,
buf_range: Range<usize>,
vm: &VirtualMachine,
)
| 1010 | |
| 1011 | /// None means non-blocking failed |
| 1012 | fn raw_write( |
| 1013 | &mut self, |
| 1014 | buf: Option<PyBuffer>, |
| 1015 | buf_range: Range<usize>, |
| 1016 | vm: &VirtualMachine, |
| 1017 | ) -> PyResult<Option<usize>> { |
| 1018 | let len = buf_range.len(); |
| 1019 | |
| 1020 | // Prepare the memoryview; if using the internal buffer, stash it |
| 1021 | // in write_buf so we can restore it after the write. |
| 1022 | let (mem_obj, write_buf) = if let Some(buf) = buf { |
| 1023 | let mem_obj = |
| 1024 | PyMemoryView::from_buffer_range(buf, buf_range, vm)?.into_ref(&vm.ctx); |
| 1025 | (mem_obj, None) |
| 1026 | } else { |
| 1027 | let v = core::mem::take(&mut self.buffer); |
| 1028 | let wb = VecBuffer::from(v).into_ref(&vm.ctx); |
| 1029 | let mem_obj = |
| 1030 | PyMemoryView::from_buffer_range(wb.clone().into_pybuffer(true), buf_range, vm)? |
| 1031 | .into_ref(&vm.ctx); |
| 1032 | (mem_obj, Some(wb)) |
| 1033 | }; |
| 1034 | |
| 1035 | // Loop if write() raises EINTR (PEP 475) |
| 1036 | let res = loop { |
| 1037 | let res = vm.call_method(self.raw.as_ref().unwrap(), "write", (mem_obj.clone(),)); |
| 1038 | match trap_eintr(res, vm) { |
| 1039 | Ok(Some(val)) => break Ok(val), |
| 1040 | Ok(None) => continue, |
| 1041 | Err(e) => break Err(e), |
| 1042 | } |
| 1043 | }; |
| 1044 | |
| 1045 | // Restore internal buffer if we borrowed it |
| 1046 | if let Some(wb) = write_buf { |
| 1047 | mem_obj.release(); |
| 1048 | self.buffer = wb.take(); |
| 1049 | } |
| 1050 | |
| 1051 | let res = res?; |
| 1052 | |
| 1053 | if vm.is_none(&res) { |
| 1054 | return Ok(None); |
| 1055 | } |
| 1056 | let n = isize::try_from_object(vm, res)?; |
| 1057 | if n < 0 || n as usize > len { |
| 1058 | return Err(vm.new_os_error(format!( |
| 1059 | "raw write() returned invalid length {n} (should have been between 0 and {len})" |
| 1060 | ))); |
| 1061 | } |
| 1062 | if self.abs_pos != -1 { |
| 1063 | self.abs_pos += n as Offset |
| 1064 | } |
| 1065 | Ok(Some(n as usize)) |
| 1066 | } |
| 1067 | |
| 1068 | fn write(&mut self, obj: ArgBytesLike, vm: &VirtualMachine) -> PyResult<usize> { |
| 1069 | if !self.valid_read() && !self.valid_write() { |
no test coverage detected