summaryrefslogtreecommitdiff
path: root/src/sys/uio.rs
diff options
context:
space:
mode:
authorCarl Lerche <me@carllerche.com>2015-02-21 14:33:27 -0800
committerCarl Lerche <me@carllerche.com>2015-02-21 14:33:27 -0800
commit60ccee778b2adca488706c586bd61c5affa90de3 (patch)
treed8738241a4e5fa8fe02331f33ab190b980d507fd /src/sys/uio.rs
parentb2454c9d793dfeb946d5e12f51ad571d32fa9987 (diff)
downloadnix-60ccee778b2adca488706c586bd61c5affa90de3.zip
Cleanup readv & writev + tests
Diffstat (limited to 'src/sys/uio.rs')
-rw-r--r--src/sys/uio.rs78
1 files changed, 78 insertions, 0 deletions
diff --git a/src/sys/uio.rs b/src/sys/uio.rs
new file mode 100644
index 00000000..322182c5
--- /dev/null
+++ b/src/sys/uio.rs
@@ -0,0 +1,78 @@
+
+mod ffi {
+ use super::IoVec;
+ use libc::{ssize_t];
+
+ // vectorized version of write
+ // doc: http://man7.org/linux/man-pages/man2/writev.2.html
+ pub fn writev(fd: Fd, iov: *const IoVec<&[u8]>, iovcnt: c_int) -> ssize_t;
+
+ // vectorized version of read
+ // doc: http://man7.org/linux/man-pages/man2/readv.2.html
+ pub fn readv(fd: Fd, iov: *const IoVec<&mut [u8]>, iovcnt: c_int) -> ssize_t;
+}
+
+pub fn writev(fd: Fd, iov: &[IoVec<&[u8]>]) -> NixResult<usize> {
+ let res = unsafe { ffi::writev(fd, iov.as_ptr(), iov.len() as c_int) };
+
+ if res < 0 {
+ return Err(NixError::Sys(Errno::last()));
+ }
+
+ return Ok(res as usize)
+}
+
+pub fn readv(fd: Fd, iov: &mut [IoVec<&mut [u8]>]) -> NixResult<usize> {
+ let res = unsafe { ffi::readv(fd, iov.as_ptr(), iov.len() as c_int) };
+ if res < 0 {
+ return Err(NixError::Sys(Errno::last()));
+ }
+
+ return Ok(res as usize)
+}
+
+#[repr(C)]
+pub struct IoVec<T> {
+ iov_base: *mut c_void,
+ iov_len: size_t,
+ phantom: PhantomData<T>
+}
+
+impl<T> IoVec<T> {
+ #[inline]
+ pub fn as_slice<'a>(&'a self) -> &'a [u8] {
+ use std::slice;
+
+ unsafe {
+ slice::from_raw_parts(
+ self.iov_base as *const u8,
+ self.iov_len as usize)
+ }
+ }
+}
+
+impl<'a> IoVec<&'a [u8]> {
+ pub fn from_slice(buf: &'a [u8]) -> IoVec<&'a [u8]> {
+ IoVec {
+ iov_base: buf.as_ptr() as *mut c_void,
+ iov_len: buf.len() as size_t,
+ phantom: PhantomData
+ }
+ }
+}
+
+impl<'a> IoVec<&'a mut [u8]> {
+ pub fn from_mut_slice(buf: &'a mut [u8]) -> IoVec<&'a mut [u8]> {
+ IoVec {
+ iov_base: buf.as_ptr() as *mut c_void,
+ iov_len: buf.len() as size_t,
+ phantom: PhantomData
+ }
+ }
+}
+
+#[test]
+pub fn test_size_of_io_vec() {
+ use nixtest;
+ nixtest::assert_size_of::<IoVec<&[u8]>>("iovec");
+}