Skip to content

Commit 5aa31c4

Browse files
committed
libnative: Implement get_host_addresses.
1 parent fce7922 commit 5aa31c4

File tree

6 files changed

+162
-59
lines changed

6 files changed

+162
-59
lines changed

src/libnative/io/addrinfo.rs

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use ai = std::io::net::addrinfo;
12+
use std::c_str::CString;
13+
use std::cast;
14+
use std::io;
15+
use std::io::IoError;
16+
use std::libc;
17+
use std::libc::{c_char, c_int};
18+
use std::ptr::null;
19+
use std::str::raw::from_c_str;
20+
21+
use super::net::sockaddr_to_addr;
22+
23+
pub struct GetAddrInfoRequest;
24+
25+
impl GetAddrInfoRequest {
26+
pub fn run(host: Option<&str>, servname: Option<&str>,
27+
hint: Option<ai::Hint>) -> Result<~[ai::Info], IoError> {
28+
assert!(host.is_some() || servname.is_some());
29+
30+
let c_host = host.map_or(unsafe { CString::new(null(), true) }, |x| x.to_c_str());
31+
let c_serv = servname.map_or(unsafe { CString::new(null(), true) }, |x| x.to_c_str());
32+
33+
let hint = hint.map(|hint| {
34+
libc::addrinfo {
35+
ai_flags: hint.flags as c_int,
36+
ai_family: hint.family as c_int,
37+
ai_socktype: 0,
38+
ai_protocol: 0,
39+
ai_addrlen: 0,
40+
ai_canonname: null(),
41+
ai_addr: null(),
42+
ai_next: null()
43+
}
44+
});
45+
46+
let hint_ptr = hint.as_ref().map_or(null(), |x| x as *libc::addrinfo);
47+
let res = null();
48+
49+
// Make the call
50+
let s = unsafe {
51+
let ch = if c_host.is_null() { null() } else { c_host.with_ref(|x| x) };
52+
let cs = if c_serv.is_null() { null() } else { c_serv.with_ref(|x| x) };
53+
getaddrinfo(ch, cs, hint_ptr, &res)
54+
};
55+
56+
// Error?
57+
if s != 0 {
58+
let err_str = unsafe { from_c_str(gai_strerror(s)) };
59+
60+
return Err(IoError {
61+
kind: io::OtherIoError,
62+
desc: "unable to resolve host",
63+
detail: Some(err_str),
64+
});
65+
}
66+
67+
// Collect all the results we found
68+
let mut addrs = ~[];
69+
let mut rp = res;
70+
while rp.is_not_null() {
71+
unsafe {
72+
let addr = match sockaddr_to_addr(cast::transmute((*rp).ai_addr),
73+
(*rp).ai_addrlen as uint) {
74+
Ok(a) => a,
75+
Err(e) => return Err(e)
76+
};
77+
addrs.push(ai::Info {
78+
address: addr,
79+
family: (*rp).ai_family as uint,
80+
socktype: None,
81+
protocol: None,
82+
flags: (*rp).ai_flags as uint
83+
});
84+
85+
rp = (*rp).ai_next;
86+
}
87+
}
88+
89+
unsafe { freeaddrinfo(res); }
90+
91+
Ok(addrs)
92+
}
93+
}
94+
95+
extern {
96+
fn getaddrinfo(node: *c_char, service: *c_char,
97+
hints: *libc::addrinfo, res: **libc::addrinfo) -> c_int;
98+
fn gai_strerror(errcode: c_int) -> *c_char;
99+
fn freeaddrinfo(res: *libc::addrinfo);
100+
}

src/libnative/io/mod.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,28 +23,29 @@
2323
2424
use std::c_str::CString;
2525
use std::comm::SharedChan;
26+
use std::io;
27+
use std::io::IoError;
28+
use std::io::net::ip::SocketAddr;
29+
use std::io::process::ProcessConfig;
30+
use std::io::signal::Signum;
2631
use std::libc::c_int;
2732
use std::libc;
2833
use std::os;
2934
use std::rt::rtio;
3035
use std::rt::rtio::{RtioTcpStream, RtioTcpListener, RtioUdpSocket,
3136
RtioUnixListener, RtioPipe, RtioFileStream, RtioProcess,
3237
RtioSignal, RtioTTY, CloseBehavior, RtioTimer};
33-
use std::io;
34-
use std::io::IoError;
35-
use std::io::net::ip::SocketAddr;
36-
use std::io::process::ProcessConfig;
37-
use std::io::signal::Signum;
3838
use ai = std::io::net::addrinfo;
3939

4040
// Local re-exports
4141
pub use self::file::FileDesc;
4242
pub use self::process::Process;
4343

4444
// Native I/O implementations
45+
pub mod addrinfo;
4546
pub mod file;
46-
pub mod process;
4747
pub mod net;
48+
pub mod process;
4849

