]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #9019 : alexcrichton/rust/reconfigure-llvm, r=brson
authorbors <bors@rust-lang.org>
Fri, 6 Sep 2013 23:51:00 +0000 (16:51 -0700)
committerbors <bors@rust-lang.org>
Fri, 6 Sep 2013 23:51:00 +0000 (16:51 -0700)
@Chris-Morgan ran into this, turns out if we have a clean llvm in the old location we won't rebuild/reconfigure even though we should.

24 files changed:
.gitmodules
mk/clean.mk
mk/dist.mk
mk/rt.mk
mk/rustllvm.mk
src/gyp [new submodule]
src/libextra/glob.rs
src/libstd/rt/io/mod.rs
src/libstd/rt/io/net/mod.rs [new file with mode: 0644]
src/libstd/rt/io/net/tcp.rs
src/libstd/rt/rtio.rs
src/libstd/rt/uv/addrinfo.rs [new file with mode: 0644]
src/libstd/rt/uv/async.rs
src/libstd/rt/uv/file.rs
src/libstd/rt/uv/idle.rs
src/libstd/rt/uv/mod.rs
src/libstd/rt/uv/net.rs
src/libstd/rt/uv/timer.rs
src/libstd/rt/uv/uvio.rs
src/libstd/rt/uv/uvll.rs
src/libstd/vec.rs
src/libuv
src/rt/rust_uv.cpp
src/rt/rustrt.def.in

index 88ead6e608d5c4ee00212451f47c281d09d00846..97e327ebfa4f859d31da2c6f4458e2aaba2469e6 100644 (file)
@@ -4,5 +4,8 @@
        branch = master
 [submodule "src/libuv"]
        path = src/libuv
-       url = https://github.com/brson/libuv.git
+       url = https://github.com/alexcrichton/libuv.git
        branch = master
+[submodule "src/gyp"]
+       path = src/gyp
+       url = https://git.chromium.org/external/gyp.git
index f38396cafff19e29db3cb0917c78007e7b47bf85..cb8861f659761982d20d3d1a3b583b4ef5c12982 100644 (file)
@@ -50,7 +50,7 @@ clean-misc:
        $(Q)rm -f $(RUSTLLVM_LIB_OBJS) $(RUSTLLVM_OBJS_OBJS) $(RUSTLLVM_DEF)
        $(Q)rm -Rf $(DOCS)
        $(Q)rm -Rf $(GENERATED)
