use alloc::arc::Arc;
use libc;
-use std::io::net::ip;
-use std::io;
use std::mem;
+use std::rt::mutex;
use std::rt::rtio;
-use std::unstable::mutex;
+use std::rt::rtio::{IoResult, IoError};
-use super::{IoResult, retry, keep_going};
+use super::{retry, keep_going};
use super::c;
use super::util;
#[cfg(unix)] pub type sock_t = super::file::fd_t;
pub fn htons(u: u16) -> u16 {
- mem::to_be16(u)
+ u.to_be()
}
pub fn ntohs(u: u16) -> u16 {
- mem::from_be16(u)
+ Int::from_be(u)
}
enum InAddr {
In6Addr(libc::in6_addr),
}
-fn ip_to_inaddr(ip: ip::IpAddr) -> InAddr {
+fn ip_to_inaddr(ip: rtio::IpAddr) -> InAddr {
match ip {
- ip::Ipv4Addr(a, b, c, d) => {
+ rtio::Ipv4Addr(a, b, c, d) => {
let ip = (a as u32 << 24) |
(b as u32 << 16) |
(c as u32 << 8) |
(d as u32 << 0);
InAddr(libc::in_addr {
- s_addr: mem::from_be32(ip)
+ s_addr: Int::from_be(ip)
})
}
- ip::Ipv6Addr(a, b, c, d, e, f, g, h) => {
+ rtio::Ipv6Addr(a, b, c, d, e, f, g, h) => {
In6Addr(libc::in6_addr {
s6_addr: [
htons(a),
}
}
-fn addr_to_sockaddr(addr: ip::SocketAddr) -> (libc::sockaddr_storage, uint) {
+fn addr_to_sockaddr(addr: rtio::SocketAddr) -> (libc::sockaddr_storage, uint) {
unsafe {
let storage: libc::sockaddr_storage = mem::zeroed();
let len = match ip_to_inaddr(addr.ip) {
}
}
-fn socket(addr: ip::SocketAddr, ty: libc::c_int) -> IoResult<sock_t> {
+fn socket(addr: rtio::SocketAddr, ty: libc::c_int) -> IoResult<sock_t> {
unsafe {
let fam = match addr.ip {
- ip::Ipv4Addr(..) => libc::AF_INET,
- ip::Ipv6Addr(..) => libc::AF_INET6,
+ rtio::Ipv4Addr(..) => libc::AF_INET,
+ rtio::Ipv6Addr(..) => libc::AF_INET6,
};
match libc::socket(fam, ty, 0) {
-1 => Err(super::last_error()),
fn setsockopt<T>(fd: sock_t, opt: libc::c_int, val: libc::c_int,
payload: T) -> IoResult<()> {
unsafe {
- let payload = &payload as *T as *libc::c_void;
+ let payload = &payload as *const T as *const libc::c_void;
let ret = libc::setsockopt(fd, opt, val,
payload,
mem::size_of::<T>() as libc::socklen_t);
}
#[cfg(windows)]
-fn last_error() -> io::IoError {
- io::IoError::from_errno(unsafe { c::WSAGetLastError() } as uint, true)
+pub fn last_error() -> IoError {
+ use std::os;
+ let code = unsafe { c::WSAGetLastError() as uint };
+ IoError {
+ code: code,
+ extra: 0,
+ detail: Some(os::error_string(code)),
+ }
}
#[cfg(not(windows))]
-fn last_error() -> io::IoError {
+fn last_error() -> IoError {
super::last_error()
}
fn sockname(fd: sock_t,
f: unsafe extern "system" fn(sock_t, *mut libc::sockaddr,
*mut libc::socklen_t) -> libc::c_int)
- -> IoResult<ip::SocketAddr>
+ -> IoResult<rtio::SocketAddr>
{
let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
let mut len = mem::size_of::<libc::sockaddr_storage>() as libc::socklen_t;
}
pub fn sockaddr_to_addr(storage: &libc::sockaddr_storage,
- len: uint) -> IoResult<ip::SocketAddr> {
+ len: uint) -> IoResult<rtio::SocketAddr> {
match storage.ss_family as libc::c_int {
libc::AF_INET => {
assert!(len as uint >= mem::size_of::<libc::sockaddr_in>());
let storage: &libc::sockaddr_in = unsafe {
mem::transmute(storage)
};
- let ip = mem::to_be32(storage.sin_addr.s_addr as u32);
+ let ip = (storage.sin_addr.s_addr as u32).to_be();
let a = (ip >> 24) as u8;
let b = (ip >> 16) as u8;
let c = (ip >> 8) as u8;
let d = (ip >> 0) as u8;
- Ok(ip::SocketAddr {
- ip: ip::Ipv4Addr(a, b, c, d),
+ Ok(rtio::SocketAddr {
+ ip: rtio::Ipv4Addr(a, b, c, d),
port: ntohs(storage.sin_port),
})
}
let f = ntohs(storage.sin6_addr.s6_addr[5]);
let g = ntohs(storage.sin6_addr.s6_addr[6]);
let h = ntohs(storage.sin6_addr.s6_addr[7]);
- Ok(ip::SocketAddr {
- ip: ip::Ipv6Addr(a, b, c, d, e, f, g, h),
+ Ok(rtio::SocketAddr {
+ ip: rtio::Ipv6Addr(a, b, c, d, e, f, g, h),
port: ntohs(storage.sin6_port),
})
}
_ => {
- Err(io::standard_error(io::OtherIoError))
+ #[cfg(unix)] use ERROR = libc::EINVAL;
+ #[cfg(windows)] use ERROR = libc::WSAEINVAL;
+ Err(IoError {
+ code: ERROR as uint,
+ extra: 0,
+ detail: None,
+ })
}
}
}
pub fn init() {
unsafe {
- use std::unstable::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
+ use std::rt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
static mut INITIALIZED: bool = false;
static mut LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT;
struct Inner {
fd: sock_t,
- lock: mutex::NativeMutex,
+
+ // Unused on Linux, where this lock is not necessary.
+ #[allow(dead_code)]
+ lock: mutex::NativeMutex
}
pub struct Guard<'a> {
}
impl TcpStream {
- pub fn connect(addr: ip::SocketAddr,
+ pub fn connect(addr: rtio::SocketAddr,
timeout: Option<u64>) -> IoResult<TcpStream> {
let fd = try!(socket(addr, libc::SOCK_STREAM));
let ret = TcpStream::new(Inner::new(fd));
let (addr, len) = addr_to_sockaddr(addr);
- let addrp = &addr as *_ as *libc::sockaddr;
+ let addrp = &addr as *const _ as *const libc::sockaddr;
let len = len as libc::socklen_t;
match timeout {
}
#[cfg(target_os = "macos")]
+ #[cfg(target_os = "ios")]
fn set_tcp_keepalive(&mut self, seconds: uint) -> IoResult<()> {
setsockopt(self.fd(), libc::IPPROTO_TCP, libc::TCP_KEEPALIVE,
seconds as libc::c_int)
}
#[cfg(target_os = "freebsd")]
+ #[cfg(target_os = "dragonfly")]
fn set_tcp_keepalive(&mut self, seconds: uint) -> IoResult<()> {
setsockopt(self.fd(), libc::IPPROTO_TCP, libc::TCP_KEEPIDLE,
seconds as libc::c_int)
}
- #[cfg(not(target_os = "macos"), not(target_os = "freebsd"))]
+ #[cfg(not(target_os = "macos"), not(target_os = "ios"), not(target_os = "freebsd"),
+ not(target_os = "dragonfly"))]
fn set_tcp_keepalive(&mut self, _seconds: uint) -> IoResult<()> {
Ok(())
}
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
let fd = self.fd();
let dolock = || self.lock_nonblocking();
- let dowrite = |nb: bool, buf: *u8, len: uint| unsafe {
+ let dowrite = |nb: bool, buf: *const u8, len: uint| unsafe {
let flags = if nb {c::MSG_DONTWAIT} else {0};
libc::send(fd,
buf as *mut libc::c_void,
Err(e) => Err(e)
}
}
- fn peer_name(&mut self) -> IoResult<ip::SocketAddr> {
+ fn peer_name(&mut self) -> IoResult<rtio::SocketAddr> {
sockname(self.fd(), libc::getpeername)
}
fn control_congestion(&mut self) -> IoResult<()> {
self.set_keepalive(None)
}
- fn clone(&self) -> Box<rtio::RtioTcpStream:Send> {
+ fn clone(&self) -> Box<rtio::RtioTcpStream + Send> {
box TcpStream {
inner: self.inner.clone(),
read_deadline: 0,
write_deadline: 0,
- } as Box<rtio::RtioTcpStream:Send>
+ } as Box<rtio::RtioTcpStream + Send>
}
fn close_write(&mut self) -> IoResult<()> {
}
impl rtio::RtioSocket for TcpStream {
- fn socket_name(&mut self) -> IoResult<ip::SocketAddr> {
+ fn socket_name(&mut self) -> IoResult<rtio::SocketAddr> {
sockname(self.fd(), libc::getsockname)
}
}
}
impl TcpListener {
- pub fn bind(addr: ip::SocketAddr) -> IoResult<TcpListener> {
+ pub fn bind(addr: rtio::SocketAddr) -> IoResult<TcpListener> {
let fd = try!(socket(addr, libc::SOCK_STREAM));
let ret = TcpListener { inner: Inner::new(fd) };
let (addr, len) = addr_to_sockaddr(addr);
- let addrp = &addr as *_ as *libc::sockaddr;
+ let addrp = &addr as *const _ as *const libc::sockaddr;
let len = len as libc::socklen_t;
// On platforms with Berkeley-derived sockets, this allows
}
impl rtio::RtioTcpListener for TcpListener {
- fn listen(~self) -> IoResult<Box<rtio::RtioTcpAcceptor:Send>> {
+ fn listen(self: Box<TcpListener>)
+ -> IoResult<Box<rtio::RtioTcpAcceptor + Send>> {
self.native_listen(128).map(|a| {
- box a as Box<rtio::RtioTcpAcceptor:Send>
+ box a as Box<rtio::RtioTcpAcceptor + Send>
})
}
}
impl rtio::RtioSocket for TcpListener {
- fn socket_name(&mut self) -> IoResult<ip::SocketAddr> {
+ fn socket_name(&mut self) -> IoResult<rtio::SocketAddr> {
sockname(self.fd(), libc::getsockname)
}
}
}
impl rtio::RtioSocket for TcpAcceptor {
- fn socket_name(&mut self) -> IoResult<ip::SocketAddr> {
+ fn socket_name(&mut self) -> IoResult<rtio::SocketAddr> {
sockname(self.fd(), libc::getsockname)
}
}
impl rtio::RtioTcpAcceptor for TcpAcceptor {
- fn accept(&mut self) -> IoResult<Box<rtio::RtioTcpStream:Send>> {
- self.native_accept().map(|s| box s as Box<rtio::RtioTcpStream:Send>)
+ fn accept(&mut self) -> IoResult<Box<rtio::RtioTcpStream + Send>> {
+ self.native_accept().map(|s| box s as Box<rtio::RtioTcpStream + Send>)
}
fn accept_simultaneously(&mut self) -> IoResult<()> { Ok(()) }
}
impl UdpSocket {
- pub fn bind(addr: ip::SocketAddr) -> IoResult<UdpSocket> {
+ pub fn bind(addr: rtio::SocketAddr) -> IoResult<UdpSocket> {
let fd = try!(socket(addr, libc::SOCK_DGRAM));
let ret = UdpSocket {
inner: Arc::new(Inner::new(fd)),
};
let (addr, len) = addr_to_sockaddr(addr);
- let addrp = &addr as *_ as *libc::sockaddr;
+ let addrp = &addr as *const _ as *const libc::sockaddr;
let len = len as libc::socklen_t;
match unsafe { libc::bind(fd, addrp, len) } {
on as libc::c_int)
}
- pub fn set_membership(&mut self, addr: ip::IpAddr,
+ pub fn set_membership(&mut self, addr: rtio::IpAddr,
opt: libc::c_int) -> IoResult<()> {
match ip_to_inaddr(addr) {
InAddr(addr) => {
}
impl rtio::RtioSocket for UdpSocket {
- fn socket_name(&mut self) -> IoResult<ip::SocketAddr> {
+ fn socket_name(&mut self) -> IoResult<rtio::SocketAddr> {
sockname(self.fd(), libc::getsockname)
}
}
#[cfg(unix)] type msglen_t = libc::size_t;
impl rtio::RtioUdpSocket for UdpSocket {
- fn recvfrom(&mut self, buf: &mut [u8]) -> IoResult<(uint, ip::SocketAddr)> {
+ fn recv_from(&mut self, buf: &mut [u8]) -> IoResult<(uint, rtio::SocketAddr)> {
let fd = self.fd();
let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
let storagep = &mut storage as *mut _ as *mut libc::sockaddr;
mem::size_of::<libc::sockaddr_storage>() as libc::socklen_t;
let dolock = || self.lock_nonblocking();
- let doread = |nb| unsafe {
+ let n = try!(read(fd, self.read_deadline, dolock, |nb| unsafe {
let flags = if nb {c::MSG_DONTWAIT} else {0};
libc::recvfrom(fd,
buf.as_mut_ptr() as *mut libc::c_void,
flags,
storagep,
&mut addrlen) as libc::c_int
- };
- let n = try!(read(fd, self.read_deadline, dolock, doread));
+ }));
sockaddr_to_addr(&storage, addrlen as uint).and_then(|addr| {
Ok((n as uint, addr))
})
}
- fn sendto(&mut self, buf: &[u8], dst: ip::SocketAddr) -> IoResult<()> {
+ fn send_to(&mut self, buf: &[u8], dst: rtio::SocketAddr) -> IoResult<()> {
let (dst, dstlen) = addr_to_sockaddr(dst);
- let dstp = &dst as *_ as *libc::sockaddr;
+ let dstp = &dst as *const _ as *const libc::sockaddr;
let dstlen = dstlen as libc::socklen_t;
let fd = self.fd();
let dolock = || self.lock_nonblocking();
- let dowrite = |nb, buf: *u8, len: uint| unsafe {
+ let dowrite = |nb, buf: *const u8, len: uint| unsafe {
let flags = if nb {c::MSG_DONTWAIT} else {0};
libc::sendto(fd,
- buf as *libc::c_void,
+ buf as *const libc::c_void,
len as msglen_t,
flags,
dstp,
let n = try!(write(fd, self.write_deadline, buf, false, dolock, dowrite));
if n != buf.len() {
- Err(io::IoError {
- kind: io::ShortWrite(n),
- desc: "couldn't send entire packet at once",
- detail: None,
- })
+ Err(util::short_write(n, "couldn't send entire packet at once"))
} else {
Ok(())
}
}
- fn join_multicast(&mut self, multi: ip::IpAddr) -> IoResult<()> {
+ fn join_multicast(&mut self, multi: rtio::IpAddr) -> IoResult<()> {
match multi {
- ip::Ipv4Addr(..) => {
+ rtio::Ipv4Addr(..) => {
self.set_membership(multi, libc::IP_ADD_MEMBERSHIP)
}
- ip::Ipv6Addr(..) => {
+ rtio::Ipv6Addr(..) => {
self.set_membership(multi, libc::IPV6_ADD_MEMBERSHIP)
}
}
}
- fn leave_multicast(&mut self, multi: ip::IpAddr) -> IoResult<()> {
+ fn leave_multicast(&mut self, multi: rtio::IpAddr) -> IoResult<()> {
match multi {
- ip::Ipv4Addr(..) => {
+ rtio::Ipv4Addr(..) => {
self.set_membership(multi, libc::IP_DROP_MEMBERSHIP)
}
- ip::Ipv6Addr(..) => {
+ rtio::Ipv6Addr(..) => {
self.set_membership(multi, libc::IPV6_DROP_MEMBERSHIP)
}
}
self.set_broadcast(false)
}
- fn clone(&self) -> Box<rtio::RtioUdpSocket:Send> {
+ fn clone(&self) -> Box<rtio::RtioUdpSocket + Send> {
box UdpSocket {
inner: self.inner.clone(),
read_deadline: 0,
write_deadline: 0,
- } as Box<rtio::RtioUdpSocket:Send>
+ } as Box<rtio::RtioUdpSocket + Send>
}
fn set_timeout(&mut self, timeout: Option<u64>) {
}
match ret {
- 0 => Err(io::standard_error(io::EndOfFile)),
+ 0 => Err(util::eof()),
n if n < 0 => Err(last_error()),
n => Ok(n as uint)
}
buf: &[u8],
write_everything: bool,
lock: || -> T,
- write: |bool, *u8, uint| -> i64) -> IoResult<uint> {
+ write: |bool, *const u8, uint| -> i64) -> IoResult<uint> {
let mut ret = -1;
let mut written = 0;
if deadline == 0 {
// As with read(), first wait for the socket to be ready for
// the I/O operation.
match util::await(fd, deadline, util::Writable) {
- Err(ref e) if e.kind == io::TimedOut && written > 0 => {
+ Err(ref e) if e.code == libc::EOF as uint && written > 0 => {
assert!(deadline.is_some());
- return Err(io::IoError {
- kind: io::ShortWrite(written),
- desc: "short write",
- detail: None,
- })
+ return Err(util::short_write(written, "short write"))
}
Err(e) => return Err(e),
Ok(()) => {}
}
// Also as with read(), we use MSG_DONTWAIT to guard ourselves
- // against unforseen circumstances.
+ // against unforeseen circumstances.
let _guard = lock();
let ptr = buf.slice_from(written).as_ptr();
let len = buf.len() - written;