Skip to content

Commit 0893fd1

Browse files
committed
sys::sendfile adding solaris' sendfilev wrapper proposal.
1 parent c1147c6 commit 0893fd1

File tree

1 file changed

+68
-0
lines changed

1 file changed

+68
-0
lines changed

src/sys/sendfile.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,49 @@ cfg_if! {
120120
)
121121
}
122122
}
123+
} else if #[cfg(any(target_os = "solaris", target_os = "illumos"))] {
124+
#[derive(Clone, Debug, Copy)]
125+
/// Mapping of the raw C sendfilevec_t struct
126+
/// no need to bother with `sfv_flag` since it needs to be always 0.
127+
pub struct SendfileVec {
128+
/// input file descriptor
129+
pub fd: i32,
130+
/// offset to read from
131+
pub off: isize,
132+
/// size of the data to read
133+
pub len: usize,
134+
}
135+
136+
const SFV_FD_SELF: i32 = -2;
137+
138+
impl SendfileVec {
139+
/// initialises SendfileVec to send data directly from the process's address space
140+
/// same in C with sfv_fd set to SFV_FD_SELF.
141+
pub fn newself(
142+
off: isize,
143+
len: usize
144+
) -> SendfileVec {
145+
SendfileVec{fd: SFV_FD_SELF, off: off, len: len}
146+
}
147+
148+
/// initialises SendfileVec to send data from `fd`.
149+
pub fn new(
150+
fd: i32,
151+
off: isize,
152+
len: usize
153+
) -> SendfileVec {
154+
SendfileVec{fd: fd, off: off, len: len}
155+
}
156+
157+
fn tosendfilevec(&self) -> libc::sendfilevec_t {
158+
libc::sendfilevec_t{
159+
sfv_fd: self.fd,
160+
sfv_flag: 0,
161+
sfv_off: self.off as off_t,
162+
sfv_len: self.len
163+
}
164+
}
165+
}
123166
}
124167
}
125168

@@ -287,5 +330,30 @@ cfg_if! {
287330
};
288331
(Errno::result(return_code).and(Ok(())), len)
289332
}
333+
} else if #[cfg(any(target_os = "solaris", target_os = "illumos"))] {
334+
/// Write data from the vec arrays to `out_sock` and returns a `Result` and a
335+
/// count of bytes written.
336+
///
337+
/// Each `SendfileVec` set needs to be instantiated either with `SendfileVec::new` or
338+
/// `SendfileVec::newself`.
339+
///
340+
/// The former allows to send data from a file descriptor through `fd`,
341+
/// from an offset `off` and for a given amount of data `len`.
342+
///
343+
/// The latter allows to send data from the process' address space, from an offset `off`
344+
/// and for a given amount of data `len`.
345+
///
346+
/// For more information, see
347+
/// [the sendfilev{3) man page.](https://docs.oracle.com/cd/E86824_01/html/E54768/sendfilev-3ext.html)
348+
pub fn sendfilev<F1: AsFd, F2: AsFd>(
349+
out_sock: F2,
350+
vec: Vec<SendfileVec>
351+
) -> Result<usize> {
352+
let rawvec: Vec<libc::sendfilevec_t> = vec.iter().map(|&v| v.tosendfilevec()).collect();
353+
let ret = unsafe {
354+
libc::sendfilev(out_sock.as_fd().as_raw_fd(), rawvec.as_ptr(), rawvec.len() as i32, ptr::null_mut())
355+
};
356+
Errno::result(ret).map(|r| r as usize)
357+
}
290358
}
291359
}

0 commit comments

Comments
 (0)