4950
type IoResult<T> = Result<T, IoError>;
5051

@@ -186,9 +187,9 @@ impl rtio::IoFactory for IoFactory {
186187
fn unix_connect(&mut self, _path: &CString) -> IoResult<~RtioPipe> {
187188
Err(unimpl())
188189
}
189-
fn get_host_addresses(&mut self, _host: Option<&str>, _servname: Option<&str>,
190-
_hint: Option<ai::Hint>) -> IoResult<~[ai::Info]> {
191-
Err(unimpl())
190+
fn get_host_addresses(&mut self, host: Option<&str>, servname: Option<&str>,
191+
hint: Option<ai::Hint>) -> IoResult<~[ai::Info]> {
192+
addrinfo::GetAddrInfoRequest::run(host, servname, hint)
192193
}
193194

194195
// filesystem operations

src/libnative/io/net.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,8 @@ fn sockname(fd: sock_t,
134134
return sockaddr_to_addr(&storage, len as uint);
135135
}
136136

137-
fn sockaddr_to_addr(storage: &libc::sockaddr_storage,
138-
len: uint) -> IoResult<ip::SocketAddr> {
137+
pub fn sockaddr_to_addr(storage: &libc::sockaddr_storage,
138+
len: uint) -> IoResult<ip::SocketAddr> {
139139
match storage.ss_family as libc::c_int {
140140
libc::AF_INET => {
141141
assert!(len as uint >= mem::size_of::<libc::sockaddr_in>());

src/librustuv/addrinfo.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
use ai = std::io::net::addrinfo;
1212
use std::cast;
13+
use std::libc;
1314
use std::libc::c_int;
1415
use std::ptr::null;
1516
use std::rt::task::BlockedTask;
@@ -19,7 +20,7 @@ use super::{Loop, UvError, Request, wait_until_woken_after, wakeup};
1920
use uvll;
2021

2122
struct Addrinfo {
22-
handle: *uvll::addrinfo,
23+
handle: *libc::addrinfo,
2324
}
2425

2526
struct Ctx {
@@ -62,7 +63,7 @@ impl GetAddrInfoRequest {
6263
let socktype = 0;
6364
let protocol = 0;
6465

65-
uvll::addrinfo {
66+
libc::addrinfo {
6667
ai_flags: flags,
6768
ai_family: hint.family as c_int,
6869
ai_socktype: socktype,
@@ -73,7 +74,7 @@ impl GetAddrInfoRequest {
7374
ai_next: null(),
7475
}
7576
});
76-
let hint_ptr = hint.as_ref().map_or(null(), |x| x as *uvll::addrinfo);
77+
let hint_ptr = hint.as_ref().map_or(null(), |x| x as *libc::addrinfo);
7778
let mut req = Request::new(uvll::UV_GETADDRINFO);
7879

7980
return match unsafe {
@@ -100,7 +101,7 @@ impl GetAddrInfoRequest {
100101

101102
extern fn getaddrinfo_cb(req: *uvll::uv_getaddrinfo_t,
102103
status: c_int,
103-
res: *uvll::addrinfo) {
104+
res: *libc::addrinfo) {
104105
let req = Request::wrap(req);
105106
assert!(status != uvll::ECANCELED);
106107
let cx: &mut Ctx = unsafe { req.get_data() };

src/librustuv/uvll.rs

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
#[allow(non_camel_case_types)]; // C types
3131

3232
use std::libc::{size_t, c_int, c_uint, c_void, c_char, c_double};
33-
use std::libc::{ssize_t, sockaddr, free};
33+
use std::libc::{ssize_t, sockaddr, free, addrinfo};
3434
use std::libc;
3535
use std::rt::global_heap::malloc_raw;
3636

@@ -249,45 +249,6 @@ pub type uv_signal_cb = extern "C" fn(handle: *uv_signal_t,
249249
signum: c_int);
250250
pub type uv_fs_cb = extern "C" fn(req: *uv_fs_t);
251251

252-
// XXX: This is a standard C type. Could probably be defined in libc
253-
#[cfg(target_os = "android")]
254-
#[cfg(target_os = "linux")]
255-
pub struct addrinfo {
256-
ai_flags: c_int,
257-
ai_family: c_int,
258-
ai_socktype: c_int,
259-
ai_protocol: c_int,
260-
ai_addrlen: libc::socklen_t,
261-
ai_addr: *sockaddr,
262-
ai_canonname: *char,
263-
ai_next: *addrinfo
264-
}
265-
266-
#[cfg(target_os = "macos")]
267-
#[cfg(target_os = "freebsd")]
268-
pub struct addrinfo {
269-
ai_flags: c_int,
270-
ai_family: c_int,
271-
ai_socktype: c_int,
272-
ai_protocol: c_int,
273-
ai_addrlen: libc::socklen_t,
274-
ai_canonname: *char,
275-
ai_addr: *sockaddr,
276-
ai_next: *addrinfo
277-
}
278-
279-
#[cfg(windows)]
280-
pub struct addrinfo {
281-
ai_flags: c_int,
282-
ai_family: c_int,
283-
ai_socktype: c_int,
284-
ai_protocol: c_int,
285-
ai_addrlen: size_t,
286-
ai_canonname: *char,
287-
ai_addr: *sockaddr,
288-
ai_next: *addrinfo
289-
}
290-
291252
#[cfg(unix)] pub type uv_uid_t = libc::types::os::arch::posix88::uid_t;
292253
#[cfg(unix)] pub type uv_gid_t = libc::types::os::arch::posix88::gid_t;
293254
#[cfg(windows)] pub type uv_uid_t = libc::c_uchar;

src/libstd/libc.rs

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ pub mod types {
267267
pub enum timezone {}
268268
}
269269
pub mod bsd44 {
270-
use libc::types::os::arch::c95::c_uint;
270+
use libc::types::os::arch::c95::{c_char, c_int, c_uint};
271271

272272
pub type socklen_t = u32;
273273
pub type sa_family_t = u16;
@@ -309,6 +309,16 @@ pub mod types {
309309
ipv6mr_multiaddr: in6_addr,
310310
ipv6mr_interface: c_uint,
311311
}
312+
pub struct addrinfo {
313+
ai_flags: c_int,
314+
ai_family: c_int,
315+
ai_socktype: c_int,
316+
ai_protocol: c_int,
317+
ai_addrlen: socklen_t,
318+
ai_addr: *sockaddr,
319+
ai_canonname: *c_char,
320+
ai_next: *addrinfo
321+
}
312322
}
313323
}
314324

@@ -624,7 +634,7 @@ pub mod types {
624634
pub enum timezone {}
625635
}
626636
pub mod bsd44 {
627-
use libc::types::os::arch::c95::c_uint;
637+
use libc::types::os::arch::c95::{c_char, c_int, c_uint};
628638

629639
pub type socklen_t = u32;
630640
pub type sa_family_t = u8;
@@ -671,6 +681,16 @@ pub mod types {
671681
ipv6mr_multiaddr: in6_addr,
672682
ipv6mr_interface: c_uint,
673683
}
684+
pub struct addrinfo {
685+
ai_flags: c_int,
686+
ai_family: c_int,
687+
ai_socktype: c_int,
688+
ai_protocol: c_int,
689+
ai_addrlen: socklen_t,
690+
ai_canonname: *c_char,
691+
ai_addr: *sockaddr,
692+
ai_next: *addrinfo
693+
}
674694
}
675695
}
676696

@@ -811,7 +831,7 @@ pub mod types {
811831
}
812832

813833
pub mod bsd44 {
814-
use libc::types::os::arch::c95::{c_int, c_uint};
834+
use libc::types::os::arch::c95::{c_char, c_int, c_uint, size_t};
815835

816836
pub type SOCKET = c_uint;
817837
pub type socklen_t = c_int;
@@ -854,6 +874,16 @@ pub mod types {
854874
ipv6mr_multiaddr: in6_addr,
855875
ipv6mr_interface: c_uint,
856876
}
877+
pub struct addrinfo {
878+
ai_flags: c_int,
879+
ai_family: c_int,
880+
ai_socktype: c_int,
881+
ai_protocol: c_int,
882+
ai_addrlen: size_t,
883+
ai_canonname: *c_char,
884+
ai_addr: *sockaddr,
885+
ai_next: *addrinfo
886+
}
857887
}
858888
}
859889

@@ -1121,7 +1151,7 @@ pub mod types {
11211151
}
11221152

11231153
pub mod bsd44 {
1124-
use libc::types::os::arch::c95::{c_int, c_uint};
1154+
use libc::types::os::arch::c95::{c_char, c_int, c_uint};
11251155

11261156
pub type socklen_t = c_int;
11271157
pub type sa_family_t = u8;
@@ -1168,6 +1198,16 @@ pub mod types {
11681198
ipv6mr_multiaddr: in6_addr,
11691199
ipv6mr_interface: c_uint,
11701200
}
1201+
pub struct addrinfo {
1202+
ai_flags: c_int,
1203+
ai_family: c_int,
1204+
ai_socktype: c_int,
1205+
ai_protocol: c_int,
1206+
ai_addrlen: socklen_t,
1207+
ai_canonname: *c_char,
1208+
ai_addr: *sockaddr,
1209+
ai_next: *addrinfo
1210+
}
11711211
}
11721212
}
11731213

0 commit comments

Comments
 (0)