wireshift_fallback/ops/
write.rs1use std::io::{Seek, SeekFrom, Write};
2
3use wireshift_core::buffer::{Buffer, Submitted};
4use wireshift_core::op::CompletionPayload;
5use wireshift_core::{Error, Result};
6
7use crate::ops::retry_eintr;
8
9pub fn execute_write(
12 mut file: std::fs::File,
13 offset: u64,
14 buffer: Buffer<Submitted>,
15) -> Result<CompletionPayload> {
16 if let Err(error) = file.seek(SeekFrom::Start(offset)) {
17 let is_espipe = error.raw_os_error() == Some(rustix::io::Errno::SPIPE.raw_os_error());
18 if !is_espipe || offset > 0 {
19 return Err(Error::io(
20 "write seek failed",
21 error,
22 "seek to a valid offset before writing",
23 ));
24 }
25 }
26 let data = &buffer.backend_ref()[..buffer.filled_len()];
27 let bytes = retry_eintr!(file.write(data)).map_err(|error| {
28 Error::io(
29 "write failed",
30 error,
31 "ensure the file descriptor is writable",
32 )
33 })?;
34 Ok(CompletionPayload::Bytes(bytes))
35}
36
37pub fn execute_write_vectored(
40 mut file: std::fs::File,
41 offset: u64,
42 buffers: Vec<Buffer<Submitted>>,
43) -> Result<CompletionPayload> {
44 if let Err(error) = file.seek(SeekFrom::Start(offset)) {
45 let is_espipe = error.raw_os_error() == Some(rustix::io::Errno::SPIPE.raw_os_error());
46 if !is_espipe || offset > 0 {
47 return Err(Error::io(
48 "writev seek failed",
49 error,
50 "seek to a valid offset before writing vectored data",
51 ));
52 }
53 }
54 let mut written = 0_usize;
55 for buffer in buffers {
56 let chunk = &buffer.backend_ref()[..buffer.filled_len()];
57 let bytes = retry_eintr!(file.write(chunk)).map_err(|error| {
58 Error::io(
59 "writev segment write failed",
60 error,
61 "ensure the file descriptor remains writable for all writev segments",
62 )
63 })?;
64 written += bytes;
65 if bytes < chunk.len() {
66 break;
67 }
68 }
69 Ok(CompletionPayload::Bytes(written))
70}