]> git.lizzy.rs Git - rust.git/blobdiff - src/libnative/io/net.rs
auto merge of #15999 : Kimundi/rust/fix_folder, r=nikomatsakis
[rust.git] / src / libnative / io / net.rs
index 26307feae91f0f62e5a41c533a6bab31eccda3bb..7a90ede8ca863283f79dd1f75666b4465cd2c76a 100644 (file)
 
 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 {
@@ -39,18 +38,18 @@ 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),
@@ -67,7 +66,7 @@ fn ip_to_inaddr(ip: ip::IpAddr) -> InAddr {
     }
 }
 
-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) {
@@ -90,11 +89,11 @@ fn addr_to_sockaddr(addr: ip::SocketAddr) -> (libc::sockaddr_storage, uint) {
     }
 }
 
-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()),
@@ -106,7 +105,7 @@ fn socket(addr: ip::SocketAddr, ty: libc::c_int) -> IoResult<sock_t> {
 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);
@@ -136,12 +135,18 @@ pub fn getsockopt<T: Copy>(fd: sock_t, opt: libc::c_int,
 }
 
 #[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()
 }
 
@@ -151,7 +156,7 @@ fn last_error() -> io::IoError {
 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;
@@ -168,20 +173,20 @@ fn sockname(fd: sock_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),
             })
         }
@@ -198,13 +203,19 @@ pub fn sockaddr_to_addr(storage: &libc::sockaddr_storage,
             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,
+            })
         }
     }
 }
@@ -216,7 +227,7 @@ pub fn init() {}
 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;
 
@@ -243,7 +254,10 @@ pub struct TcpStream {
 
 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> {
@@ -258,13 +272,13 @@ fn new(fd: sock_t) -> Inner {
 }
 
 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 {
@@ -306,16 +320,19 @@ fn set_keepalive(&mut self, seconds: Option<uint>) -> IoResult<()> {
     }
 
     #[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(())
     }
@@ -354,7 +371,7 @@ fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
     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,
@@ -366,7 +383,7 @@ fn write(&mut self, buf: &[u8]) -> IoResult<()> {
             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<()> {
@@ -382,12 +399,12 @@ fn letdie(&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<()> {
@@ -411,7 +428,7 @@ fn set_write_timeout(&mut self, timeout: Option<u64>) {
 }
 
 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)
     }
 }
@@ -436,12 +453,12 @@ pub struct TcpListener {
 }
 
 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
@@ -469,15 +486,16 @@ pub fn native_listen(self, backlog: int) -> IoResult<TcpAcceptor> {
 }
 
 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)
     }
 }
@@ -512,14 +530,14 @@ pub fn native_accept(&mut self) -> IoResult<TcpStream> {
 }
 
 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(()) }
@@ -540,7 +558,7 @@ pub struct UdpSocket {
 }
 
 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)),
@@ -549,7 +567,7 @@ pub fn bind(addr: ip::SocketAddr) -> IoResult<UdpSocket> {
         };
 
         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) } {
@@ -570,7 +588,7 @@ pub fn set_multicast_loop(&mut self, on: bool) -> IoResult<()> {
                    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) => {
@@ -606,7 +624,7 @@ fn lock_nonblocking<'a>(&'a self) -> Guard<'a> {
 }
 
 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)
     }
 }
@@ -615,7 +633,7 @@ fn socket_name(&mut self) -> IoResult<ip::SocketAddr> {
 #[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;
@@ -623,7 +641,7 @@ fn recvfrom(&mut self, buf: &mut [u8]) -> IoResult<(uint, ip::SocketAddr)> {
                 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,
@@ -631,24 +649,23 @@ fn recvfrom(&mut self, buf: &mut [u8]) -> IoResult<(uint, ip::SocketAddr)> {
                            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,
@@ -657,32 +674,28 @@ fn sendto(&mut self, buf: &[u8], dst: ip::SocketAddr) -> IoResult<()> {
 
         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)
             }
         }
@@ -710,12 +723,12 @@ fn ignore_broadcasts(&mut self) -> IoResult<()> {
         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>) {
@@ -821,7 +834,7 @@ pub fn read<T>(fd: sock_t,
     }
 
     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)
     }
@@ -832,7 +845,7 @@ pub fn write<T>(fd: sock_t,
                 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 {
@@ -858,20 +871,16 @@ pub fn write<T>(fd: sock_t,
             // 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;