about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2013-11-07 15:26:47 -0800
committerAlex Crichton <alex@alexcrichton.com>2013-11-10 01:37:11 -0800
commit3a3eefc5c3ce95de3001d8ee830296345c2f6bc9 (patch)
treec9be634bc3bc799e793df728cd782f27f0f3e9e4 /src
parentb652bbc6700e36c9ad80105c89d7fc2e3afec111 (diff)
downloadrust-3a3eefc5c3ce95de3001d8ee830296345c2f6bc9.tar.gz
rust-3a3eefc5c3ce95de3001d8ee830296345c2f6bc9.zip
Update to the latest libuv
At this time, also point the libuv submodule to the official repo instead of my
own off to the side.

cc #10246
Closes #10329
Diffstat (limited to 'src')
-rw-r--r--src/librustuv/addrinfo.rs3
-rw-r--r--src/librustuv/lib.rs2
-rw-r--r--src/librustuv/net.rs221
-rw-r--r--src/librustuv/process.rs4
-rw-r--r--src/librustuv/stream.rs13
-rw-r--r--src/librustuv/uvll.rs216
m---------src/libuv0
-rw-r--r--src/rt/rust_uv.cpp177
8 files changed, 169 insertions, 467 deletions
diff --git a/src/librustuv/addrinfo.rs b/src/librustuv/addrinfo.rs
index 56f6eda5357..601cc9f84ad 100644
--- a/src/librustuv/addrinfo.rs
+++ b/src/librustuv/addrinfo.rs
@@ -141,8 +141,7 @@ pub fn accum_addrinfo(addr: &Addrinfo) -> ~[ai::Info] {
 
         let mut addrs = ~[];
         loop {
-            let uvaddr = net::sockaddr_to_UvSocketAddr((*addr).ai_addr);
-            let rustaddr = net::uv_socket_addr_to_socket_addr(uvaddr);
+            let rustaddr = net::sockaddr_to_socket_addr((*addr).ai_addr);
 
             let mut flags = 0;
             do each_ai_flag |cval, aival| {
diff --git a/src/librustuv/lib.rs b/src/librustuv/lib.rs
index 4da5ad4275f..7c84ccb8f2c 100644
--- a/src/librustuv/lib.rs
+++ b/src/librustuv/lib.rs
@@ -47,7 +47,7 @@ via `close` and `delete` methods.
 
 use std::cast::transmute;
 use std::cast;
-use std::libc::{c_int, malloc, free};
+use std::libc::{c_int, malloc};
 use std::ptr::null;
 use std::ptr;
 use std::rt::BlockedTask;
diff --git a/src/librustuv/net.rs b/src/librustuv/net.rs
index bf5f6c88527..10b8f50e387 100644
--- a/src/librustuv/net.rs
+++ b/src/librustuv/net.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use std::cast;
+use std::libc;
 use std::libc::{size_t, ssize_t, c_int, c_void, c_uint, c_char};
 use std::ptr;
 use std::rt::BlockedTask;
@@ -28,87 +29,61 @@ use super::{Loop, Request, UvError, Buf, status_to_io_result,
             wait_until_woken_after};
 use uvio::HomingIO;
 use uvll;
+use uvll::sockaddr;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Generic functions related to dealing with sockaddr things
 ////////////////////////////////////////////////////////////////////////////////
 
-pub enum UvSocketAddr {
-    UvIpv4SocketAddr(*uvll::sockaddr_in),
-    UvIpv6SocketAddr(*uvll::sockaddr_in6),
-}
-
-pub fn sockaddr_to_UvSocketAddr(addr: *uvll::sockaddr) -> UvSocketAddr {
-    unsafe {
-        assert!((uvll::is_ip4_addr(addr) || uvll::is_ip6_addr(addr)));
-        assert!(!(uvll::is_ip4_addr(addr) && uvll::is_ip6_addr(addr)));
-        match addr {
-            _ if uvll::is_ip4_addr(addr) =>
-                UvIpv4SocketAddr(addr as *uvll::sockaddr_in),
-            _ if uvll::is_ip6_addr(addr) =>
-                UvIpv6SocketAddr(addr as *uvll::sockaddr_in6),
-            _ => fail!(),
-        }
-    }
-}
-
-fn socket_addr_as_uv_socket_addr<T>(addr: SocketAddr, f: &fn(UvSocketAddr) -> T) -> T {
+#[fixed_stack_segment]
+fn socket_addr_as_sockaddr<T>(addr: SocketAddr, f: &fn(*sockaddr) -> T) -> T {
     let malloc = match addr.ip {
-        Ipv4Addr(*) => uvll::malloc_ip4_addr,
-        Ipv6Addr(*) => uvll::malloc_ip6_addr,
-    };
-    let wrap = match addr.ip {
-        Ipv4Addr(*) => UvIpv4SocketAddr,
-        Ipv6Addr(*) => UvIpv6SocketAddr,
-    };
-    let free = match addr.ip {
-        Ipv4Addr(*) => uvll::free_ip4_addr,
-        Ipv6Addr(*) => uvll::free_ip6_addr,
+        Ipv4Addr(*) => uvll::rust_malloc_ip4_addr,
+        Ipv6Addr(*) => uvll::rust_malloc_ip6_addr,
     };
 
-    let addr = unsafe { malloc(addr.ip.to_str(), addr.port as int) };
+    let ip = addr.ip.to_str();
+    let addr = ip.with_c_str(|p| unsafe { malloc(p, addr.port as c_int) });
     do (|| {
-        f(wrap(addr))
+        f(addr)
     }).finally {
-        unsafe { free(addr) };
+        unsafe { libc::free(addr) };
     }
 }
 
-fn uv_socket_addr_as_socket_addr<T>(addr: UvSocketAddr, f: &fn(SocketAddr) -> T) -> T {
-    let ip_size = match addr {
-        UvIpv4SocketAddr(*) => 4/*groups of*/ * 3/*digits separated by*/ + 3/*periods*/,
-        UvIpv6SocketAddr(*) => 8/*groups of*/ * 4/*hex digits separated by*/ + 7 /*colons*/,
-    };
-    let ip_name = {
-        let buf = vec::from_elem(ip_size + 1 /*null terminated*/, 0u8);
-        unsafe {
+#[fixed_stack_segment]
+pub fn sockaddr_to_socket_addr(addr: *sockaddr) -> SocketAddr {
+    unsafe {
+        let ip_size = if uvll::rust_is_ipv4_sockaddr(addr) == 1 {
+            4/*groups of*/ * 3/*digits separated by*/ + 3/*periods*/
+        } else if uvll::rust_is_ipv6_sockaddr(addr) == 1 {
+            8/*groups of*/ * 4/*hex digits separated by*/ + 7 /*colons*/
+        } else {
+            fail!("unknown address?");
+        };
+        let ip_name = {
+            let buf = vec::from_elem(ip_size + 1 /*null terminated*/, 0u8);
             let buf_ptr = vec::raw::to_ptr(buf);
-            match addr {
-                UvIpv4SocketAddr(addr) =>
-                    uvll::uv_ip4_name(addr, buf_ptr as *c_char, ip_size as size_t),
-                UvIpv6SocketAddr(addr) =>
-                    uvll::uv_ip6_name(addr, buf_ptr as *c_char, ip_size as size_t),
+            if uvll::rust_is_ipv4_sockaddr(addr) == 1 {
+                uvll::uv_ip4_name(addr, buf_ptr as *c_char, ip_size as size_t);
+            } else {
+                uvll::uv_ip6_name(addr, buf_ptr as *c_char, ip_size as size_t);
             }
+            buf
         };
-        buf
-    };
-    let ip_port = unsafe {
-        let port = match addr {
-            UvIpv4SocketAddr(addr) => uvll::ip4_port(addr),
-            UvIpv6SocketAddr(addr) => uvll::ip6_port(addr),
+        let ip_port = {
+            let port = if uvll::rust_is_ipv4_sockaddr(addr) == 1 {
+                uvll::rust_ip4_port(addr)
+            } else {
+                uvll::rust_ip6_port(addr)
+            };
+            port as u16
         };
-        port as u16
-    };
-    let ip_str = str::from_utf8_slice(ip_name).trim_right_chars(&'\x00');
-    let ip_addr = FromStr::from_str(ip_str).unwrap();
+        let ip_str = str::from_utf8_slice(ip_name).trim_right_chars(&'\x00');
+        let ip_addr = FromStr::from_str(ip_str).unwrap();
 
-    // finally run the closure
-    f(SocketAddr { ip: ip_addr, port: ip_port })
-}
-
-pub fn uv_socket_addr_to_socket_addr(addr: UvSocketAddr) -> SocketAddr {
-    use std::util;
-    uv_socket_addr_as_socket_addr(addr, util::id)
+        SocketAddr { ip: ip_addr, port: ip_port }
+    }
 }
 
 #[cfg(test)]
@@ -116,7 +91,9 @@ pub fn uv_socket_addr_to_socket_addr(addr: UvSocketAddr) -> SocketAddr {
 fn test_ip4_conversion() {
     use std::rt;
     let ip4 = rt::test::next_test_ip4();
-    assert_eq!(ip4, socket_addr_as_uv_socket_addr(ip4, uv_socket_addr_to_socket_addr));
+    do socket_addr_as_sockaddr(ip4) |addr| {
+        assert_eq!(ip4, sockaddr_to_socket_addr(addr));
+    }
 }
 
 #[cfg(test)]
@@ -124,7 +101,9 @@ fn test_ip4_conversion() {
 fn test_ip6_conversion() {
     use std::rt;
     let ip6 = rt::test::next_test_ip6();
-    assert_eq!(ip6, socket_addr_as_uv_socket_addr(ip6, uv_socket_addr_to_socket_addr));
+    do socket_addr_as_sockaddr(ip6) |addr| {
+        assert_eq!(ip6, sockaddr_to_socket_addr(addr));
+    }
 }
 
 enum SocketNameKind {
@@ -133,37 +112,29 @@ enum SocketNameKind {
     Udp
 }
 
+#[fixed_stack_segment]
 fn socket_name(sk: SocketNameKind, handle: *c_void) -> Result<SocketAddr, IoError> {
-    let getsockname = match sk {
-        TcpPeer => uvll::tcp_getpeername,
-        Tcp     => uvll::tcp_getsockname,
-        Udp     => uvll::udp_getsockname,
-    };
-
-    // Allocate a sockaddr_storage
-    // since we don't know if it's ipv4 or ipv6
-    let r_addr = unsafe { uvll::malloc_sockaddr_storage() };
+    unsafe {
+        let getsockname = match sk {
+            TcpPeer => uvll::uv_tcp_getpeername,
+            Tcp     => uvll::uv_tcp_getsockname,
+            Udp     => uvll::uv_udp_getsockname,
+        };
 
-    let r = unsafe {
-        getsockname(handle, r_addr as *uvll::sockaddr_storage)
-    };
+        // Allocate a sockaddr_storage
+        // since we don't know if it's ipv4 or ipv6
+        let size = uvll::rust_sockaddr_size();
+        let name = libc::malloc(size as size_t);
+        assert!(!name.is_null());
+        let mut namelen = size;
 
-    if r != 0 {
-        return Err(uv_error_to_io_error(UvError(r)));
+        let ret = match getsockname(handle, name, &mut namelen) {
+            0 => Ok(sockaddr_to_socket_addr(name)),
+            n => Err(uv_error_to_io_error(UvError(n)))
+        };
+        libc::free(name);
+        ret
     }
-
-    let addr = unsafe {
-        if uvll::is_ip6_addr(r_addr as *uvll::sockaddr) {
-            uv_socket_addr_to_socket_addr(UvIpv6SocketAddr(r_addr as *uvll::sockaddr_in6))
-        } else {
-            uv_socket_addr_to_socket_addr(UvIpv4SocketAddr(r_addr as *uvll::sockaddr_in))
-        }
-    };
-
-    unsafe { uvll::free_sockaddr_storage(r_addr); }
-
-    Ok(addr)
-
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -210,17 +181,11 @@ impl TcpWatcher {
 
         return do task::unkillable {
             let tcp = TcpWatcher::new(loop_);
-            let ret = do socket_addr_as_uv_socket_addr(address) |addr| {
+            let ret = do socket_addr_as_sockaddr(address) |addr| {
                 let mut req = Request::new(uvll::UV_CONNECT);
-                let result = match addr {
-                    UvIpv4SocketAddr(addr) => unsafe {
-                        uvll::tcp_connect(req.handle, tcp.handle, addr,
-                                          connect_cb)
-                    },
-                    UvIpv6SocketAddr(addr) => unsafe {
-                        uvll::tcp_connect6(req.handle, tcp.handle, addr,
-                                           connect_cb)
-                    },
+                let result = unsafe {
+                    uvll::uv_tcp_connect(req.handle, tcp.handle, addr,
+                                         connect_cb)
                 };
                 match result {
                     0 => {
@@ -340,11 +305,8 @@ impl TcpListener {
                 closing_task: None,
                 outgoing: Tube::new(),
             };
-            let res = socket_addr_as_uv_socket_addr(address, |addr| unsafe {
-                match addr {
-                    UvIpv4SocketAddr(addr) => uvll::tcp_bind(l.handle, addr),
-                    UvIpv6SocketAddr(addr) => uvll::tcp_bind6(l.handle, addr),
-                }
+            let res = socket_addr_as_sockaddr(address, |addr| unsafe {
+                uvll::uv_tcp_bind(l.handle, addr)
             });
             match res {
                 0 => Ok(l.install()),
@@ -475,13 +437,8 @@ impl UdpWatcher {
             assert_eq!(unsafe {
                 uvll::uv_udp_init(loop_.handle, udp.handle)
             }, 0);
-            let result = socket_addr_as_uv_socket_addr(address, |addr| unsafe {
-                match addr {
-                    UvIpv4SocketAddr(addr) =>
-                        uvll::udp_bind(udp.handle, addr, 0u32),
-                    UvIpv6SocketAddr(addr) =>
-                        uvll::udp_bind6(udp.handle, addr, 0u32),
-                }
+            let result = socket_addr_as_sockaddr(address, |addr| unsafe {
+                uvll::uv_udp_bind(udp.handle, addr, 0u32)
             });
             match result {
                 0 => Ok(udp),
@@ -513,7 +470,7 @@ impl rtio::RtioUdpSocket for UdpWatcher {
         struct Ctx {
             task: Option<BlockedTask>,
             buf: Option<Buf>,
-            result: Option<(ssize_t, SocketAddr)>,
+            result: Option<(ssize_t, Option<SocketAddr>)>,
         }
         let _m = self.fire_homing_missile();
 
@@ -532,7 +489,7 @@ impl rtio::RtioUdpSocket for UdpWatcher {
                 match cx.result.take_unwrap() {
                     (n, _) if n < 0 =>
                         Err(uv_error_to_io_error(UvError(n as c_int))),
-                    (n, addr) => Ok((n as uint, addr))
+                    (n, addr) => Ok((n as uint, addr.unwrap()))
                 }
             }
             n => Err(uv_error_to_io_error(UvError(n)))
@@ -540,14 +497,16 @@ impl rtio::RtioUdpSocket for UdpWatcher {
         return a;
 
         extern fn alloc_cb(handle: *uvll::uv_udp_t,
-                           _suggested_size: size_t) -> Buf {
-            let cx: &mut Ctx = unsafe {
-                cast::transmute(uvll::get_data_for_uv_handle(handle))
-            };
-            cx.buf.take().expect("recv alloc_cb called more than once")
+                           _suggested_size: size_t,
+                           buf: *mut Buf) {
+            unsafe {
+                let cx: &mut Ctx =
+                    cast::transmute(uvll::get_data_for_uv_handle(handle));
+                *buf = cx.buf.take().expect("recv alloc_cb called more than once")
+            }
         }
 
-        extern fn recv_cb(handle: *uvll::uv_udp_t, nread: ssize_t, buf: Buf,
+        extern fn recv_cb(handle: *uvll::uv_udp_t, nread: ssize_t, buf: *Buf,
                           addr: *uvll::sockaddr, _flags: c_uint) {
             assert!(nread != uvll::ECANCELED as ssize_t);
             let cx: &mut Ctx = unsafe {
@@ -558,7 +517,7 @@ impl rtio::RtioUdpSocket for UdpWatcher {
             // This can happen if read returns EAGAIN/EWOULDBLOCK. By ignoring
             // this we just drop back to kqueue and wait for the next callback.
             if nread == 0 {
-                cx.buf = Some(buf);
+                cx.buf = Some(unsafe { *buf });
                 return
             }
 
@@ -569,8 +528,11 @@ impl rtio::RtioUdpSocket for UdpWatcher {
             let cx: &mut Ctx = unsafe {
                 cast::transmute(uvll::get_data_for_uv_handle(handle))
             };
-            let addr = sockaddr_to_UvSocketAddr(addr);
-            let addr = uv_socket_addr_to_socket_addr(addr);
+            let addr = if addr == ptr::null() {
+                None
+            } else {
+                Some(sockaddr_to_socket_addr(addr))
+            };
             cx.result = Some((nread, addr));
 
             let sched: ~Scheduler = Local::take();
@@ -585,13 +547,8 @@ impl rtio::RtioUdpSocket for UdpWatcher {
 
         let mut req = Request::new(uvll::UV_UDP_SEND);
         let buf = slice_to_uv_buf(buf);
-        let result = socket_addr_as_uv_socket_addr(dst, |dst| unsafe {
-            match dst {
-                UvIpv4SocketAddr(dst) =>
-                    uvll::udp_send(req.handle, self.handle, [buf], dst, send_cb),
-                UvIpv6SocketAddr(dst) =>
-                    uvll::udp_send6(req.handle, self.handle, [buf], dst, send_cb),
-            }
+        let result = socket_addr_as_sockaddr(dst, |dst| unsafe {
+            uvll::uv_udp_send(req.handle, self.handle, [buf], dst, send_cb)
         });
 
         return match result {
diff --git a/src/librustuv/process.rs b/src/librustuv/process.rs
index 17a7510aa19..d0b0d6429b8 100644
--- a/src/librustuv/process.rs
+++ b/src/librustuv/process.rs
@@ -78,7 +78,7 @@ impl Process {
 
                 let handle = UvHandle::alloc(None::<Process>, uvll::UV_PROCESS);
                 match unsafe {
-                    uvll::uv_spawn(loop_.handle, handle, options)
+                    uvll::uv_spawn(loop_.handle, handle, &options)
                 } {
                     0 => {
                         let process = ~Process {
@@ -106,7 +106,7 @@ impl Process {
 }
 
 extern fn on_exit(handle: *uvll::uv_process_t,
-                  exit_status: libc::c_int,
+                  exit_status: i64,
                   term_signal: libc::c_int) {
     let p: &mut Process = unsafe { UvHandle::from_uv_handle(&handle) };
 
diff --git a/src/librustuv/stream.rs b/src/librustuv/stream.rs
index b9ccacf4df7..08b307700c7 100644
--- a/src/librustuv/stream.rs
+++ b/src/librustuv/stream.rs
@@ -135,17 +135,18 @@ impl StreamWatcher {
 // This allocation callback expects to be invoked once and only once. It will
 // unwrap the buffer in the ReadContext stored in the stream and return it. This
 // will fail if it is called more than once.
-extern fn alloc_cb(stream: *uvll::uv_stream_t, _hint: size_t) -> Buf {
+extern fn alloc_cb(stream: *uvll::uv_stream_t, _hint: size_t, buf: *mut Buf) {
     uvdebug!("alloc_cb");
-    let rcx: &mut ReadContext = unsafe {
-        cast::transmute(uvll::get_data_for_uv_handle(stream))
-    };
-    rcx.buf.take().expect("stream alloc_cb called more than once")
+    unsafe {
+        let rcx: &mut ReadContext =
+            cast::transmute(uvll::get_data_for_uv_handle(stream));
+        *buf = rcx.buf.take().expect("stream alloc_cb called more than once");
+    }
 }
 
 // When a stream has read some data, we will always forcibly stop reading and
 // return all the data read (even if it didn't fill the whole buffer).
-extern fn read_cb(handle: *uvll::uv_stream_t, nread: ssize_t, _buf: Buf) {
+extern fn read_cb(handle: *uvll::uv_stream_t, nread: ssize_t, _buf: *Buf) {
     uvdebug!("read_cb {}", nread);
     assert!(nread != uvll::ECANCELED as ssize_t);
     let rcx: &mut ReadContext = unsafe {
diff --git a/src/librustuv/uvll.rs b/src/librustuv/uvll.rs
index 58d182a22c3..4183ce4309e 100644
--- a/src/librustuv/uvll.rs
+++ b/src/librustuv/uvll.rs
@@ -206,15 +206,16 @@ impl uv_stat_t {
 pub type uv_idle_cb = extern "C" fn(handle: *uv_idle_t,
                                     status: c_int);
 pub type uv_alloc_cb = extern "C" fn(stream: *uv_stream_t,
-                                     suggested_size: size_t) -> uv_buf_t;
+                                     suggested_size: size_t,
+                                     buf: *mut uv_buf_t);
 pub type uv_read_cb = extern "C" fn(stream: *uv_stream_t,
                                     nread: ssize_t,
-                                    buf: uv_buf_t);
+                                    buf: *uv_buf_t);
 pub type uv_udp_send_cb = extern "C" fn(req: *uv_udp_send_t,
                                         status: c_int);
 pub type uv_udp_recv_cb = extern "C" fn(handle: *uv_udp_t,
                                         nread: ssize_t,
-                                        buf: uv_buf_t,
+                                        buf: *uv_buf_t,
                                         addr: *sockaddr,
                                         flags: c_uint);
 pub type uv_close_cb = extern "C" fn(handle: *uv_handle_t);
@@ -234,16 +235,13 @@ pub type uv_getaddrinfo_cb = extern "C" fn(req: *uv_getaddrinfo_t,
                                            status: c_int,
                                            res: *addrinfo);
 pub type uv_exit_cb = extern "C" fn(handle: *uv_process_t,
-                                    exit_status: c_int,
+                                    exit_status: i64,
                                     term_signal: c_int);
 pub type uv_signal_cb = extern "C" fn(handle: *uv_signal_t,
                                       signum: c_int);
 pub type uv_fs_cb = extern "C" fn(req: *uv_fs_t);
 
 pub type sockaddr = c_void;
-pub type sockaddr_in = c_void;
-pub type sockaddr_in6 = c_void;
-pub type sockaddr_storage = c_void;
 
 #[cfg(unix)]
 pub type socklen_t = c_int;
@@ -420,86 +418,12 @@ pub unsafe fn loop_new() -> *c_void {
     return rust_uv_loop_new();
 }
 
-pub unsafe fn udp_bind(server: *uv_udp_t, addr: *sockaddr_in, flags: c_uint) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_udp_bind(server, addr, flags);
-}
-
-pub unsafe fn udp_bind6(server: *uv_udp_t, addr: *sockaddr_in6, flags: c_uint) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_udp_bind6(server, addr, flags);
-}
-
-pub unsafe fn udp_send<T>(req: *uv_udp_send_t, handle: *T, buf_in: &[uv_buf_t],
-                          addr: *sockaddr_in, cb: uv_udp_send_cb) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    let buf_ptr = vec::raw::to_ptr(buf_in);
-    let buf_cnt = buf_in.len() as i32;
-    return rust_uv_udp_send(req, handle as *c_void, buf_ptr, buf_cnt, addr, cb);
-}
-
-pub unsafe fn udp_send6<T>(req: *uv_udp_send_t, handle: *T, buf_in: &[uv_buf_t],
-                          addr: *sockaddr_in6, cb: uv_udp_send_cb) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    let buf_ptr = vec::raw::to_ptr(buf_in);
-    let buf_cnt = buf_in.len() as i32;
-    return rust_uv_udp_send6(req, handle as *c_void, buf_ptr, buf_cnt, addr, cb);
-}
-
 pub unsafe fn get_udp_handle_from_send_req(send_req: *uv_udp_send_t) -> *uv_udp_t {
     #[fixed_stack_segment]; #[inline(never)];
 
     return rust_uv_get_udp_handle_from_send_req(send_req);
 }
 
-pub unsafe fn udp_getsockname(handle: *uv_udp_t, name: *sockaddr_storage) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_udp_getsockname(handle, name);
-}
-
-pub unsafe fn tcp_connect(connect_ptr: *uv_connect_t, tcp_handle_ptr: *uv_tcp_t,
-                          addr_ptr: *sockaddr_in, after_connect_cb: uv_connect_cb) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_tcp_connect(connect_ptr, tcp_handle_ptr, after_connect_cb, addr_ptr);
-}
-
-pub unsafe fn tcp_connect6(connect_ptr: *uv_connect_t, tcp_handle_ptr: *uv_tcp_t,
-                           addr_ptr: *sockaddr_in6, after_connect_cb: uv_connect_cb) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_tcp_connect6(connect_ptr, tcp_handle_ptr, after_connect_cb, addr_ptr);
-}
-
-pub unsafe fn tcp_bind(tcp_server_ptr: *uv_tcp_t, addr_ptr: *sockaddr_in) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_tcp_bind(tcp_server_ptr, addr_ptr);
-}
-
-pub unsafe fn tcp_bind6(tcp_server_ptr: *uv_tcp_t, addr_ptr: *sockaddr_in6) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_tcp_bind6(tcp_server_ptr, addr_ptr);
-}
-
-pub unsafe fn tcp_getpeername(tcp_handle_ptr: *uv_tcp_t, name: *sockaddr_storage) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_tcp_getpeername(tcp_handle_ptr, name);
-}
-
-pub unsafe fn tcp_getsockname(handle: *uv_tcp_t, name: *sockaddr_storage) -> c_int {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_tcp_getsockname(handle, name);
-}
-
 pub unsafe fn uv_write(req: *uv_write_t,
                        stream: *uv_stream_t,
                        buf_in: &[uv_buf_t],
@@ -513,67 +437,6 @@ pub unsafe fn uv_write(req: *uv_write_t,
     return uv_write(req, stream, buf_ptr, buf_cnt, cb);
 }
 
-pub unsafe fn is_ip4_addr(addr: *sockaddr) -> bool {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    match rust_uv_is_ipv4_sockaddr(addr) { 0 => false, _ => true }
-}
-
-pub unsafe fn is_ip6_addr(addr: *sockaddr) -> bool {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    match rust_uv_is_ipv6_sockaddr(addr) { 0 => false, _ => true }
-}
-
-pub unsafe fn malloc_ip4_addr(ip: &str, port: int) -> *sockaddr_in {
-    #[fixed_stack_segment]; #[inline(never)];
-    do ip.with_c_str |ip_buf| {
-        rust_uv_ip4_addrp(ip_buf as *u8, port as libc::c_int)
-    }
-}
-pub unsafe fn malloc_ip6_addr(ip: &str, port: int) -> *sockaddr_in6 {
-    #[fixed_stack_segment]; #[inline(never)];
-    do ip.with_c_str |ip_buf| {
-        rust_uv_ip6_addrp(ip_buf as *u8, port as libc::c_int)
-    }
-}
-
-pub unsafe fn malloc_sockaddr_storage() -> *sockaddr_storage {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_malloc_sockaddr_storage()
-}
-
-pub unsafe fn free_sockaddr_storage(ss: *sockaddr_storage) {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_free_sockaddr_storage(ss);
-}
-
-pub unsafe fn free_ip4_addr(addr: *sockaddr_in) {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_free_ip4_addr(addr);
-}
-
-pub unsafe fn free_ip6_addr(addr: *sockaddr_in6) {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    rust_uv_free_ip6_addr(addr);
-}
-
-pub unsafe fn ip4_port(addr: *sockaddr_in) -> c_uint {
-    #[fixed_stack_segment]; #[inline(never)];
-
-   return rust_uv_ip4_port(addr);
-}
-
-pub unsafe fn ip6_port(addr: *sockaddr_in6) -> c_uint {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_ip6_port(addr);
-}
-
 pub unsafe fn process_pid(p: *uv_process_t) -> c_int {
     #[fixed_stack_segment]; #[inline(never)];
     return rust_uv_process_pid(p);
@@ -685,36 +548,19 @@ pub unsafe fn guess_handle(handle: c_int) -> c_int {
 extern {
     fn rust_uv_loop_new() -> *c_void;
 
+    // dealing with sockaddr things
+    pub fn rust_sockaddr_size() -> c_int;
+    pub fn rust_malloc_ip4_addr(s: *c_char, port: c_int) -> *sockaddr;
+    pub fn rust_malloc_ip6_addr(s: *c_char, port: c_int) -> *sockaddr;
+    pub fn rust_ip4_port(src: *sockaddr) -> c_uint;
+    pub fn rust_ip6_port(src: *sockaddr) -> c_uint;
+    pub fn rust_is_ipv4_sockaddr(addr: *sockaddr) -> c_int;
+    pub fn rust_is_ipv6_sockaddr(addr: *sockaddr) -> c_int;
+
     fn rust_uv_handle_type_max() -> uintptr_t;
     fn rust_uv_req_type_max() -> uintptr_t;
-    fn rust_uv_ip4_addrp(ip: *u8, port: c_int) -> *sockaddr_in;
-    fn rust_uv_ip6_addrp(ip: *u8, port: c_int) -> *sockaddr_in6;
-    fn rust_uv_free_ip4_addr(addr: *sockaddr_in);
-    fn rust_uv_free_ip6_addr(addr: *sockaddr_in6);
-    fn rust_uv_ip4_port(src: *sockaddr_in) -> c_uint;
-    fn rust_uv_ip6_port(src: *sockaddr_in6) -> c_uint;
-    fn rust_uv_tcp_connect(req: *uv_connect_t, handle: *uv_tcp_t,
-                           cb: uv_connect_cb,
-                           addr: *sockaddr_in) -> c_int;
-    fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t, addr: *sockaddr_in) -> c_int;
-    fn rust_uv_tcp_connect6(req: *uv_connect_t, handle: *uv_tcp_t,
-                            cb: uv_connect_cb,
-                            addr: *sockaddr_in6) -> c_int;
-    fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t, addr: *sockaddr_in6) -> c_int;
-    fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t, name: *sockaddr_storage) -> c_int;
-    fn rust_uv_tcp_getsockname(handle: *uv_tcp_t, name: *sockaddr_storage) -> c_int;
-    fn rust_uv_udp_bind(server: *uv_udp_t, addr: *sockaddr_in, flags: c_uint) -> c_int;
-    fn rust_uv_udp_bind6(server: *uv_udp_t, addr: *sockaddr_in6, flags: c_uint) -> c_int;
-    fn rust_uv_udp_send(req: *uv_udp_send_t, handle: *uv_udp_t, buf_in: *uv_buf_t,
-                        buf_cnt: c_int, addr: *sockaddr_in, cb: uv_udp_send_cb) -> c_int;
-    fn rust_uv_udp_send6(req: *uv_udp_send_t, handle: *uv_udp_t, buf_in: *uv_buf_t,
-                         buf_cnt: c_int, addr: *sockaddr_in6, cb: uv_udp_send_cb) -> c_int;
     fn rust_uv_get_udp_handle_from_send_req(req: *uv_udp_send_t) -> *uv_udp_t;
-    fn rust_uv_udp_getsockname(handle: *uv_udp_t, name: *sockaddr_storage) -> c_int;
-    fn rust_uv_is_ipv4_sockaddr(addr: *sockaddr) -> c_int;
-    fn rust_uv_is_ipv6_sockaddr(addr: *sockaddr) -> c_int;
-    fn rust_uv_malloc_sockaddr_storage() -> *sockaddr_storage;
-    fn rust_uv_free_sockaddr_storage(ss: *sockaddr_storage);
+
     fn rust_uv_populate_uv_stat(req_in: *uv_fs_t, stat_out: *uv_stat_t);
     fn rust_uv_get_result_from_fs_req(req: *uv_fs_t) -> c_int;
     fn rust_uv_get_ptr_from_fs_req(req: *uv_fs_t) -> *libc::c_void;
@@ -768,17 +614,27 @@ externfn!(fn uv_async_send(a: *uv_async_t))
 
 // tcp bindings
 externfn!(fn uv_tcp_init(l: *uv_loop_t, h: *uv_tcp_t) -> c_int)
-externfn!(fn uv_ip4_name(src: *sockaddr_in, dst: *c_char,
+externfn!(fn uv_tcp_connect(c: *uv_connect_t, h: *uv_tcp_t,
+                            addr: *sockaddr, cb: uv_connect_cb) -> c_int)
+externfn!(fn uv_tcp_bind(t: *uv_tcp_t, addr: *sockaddr) -> c_int)
+externfn!(fn uv_ip4_name(src: *sockaddr, dst: *c_char,
                          size: size_t) -> c_int)
-externfn!(fn uv_ip6_name(src: *sockaddr_in6, dst: *c_char,
+externfn!(fn uv_ip6_name(src: *sockaddr, dst: *c_char,
                          size: size_t) -> c_int)
 externfn!(fn uv_tcp_nodelay(h: *uv_tcp_t, enable: c_int) -> c_int)
 externfn!(fn uv_tcp_keepalive(h: *uv_tcp_t, enable: c_int,
                               delay: c_uint) -> c_int)
 externfn!(fn uv_tcp_simultaneous_accepts(h: *uv_tcp_t, enable: c_int) -> c_int)
+externfn!(fn uv_tcp_getsockname(h: *uv_tcp_t, name: *sockaddr,
+                                len: *mut c_int) -> c_int)
+externfn!(fn uv_tcp_getpeername(h: *uv_tcp_t, name: *sockaddr,
+                                len: *mut c_int) -> c_int)
+externfn!(fn uv_ip4_addr(ip: *c_char, port: c_int, addr: *sockaddr) -> c_int)
+externfn!(fn uv_ip6_addr(ip: *c_char, port: c_int, addr: *sockaddr) -> c_int)
 
 // udp bindings
 externfn!(fn uv_udp_init(l: *uv_loop_t, h: *uv_udp_t) -> c_int)
+externfn!(fn uv_udp_bind(h: *uv_udp_t, addr: *sockaddr, flags: c_uint) -> c_int)
 externfn!(fn uv_udp_recv_start(server: *uv_udp_t,
                                on_alloc: uv_alloc_cb,
                                on_recv: uv_udp_recv_cb) -> c_int)
@@ -790,6 +646,22 @@ externfn!(fn uv_udp_set_multicast_loop(handle: *uv_udp_t, on: c_int) -> c_int)
 externfn!(fn uv_udp_set_multicast_ttl(handle: *uv_udp_t, ttl: c_int) -> c_int)
 externfn!(fn uv_udp_set_ttl(handle: *uv_udp_t, ttl: c_int) -> c_int)
 externfn!(fn uv_udp_set_broadcast(handle: *uv_udp_t, on: c_int) -> c_int)
+externfn!(fn uv_udp_getsockname(h: *uv_udp_t, name: *sockaddr,
+                                len: *mut c_int) -> c_int)
+
+pub unsafe fn uv_udp_send(req: *uv_udp_send_t,
+                          handle: *uv_udp_t,
+                          buf_in: &[uv_buf_t],
+                          addr: *sockaddr,
+                          cb: uv_udp_send_cb) -> c_int {
+    externfn!(fn uv_udp_send(req: *uv_write_t, stream: *uv_stream_t,
+                             buf_in: *uv_buf_t, buf_cnt: c_int, addr: *sockaddr,
+                             cb: uv_udp_send_cb) -> c_int)
+
+    let buf_ptr = vec::raw::to_ptr(buf_in);
+    let buf_cnt = buf_in.len() as i32;
+    return uv_udp_send(req, handle, buf_ptr, buf_cnt, addr, cb);
+}
 
 // timer bindings
 externfn!(fn uv_timer_init(l: *uv_loop_t, t: *uv_timer_t) -> c_int)
@@ -853,7 +725,7 @@ externfn!(fn uv_freeaddrinfo(ai: *addrinfo))
 
 // process spawning
 externfn!(fn uv_spawn(loop_ptr: *uv_loop_t, outptr: *uv_process_t,
-                      options: uv_process_options_t) -> c_int)
+                      options: *uv_process_options_t) -> c_int)
 externfn!(fn uv_process_kill(p: *uv_process_t, signum: c_int) -> c_int)
 
 // pipes
diff --git a/src/libuv b/src/libuv
-Subproject d88cf5652a1afb23939da0bae86c70ec521b992
+Subproject c6ecf97aafc858c2ad1089fb78da6c586d61d8b
diff --git a/src/rt/rust_uv.cpp b/src/rt/rust_uv.cpp
index 6f619431ad7..280b016af10 100644
--- a/src/rt/rust_uv.cpp
+++ b/src/rt/rust_uv.cpp
@@ -36,96 +36,11 @@ rust_uv_loop_set_data(uv_loop_t* loop, void* data) {
     loop->data = data;
 }
 
-extern "C" int
-rust_uv_tcp_connect(uv_connect_t* connect_ptr,
-        uv_tcp_t* tcp_ptr,
-        uv_connect_cb cb,
-        sockaddr_in* addr_ptr) {
-    // FIXME ref #2064
-    sockaddr_in addr = *addr_ptr;
-    int result = uv_tcp_connect(connect_ptr, tcp_ptr, addr, cb);
-    return result;
-}
-
-extern "C" int
-rust_uv_tcp_bind(uv_tcp_t* tcp_server, sockaddr_in* addr_ptr) {
-    // FIXME ref #2064
-    sockaddr_in addr = *addr_ptr;
-    return uv_tcp_bind(tcp_server, addr);
-}
-extern "C" int
-rust_uv_tcp_connect6(uv_connect_t* connect_ptr,
-        uv_tcp_t* tcp_ptr,
-        uv_connect_cb cb,
-        sockaddr_in6* addr_ptr) {
-    // FIXME ref #2064
-    sockaddr_in6 addr = *addr_ptr;
-    int result = uv_tcp_connect6(connect_ptr, tcp_ptr, addr, cb);
-    return result;
-}
-
-extern "C" int
-rust_uv_tcp_bind6
-(uv_tcp_t* tcp_server, sockaddr_in6* addr_ptr) {
-    // FIXME ref #2064
-    sockaddr_in6 addr = *addr_ptr;
-    return uv_tcp_bind6(tcp_server, addr);
-}
-
-extern "C" int
-rust_uv_tcp_getpeername
-(uv_tcp_t* handle, sockaddr_storage* name) {
-    // sockaddr_storage is big enough to hold either
-    // sockaddr_in or sockaddr_in6
-    int namelen = sizeof(sockaddr_in);
-    return uv_tcp_getpeername(handle, (sockaddr*)name, &namelen);
-}
-
-extern "C" int
-rust_uv_tcp_getsockname
-(uv_tcp_t* handle, sockaddr_storage* name) {
-    // sockaddr_storage is big enough to hold either
-    // sockaddr_in or sockaddr_in6
-    int namelen = sizeof(sockaddr_storage);
-    return uv_tcp_getsockname(handle, (sockaddr*)name, &namelen);
-}
-
-extern "C" int
-rust_uv_udp_bind(uv_udp_t* server, sockaddr_in* addr_ptr, unsigned flags) {
-    return uv_udp_bind(server, *addr_ptr, flags);
-}
-
-extern "C" int
-rust_uv_udp_bind6(uv_udp_t* server, sockaddr_in6* addr_ptr, unsigned flags) {
-    return uv_udp_bind6(server, *addr_ptr, flags);
-}
-
-extern "C" int
-rust_uv_udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t* buf_in,
-                 int buf_cnt, sockaddr_in* addr_ptr, uv_udp_send_cb cb) {
-    return uv_udp_send(req, handle, buf_in, buf_cnt, *addr_ptr, cb);
-}
-
-extern "C" int
-rust_uv_udp_send6(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t* buf_in,
-                  int buf_cnt, sockaddr_in6* addr_ptr, uv_udp_send_cb cb) {
-    return uv_udp_send6(req, handle, buf_in, buf_cnt, *addr_ptr, cb);
-}
-
 extern "C" uv_udp_t*
 rust_uv_get_udp_handle_from_send_req(uv_udp_send_t* send_req) {
     return send_req->handle;
 }
 
-extern "C" int
-rust_uv_udp_getsockname
-(uv_udp_t* handle, sockaddr_storage* name) {
-    // sockaddr_storage is big enough to hold either
-    // sockaddr_in or sockaddr_in6
-    int namelen = sizeof(sockaddr_storage);
-    return uv_udp_getsockname(handle, (sockaddr*)name, &namelen);
-}
-
 extern "C" uv_stream_t*
 rust_uv_get_stream_handle_from_connect_req(uv_connect_t* connect) {
     return connect->handle;
@@ -171,94 +86,52 @@ rust_uv_set_data_for_req(uv_req_t* req, void* data) {
     req->data = data;
 }
 
-extern "C" struct sockaddr_in
-rust_uv_ip4_addr(const char* ip, int port) {
-    struct sockaddr_in addr = uv_ip4_addr(ip, port);
-    return addr;
-}
-extern "C" struct sockaddr_in6
-rust_uv_ip6_addr(const char* ip, int port) {
-    return uv_ip6_addr(ip, port);
-}
-
-extern "C" struct sockaddr_in*
-rust_uv_ip4_addrp(const char* ip, int port) {
-  struct sockaddr_in addr = uv_ip4_addr(ip, port);
-  struct sockaddr_in *addrp = (sockaddr_in*)malloc(sizeof(struct sockaddr_in));
-  assert(addrp);
-  memcpy(addrp, &addr, sizeof(struct sockaddr_in));
-  return addrp;
-}
-extern "C" struct sockaddr_in6*
-rust_uv_ip6_addrp(const char* ip, int port) {
-  struct sockaddr_in6 addr = uv_ip6_addr(ip, port);
-  struct sockaddr_in6 *addrp = (sockaddr_in6*)malloc(sizeof(struct sockaddr_in6));
-  assert(addrp);
-  memcpy(addrp, &addr, sizeof(struct sockaddr_in6));
-  return addrp;
-}
-
-extern "C" struct sockaddr_storage *
-rust_uv_malloc_sockaddr_storage() {
-    struct sockaddr_storage *ss = (sockaddr_storage *)malloc(sizeof(struct sockaddr_storage));
-    return ss;
+extern "C" int
+rust_sockaddr_size() {
+    return sizeof(struct sockaddr_storage);
 }
 
-extern "C" void
-rust_uv_free_sockaddr_storage(struct sockaddr_storage *ss) {
-    free(ss);
+extern "C" struct sockaddr*
+rust_malloc_ip4_addr(char *name, int port) {
+    struct sockaddr_in *addr = (struct sockaddr_in*) malloc(sizeof(struct sockaddr_in));
+    memset(addr, 0, sizeof(struct sockaddr_in));
+    assert(addr != NULL);
+    addr->sin_port = htons(port);
+    assert(uv_inet_pton(AF_INET, name, &addr->sin_addr) == 0);
+    addr->sin_family = AF_INET;
+    return (struct sockaddr*) addr;
 }
 
-extern "C" void
-rust_uv_free_ip4_addr(sockaddr_in *addrp) {
-  free(addrp);
+extern "C" struct sockaddr*
+rust_malloc_ip6_addr(char *name, int port) {
+    struct sockaddr_in6 *addr = (struct sockaddr_in6*) malloc(sizeof(struct sockaddr_in6));
+    memset(addr, 0, sizeof(struct sockaddr));
+    assert(addr != NULL);
+    addr->sin6_port = htons(port);
+    assert(uv_inet_pton(AF_INET6, name, &addr->sin6_addr) == 0);
+    addr->sin6_family = AF_INET6;
+    return (struct sockaddr*) addr;
 }
 
-extern "C" void
-rust_uv_free_ip6_addr(sockaddr_in6 *addrp) {
-  free(addrp);
-}
 extern "C" unsigned int
-rust_uv_ip4_port(struct sockaddr_in* src) {
+rust_ip4_port(struct sockaddr_in* src) {
     return ntohs(src->sin_port);
 }
 extern "C" unsigned int
-rust_uv_ip6_port(struct sockaddr_in6* src) {
+rust_ip6_port(struct sockaddr_in6* src) {
     return ntohs(src->sin6_port);
 }
 
 extern "C" int
-rust_uv_is_ipv4_sockaddr(sockaddr* addr) {
+rust_is_ipv4_sockaddr(sockaddr* addr) {
     return addr->sa_family == AF_INET;
 }
 
 extern "C" int
-rust_uv_is_ipv6_sockaddr(sockaddr* addr) {
+rust_is_ipv6_sockaddr(sockaddr* addr) {
     return addr->sa_family == AF_INET6;
 }
 
-extern "C" bool
-rust_uv_is_ipv4_addrinfo(addrinfo* input) {
-    return input->ai_family == AF_INET;
-}
-
-extern "C" bool
-rust_uv_is_ipv6_addrinfo(addrinfo* input) {
-    return input->ai_family == AF_INET6;
-}
-extern "C" addrinfo*
-rust_uv_get_next_addrinfo(addrinfo* input) {
-    return input->ai_next;
-}
-extern "C" sockaddr_in*
-rust_uv_addrinfo_as_sockaddr_in(addrinfo* input) {
-    return (sockaddr_in*)input->ai_addr;
-}
-extern "C" sockaddr_in6*
-rust_uv_addrinfo_as_sockaddr_in6(addrinfo* input) {
-    return (sockaddr_in6*)input->ai_addr;
-}
-
 extern "C" uintptr_t
 rust_uv_handle_type_max() {
   return UV_HANDLE_TYPE_MAX;