-       $(Q)rm -f tmp/*
+       $(Q)rm -Rf tmp/*
        $(Q)rm -Rf rust-stage0-*.tar.bz2 $(PKG_NAME)-*.tar.gz dist
        $(Q)rm -Rf $(foreach ext, \
                  html aux cp fn ky log pdf pg toc tp vr cps, \
index 8e568124d4152c47a1650843e2c4064599f142ab..4a980edf7673141df16ae7895f9c14c37e9b5f7e 100644 (file)
@@ -12,7 +12,7 @@ PKG_ICO = $(S)src/etc/pkg/rust-logo.ico
 PKG_EXE = $(PKG_DIR)-install.exe
 endif
 
-PKG_GITMODULES := $(S)src/libuv $(S)src/llvm
+PKG_GITMODULES := $(S)src/libuv $(S)src/llvm $(S)src/gyp
 
 PKG_FILES := \
     $(S)COPYRIGHT                              \
index 185053e5757b04a596449e11aa6c2421cae945c9..14aa2884b600eacd52bbce1e75f7d5f81ae4460a 100644 (file)
--- a/mk/rt.mk
+++ b/mk/rt.mk
@@ -170,16 +170,28 @@ LIBUV_DEPS := $$(wildcard \
               $$(S)src/libuv/*/*/*/*)
 endif
 
+LIBUV_MAKEFILE_$(1)_$(2) := $$(CFG_BUILD_DIR)$$(RT_BUILD_DIR_$(1)_$(2))/libuv/Makefile
+LIBUV_NO_LOAD = run-benchmarks.target.mk run-tests.target.mk \
+               uv_dtrace_header.target.mk uv_dtrace_provider.target.mk
+
+export PYTHONPATH := $(PYTHONPATH):$$(S)src/gyp/pylib
+
+$$(LIBUV_MAKEFILE_$(1)_$(2)):
+       (cd $(S)src/libuv/ && \
+        ./gyp_uv -f make -Dtarget_arch=$$(LIBUV_ARCH_$(1)) -D ninja \
+          -Goutput_dir=$$(@D) --generator-output $$(@D))
+
 # XXX: Shouldn't need platform-specific conditions here
 ifdef CFG_WINDOWSY_$(1)
 $$(LIBUV_LIB_$(1)_$(2)): $$(LIBUV_DEPS)
-       $$(Q)$$(MAKE) -C $$(S)src/libuv/ \
-               builddir_name="$$(CFG_BUILD_DIR)/$$(RT_BUILD_DIR_$(1)_$(2))/libuv" \
-               OS=mingw \
+       $$(Q)$$(MAKE) -C $$(S)src/libuv -f Makefile.mingw \
+               CFLAGS="$$(CFG_GCCISH_CFLAGS) $$(LIBUV_FLAGS_$$(HOST_$(1))) $$(SNAP_DEFINES)" \
+               AR="$$(AR_$(1))" \
                V=$$(VERBOSE)
+       $$(Q)cp $$(S)src/libuv/libuv.a $$@
 else ifeq ($(OSTYPE_$(1)), linux-androideabi)
-$$(LIBUV_LIB_$(1)_$(2)): $$(LIBUV_DEPS)
-       $$(Q)$$(MAKE) -C $$(S)src/libuv/ \
+$$(LIBUV_LIB_$(1)_$(2)): $$(LIBUV_DEPS) $$(LIBUV_MAKEFILE_$(1)_$(2))
+       $$(Q)$$(MAKE) -C $$(@D) \
                CFLAGS="$$(CFG_GCCISH_CFLAGS) $$(LIBUV_FLAGS_$$(HOST_$(1))) $$(SNAP_DEFINES)" \
                LDFLAGS="$$(CFG_GCCISH_LINK_FLAGS) $$(LIBUV_FLAGS_$$(HOST_$(1)))" \
                CC="$$(CC_$(1))" \
@@ -187,19 +199,22 @@ $$(LIBUV_LIB_$(1)_$(2)): $$(LIBUV_DEPS)
                LINK="$$(CXX_$(1))" \
                AR="$$(AR_$(1))" \
                PLATFORM=android \
-               BUILDTYPE=Release \
-               builddir_name="$$(CFG_BUILD_DIR)/$$(RT_BUILD_DIR_$(1)_$(2))/libuv" \
                host=android OS=linux \
+               builddir="." \
+               BUILDTYPE=Release \
+               NO_LOAD="$$(LIBUV_NO_LOAD)" \
                V=$$(VERBOSE)
 else
-$$(LIBUV_LIB_$(1)_$(2)): $$(LIBUV_DEPS)
-       $$(Q)$$(MAKE) -C $$(S)src/libuv/ \
+$$(LIBUV_LIB_$(1)_$(2)): $$(LIBUV_DEPS) $$(LIBUV_MAKEFILE_$(1)_$(2))
+       $$(Q)$$(MAKE) -C $$(@D) \
                CFLAGS="$$(CFG_GCCISH_CFLAGS) $$(LIBUV_FLAGS_$$(HOST_$(1))) $$(SNAP_DEFINES)" \
                LDFLAGS="$$(CFG_GCCISH_LINK_FLAGS) $$(LIBUV_FLAGS_$$(HOST_$(1)))" \
                CC="$$(CC_$(1))" \
                CXX="$$(CXX_$(1))" \
                AR="$$(AR_$(1))" \
-               builddir_name="$$(CFG_BUILD_DIR)/$$(RT_BUILD_DIR_$(1)_$(2))/libuv" \
+               builddir="." \
+               BUILDTYPE=Release \
+               NO_LOAD="$$(LIBUV_NO_LOAD)" \
                V=$$(VERBOSE)
 endif
 
index 8c3bf4e05b934e68d82ced050d6ec8a61ed82f32..b543926a4f35008660fa85f9831420253bed7297 100644 (file)
@@ -19,7 +19,7 @@ define DEF_RUSTLLVM_TARGETS
 # llvm, but using it straight out of the build directory)
 ifdef CFG_WINDOWSY_$(1)
 LLVM_EXTRA_INCDIRS_$(1)= -iquote $(S)src/llvm/include \
-                         -iquote llvm/$(1)/include
+                         -iquote $$(CFG_LLVM_BUILD_DIR_$(1))/include
 endif
 
 RUSTLLVM_OBJS_CS_$(1) := $$(addprefix rustllvm/, RustWrapper.cpp PassWrapper.cpp)
diff --git a/src/gyp b/src/gyp
new file mode 160000 (submodule)
index 0000000..f407f09
--- /dev/null
+++ b/src/gyp
@@ -0,0 +1 @@
+Subproject commit f407f09c94e00d2d570e8e42114e3f6848b2deb2
index 7598049737454ece58de8a07a6f51bdb6fc85206..6f58102e00a45607640af6001563a985f2eaf639 100644 (file)
@@ -448,11 +448,21 @@ pub fn new() -> MatchOptions {
 #[cfg(test)]
 mod test {
     use std::{io, os, unstable};
+    use std::unstable::finally::Finally;
     use super::*;
+    use tempfile;
 
     #[test]
     fn test_relative_pattern() {
 
+        fn change_then_remove(p: &Path, f: &fn()) {
+            do (|| {
+                unstable::change_dir_locked(p, || f());
+            }).finally {
+                os::remove_dir_recursive(p);
+            }
+        }
+
         fn mk_file(path: &str, directory: bool) {
             if directory {
                 os::make_dir(&Path(path), 0xFFFF);
@@ -469,10 +479,10 @@ fn glob_vec(pattern: &str) -> ~[Path] {
             glob(pattern).collect()
         }
 
-        mk_file("tmp", true);
-        mk_file("tmp/glob-tests", true);
+        let root = tempfile::mkdtemp(&os::tmpdir(), "glob-tests");
+        let root = root.expect("Should have created a temp directory");
 
-        do unstable::change_dir_locked(&Path("tmp/glob-tests")) {
+        do change_then_remove(&root) {
 
             mk_file("aaa", true);
             mk_file("aaa/apple", true);
index d1919905236b24b46ed0773f8de3f7654aa564fd..5ceea8774536a96c89ca9d890c4f29c8c0d4f1fc 100644 (file)
 pub mod file;
 
 /// Synchronous, non-blocking network I/O.
-pub mod net {
-    pub mod tcp;
-    pub mod udp;
-    pub mod ip;
-    #[cfg(unix)]
-    pub mod unix;
-}
+pub mod net;
 
 /// Readers and Writers for memory buffers and strings.
 pub mod mem;
diff --git a/src/libstd/rt/io/net/mod.rs b/src/libstd/rt/io/net/mod.rs
new file mode 100644 (file)
index 0000000..f44e879
--- /dev/null
@@ -0,0 +1,62 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use option::{Option, Some, None};
+use result::{Ok, Err};
+use rt::io::io_error;
+use rt::io::net::ip::IpAddr;
+use rt::rtio::{IoFactory, IoFactoryObject};
+use rt::local::Local;
+
+pub mod tcp;
+pub mod udp;
+pub mod ip;
+#[cfg(unix)]
+pub mod unix;
+
+/// Simplistic name resolution
+pub fn get_host_addresses(host: &str) -> Option<~[IpAddr]> {
+    /*!
+     * Get the IP addresses for a given host name.
+     *
+     * Raises io_error on failure.
+     */
+
+    let ipaddrs = unsafe {
+        let io: *mut IoFactoryObject = Local::unsafe_borrow();
+        (*io).get_host_addresses(host)
+    };
+
+    match ipaddrs {
+        Ok(i) => Some(i),
+        Err(ioerr) => {
+            io_error::cond.raise(ioerr);
+            None
+        }
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use option::Some;
+    use rt::io::net::ip::Ipv4Addr;
+    use super::*;
+
+    #[test]
+    fn dns_smoke_test() {
+        let ipaddrs = get_host_addresses("localhost").unwrap();
+        let mut found_local = false;
+        let local_addr = &Ipv4Addr(127, 0, 0, 1);
+        for addr in ipaddrs.iter() {
+            found_local = found_local || addr == local_addr;
+        }
+        assert!(found_local);
+    }
+}
index b7cb703eb25477fb8018c2492d241718c8abc2e9..b533ebe923b7c87d55cb4096d5233e6c252a3b8d 100644 (file)
@@ -182,7 +182,7 @@ fn connect_error() {
         do run_in_newsched_task {
             let mut called = false;
             do io_error::cond.trap(|e| {
-                assert!(e.kind == ConnectionRefused);
+                assert_eq!(e.kind, ConnectionRefused);
                 called = true;
             }).inside {
                 let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
index 6f1b33d1e219fc6b0dcd84a40410effc0baef5b0..c9c402baaf0fa1d979149faffb9629c714e2db13 100644 (file)
@@ -73,6 +73,7 @@ pub trait IoFactory {
     fn fs_open<P: PathLike>(&mut self, path: &P, fm: FileMode, fa: FileAccess)
         -> Result<~RtioFileStream, IoError>;
     fn fs_unlink<P: PathLike>(&mut self, path: &P) -> Result<(), IoError>;
+    fn get_host_addresses(&mut self, host: &str) -> Result<~[IpAddr], IoError>;
 }
 
 pub trait RtioTcpListener : RtioSocket {
diff --git a/src/libstd/rt/uv/addrinfo.rs b/src/libstd/rt/uv/addrinfo.rs
new file mode 100644 (file)
index 0000000..83a7e64
--- /dev/null
@@ -0,0 +1,177 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use cast::transmute;
+use cell::Cell;
+use c_str::ToCStr;
+use libc::{c_int, c_void};
+use option::{Option, Some, None};
+use ptr::null;
+use rt::uv::uvll;
+use rt::uv::uvll::UV_GETADDRINFO;
+use rt::uv::{Loop, UvError, NativeHandle};
+use rt::uv::status_to_maybe_uv_error;
+use rt::uv::net::UvAddrInfo;
+
+type GetAddrInfoCallback = ~fn(GetAddrInfoRequest, &UvAddrInfo, Option<UvError>);
+
+pub struct GetAddrInfoRequest(*uvll::uv_getaddrinfo_t);
+
+pub struct RequestData {
+    getaddrinfo_cb: Option<GetAddrInfoCallback>,
+}
+
+impl GetAddrInfoRequest {
+    pub fn new() -> GetAddrInfoRequest {
+        let req = unsafe { uvll::malloc_req(UV_GETADDRINFO) };
+        assert!(req.is_not_null());
+        let mut req: GetAddrInfoRequest = NativeHandle::from_native_handle(req);
+        req.install_req_data();
+        return req;
+    }
+
+    pub fn getaddrinfo(&mut self, loop_: &Loop, node: Option<&str>,
+                       service: Option<&str>, hints: Option<UvAddrInfo>,
+                       cb: GetAddrInfoCallback) {
+
+        assert!(node.is_some() || service.is_some());
+
+        let (c_node, c_node_ptr) = match node {
+            Some(n) => {
+                let c_node = n.to_c_str();
+                let c_node_ptr = c_node.with_ref(|r| r);
+                (Some(c_node), c_node_ptr)
+            }
+            None => (None, null())
+        };
+
+        let (c_service, c_service_ptr) = match service {
+            Some(s) => {
+                let c_service = s.to_c_str();
+                let c_service_ptr = c_service.with_ref(|r| r);
+                (Some(c_service), c_service_ptr)
+            }
+            None => (None, null())
+        };
+
+        let cb = Cell::new(cb);
+        let wrapper_cb: GetAddrInfoCallback = |req, addrinfo, err| {
+            // Capture some heap values that need to stay alive for the
+            // getaddrinfo call
+            let _ = &c_node;
+            let _ = &c_service;
+
+            let cb = cb.take();
+            cb(req, addrinfo, err)
+        };
+
+        // XXX: Implement hints
+        assert!(hints.is_none());
+
+        self.get_req_data().getaddrinfo_cb = Some(wrapper_cb);
+
+        unsafe {
+            assert!(0 == uvll::getaddrinfo(loop_.native_handle(),
+                                           self.native_handle(),
+                                           getaddrinfo_cb,
+                                           c_node_ptr,
+                                           c_service_ptr,
+                                           null()));
+        }
+
+        extern "C" fn getaddrinfo_cb(req: *uvll::uv_getaddrinfo_t,
+                                     status: c_int,
+                                     res: *uvll::addrinfo) {
+            let mut req: GetAddrInfoRequest = NativeHandle::from_native_handle(req);
+            let err = status_to_maybe_uv_error(status);
+            let addrinfo = UvAddrInfo(res);
+            let data = req.get_req_data();
+            (*data.getaddrinfo_cb.get_ref())(req, &addrinfo, err);
+            unsafe {
+                uvll::freeaddrinfo(res);
+            }
+        }
+    }
+
+    fn get_loop(&self) -> Loop {
+        unsafe {
+            Loop {
+                handle: uvll::get_loop_from_fs_req(self.native_handle())
+            }
+        }
+    }
+
+    fn install_req_data(&mut self) {
+        let req = self.native_handle() as *uvll::uv_getaddrinfo_t;
+        let data = ~RequestData {
+            getaddrinfo_cb: None
+        };
+        unsafe {
+            let data = transmute::<~RequestData, *c_void>(data);
+            uvll::set_data_for_req(req, data);
+        }
+    }
+
+    fn get_req_data<'r>(&'r mut self) -> &'r mut RequestData {
+        unsafe {
+            let data = uvll::get_data_for_req(self.native_handle());
+            let data = transmute::<&*c_void, &mut ~RequestData>(&data);
+            return &mut **data;
+        }
+    }
+
+    fn delete(self) {
+        unsafe {
+            let data = uvll::get_data_for_req(self.native_handle());
+            let _data = transmute::<*c_void, ~RequestData>(data);
+            uvll::set_data_for_req(self.native_handle(), null::<()>());
+            uvll::free_req(self.native_handle());
+        }
+    }
+}
+
+impl NativeHandle<*uvll::uv_getaddrinfo_t> for GetAddrInfoRequest {
+    fn from_native_handle(handle: *uvll::uv_getaddrinfo_t) -> GetAddrInfoRequest {
+        GetAddrInfoRequest(handle)
+    }
+    fn native_handle(&self) -> *uvll::uv_getaddrinfo_t {
+        match self { &GetAddrInfoRequest(ptr) => ptr }
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use option::{Some, None};
+    use rt::uv::Loop;
+    use rt::uv::net::accum_sockaddrs;
+    use rt::io::net::ip::{SocketAddr, Ipv4Addr};
+    use super::*;
+
+    #[test]
+    fn getaddrinfo_test() {
+        let mut loop_ = Loop::new();
+        let mut req = GetAddrInfoRequest::new();
+        do req.getaddrinfo(&loop_, Some("localhost"), None, None) |_, addrinfo, _| {
+            let sockaddrs = accum_sockaddrs(addrinfo);
+            let mut found_local = false;
+            let local_addr = &SocketAddr {
+                ip: Ipv4Addr(127, 0, 0, 1),
+                port: 0
+            };
+            for addr in sockaddrs.iter() {
+                found_local = found_local || addr == local_addr;
+            }
+            assert!(found_local);
+        }
+        loop_.run();
+        loop_.close();
+        req.delete();
+    }
+}
index d0ca38317cbededd13675b41c17ad764ee7f982b..ff7bb9dd03abcf8403fd40a0d703e44c2c339618 100644 (file)
@@ -34,7 +34,7 @@ pub fn new(loop_: &mut Loop, cb: AsyncCallback) -> AsyncWatcher {
 
         extern fn async_cb(handle: *uvll::uv_async_t, status: c_int) {
             let mut watcher: AsyncWatcher = NativeHandle::from_native_handle(handle);
-            let status = status_to_maybe_uv_error(watcher, status);
+            let status = status_to_maybe_uv_error(status);
             let data = watcher.get_watcher_data();
             let cb = data.async_cb.get_ref();
             (*cb)(watcher, status);
index 15fe9abaa2c50ef90156cf4e81e5a89d68d89a53..45a5fce3f1e8aa0e33575244b98897eb3f73a4f8 100644 (file)
@@ -12,7 +12,7 @@
 use ptr::null;
 use libc::c_void;
 use rt::uv::{Request, NativeHandle, Loop, FsCallback, Buf,
-             status_to_maybe_uv_error_with_loop, UvError};
+             status_to_maybe_uv_error, UvError};
 use rt::uv::uvll;
 use rt::uv::uvll::*;
 use super::super::io::support::PathLike;
@@ -62,7 +62,7 @@ pub fn open<P: PathLike>(loop_: &Loop, path: &P, flags: int, mode: int,
     pub fn open_sync<P: PathLike>(loop_: &Loop, path: &P, flags: int, mode: int)
           -> Result<int, UvError> {
         let result = FsRequest::open_common(loop_, path, flags, mode, None);
-        sync_cleanup(loop_, result)
+        sync_cleanup(result)
     }
 
     fn unlink_common<P: PathLike>(loop_: &Loop, path: &P, cb: Option<FsCallback>) -> int {
@@ -83,11 +83,11 @@ fn unlink_common<P: PathLike>(loop_: &Loop, path: &P, cb: Option<FsCallback>) ->
     }
     pub fn unlink<P: PathLike>(loop_: &Loop, path: &P, cb: FsCallback) {
         let result = FsRequest::unlink_common(loop_, path, Some(cb));
-        sync_cleanup(loop_, result);
+        sync_cleanup(result);
     }
     pub fn unlink_sync<P: PathLike>(loop_: &Loop, path: &P) -> Result<int, UvError> {
         let result = FsRequest::unlink_common(loop_, path, None);
-        sync_cleanup(loop_, result)
+        sync_cleanup(result)
     }
 
     pub fn install_req_data(&self, cb: Option<FsCallback>) {
@@ -139,15 +139,17 @@ fn native_handle(&self) -> *uvll::uv_fs_t {
         match self { &FsRequest(ptr) => ptr }
     }
 }
-    fn sync_cleanup(loop_: &Loop, result: int)
-          -> Result<int, UvError> {
-        match status_to_maybe_uv_error_with_loop(loop_.native_handle(), result as i32) {
-            Some(err) => Err(err),
-            None => Ok(result)
-        }
+
+fn sync_cleanup(result: int)
+    -> Result<int, UvError> {
+    match status_to_maybe_uv_error(result as i32) {
+        Some(err) => Err(err),
+        None => Ok(result)
     }
+}
 
 pub struct FileDescriptor(c_int);
+
 impl FileDescriptor {
     fn new(fd: c_int) -> FileDescriptor {
         FileDescriptor(fd)
@@ -184,7 +186,7 @@ pub fn write(&mut self, loop_: &Loop, buf: Buf, offset: i64, cb: FsCallback) {
     pub fn write_sync(&mut self, loop_: &Loop, buf: Buf, offset: i64)
           -> Result<int, UvError> {
         let result = self.write_common(loop_, buf, offset, None);
-        sync_cleanup(loop_, result)
+        sync_cleanup(result)
     }
 
     fn read_common(&mut self, loop_: &Loop, buf: Buf,
@@ -212,7 +214,7 @@ pub fn read(&mut self, loop_: &Loop, buf: Buf, offset: i64, cb: FsCallback) {
     pub fn read_sync(&mut self, loop_: &Loop, buf: Buf, offset: i64)
           -> Result<int, UvError> {
         let result = self.read_common(loop_, buf, offset, None);
-        sync_cleanup(loop_, result)
+        sync_cleanup(result)
     }
 
     fn close_common(self, loop_: &Loop, cb: Option<FsCallback>) -> int {
@@ -234,12 +236,11 @@ pub fn close(self, loop_: &Loop, cb: FsCallback) {
     }
     pub fn close_sync(self, loop_: &Loop) -> Result<int, UvError> {
         let result = self.close_common(loop_, None);
-        sync_cleanup(loop_, result)
+        sync_cleanup(result)
     }
 }
 extern fn compl_cb(req: *uv_fs_t) {
     let mut req: FsRequest = NativeHandle::from_native_handle(req);
-    let loop_ = req.get_loop();
     // pull the user cb out of the req data
     let cb = {
         let data = req.get_req_data();
@@ -250,8 +251,7 @@ pub fn close_sync(self, loop_: &Loop) -> Result<int, UvError> {
     // in uv_fs_open calls, the result will be the fd in the
     // case of success, otherwise it's -1 indicating an error
     let result = req.get_result();
-    let status = status_to_maybe_uv_error_with_loop(
-        loop_.native_handle(), result);
+    let status = status_to_maybe_uv_error(result);
     // we have a req and status, call the user cb..
     // only giving the user a ref to the FsRequest, as we
     // have to clean it up, afterwards (and they aren't really
index a21146620ca823ec8643adfdb84c00f31a391b38..8cbcd7b77c0824fdea0b1df2e1234cdc0a412b3c 100644 (file)
@@ -43,7 +43,7 @@ pub fn start(&mut self, cb: IdleCallback) {
             let mut idle_watcher: IdleWatcher = NativeHandle::from_native_handle(handle);
             let data = idle_watcher.get_watcher_data();
             let cb: &IdleCallback = data.idle_cb.get_ref();
-            let status = status_to_maybe_uv_error(idle_watcher, status);
+            let status = status_to_maybe_uv_error(status);
             (*cb)(idle_watcher, status);
         }
     }
@@ -57,7 +57,7 @@ pub fn restart(&mut self) {
             let mut idle_watcher: IdleWatcher = NativeHandle::from_native_handle(handle);
             let data = idle_watcher.get_watcher_data();
             let cb: &IdleCallback = data.idle_cb.get_ref();
-            let status = status_to_maybe_uv_error(idle_watcher, status);
+            let status = status_to_maybe_uv_error(status);
             (*cb)(idle_watcher, status);
         }
     }
index 75b9a5ac553e8eff77d5d096730081f2e12cd902..451d454d2d822262c4279ca94f379cb8f0e29b98 100644 (file)
@@ -70,6 +70,7 @@
 pub mod idle;
 pub mod timer;
 pub mod async;
+pub mod addrinfo;
 
 /// XXX: Loop(*handle) is buggy with destructors. Normal structs
 /// with dtors may not be destructured, but tuple structs can,
@@ -132,7 +133,8 @@ fn native_handle(&self) -> *uvll::uv_loop_t {
 pub type UdpSendCallback = ~fn(UdpWatcher, Option<UvError>);
 
 
-/// Callbacks used by StreamWatchers, set as custom data on the foreign handle
+/// Callbacks used by StreamWatchers, set as custom data on the foreign handle.
+/// XXX: Would be better not to have all watchers allocate room for all callback types.
 struct WatcherData {
     read_cb: Option<ReadCallback>,
     write_cb: Option<ConnectionCallback>,
@@ -202,12 +204,12 @@ fn drop_watcher_data(&mut self) {
 // XXX: Need to define the error constants like EOF so they can be
 // compared to the UvError type
 
-pub struct UvError(uvll::uv_err_t);
+pub struct UvError(c_int);
 
 impl UvError {
     pub fn name(&self) -> ~str {
         unsafe {
-            let inner = match self { &UvError(ref a) => a };
+            let inner = match self { &UvError(a) => a };
             let name_str = uvll::err_name(inner);
             assert!(name_str.is_not_null());
             from_c_str(name_str)
@@ -216,7 +218,7 @@ pub fn name(&self) -> ~str {
 
     pub fn desc(&self) -> ~str {
         unsafe {
-            let inner = match self { &UvError(ref a) => a };
+            let inner = match self { &UvError(a) => a };
             let desc_str = uvll::strerror(inner);
             assert!(desc_str.is_not_null());
             from_c_str(desc_str)
@@ -224,7 +226,7 @@ pub fn desc(&self) -> ~str {
     }
 
     pub fn is_eof(&self) -> bool {
-        self.code == uvll::EOF
+        **self == uvll::EOF
     }
 }
 
@@ -236,18 +238,10 @@ fn to_str(&self) -> ~str {
 
 #[test]
 fn error_smoke_test() {
-    let err = uvll::uv_err_t { code: 1, sys_errno_: 1 };
-    let err: UvError = UvError(err);
+    let err: UvError = UvError(uvll::EOF);
     assert_eq!(err.to_str(), ~"EOF: end of file");
 }
 
-pub fn last_uv_error<H, W: Watcher + NativeHandle<*H>>(watcher: &W) -> UvError {
-    unsafe {
-        let loop_ = watcher.event_loop();
-        UvError(uvll::last_error(loop_.native_handle()))
-    }
-}
-
 pub fn uv_error_to_io_error(uverr: UvError) -> IoError {
     unsafe {
         // Importing error constants
@@ -255,10 +249,10 @@ pub fn uv_error_to_io_error(uverr: UvError) -> IoError {
         use rt::io::*;
 
         // uv error descriptions are static
-        let c_desc = uvll::strerror(&*uverr);
+        let c_desc = uvll::strerror(*uverr);
         let desc = str::raw::c_str_to_static_slice(c_desc);
 
-        let kind = match uverr.code {
+        let kind = match *uverr {
             UNKNOWN => OtherIoError,
             OK => OtherIoError,
             EOF => EndOfFile,
@@ -266,8 +260,8 @@ pub fn uv_error_to_io_error(uverr: UvError) -> IoError {
             ECONNREFUSED => ConnectionRefused,
             ECONNRESET => ConnectionReset,
             EPIPE => BrokenPipe,
-            _ => {
-                rtdebug!("uverr.code %u", uverr.code as uint);
+            err => {
+                rtdebug!("uverr.code %d", err as int);
                 // XXX: Need to map remaining uv error types
                 OtherIoError
             }
@@ -282,30 +276,12 @@ pub fn uv_error_to_io_error(uverr: UvError) -> IoError {
 }
 
 /// Given a uv handle, convert a callback status to a UvError
-pub fn status_to_maybe_uv_error_with_loop(
-    loop_: *uvll::uv_loop_t,
-    status: c_int) -> Option<UvError> {
-    if status != -1 {
+pub fn status_to_maybe_uv_error(status: c_int) -> Option<UvError>
+{
+    if status >= 0 {
         None
     } else {
-        unsafe {
-            rtdebug!("loop: %x", loop_ as uint);
-            let err = uvll::last_error(loop_);
-            Some(UvError(err))
-        }
-    }
-}
-/// Given a uv handle, convert a callback status to a UvError
-pub fn status_to_maybe_uv_error<T, U: Watcher + NativeHandle<*T>>(handle: U,
-                                                                 status: c_int) -> Option<UvError> {
-    if status != -1 {
-        None
-    } else {
-        unsafe {
-            rtdebug!("handle: %x", handle.native_handle() as uint);
-            let loop_ = uvll::get_loop_for_uv_handle(handle.native_handle());
-            status_to_maybe_uv_error_with_loop(loop_, status)
-        }
+        Some(UvError(status))
     }
 }
 
index 6e8908506544a043460804b6fdd0b586506f5205..2535e40ba4f0f641f5b87c5dc8d348fe02bf11e4 100644 (file)
 use rt::uv::{Loop, Watcher, Request, UvError, Buf, NativeHandle, NullCallback,
              status_to_maybe_uv_error};
 use rt::io::net::ip::{SocketAddr, Ipv4Addr, Ipv6Addr};
-use rt::uv::last_uv_error;
 use vec;
 use str;
 use from_str::{FromStr};
 
+pub struct UvAddrInfo(*uvll::addrinfo);
+
 pub enum UvSocketAddr {
     UvIpv4SocketAddr(*sockaddr_in),
     UvIpv6SocketAddr(*sockaddr_in6),
@@ -95,6 +96,28 @@ pub fn uv_socket_addr_to_socket_addr(addr: UvSocketAddr) -> SocketAddr {
     uv_socket_addr_as_socket_addr(addr, util::id)
 }
 
+// Traverse the addrinfo linked list, producing a vector of Rust socket addresses
+pub fn accum_sockaddrs(addr: &UvAddrInfo) -> ~[SocketAddr] {
+    unsafe {
+        let &UvAddrInfo(addr) = addr;
+        let mut addr = addr;
+
+        let mut addrs = ~[];
+        loop {
+            let uvaddr = sockaddr_to_UvSocketAddr((*addr).ai_addr);
+            let rustaddr = uv_socket_addr_to_socket_addr(uvaddr);
+            addrs.push(rustaddr);
+            if (*addr).ai_next.is_not_null() {
+                addr = (*addr).ai_next;
+            } else {
+                break;
+            }
+        }
+
+        return addrs;
+    }
+}
+
 #[cfg(test)]
 #[test]
 fn test_ip4_conversion() {
@@ -137,7 +160,7 @@ pub fn read_start(&mut self, alloc: AllocCallback, cb: ReadCallback) {
             rtdebug!("buf len: %d", buf.len as int);
             let mut stream_watcher: StreamWatcher = NativeHandle::from_native_handle(stream);
             let cb = stream_watcher.get_watcher_data().read_cb.get_ref();
-            let status = status_to_maybe_uv_error(stream_watcher, nread as c_int);
+            let status = status_to_maybe_uv_error(nread as c_int);
             (*cb)(stream_watcher, nread as int, buf, status);
         }
     }
@@ -167,7 +190,7 @@ pub fn write(&mut self, buf: Buf, cb: ConnectionCallback) {
             let mut stream_watcher = write_request.stream();
             write_request.delete();
             let cb = stream_watcher.get_watcher_data().write_cb.take_unwrap();
-            let status = status_to_maybe_uv_error(stream_watcher, status);
+            let status = status_to_maybe_uv_error(status);
             cb(stream_watcher, status);
         }
     }
@@ -232,7 +255,7 @@ pub fn bind(&mut self, address: SocketAddr) -> Result<(), UvError> {
             };
             match result {
                 0 => Ok(()),
-                _ => Err(last_uv_error(self)),
+                _ => Err(UvError(result)),
             }
         }
     }
@@ -260,7 +283,7 @@ pub fn connect(&mut self, address: SocketAddr, cb: ConnectionCallback) {
                 let mut stream_watcher = connect_request.stream();
                 connect_request.delete();
                 let cb = stream_watcher.get_watcher_data().connect_cb.take_unwrap();
-                let status = status_to_maybe_uv_error(stream_watcher, status);
+                let status = status_to_maybe_uv_error(status);
                 cb(stream_watcher, status);
             }
         }
@@ -283,7 +306,7 @@ pub fn listen(&mut self, cb: ConnectionCallback) {
             rtdebug!("connection_cb");
             let mut stream_watcher: StreamWatcher = NativeHandle::from_native_handle(handle);
             let cb = stream_watcher.get_watcher_data().connect_cb.get_ref();
-            let status = status_to_maybe_uv_error(stream_watcher, status);
+            let status = status_to_maybe_uv_error(status);
             (*cb)(stream_watcher, status);
         }
     }
@@ -327,7 +350,7 @@ pub fn bind(&mut self, address: SocketAddr) -> Result<(), UvError> {
             };
             match result {
                 0 => Ok(()),
-                _ => Err(last_uv_error(self)),
+                _ => Err(UvError(result)),
             }
         }
     }
@@ -360,7 +383,7 @@ pub fn recv_start(&mut self, alloc: AllocCallback, cb: UdpReceiveCallback) {
             rtdebug!("buf len: %d", buf.len as int);
             let mut udp_watcher: UdpWatcher = NativeHandle::from_native_handle(handle);
             let cb = udp_watcher.get_watcher_data().udp_recv_cb.get_ref();
-            let status = status_to_maybe_uv_error(udp_watcher, nread as c_int);
+            let status = status_to_maybe_uv_error(nread as c_int);
             let addr = uv_socket_addr_to_socket_addr(sockaddr_to_UvSocketAddr(addr));
             (*cb)(udp_watcher, nread as int, buf, addr, flags as uint, status);
         }
@@ -395,7 +418,7 @@ pub fn send(&mut self, buf: Buf, address: SocketAddr, cb: UdpSendCallback) {
             let mut udp_watcher = send_request.handle();
             send_request.delete();
             let cb = udp_watcher.get_watcher_data().udp_send_cb.take_unwrap();
-            let status = status_to_maybe_uv_error(udp_watcher, status);
+            let status = status_to_maybe_uv_error(status);
             cb(udp_watcher, status);
         }
     }
index eaa5e77a6da2fe71b3a67a11105dc5acee18c4f5..7b09cf2eb0e3ab058f4c2cf2d65526585964e758 100644 (file)
@@ -43,7 +43,7 @@ pub fn start(&mut self, timeout: u64, repeat: u64, cb: TimerCallback) {
             let mut watcher: TimerWatcher = NativeHandle::from_native_handle(handle);
             let data = watcher.get_watcher_data();
             let cb = data.timer_cb.get_ref();
-            let status = status_to_maybe_uv_error(watcher, status);
+            let status = status_to_maybe_uv_error(status);
             (*cb)(watcher, status);
         }
     }
index 6f9e3c43b0e84204e5ddb73dd7e10144bd7baf7a..c9b12e47f9226a7a3003daa79590d1bcf6e84645 100644 (file)
@@ -29,7 +29,8 @@
 use rt::task::SchedHome;
 use rt::uv::*;
 use rt::uv::idle::IdleWatcher;
-use rt::uv::net::{UvIpv4SocketAddr, UvIpv6SocketAddr};
+use rt::uv::net::{UvIpv4SocketAddr, UvIpv6SocketAddr, accum_sockaddrs};
+use rt::uv::addrinfo::GetAddrInfoRequest;
 use unstable::sync::Exclusive;
 use super::super::io::support::PathLike;
 use libc::{lseek, off_t, O_CREAT, O_APPEND, O_TRUNC, O_RDWR, O_RDONLY, O_WRONLY,
@@ -153,7 +154,7 @@ fn socket_name<T, U: Watcher + NativeHandle<*T>>(sk: SocketNameKind,
     };
 
     if r != 0 {
-        let status = status_to_maybe_uv_error(handle, r);
+        let status = status_to_maybe_uv_error(r);
         return Err(uv_error_to_io_error(status.unwrap()));
     }
 
@@ -596,6 +597,37 @@ fn fs_unlink<P: PathLike>(&mut self, path: &P) -> Result<(), IoError> {
         assert!(!result_cell.is_empty());
         return result_cell.take();
     }
+
+    fn get_host_addresses(&mut self, host: &str) -> Result<~[IpAddr], IoError> {
+        let result_cell = Cell::new_empty();
+        let result_cell_ptr: *Cell<Result<~[IpAddr], IoError>> = &result_cell;
+        let host_ptr: *&str = &host;
+        let addrinfo_req = GetAddrInfoRequest::new();
+        let addrinfo_req_cell = Cell::new(addrinfo_req);
+        do task::unkillable { // FIXME(#8674)
+            let scheduler: ~Scheduler = Local::take();
+            do scheduler.deschedule_running_task_and_then |_, task| {
+                let task_cell = Cell::new(task);
+                let mut addrinfo_req = addrinfo_req_cell.take();
+                unsafe {
+                    do addrinfo_req.getaddrinfo(self.uv_loop(),
+                                                Some(*host_ptr),
+                                                None, None) |_, addrinfo, err| {
+                        let res = match err {
+                            None => Ok(accum_sockaddrs(addrinfo).map(|addr| addr.ip.clone())),
+                            Some(err) => Err(uv_error_to_io_error(err))
+                        };
+                        (*result_cell_ptr).put_back(res);
+                        let scheduler: ~Scheduler = Local::take();
+                        scheduler.resume_blocked_task_immediately(task_cell.take());
+                    }
+                }
+            }
+        }
+        addrinfo_req.delete();
+        assert!(!result_cell.is_empty());
+        return result_cell.take();
+    }
 }
 
 pub struct UvTcpListener {
@@ -696,7 +728,7 @@ fn accept_simultaneously(&mut self) -> Result<(), IoError> {
                 uvll::tcp_simultaneous_accepts(self_.listener.watcher.native_handle(), 1 as c_int)
             };
 
-            match status_to_maybe_uv_error(self_.listener.watcher, r) {
+            match status_to_maybe_uv_error(r) {
                 Some(err) => Err(uv_error_to_io_error(err)),
                 None => Ok(())
             }
@@ -709,7 +741,7 @@ fn dont_accept_simultaneously(&mut self) -> Result<(), IoError> {
                 uvll::tcp_simultaneous_accepts(self_.listener.watcher.native_handle(), 0 as c_int)
             };
 
-            match status_to_maybe_uv_error(self_.listener.watcher, r) {
+            match status_to_maybe_uv_error(r) {
                 Some(err) => Err(uv_error_to_io_error(err)),
                 None => Ok(())
             }
@@ -830,7 +862,7 @@ fn control_congestion(&mut self) -> Result<(), IoError> {
         do self.home_for_io |self_| {
             let r = unsafe { uvll::tcp_nodelay(self_.watcher.native_handle(), 0 as c_int) };
 
-            match status_to_maybe_uv_error(self_.watcher, r) {
+            match status_to_maybe_uv_error(r) {
                 Some(err) => Err(uv_error_to_io_error(err)),
                 None => Ok(())
             }
@@ -841,7 +873,7 @@ fn nodelay(&mut self) -> Result<(), IoError> {
         do self.home_for_io |self_| {
             let r = unsafe { uvll::tcp_nodelay(self_.watcher.native_handle(), 1 as c_int) };
 
-            match status_to_maybe_uv_error(self_.watcher, r) {
+            match status_to_maybe_uv_error(r) {
                 Some(err) => Err(uv_error_to_io_error(err)),
                 None => Ok(())
             }
@@ -855,7 +887,7 @@ fn keepalive(&mut self, delay_in_seconds: uint) -> Result<(), IoError> {
                                     delay_in_seconds as c_uint)
             };
 
-            match status_to_maybe_uv_error(self_.watcher, r) {
+            match status_to_maybe_uv_error(r) {
                 Some(err) => Err(uv_error_to_io_error(err)),
                 None => Ok(())
             }
@@ -868,7 +900,7 @@ fn letdie(&mut self) -> Result<(), IoError> {
                 uvll::tcp_keepalive(self_.watcher.native_handle(), 0 as c_int, 0 as c_uint)
             };
 
-            match status_to_maybe_uv_error(self_.watcher, r) {
+            match status_to_maybe_uv_error(r) {
                 Some(err) => Err(uv_error_to_io_error(err)),
                 None => Ok(())
             }
@@ -980,7 +1012,7 @@ fn join_multicast(&mut self, multi: IpAddr) -> Result<(), IoError> {
                 }
             };
 
-            match status_to_maybe_uv_error(self_.watcher, r) {
+            match status_to_maybe_uv_error(r) {
                 Some(err) => Err(uv_error_to_io_error(err)),
                 None => Ok(())
             }
@@ -996,7 +1028,7 @@ fn leave_multicast(&mut self, multi: IpAddr) -> Result<(), IoError> {
                 }
             };
 
-            match status_to_maybe_uv_error(self_.watcher, r) {
+            match status_to_maybe_uv_error(r) {
                 Some(err) => Err(uv_error_to_io_error(err)),
                 None => Ok(())
             }
@@ -1010,7 +1042,7 @@ fn loop_multicast_locally(&mut self) -> Result<(), IoError> {
                 uvll::udp_set_multicast_loop(self_.watcher.native_handle(), 1 as c_int)
             };
 
-            match status_to_maybe_uv_error(self_.watcher, r) {
+            match status_to_maybe_uv_error(r) {
                 Some(err) => Err(uv_error_to_io_error(err)),
                 None => Ok(())
             }
@@ -1024,7 +1056,7 @@ fn dont_loop_multicast_locally(&mut self) -> Result<(), IoError> {
                 uvll::udp_set_multicast_loop(self_.watcher.native_handle(), 0 as c_int)
             };
 
-            match status_to_maybe_uv_error(self_.watcher, r) {
+            match status_to_maybe_uv_error(r) {
                 Some(err) => Err(uv_error_to_io_error(err)),
                 None => Ok(())
             }
@@ -1038,7 +1070,7 @@ fn multicast_time_to_live(&mut self, ttl: int) -> Result<(), IoError> {
                 uvll::udp_set_multicast_ttl(self_.watcher.native_handle(), ttl as c_int)
             };
 
-            match status_to_maybe_uv_error(self_.watcher, r) {
+            match status_to_maybe_uv_error(r) {
                 Some(err) => Err(uv_error_to_io_error(err)),
                 None => Ok(())
             }
@@ -1052,7 +1084,7 @@ fn time_to_live(&mut self, ttl: int) -> Result<(), IoError> {
                 uvll::udp_set_ttl(self_.watcher.native_handle(), ttl as c_int)
             };
 
-            match status_to_maybe_uv_error(self_.watcher, r) {
+            match status_to_maybe_uv_error(r) {
                 Some(err) => Err(uv_error_to_io_error(err)),
                 None => Ok(())
             }
@@ -1066,7 +1098,7 @@ fn hear_broadcasts(&mut self) -> Result<(), IoError> {
                 uvll::udp_set_broadcast(self_.watcher.native_handle(), 1 as c_int)
             };
 
-            match status_to_maybe_uv_error(self_.watcher, r) {
+            match status_to_maybe_uv_error(r) {
                 Some(err) => Err(uv_error_to_io_error(err)),
                 None => Ok(())
             }
@@ -1080,7 +1112,7 @@ fn ignore_broadcasts(&mut self) -> Result<(), IoError> {
                 uvll::udp_set_broadcast(self_.watcher.native_handle(), 0 as c_int)
             };
 
-            match status_to_maybe_uv_error(self_.watcher, r) {
+            match status_to_maybe_uv_error(r) {
                 Some(err) => Err(uv_error_to_io_error(err)),
                 None => Ok(())
             }
index d2e3b4176f96150dc443248e10d44bd6ba0e8f33..4ef97677bd353b54b4118550d3cb469641c61e8e 100644 (file)
 use libc;
 use prelude::*;
 use ptr;
-use str;
 use vec;
 
-pub static UNKNOWN: c_int = -1;
+pub use self::errors::*;
+
 pub static OK: c_int = 0;
-pub static EOF: c_int = 1;
-pub static EADDRINFO: c_int = 2;
-pub static EACCES: c_int = 3;
-pub static ECONNREFUSED: c_int = 12;
-pub static ECONNRESET: c_int = 13;
-pub static EPIPE: c_int = 36;
+pub static EOF: c_int = -4095;
+pub static UNKNOWN: c_int = -4094;
+
+// uv-errno.h redefines error codes for windows, but not for unix...
+
+#[cfg(windows)]
+pub mod errors {
+    use libc::c_int;
 
-pub struct uv_err_t {
-    code: c_int,
-    sys_errno_: c_int
+    pub static EACCES: c_int = -4093;
+    pub static ECONNREFUSED: c_int = -4079;
+    pub static ECONNRESET: c_int = -4078;
+    pub static EPIPE: c_int = -4048;
+}
+#[cfg(not(windows))]
+pub mod errors {
+    use libc;
+    use libc::c_int;
+
+    pub static EACCES: c_int = -libc::EACCES;
+    pub static ECONNREFUSED: c_int = -libc::ECONNREFUSED;
+    pub static ECONNRESET: c_int = -libc::ECONNRESET;
+    pub static EPIPE: c_int = -libc::EPIPE;
 }
 
 pub struct uv_buf_t {
@@ -72,6 +85,7 @@ pub struct uv_buf_t {
 pub type uv_stream_t = c_void;
 pub type uv_fs_t = c_void;
 pub type uv_udp_send_t = c_void;
+pub type uv_getaddrinfo_t = c_void;
 
 #[cfg(stage0)]
 pub type uv_idle_cb = *u8;
@@ -97,6 +111,8 @@ pub struct uv_buf_t {
 pub type uv_timer_cb = *u8;
 #[cfg(stage0)]
 pub type uv_write_cb = *u8;
+#[cfg(stage0)]
+pub type uv_getaddrinfo_cb = *u8;
 
 #[cfg(not(stage0))]
 pub type uv_idle_cb = extern "C" fn(handle: *uv_idle_t,
@@ -137,12 +153,58 @@ pub struct uv_buf_t {
 #[cfg(not(stage0))]
 pub type uv_write_cb = extern "C" fn(handle: *uv_write_t,
                                      status: c_int);
+#[cfg(not(stage0))]
+pub type uv_getaddrinfo_cb = extern "C" fn(req: *uv_getaddrinfo_t,
+                                           status: c_int,
+                                           res: *addrinfo);
 
 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;
+
+// XXX: This is a standard C type. Could probably be defined in libc
+#[cfg(target_os = "android")]
+#[cfg(target_os = "linux")]
+pub struct addrinfo {
+    ai_flags: c_int,
+    ai_family: c_int,
+    ai_socktype: c_int,
+    ai_protocol: c_int,
+    ai_addrlen: socklen_t,
+    ai_addr: *sockaddr,
+    ai_canonname: *char,
+    ai_next: *addrinfo
+}
+
+#[cfg(target_os = "macos")]
+#[cfg(target_os = "freebsd")]
+pub struct addrinfo {
+    ai_flags: c_int,
+    ai_family: c_int,
+    ai_socktype: c_int,
+    ai_protocol: c_int,
+    ai_addrlen: socklen_t,
+    ai_canonname: *char,
+    ai_addr: *sockaddr,
+    ai_next: *addrinfo
+}
+
+#[cfg(windows)]
+pub struct addrinfo {
+    ai_flags: c_int,
+    ai_family: c_int,
+    ai_socktype: c_int,
+    ai_protocol: c_int,
+    ai_addrlen: size_t,
+    ai_canonname: *char,
+    ai_addr: *sockaddr,
+    ai_next: *addrinfo
+}
+
 #[deriving(Eq)]
 pub enum uv_handle_type {
     UV_UNKNOWN_HANDLE,
@@ -488,20 +550,12 @@ pub unsafe fn read_stop(stream: *uv_stream_t) -> c_int {
     return rust_uv_read_stop(stream as *c_void);
 }
 
-pub unsafe fn last_error(loop_handle: *c_void) -> uv_err_t {
+pub unsafe fn strerror(err: c_int) -> *c_char {
     #[fixed_stack_segment]; #[inline(never)];
-
-    return rust_uv_last_error(loop_handle);
-}
-
-pub unsafe fn strerror(err: *uv_err_t) -> *c_char {
-    #[fixed_stack_segment]; #[inline(never)];
-
     return rust_uv_strerror(err);
 }
-pub unsafe fn err_name(err: *uv_err_t) -> *c_char {
+pub unsafe fn err_name(err: c_int) -> *c_char {
     #[fixed_stack_segment]; #[inline(never)];
-
     return rust_uv_err_name(err);
 }
 
@@ -666,6 +720,11 @@ pub unsafe fn get_loop_from_fs_req(req: *uv_fs_t) -> *uv_loop_t {
 
     rust_uv_get_loop_from_fs_req(req)
 }
+pub unsafe fn get_loop_from_getaddrinfo_req(req: *uv_getaddrinfo_t) -> *uv_loop_t {
+    #[fixed_stack_segment]; #[inline(never)];
+
+    rust_uv_get_loop_from_getaddrinfo_req(req)
+}
 pub unsafe fn get_loop_for_uv_handle<T>(handle: *T) -> *c_void {
     #[fixed_stack_segment]; #[inline(never)];
 
@@ -721,21 +780,16 @@ pub unsafe fn get_len_from_buf(buf: uv_buf_t) -> size_t {
 
     return rust_uv_get_len_from_buf(buf);
 }
-pub unsafe fn get_last_err_info(uv_loop: *c_void) -> ~str {
-    let err = last_error(uv_loop);
-    let err_ptr = ptr::to_unsafe_ptr(&err);
-    let err_name = str::raw::from_c_str(err_name(err_ptr));
-    let err_msg = str::raw::from_c_str(strerror(err_ptr));
-    return fmt!("LIBUV ERROR: name: %s msg: %s",
-                    err_name, err_msg);
+pub unsafe fn getaddrinfo(loop_: *uv_loop_t, req: *uv_getaddrinfo_t,
+               getaddrinfo_cb: uv_getaddrinfo_cb,
+               node: *c_char, service: *c_char,
+               hints: *addrinfo) -> c_int {
+    #[fixed_stack_segment]; #[inline(never)];
+    return rust_uv_getaddrinfo(loop_, req, getaddrinfo_cb, node, service, hints);
 }
-
-pub unsafe fn get_last_err_data(uv_loop: *c_void) -> uv_err_data {
-    let err = last_error(uv_loop);
-    let err_ptr = ptr::to_unsafe_ptr(&err);
-    let err_name = str::raw::from_c_str(err_name(err_ptr));
-    let err_msg = str::raw::from_c_str(strerror(err_ptr));
-    uv_err_data { err_name: err_name, err_msg: err_msg }
+pub unsafe fn freeaddrinfo(ai: *addrinfo) {
+    #[fixed_stack_segment]; #[inline(never)];
+    rust_uv_freeaddrinfo(ai);
 }
 
 pub struct uv_err_data {
@@ -769,9 +823,8 @@ fn rust_uv_async_init(loop_handle: *c_void,
                           cb: uv_async_cb) -> c_int;
     fn rust_uv_tcp_init(loop_handle: *c_void, handle_ptr: *uv_tcp_t) -> c_int;
     fn rust_uv_buf_init(out_buf: *uv_buf_t, base: *u8, len: size_t);
-    fn rust_uv_last_error(loop_handle: *c_void) -> uv_err_t;
-    fn rust_uv_strerror(err: *uv_err_t) -> *c_char;
-    fn rust_uv_err_name(err: *uv_err_t) -> *c_char;
+    fn rust_uv_strerror(err: c_int) -> *c_char;
+    fn rust_uv_err_name(err: c_int) -> *c_char;
     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);
@@ -845,6 +898,7 @@ fn rust_uv_fs_close(loop_ptr: *c_void, req: *uv_fs_t, fd: c_int,
     fn rust_uv_fs_req_cleanup(req: *uv_fs_t);
     fn rust_uv_get_result_from_fs_req(req: *uv_fs_t) -> c_int;
     fn rust_uv_get_loop_from_fs_req(req: *uv_fs_t) -> *uv_loop_t;
+    fn rust_uv_get_loop_from_getaddrinfo_req(req: *uv_fs_t) -> *uv_loop_t;
 
     fn rust_uv_get_stream_handle_from_connect_req(connect_req: *uv_connect_t) -> *uv_stream_t;
     fn rust_uv_get_stream_handle_from_write_req(write_req: *uv_write_t) -> *uv_stream_t;
@@ -857,4 +911,9 @@ fn rust_uv_fs_close(loop_ptr: *c_void, req: *uv_fs_t, fd: c_int,
     fn rust_uv_set_data_for_req(req: *c_void, data: *c_void);
     fn rust_uv_get_base_from_buf(buf: uv_buf_t) -> *u8;
     fn rust_uv_get_len_from_buf(buf: uv_buf_t) -> size_t;
+    fn rust_uv_getaddrinfo(loop_: *uv_loop_t, req: *uv_getaddrinfo_t,
+                           getaddrinfo_cb: uv_getaddrinfo_cb,
+                           node: *c_char, service: *c_char,
+                           hints: *addrinfo) -> c_int;
+    fn rust_uv_freeaddrinfo(ai: *addrinfo);
 }
index f607d1612ad81905c0a0b27cb4b2f28adfcd904e..4cc5c4f14ffdfba3f8e0747784802797edf5f50e 100644 (file)
@@ -1201,8 +1201,6 @@ pub trait OwnedVector<T> {
     fn shrink_to_fit(&mut self);
 
     fn push(&mut self, t: T);
-    unsafe fn push_fast(&mut self, t: T);
-
     fn push_all_move(&mut self, rhs: ~[T]);
     fn pop(&mut self) -> T;
     fn pop_opt(&mut self) -> Option<T>;
@@ -1334,7 +1332,7 @@ fn push(&mut self, t: T) {
                     self.reserve_at_least(new_len);
                 }
 
-                self.push_fast(t);
+                push_fast(self, t);
             } else {
                 let repr: **Vec<()> = cast::transmute(&mut *self);
                 let fill = (**repr).fill;
@@ -1343,29 +1341,30 @@ fn push(&mut self, t: T) {
                     self.reserve_at_least(new_len);
                 }
 
-                self.push_fast(t);
+                push_fast(self, t);
             }
         }
-    }
 
-    // This doesn't bother to make sure we have space.
-    #[inline] // really pretty please
-    unsafe fn push_fast(&mut self, t: T) {
-        if contains_managed::<T>() {
-            let repr: **mut Box<Vec<u8>> = cast::transmute(self);
-            let fill = (**repr).data.fill;
-            (**repr).data.fill += sys::nonzero_size_of::<T>();
-            let p = to_unsafe_ptr(&((**repr).data.data));
-            let p = ptr::offset(p, fill as int) as *mut T;
-            intrinsics::move_val_init(&mut(*p), t);
-        } else {
-            let repr: **mut Vec<u8> = cast::transmute(self);
-            let fill = (**repr).fill;
-            (**repr).fill += sys::nonzero_size_of::<T>();
-            let p = to_unsafe_ptr(&((**repr).data));
-            let p = ptr::offset(p, fill as int) as *mut T;
-            intrinsics::move_val_init(&mut(*p), t);
+        // This doesn't bother to make sure we have space.
+        #[inline] // really pretty please
+        unsafe fn push_fast<T>(this: &mut ~[T], t: T) {
+            if contains_managed::<T>() {
+                let repr: **mut Box<Vec<u8>> = cast::transmute(this);
+                let fill = (**repr).data.fill;
+                (**repr).data.fill += sys::nonzero_size_of::<T>();
+                let p = to_unsafe_ptr(&((**repr).data.data));
+                let p = ptr::offset(p, fill as int) as *mut T;
+                intrinsics::move_val_init(&mut(*p), t);
+            } else {
+                let repr: **mut Vec<u8> = cast::transmute(this);
+                let fill = (**repr).fill;
+                (**repr).fill += sys::nonzero_size_of::<T>();
+                let p = to_unsafe_ptr(&((**repr).data));
+                let p = ptr::offset(p, fill as int) as *mut T;
+                intrinsics::move_val_init(&mut(*p), t);
+            }
         }
+
     }
 
     /// Takes ownership of the vector `rhs`, moving all elements into
index dfae9c3e958dc086d9c0ab068cd76d196c95a433..d88cf5652a1afb23939da0bae86c70ec521b9921 160000 (submodule)
--- a/src/libuv
+++ b/src/libuv
@@ -1 +1 @@
-Subproject commit dfae9c3e958dc086d9c0ab068cd76d196c95a433
+Subproject commit d88cf5652a1afb23939da0bae86c70ec521b9921
index 8ef4572f8108f0170b577359475da5cde9fbad4b..bfdf0e67a9b81f8616d7873edf9b0d8d4f7a543c 100644 (file)
@@ -329,20 +329,13 @@ rust_uv_get_len_from_buf(uv_buf_t buf) {
     return buf.len;
 }
 
-extern "C" uv_err_t
-rust_uv_last_error(uv_loop_t* loop) {
-    return uv_last_error(loop);
-}
-
 extern "C" const char*
-rust_uv_strerror(uv_err_t* err_ptr) {
-    uv_err_t err = *err_ptr;
+rust_uv_strerror(int err) {
     return uv_strerror(err);
 }
 
 extern "C" const char*
-rust_uv_err_name(uv_err_t* err_ptr) {
-    uv_err_t err = *err_ptr;
+rust_uv_err_name(int err) {
     return uv_err_name(err);
 }
 
@@ -553,3 +546,8 @@ extern "C" uv_loop_t*
 rust_uv_get_loop_from_fs_req(uv_fs_t* req) {
   return req->loop;
 }
+
+extern "C" uv_loop_t*
+rust_uv_get_loop_from_getaddrinfo_req(uv_getaddrinfo_t* req) {
+  return req->loop;
+}
index c1ba0524be9bc2d3f36a25c81b52622e2ecf2814..bf3500e4c724e12548cd245955d8a83ff8d5df1f 100644 (file)
@@ -47,7 +47,6 @@ rust_uv_timer_start
 rust_uv_timer_stop
 rust_uv_tcp_init
 rust_uv_buf_init
-rust_uv_last_error
 rust_uv_strerror
 rust_uv_err_name
 rust_uv_ip4_addr
@@ -192,3 +191,4 @@ rust_take_change_dir_lock
 rust_drop_change_dir_lock
 rust_get_test_int
 rust_get_task
+rust_uv_get_loop_from_getaddrinfo_req