From 6af51aa23225504022acdbcecc9f2e5d559522c4 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Sat, 21 Feb 2015 22:42:10 -0800 Subject: Fix uio and add SockAddr conversions --- src/sys/mod.rs | 2 ++ src/sys/socket.rs | 105 +++++++++++++++++++++++++++++++++++++++++++++++++----- src/sys/uio.rs | 22 ++++++++---- 3 files changed, 114 insertions(+), 15 deletions(-) (limited to 'src/sys') diff --git a/src/sys/mod.rs b/src/sys/mod.rs index fbcf9e27..5dacde21 100644 --- a/src/sys/mod.rs +++ b/src/sys/mod.rs @@ -26,3 +26,5 @@ pub mod utsname; pub mod wait; pub mod mman; + +pub mod uio; diff --git a/src/sys/socket.rs b/src/sys/socket.rs index b462570d..ff2d7ee7 100644 --- a/src/sys/socket.rs +++ b/src/sys/socket.rs @@ -1,13 +1,29 @@ -use std::{mem, ptr, fmt}; -use libc::{c_void, c_int, socklen_t, size_t, ssize_t}; +use {NixError, NixResult, from_ffi}; use errno::Errno; -use fcntl::{Fd, fcntl, FD_CLOEXEC, O_NONBLOCK}; -use fcntl::FcntlArg::{F_SETFD, F_SETFL}; use features; -use {NixError, NixResult, from_ffi}; - -pub use libc::{in_addr, sockaddr, sockaddr_storage, sockaddr_in, sockaddr_in6, sockaddr_un, sa_family_t, ip_mreq}; - +use fcntl::{fcntl, FD_CLOEXEC, O_NONBLOCK}; +use fcntl::FcntlArg::{F_SETFD, F_SETFL}; +use libc::{c_void, c_int, socklen_t, size_t, ssize_t}; +use std::{fmt, mem, net, ptr, path}; +use std::ffi::AsOsStr; +use std::os::unix::prelude::*; + +/* + * + * ===== Re-exports ===== + * + */ + +pub use libc::{ + in_addr, + sockaddr, + sockaddr_storage, + sockaddr_in, + sockaddr_in6, + sockaddr_un, + sa_family_t, + ip_mreq +}; pub use self::consts::*; mod ffi { @@ -32,13 +48,86 @@ bitflags!( } ); +/* + * + * ===== SockAddr ===== + * + */ + +/// Represents a socket address #[derive(Copy)] pub enum SockAddr { + // TODO: Rename these variants IpV4, IpV6, Unix SockIpV4(sockaddr_in), SockIpV6(sockaddr_in6), SockUnix(sockaddr_un) } +/// Convert a value into a socket address +pub trait AsSockAddr { + fn as_sock_addr(&self) -> NixResult; +} + +/// Convert a path into a unix domain socket address +impl AsSockAddr for path::Path { + fn as_sock_addr(&self) -> NixResult { + let bytes = self.as_os_str().as_bytes(); + + Ok(SockAddr::SockUnix(unsafe { + let mut ret = sockaddr_un { + sun_family: AF_UNIX as sa_family_t, + .. mem::zeroed() + }; + + // Make sure the destination has enough capacity + if bytes.len() >= ret.sun_path.len() { + return Err(NixError::Sys(Errno::ENAMETOOLONG)); + } + + // Copy the path + ptr::copy_memory( + ret.sun_path.as_mut_ptr(), + bytes.as_ptr() as *const i8, + bytes.len()); + + ret + })) + } +} + +/// Convert an inet address into a socket address +impl AsSockAddr for net::SocketAddr { + fn as_sock_addr(&self) -> NixResult { + use std::net::IpAddr; + use std::num::Int; + + match self.ip() { + IpAddr::V4(ip) => { + let addr = ip.octets(); + Ok(SockAddr::SockIpV4(sockaddr_in { + sin_family: AF_INET as sa_family_t, + sin_port: self.port(), + sin_addr: in_addr { + s_addr: Int::from_be( + ((addr[0] as u32) << 24) | + ((addr[1] as u32) << 16) | + ((addr[2] as u32) << 8) | + ((addr[3] as u32) << 0)) + }, + .. unsafe { mem::zeroed() } + })) + } + _ => unimplemented!() + } + } +} + +/* + * + * ===== Consts ===== + * + */ + #[cfg(target_os = "linux")] mod consts { use libc::{c_int, uint8_t}; diff --git a/src/sys/uio.rs b/src/sys/uio.rs index 322182c5..35ae6da3 100644 --- a/src/sys/uio.rs +++ b/src/sys/uio.rs @@ -1,15 +1,23 @@ +use {NixResult, NixError}; +use errno::Errno; +use fcntl::Fd; +use libc::{c_int, c_void, size_t}; +use std::marker::PhantomData; mod ffi { use super::IoVec; - use libc::{ssize_t]; + use libc::{ssize_t, c_int}; + use fcntl::Fd; - // 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; + extern { + // 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; + // 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 { -- cgit v1.2.3