about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2013-09-05 14:16:17 -0700
committerBrian Anderson <banderson@mozilla.com>2013-09-05 14:22:16 -0700
commit0948f54e65227a95d386e429f4e1356d7dd3fba7 (patch)
treefca9d4628b36c014022f0a27df489850d1cf2723 /src/libstd
parentc218694cece7c3018b4a809a52a35fcf3716d92e (diff)
downloadrust-0948f54e65227a95d386e429f4e1356d7dd3fba7.tar.gz
rust-0948f54e65227a95d386e429f4e1356d7dd3fba7.zip
std::rt: Add get_host_addresses function
This is a very simplistic method for host name resolution. It converts
a host name to a vector of IP addresses. Should be enough to get started.
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/rt/io/mod.rs8
-rw-r--r--src/libstd/rt/io/net/mod.rs45
-rw-r--r--src/libstd/rt/rtio.rs1
-rw-r--r--src/libstd/rt/uv/uvio.rs34
4 files changed, 78 insertions, 10 deletions
diff --git a/src/libstd/rt/io/mod.rs b/src/libstd/rt/io/mod.rs
index d1919905236..5ceea877453 100644
--- a/src/libstd/rt/io/mod.rs
+++ b/src/libstd/rt/io/mod.rs
@@ -269,13 +269,7 @@ pub use self::extensions::WriterByteConversions;
 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
index 8f316364d27..f44e879a63a 100644
--- a/src/libstd/rt/io/net/mod.rs
+++ b/src/libstd/rt/io/net/mod.rs
@@ -8,14 +8,55 @@
 // 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;
 
-fn get_host_addresses(host: &str) -> Option<~[IpAddr]> {
+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.
      */
 
-    fail!()
+    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);
+    }
 }
diff --git a/src/libstd/rt/rtio.rs b/src/libstd/rt/rtio.rs
index 6f1b33d1e21..c9c402baaf0 100644
--- a/src/libstd/rt/rtio.rs
+++ b/src/libstd/rt/rtio.rs
@@ -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/uvio.rs b/src/libstd/rt/uv/uvio.rs
index e37dfba0cc1..b225513e94f 100644
--- a/src/libstd/rt/uv/uvio.rs
+++ b/src/libstd/rt/uv/uvio.rs
@@ -29,7 +29,8 @@ use rt::tube::Tube;
 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,
@@ -596,6 +597,37 @@ impl IoFactory for UvIoFactory {
         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 {