use std::io::{Seek, SeekFrom, Write};
use wireshift_core::buffer::{Buffer, Submitted};
use wireshift_core::op::CompletionPayload;
use wireshift_core::{Error, Result};
use crate::ops::retry_eintr;
pub fn execute_write(
mut file: std::fs::File,
offset: u64,
buffer: Buffer<Submitted>,
) -> Result<CompletionPayload> {
if let Err(error) = file.seek(SeekFrom::Start(offset)) {
let is_espipe = error.raw_os_error() == Some(rustix::io::Errno::SPIPE.raw_os_error());
if !is_espipe || offset > 0 {
return Err(Error::io(
"write seek failed",
error,
"seek to a valid offset before writing",
));
}
}
let data = &buffer.backend_ref()[..buffer.filled_len()];
let bytes = retry_eintr!(file.write(data)).map_err(|error| {
Error::io(
"write failed",
error,
"ensure the file descriptor is writable",
)
})?;
Ok(CompletionPayload::Bytes(bytes))
}
pub fn execute_write_vectored(
mut file: std::fs::File,
offset: u64,
buffers: Vec<Buffer<Submitted>>,
) -> Result<CompletionPayload> {
if let Err(error) = file.seek(SeekFrom::Start(offset)) {
let is_espipe = error.raw_os_error() == Some(rustix::io::Errno::SPIPE.raw_os_error());
if !is_espipe || offset > 0 {
return Err(Error::io(
"writev seek failed",
error,
"seek to a valid offset before writing vectored data",
));
}
}
let mut written = 0_usize;
for buffer in buffers {
let chunk = &buffer.backend_ref()[..buffer.filled_len()];
let bytes = retry_eintr!(file.write(chunk)).map_err(|error| {
Error::io(
"writev segment write failed",
error,
"ensure the file descriptor remains writable for all writev segments",
)
})?;
written += bytes;
if bytes < chunk.len() {
break;
}
}
Ok(CompletionPayload::Bytes(written))
}