Skip to content

Commit

Permalink
sys::sendfile adding solaris' sendfilev wrapper proposal.
Browse files Browse the repository at this point in the history
  • Loading branch information
devnexen committed Nov 24, 2023
1 parent c1147c6 commit 791a613
Showing 1 changed file with 68 additions and 0 deletions.
68 changes: 68 additions & 0 deletions src/sys/sendfile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,49 @@ cfg_if! {
)
}
}
} else if #[cfg(any(target_os = "solaris", target_os = "illumos"))] {
#[derive(Clone, Debug, Copy)]
/// Mapping of the raw C sendfilevec_t struct
/// no need to bother with `sfv_flag` since it needs to be always 0.
pub struct SendfileVec {
/// input file descriptor
pub fd: i32,
/// offset to read from
pub off: isize,
/// size of the data to read
pub len: usize,
}

const SFV_FD_SELF: i32 = -2;

impl SendfileVec {
/// initialises SendfileVec to send data directly from the process's address space
/// same in C with sfv_fd set to SFV_FD_SELF.
pub fn newself(
off: isize,
len: usize
) -> SendfileVec {
SendfileVec{fd: SFV_FD_SELF, off, len}
}

/// initialises SendfileVec to send data from `fd`.
pub fn new(
fd: i32,
off: isize,
len: usize
) -> SendfileVec {
SendfileVec{fd, off, len}
}

fn tosendfilevec(&self) -> libc::sendfilevec_t {
libc::sendfilevec_t{
sfv_fd: self.fd,
sfv_flag: 0,
sfv_off: self.off as off_t,
sfv_len: self.len
}
}
}
}
}

Expand Down Expand Up @@ -287,5 +330,30 @@ cfg_if! {
};
(Errno::result(return_code).and(Ok(())), len)
}
} else if #[cfg(any(target_os = "solaris", target_os = "illumos"))] {
/// Write data from the vec arrays to `out_sock` and returns a `Result` and a
/// count of bytes written.
///
/// Each `SendfileVec` set needs to be instantiated either with `SendfileVec::new` or
/// `SendfileVec::newself`.
///
/// The former allows to send data from a file descriptor through `fd`,
/// from an offset `off` and for a given amount of data `len`.
///
/// The latter allows to send data from the process' address space, from an offset `off`
/// and for a given amount of data `len`.
///
/// For more information, see
/// [the sendfilev{3) man page.](https://docs.oracle.com/cd/E86824_01/html/E54768/sendfilev-3ext.html)
pub fn sendfilev<F1: AsFd, F2: AsFd>(
out_sock: F2,
vec: Vec<SendfileVec>
) -> Result<usize> {
let rawvec: Vec<libc::sendfilevec_t> = vec.iter().map(|&v| v.tosendfilevec()).collect();
let ret = unsafe {
libc::sendfilev(out_sock.as_fd().as_raw_fd(), rawvec.as_ptr(), rawvec.len() as i32, ptr::null_mut())
};
Errno::result(ret).map(|r| r as usize)
}
}
}

0 comments on commit 791a613

Please sign in to comment.