2f6b66ecd3
hat tip to @jruderman
1647 lines
60 KiB
Rust
1647 lines
60 KiB
Rust
/*!
|
|
* Low-level bindings to the libuv library.
|
|
*
|
|
* This module contains a set of direct, 'bare-metal' wrappers around
|
|
* the libuv C-API.
|
|
*
|
|
* Also contained herein are a set of rust records that map, in
|
|
* approximate memory-size, to the libuv data structures. The record
|
|
* implementations are adjusted, per-platform, to match their respective
|
|
* representations.
|
|
*
|
|
* There are also a collection of helper functions to ease interacting
|
|
* with the low-level API (such as a function to return the latest
|
|
* libuv error as a rust-formatted string).
|
|
*
|
|
* As new functionality, existant in uv.h, is added to the rust stdlib,
|
|
* the mappings should be added in this module.
|
|
*
|
|
* This module's implementation will hopefully be, eventually, replaced
|
|
* with per-platform, generated source files from rust-bindgen.
|
|
*/
|
|
|
|
#[allow(non_camel_case_types)]; // C types
|
|
|
|
use libc::size_t;
|
|
use comm = core::comm;
|
|
use ptr::to_unsafe_ptr;
|
|
|
|
// libuv struct mappings
|
|
type uv_ip4_addr = {
|
|
ip: ~[u8],
|
|
port: int
|
|
};
|
|
type uv_ip6_addr = uv_ip4_addr;
|
|
|
|
enum uv_handle_type {
|
|
UNKNOWN_HANDLE = 0,
|
|
UV_TCP,
|
|
UV_UDP,
|
|
UV_NAMED_PIPE,
|
|
UV_TTY,
|
|
UV_FILE,
|
|
UV_TIMER,
|
|
UV_PREPARE,
|
|
UV_CHECK,
|
|
UV_IDLE,
|
|
UV_ASYNC,
|
|
UV_ARES_TASK,
|
|
UV_ARES_EVENT,
|
|
UV_PROCESS,
|
|
UV_FS_EVENT
|
|
}
|
|
|
|
type handle_type = libc::c_uint;
|
|
|
|
type uv_handle_fields = {
|
|
loop_handle: *libc::c_void,
|
|
type_: handle_type,
|
|
close_cb: *u8,
|
|
mut data: *libc::c_void,
|
|
};
|
|
|
|
// unix size: 8
|
|
type uv_err_t = {
|
|
code: libc::c_int,
|
|
sys_errno_: libc::c_int
|
|
};
|
|
|
|
// don't create one of these directly. instead,
|
|
// count on it appearing in libuv callbacks or embedded
|
|
// in other types as a pointer to be used in other
|
|
// operations (so mostly treat it as opaque, once you
|
|
// have it in this form..)
|
|
type uv_stream_t = {
|
|
fields: uv_handle_fields
|
|
};
|
|
|
|
// 64bit unix size: 272
|
|
#[cfg(unix)]
|
|
type uv_tcp_t = {
|
|
fields: uv_handle_fields,
|
|
a00: *u8, a01: *u8, a02: *u8, a03: *u8,
|
|
a04: *u8, a05: *u8, a06: *u8, a07: *u8,
|
|
a08: *u8, a09: *u8, a10: *u8, a11: *u8,
|
|
a12: *u8, a13: *u8, a14: *u8, a15: *u8,
|
|
a16: *u8, a17: *u8, a18: *u8, a19: *u8,
|
|
a20: *u8, a21: *u8, a22: *u8, a23: *u8,
|
|
a24: *u8, a25: *u8, a26: *u8, a27: *u8,
|
|
a28: *u8,
|
|
a30: uv_tcp_t_32bit_unix_riders
|
|
};
|
|
// 32bit unix size: 328 (164)
|
|
#[cfg(target_arch="x86_64")]
|
|
type uv_tcp_t_32bit_unix_riders = {
|
|
a29: *u8
|
|
};
|
|
#[cfg(target_arch="x86")]
|
|
type uv_tcp_t_32bit_unix_riders = {
|
|
a29: *u8, a30: *u8, a31: *u8,
|
|
a32: *u8, a33: *u8, a34: *u8,
|
|
a35: *u8, a36: *u8
|
|
};
|
|
|
|
// 32bit win32 size: 240 (120)
|
|
#[cfg(windows)]
|
|
type uv_tcp_t = {
|
|
fields: uv_handle_fields,
|
|
a00: *u8, a01: *u8, a02: *u8, a03: *u8,
|
|
a04: *u8, a05: *u8, a06: *u8, a07: *u8,
|
|
a08: *u8, a09: *u8, a10: *u8, a11: *u8,
|
|
a12: *u8, a13: *u8, a14: *u8, a15: *u8,
|
|
a16: *u8, a17: *u8, a18: *u8, a19: *u8,
|
|
a20: *u8, a21: *u8, a22: *u8, a23: *u8,
|
|
a24: *u8, a25: *u8
|
|
};
|
|
|
|
// unix size: 48
|
|
#[cfg(unix)]
|
|
type uv_connect_t = {
|
|
a00: *u8, a01: *u8, a02: *u8, a03: *u8,
|
|
a04: *u8, a05: *u8
|
|
};
|
|
// win32 size: 88 (44)
|
|
#[cfg(windows)]
|
|
type uv_connect_t = {
|
|
a00: *u8, a01: *u8, a02: *u8, a03: *u8,
|
|
a04: *u8, a05: *u8, a06: *u8, a07: *u8,
|
|
a08: *u8, a09: *u8, a10: *u8
|
|
};
|
|
|
|
// unix size: 16
|
|
type uv_buf_t = {
|
|
base: *u8,
|
|
len: libc::size_t
|
|
};
|
|
// no gen stub method.. should create
|
|
// it via uv::direct::buf_init()
|
|
|
|
// unix size: 144
|
|
#[cfg(unix)]
|
|
type uv_write_t = {
|
|
fields: uv_handle_fields,
|
|
a00: *u8, a01: *u8, a02: *u8, a03: *u8,
|
|
a04: *u8, a05: *u8, a06: *u8, a07: *u8,
|
|
a08: *u8, a09: *u8, a10: *u8, a11: *u8,
|
|
a12: *u8,
|
|
a14: uv_write_t_32bit_unix_riders
|
|
};
|
|
#[cfg(target_arch="x86_64")]
|
|
type uv_write_t_32bit_unix_riders = {
|
|
a13: *u8
|
|
};
|
|
#[cfg(target_arch="x86")]
|
|
type uv_write_t_32bit_unix_riders = {
|
|
a13: *u8, a14: *u8
|
|
};
|
|
// win32 size: 136 (68)
|
|
#[cfg(windows)]
|
|
type uv_write_t = {
|
|
fields: uv_handle_fields,
|
|
a00: *u8, a01: *u8, a02: *u8, a03: *u8,
|
|
a04: *u8, a05: *u8, a06: *u8, a07: *u8,
|
|
a08: *u8, a09: *u8, a10: *u8, a11: *u8,
|
|
a12: *u8
|
|
};
|
|
// 64bit unix size: 120
|
|
// 32bit unix size: 152 (76)
|
|
#[cfg(unix)]
|
|
type uv_async_t = {
|
|
fields: uv_handle_fields,
|
|
a00: *u8, a01: *u8, a02: *u8, a03: *u8,
|
|
a04: *u8, a05: *u8, a06: *u8, a07: *u8,
|
|
a08: *u8, a09: *u8,
|
|
a11: uv_async_t_32bit_unix_riders
|
|
};
|
|
#[cfg(target_arch="x86_64")]
|
|
type uv_async_t_32bit_unix_riders = {
|
|
a10: *u8
|
|
};
|
|
#[cfg(target_arch="x86")]
|
|
type uv_async_t_32bit_unix_riders = {
|
|
a10: *u8, a11: *u8, a12: *u8, a13: *u8
|
|
};
|
|
// win32 size 132 (68)
|
|
#[cfg(windows)]
|
|
type uv_async_t = {
|
|
fields: uv_handle_fields,
|
|
a00: *u8, a01: *u8, a02: *u8, a03: *u8,
|
|
a04: *u8, a05: *u8, a06: *u8, a07: *u8,
|
|
a08: *u8, a09: *u8, a10: *u8, a11: *u8,
|
|
a12: *u8
|
|
};
|
|
|
|
// 64bit unix size: 128
|
|
// 32bit unix size: 84
|
|
#[cfg(unix)]
|
|
type uv_timer_t = {
|
|
fields: uv_handle_fields,
|
|
a00: *u8, a01: *u8, a02: *u8, a03: *u8,
|
|
a04: *u8, a05: *u8, a06: *u8, a07: *u8,
|
|
a08: *u8, a09: *u8,
|
|
a11: uv_timer_t_32bit_unix_riders
|
|
};
|
|
#[cfg(target_arch="x86_64")]
|
|
type uv_timer_t_32bit_unix_riders = {
|
|
a10: *u8, a11: *u8
|
|
};
|
|
#[cfg(target_arch="x86")]
|
|
type uv_timer_t_32bit_unix_riders = {
|
|
a10: *u8, a11: *u8, a12: *u8, a13: *u8,
|
|
a14: *u8, a15: *u8, a16: *u8
|
|
};
|
|
// win32 size: 64
|
|
#[cfg(windows)]
|
|
type uv_timer_t = {
|
|
fields: uv_handle_fields,
|
|
a00: *u8, a01: *u8, a02: *u8, a03: *u8,
|
|
a04: *u8, a05: *u8, a06: *u8, a07: *u8,
|
|
a08: *u8, a09: *u8, a10: *u8, a11: *u8
|
|
};
|
|
|
|
// unix size: 16
|
|
type sockaddr_in = {
|
|
mut sin_family: u16,
|
|
mut sin_port: u16,
|
|
mut sin_addr: u32, // in_addr: this is an opaque, per-platform struct
|
|
mut sin_zero: (u8, u8, u8, u8, u8, u8, u8, u8)
|
|
};
|
|
|
|
// unix size: 28 .. FIXME #1645
|
|
// stuck with 32 becuse of rust padding structs?
|
|
#[cfg(target_arch="x86_64")]
|
|
type sockaddr_in6 = {
|
|
a0: *u8, a1: *u8,
|
|
a2: *u8, a3: *u8
|
|
};
|
|
#[cfg(target_arch="x86")]
|
|
type sockaddr_in6 = {
|
|
a0: *u8, a1: *u8,
|
|
a2: *u8, a3: *u8,
|
|
a4: *u8, a5: *u8,
|
|
a6: *u8, a7: *u8
|
|
};
|
|
|
|
// unix size: 28 .. FIXME #1645
|
|
// stuck with 32 becuse of rust padding structs?
|
|
type addr_in = addr_in_impl::addr_in;
|
|
#[cfg(unix)]
|
|
mod addr_in_impl {
|
|
#[cfg(target_arch="x86_64")]
|
|
type addr_in = {
|
|
a0: *u8, a1: *u8,
|
|
a2: *u8, a3: *u8
|
|
};
|
|
#[cfg(target_arch="x86")]
|
|
type addr_in = {
|
|
a0: *u8, a1: *u8,
|
|
a2: *u8, a3: *u8,
|
|
a4: *u8, a5: *u8,
|
|
a6: *u8, a7: *u8,
|
|
};
|
|
}
|
|
#[cfg(windows)]
|
|
mod addr_in_impl {
|
|
type addr_in = {
|
|
a0: *u8, a1: *u8,
|
|
a2: *u8, a3: *u8
|
|
};
|
|
}
|
|
|
|
// unix size: 48, 32bit: 32
|
|
type addrinfo = addrinfo_impl::addrinfo;
|
|
#[cfg(target_os="linux")]
|
|
mod addrinfo_impl {
|
|
#[cfg(target_arch="x86_64")]
|
|
type addrinfo = {
|
|
a00: *u8, a01: *u8, a02: *u8, a03: *u8,
|
|
a04: *u8, a05: *u8
|
|
};
|
|
#[cfg(target_arch="x86")]
|
|
type addrinfo = {
|
|
a00: *u8, a01: *u8, a02: *u8, a03: *u8,
|
|
a04: *u8, a05: *u8, a06: *u8, a07: *u8
|
|
};
|
|
}
|
|
#[cfg(target_os="macos")]
|
|
#[cfg(target_os="freebsd")]
|
|
mod addrinfo_impl {
|
|
type addrinfo = {
|
|
a00: *u8, a01: *u8, a02: *u8, a03: *u8,
|
|
a04: *u8, a05: *u8
|
|
};
|
|
}
|
|
#[cfg(windows)]
|
|
mod addrinfo_impl {
|
|
type addrinfo = {
|
|
a00: *u8, a01: *u8, a02: *u8, a03: *u8,
|
|
a04: *u8, a05: *u8
|
|
};
|
|
}
|
|
|
|
// unix size: 72
|
|
type uv_getaddrinfo_t = {
|
|
a00: *u8, a01: *u8, a02: *u8, a03: *u8, a04: *u8, a05: *u8,
|
|
a06: *u8, a07: *u8, a08: *u8
|
|
};
|
|
|
|
mod uv_ll_struct_stubgen {
|
|
fn gen_stub_uv_tcp_t() -> uv_tcp_t {
|
|
return gen_stub_os();
|
|
#[cfg(target_os = "linux")]
|
|
#[cfg(target_os = "macos")]
|
|
#[cfg(target_os = "freebsd")]
|
|
fn gen_stub_os() -> uv_tcp_t {
|
|
return gen_stub_arch();
|
|
#[cfg(target_arch="x86_64")]
|
|
fn gen_stub_arch() -> uv_tcp_t {
|
|
return { fields: { loop_handle: ptr::null(), type_: 0u32,
|
|
close_cb: ptr::null(),
|
|
mut data: ptr::null() },
|
|
a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
|
|
a03: 0 as *u8,
|
|
a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
|
|
a07: 0 as *u8,
|
|
a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
|
|
a11: 0 as *u8,
|
|
a12: 0 as *u8, a13: 0 as *u8, a14: 0 as *u8,
|
|
a15: 0 as *u8,
|
|
a16: 0 as *u8, a17: 0 as *u8, a18: 0 as *u8,
|
|
a19: 0 as *u8,
|
|
a20: 0 as *u8, a21: 0 as *u8, a22: 0 as *u8,
|
|
a23: 0 as *u8,
|
|
a24: 0 as *u8, a25: 0 as *u8, a26: 0 as *u8,
|
|
a27: 0 as *u8,
|
|
a28: 0 as *u8,
|
|
a30: {
|
|
a29: 0 as *u8
|
|
}
|
|
};
|
|
}
|
|
#[cfg(target_arch="x86")]
|
|
fn gen_stub_arch() -> uv_tcp_t {
|
|
return { fields: { loop_handle: ptr::null(), type_: 0u32,
|
|
close_cb: ptr::null(),
|
|
mut data: ptr::null() },
|
|
a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
|
|
a03: 0 as *u8,
|
|
a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
|
|
a07: 0 as *u8,
|
|
a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
|
|
a11: 0 as *u8,
|
|
a12: 0 as *u8, a13: 0 as *u8, a14: 0 as *u8,
|
|
a15: 0 as *u8,
|
|
a16: 0 as *u8, a17: 0 as *u8, a18: 0 as *u8,
|
|
a19: 0 as *u8,
|
|
a20: 0 as *u8, a21: 0 as *u8, a22: 0 as *u8,
|
|
a23: 0 as *u8,
|
|
a24: 0 as *u8, a25: 0 as *u8, a26: 0 as *u8,
|
|
a27: 0 as *u8,
|
|
a28: 0 as *u8,
|
|
a30: {
|
|
a29: 0 as *u8, a30: 0 as *u8, a31: 0 as *u8,
|
|
a32: 0 as *u8, a33: 0 as *u8, a34: 0 as *u8,
|
|
a35: 0 as *u8, a36: 0 as *u8
|
|
}
|
|
};
|
|
}
|
|
}
|
|
#[cfg(windows)]
|
|
fn gen_stub_os() -> uv_tcp_t {
|
|
return { fields: { loop_handle: ptr::null(), type_: 0u32,
|
|
close_cb: ptr::null(),
|
|
mut data: ptr::null() },
|
|
a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
|
|
a03: 0 as *u8,
|
|
a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
|
|
a07: 0 as *u8,
|
|
a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
|
|
a11: 0 as *u8,
|
|
a12: 0 as *u8, a13: 0 as *u8, a14: 0 as *u8,
|
|
a15: 0 as *u8,
|
|
a16: 0 as *u8, a17: 0 as *u8, a18: 0 as *u8,
|
|
a19: 0 as *u8,
|
|
a20: 0 as *u8, a21: 0 as *u8, a22: 0 as *u8,
|
|
a23: 0 as *u8,
|
|
a24: 0 as *u8, a25: 0 as *u8
|
|
};
|
|
}
|
|
}
|
|
#[cfg(unix)]
|
|
fn gen_stub_uv_connect_t() -> uv_connect_t {
|
|
return {
|
|
a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
|
|
a03: 0 as *u8,
|
|
a04: 0 as *u8, a05: 0 as *u8
|
|
};
|
|
}
|
|
#[cfg(windows)]
|
|
fn gen_stub_uv_connect_t() -> uv_connect_t {
|
|
return {
|
|
a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
|
|
a03: 0 as *u8,
|
|
a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
|
|
a07: 0 as *u8,
|
|
a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8
|
|
};
|
|
}
|
|
#[cfg(unix)]
|
|
fn gen_stub_uv_async_t() -> uv_async_t {
|
|
return gen_stub_arch();
|
|
#[cfg(target_arch = "x86_64")]
|
|
fn gen_stub_arch() -> uv_async_t {
|
|
return { fields: { loop_handle: ptr::null(), type_: 0u32,
|
|
close_cb: ptr::null(),
|
|
mut data: ptr::null() },
|
|
a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
|
|
a03: 0 as *u8,
|
|
a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
|
|
a07: 0 as *u8,
|
|
a08: 0 as *u8, a09: 0 as *u8,
|
|
a11: {
|
|
a10: 0 as *u8
|
|
}
|
|
};
|
|
}
|
|
#[cfg(target_arch = "x86")]
|
|
fn gen_stub_arch() -> uv_async_t {
|
|
return { fields: { loop_handle: ptr::null(), type_: 0u32,
|
|
close_cb: ptr::null(),
|
|
mut data: ptr::null() },
|
|
a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
|
|
a03: 0 as *u8,
|
|
a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
|
|
a07: 0 as *u8,
|
|
a08: 0 as *u8, a09: 0 as *u8,
|
|
a11: {
|
|
a10: 0 as *u8, a11: 0 as *u8,
|
|
a12: 0 as *u8, a13: 0 as *u8
|
|
}
|
|
};
|
|
}
|
|
}
|
|
#[cfg(windows)]
|
|
fn gen_stub_uv_async_t() -> uv_async_t {
|
|
return { fields: { loop_handle: ptr::null(), type_: 0u32,
|
|
close_cb: ptr::null(),
|
|
mut data: ptr::null() },
|
|
a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
|
|
a03: 0 as *u8,
|
|
a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
|
|
a07: 0 as *u8,
|
|
a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
|
|
a11: 0 as *u8,
|
|
a12: 0 as *u8
|
|
};
|
|
}
|
|
#[cfg(unix)]
|
|
fn gen_stub_uv_timer_t() -> uv_timer_t {
|
|
return gen_stub_arch();
|
|
#[cfg(target_arch = "x86_64")]
|
|
fn gen_stub_arch() -> uv_timer_t {
|
|
return { fields: { loop_handle: ptr::null(), type_: 0u32,
|
|
close_cb: ptr::null(),
|
|
mut data: ptr::null() },
|
|
a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
|
|
a03: 0 as *u8,
|
|
a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
|
|
a07: 0 as *u8,
|
|
a08: 0 as *u8, a09: 0 as *u8,
|
|
a11: {
|
|
a10: 0 as *u8, a11: 0 as *u8
|
|
}
|
|
};
|
|
}
|
|
#[cfg(target_arch = "x86")]
|
|
fn gen_stub_arch() -> uv_timer_t {
|
|
return { fields: { loop_handle: ptr::null(), type_: 0u32,
|
|
close_cb: ptr::null(),
|
|
mut data: ptr::null() },
|
|
a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
|
|
a03: 0 as *u8,
|
|
a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
|
|
a07: 0 as *u8,
|
|
a08: 0 as *u8, a09: 0 as *u8,
|
|
a11: {
|
|
a10: 0 as *u8, a11: 0 as *u8,
|
|
a12: 0 as *u8, a13: 0 as *u8,
|
|
a14: 0 as *u8, a15: 0 as *u8,
|
|
a16: 0 as *u8
|
|
}
|
|
};
|
|
}
|
|
}
|
|
#[cfg(windows)]
|
|
fn gen_stub_uv_timer_t() -> uv_timer_t {
|
|
return { fields: { loop_handle: ptr::null(), type_: 0u32,
|
|
close_cb: ptr::null(),
|
|
mut data: ptr::null() },
|
|
a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
|
|
a03: 0 as *u8,
|
|
a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
|
|
a07: 0 as *u8,
|
|
a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
|
|
a11: 0 as *u8
|
|
};
|
|
}
|
|
#[cfg(unix)]
|
|
fn gen_stub_uv_write_t() -> uv_write_t {
|
|
return gen_stub_arch();
|
|
#[cfg(target_arch="x86_64")]
|
|
fn gen_stub_arch() -> uv_write_t {
|
|
return { fields: { loop_handle: ptr::null(), type_: 0u32,
|
|
close_cb: ptr::null(),
|
|
mut data: ptr::null() },
|
|
a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
|
|
a03: 0 as *u8,
|
|
a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
|
|
a07: 0 as *u8,
|
|
a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
|
|
a11: 0 as *u8,
|
|
a12: 0 as *u8, a14: { a13: 0 as *u8 }
|
|
};
|
|
}
|
|
#[cfg(target_arch="x86")]
|
|
fn gen_stub_arch() -> uv_write_t {
|
|
return { fields: { loop_handle: ptr::null(), type_: 0u32,
|
|
close_cb: ptr::null(),
|
|
mut data: ptr::null() },
|
|
a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
|
|
a03: 0 as *u8,
|
|
a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
|
|
a07: 0 as *u8,
|
|
a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
|
|
a11: 0 as *u8,
|
|
a12: 0 as *u8, a14: { a13: 0 as *u8, a14: 0 as *u8 }
|
|
};
|
|
}
|
|
}
|
|
#[cfg(windows)]
|
|
fn gen_stub_uv_write_t() -> uv_write_t {
|
|
return { fields: { loop_handle: ptr::null(), type_: 0u32,
|
|
close_cb: ptr::null(),
|
|
mut data: ptr::null() },
|
|
a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
|
|
a03: 0 as *u8,
|
|
a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
|
|
a07: 0 as *u8,
|
|
a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
|
|
a11: 0 as *u8,
|
|
a12: 0 as *u8
|
|
};
|
|
}
|
|
fn gen_stub_uv_getaddrinfo_t() -> uv_getaddrinfo_t {
|
|
{
|
|
a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8, a03: 0 as *u8,
|
|
a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8, a07: 0 as *u8,
|
|
a08: 0 as *u8
|
|
}
|
|
}
|
|
}
|
|
|
|
#[nolink]
|
|
extern mod rustrt {
|
|
// libuv public API
|
|
fn rust_uv_loop_new() -> *libc::c_void;
|
|
fn rust_uv_loop_delete(lp: *libc::c_void);
|
|
fn rust_uv_loop_refcount(loop_ptr: *libc::c_void) -> libc::c_int;
|
|
fn rust_uv_run(loop_handle: *libc::c_void);
|
|
fn rust_uv_close(handle: *libc::c_void, cb: *u8);
|
|
fn rust_uv_async_send(handle: *uv_async_t);
|
|
fn rust_uv_async_init(loop_handle: *libc::c_void,
|
|
async_handle: *uv_async_t,
|
|
cb: *u8) -> libc::c_int;
|
|
fn rust_uv_tcp_init(
|
|
loop_handle: *libc::c_void,
|
|
handle_ptr: *uv_tcp_t) -> libc::c_int;
|
|
// FIXME ref #2604 .. ?
|
|
fn rust_uv_buf_init(out_buf: *uv_buf_t, base: *u8,
|
|
len: libc::size_t);
|
|
fn rust_uv_last_error(loop_handle: *libc::c_void) -> uv_err_t;
|
|
// FIXME ref #2064
|
|
fn rust_uv_strerror(err: *uv_err_t) -> *libc::c_char;
|
|
// FIXME ref #2064
|
|
fn rust_uv_err_name(err: *uv_err_t) -> *libc::c_char;
|
|
fn rust_uv_ip4_addr(ip: *u8, port: libc::c_int)
|
|
-> sockaddr_in;
|
|
fn rust_uv_ip6_addr(ip: *u8, port: libc::c_int)
|
|
-> sockaddr_in6;
|
|
fn rust_uv_ip4_name(src: *sockaddr_in, dst: *u8, size: libc::size_t)
|
|
-> libc::c_int;
|
|
fn rust_uv_ip6_name(src: *sockaddr_in6, dst: *u8, size: libc::size_t)
|
|
-> libc::c_int;
|
|
// FIXME ref #2064
|
|
fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t,
|
|
tcp_handle_ptr: *uv_tcp_t,
|
|
++after_cb: *u8,
|
|
++addr: *sockaddr_in) -> libc::c_int;
|
|
// FIXME ref #2064
|
|
fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t,
|
|
++addr: *sockaddr_in) -> libc::c_int;
|
|
// FIXME ref #2064
|
|
fn rust_uv_tcp_connect6(connect_ptr: *uv_connect_t,
|
|
tcp_handle_ptr: *uv_tcp_t,
|
|
++after_cb: *u8,
|
|
++addr: *sockaddr_in6) -> libc::c_int;
|
|
// FIXME ref #2064
|
|
fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t,
|
|
++addr: *sockaddr_in6) -> libc::c_int;
|
|
fn rust_uv_listen(stream: *libc::c_void, backlog: libc::c_int,
|
|
cb: *u8) -> libc::c_int;
|
|
fn rust_uv_accept(server: *libc::c_void, client: *libc::c_void)
|
|
-> libc::c_int;
|
|
fn rust_uv_write(req: *libc::c_void, stream: *libc::c_void,
|
|
++buf_in: *uv_buf_t, buf_cnt: libc::c_int,
|
|
cb: *u8) -> libc::c_int;
|
|
fn rust_uv_read_start(stream: *libc::c_void, on_alloc: *u8,
|
|
on_read: *u8) -> libc::c_int;
|
|
fn rust_uv_read_stop(stream: *libc::c_void) -> libc::c_int;
|
|
fn rust_uv_timer_init(loop_handle: *libc::c_void,
|
|
timer_handle: *uv_timer_t) -> libc::c_int;
|
|
fn rust_uv_timer_start(
|
|
timer_handle: *uv_timer_t,
|
|
cb: *u8,
|
|
timeout: libc::c_uint,
|
|
repeat: libc::c_uint) -> libc::c_int;
|
|
fn rust_uv_timer_stop(handle: *uv_timer_t) -> libc::c_int;
|
|
|
|
fn rust_uv_getaddrinfo(loop_ptr: *libc::c_void,
|
|
handle: *uv_getaddrinfo_t,
|
|
cb: *u8,
|
|
node_name_ptr: *u8,
|
|
service_name_ptr: *u8,
|
|
// should probably only pass ptr::null()
|
|
hints: *addrinfo) -> libc::c_int;
|
|
fn rust_uv_freeaddrinfo(res: *addrinfo);
|
|
|
|
// data accessors/helpers for rust-mapped uv structs
|
|
fn rust_uv_helper_get_INADDR_NONE() -> u32;
|
|
fn rust_uv_is_ipv4_addrinfo(input: *addrinfo) -> bool;
|
|
fn rust_uv_is_ipv6_addrinfo(input: *addrinfo) -> bool;
|
|
fn rust_uv_get_next_addrinfo(input: *addrinfo) -> *addrinfo;
|
|
fn rust_uv_addrinfo_as_sockaddr_in(input: *addrinfo) -> *sockaddr_in;
|
|
fn rust_uv_addrinfo_as_sockaddr_in6(input: *addrinfo) -> *sockaddr_in6;
|
|
fn rust_uv_malloc_buf_base_of(sug_size: libc::size_t) -> *u8;
|
|
fn rust_uv_free_base_of_buf(++buf: uv_buf_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;
|
|
fn rust_uv_get_loop_for_uv_handle(handle: *libc::c_void)
|
|
-> *libc::c_void;
|
|
fn rust_uv_get_data_for_uv_loop(loop_ptr: *libc::c_void) -> *libc::c_void;
|
|
fn rust_uv_set_data_for_uv_loop(loop_ptr: *libc::c_void,
|
|
data: *libc::c_void);
|
|
fn rust_uv_get_data_for_uv_handle(handle: *libc::c_void)
|
|
-> *libc::c_void;
|
|
fn rust_uv_set_data_for_uv_handle(handle: *libc::c_void,
|
|
data: *libc::c_void);
|
|
fn rust_uv_get_data_for_req(req: *libc::c_void) -> *libc::c_void;
|
|
fn rust_uv_set_data_for_req(req: *libc::c_void,
|
|
data: *libc::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) -> libc::size_t;
|
|
|
|
// sizeof testing helpers
|
|
fn rust_uv_helper_uv_tcp_t_size() -> libc::c_uint;
|
|
fn rust_uv_helper_uv_connect_t_size() -> libc::c_uint;
|
|
fn rust_uv_helper_uv_buf_t_size() -> libc::c_uint;
|
|
fn rust_uv_helper_uv_write_t_size() -> libc::c_uint;
|
|
fn rust_uv_helper_uv_err_t_size() -> libc::c_uint;
|
|
fn rust_uv_helper_sockaddr_in_size() -> libc::c_uint;
|
|
fn rust_uv_helper_sockaddr_in6_size() -> libc::c_uint;
|
|
fn rust_uv_helper_uv_async_t_size() -> libc::c_uint;
|
|
fn rust_uv_helper_uv_timer_t_size() -> libc::c_uint;
|
|
fn rust_uv_helper_uv_getaddrinfo_t_size() -> libc::c_uint;
|
|
fn rust_uv_helper_addrinfo_size() -> libc::c_uint;
|
|
fn rust_uv_helper_addr_in_size() -> libc::c_uint;
|
|
}
|
|
|
|
unsafe fn loop_new() -> *libc::c_void {
|
|
return rustrt::rust_uv_loop_new();
|
|
}
|
|
|
|
unsafe fn loop_delete(loop_handle: *libc::c_void) {
|
|
rustrt::rust_uv_loop_delete(loop_handle);
|
|
}
|
|
|
|
unsafe fn loop_refcount(loop_ptr: *libc::c_void) -> libc::c_int {
|
|
return rustrt::rust_uv_loop_refcount(loop_ptr);
|
|
}
|
|
|
|
unsafe fn run(loop_handle: *libc::c_void) {
|
|
rustrt::rust_uv_run(loop_handle);
|
|
}
|
|
|
|
unsafe fn close<T>(handle: *T, cb: *u8) {
|
|
rustrt::rust_uv_close(handle as *libc::c_void, cb);
|
|
}
|
|
|
|
unsafe fn tcp_init(loop_handle: *libc::c_void, handle: *uv_tcp_t)
|
|
-> libc::c_int {
|
|
return rustrt::rust_uv_tcp_init(loop_handle, handle);
|
|
}
|
|
// FIXME ref #2064
|
|
unsafe fn tcp_connect(connect_ptr: *uv_connect_t,
|
|
tcp_handle_ptr: *uv_tcp_t,
|
|
addr_ptr: *sockaddr_in,
|
|
++after_connect_cb: *u8)
|
|
-> libc::c_int {
|
|
log(debug, fmt!("b4 foreign tcp_connect--addr port: %u cb: %u",
|
|
(*addr_ptr).sin_port as uint, after_connect_cb as uint));
|
|
return rustrt::rust_uv_tcp_connect(connect_ptr, tcp_handle_ptr,
|
|
after_connect_cb, addr_ptr);
|
|
}
|
|
// FIXME ref #2064
|
|
unsafe fn tcp_connect6(connect_ptr: *uv_connect_t,
|
|
tcp_handle_ptr: *uv_tcp_t,
|
|
addr_ptr: *sockaddr_in6,
|
|
++after_connect_cb: *u8)
|
|
-> libc::c_int {
|
|
return rustrt::rust_uv_tcp_connect6(connect_ptr, tcp_handle_ptr,
|
|
after_connect_cb, addr_ptr);
|
|
}
|
|
// FIXME ref #2064
|
|
unsafe fn tcp_bind(tcp_server_ptr: *uv_tcp_t,
|
|
addr_ptr: *sockaddr_in) -> libc::c_int {
|
|
return rustrt::rust_uv_tcp_bind(tcp_server_ptr,
|
|
addr_ptr);
|
|
}
|
|
// FIXME ref #2064
|
|
unsafe fn tcp_bind6(tcp_server_ptr: *uv_tcp_t,
|
|
addr_ptr: *sockaddr_in6) -> libc::c_int {
|
|
return rustrt::rust_uv_tcp_bind6(tcp_server_ptr,
|
|
addr_ptr);
|
|
}
|
|
|
|
unsafe fn listen<T>(stream: *T, backlog: libc::c_int,
|
|
cb: *u8) -> libc::c_int {
|
|
return rustrt::rust_uv_listen(stream as *libc::c_void, backlog, cb);
|
|
}
|
|
|
|
unsafe fn accept(server: *libc::c_void, client: *libc::c_void)
|
|
-> libc::c_int {
|
|
return rustrt::rust_uv_accept(server as *libc::c_void,
|
|
client as *libc::c_void);
|
|
}
|
|
|
|
unsafe fn write<T>(req: *uv_write_t, stream: *T,
|
|
buf_in: *~[uv_buf_t], cb: *u8) -> libc::c_int {
|
|
let buf_ptr = vec::raw::to_ptr(*buf_in);
|
|
let buf_cnt = vec::len(*buf_in) as i32;
|
|
return rustrt::rust_uv_write(req as *libc::c_void,
|
|
stream as *libc::c_void,
|
|
buf_ptr, buf_cnt, cb);
|
|
}
|
|
unsafe fn read_start(stream: *uv_stream_t, on_alloc: *u8,
|
|
on_read: *u8) -> libc::c_int {
|
|
return rustrt::rust_uv_read_start(stream as *libc::c_void,
|
|
on_alloc, on_read);
|
|
}
|
|
|
|
unsafe fn read_stop(stream: *uv_stream_t) -> libc::c_int {
|
|
return rustrt::rust_uv_read_stop(stream as *libc::c_void);
|
|
}
|
|
|
|
unsafe fn last_error(loop_handle: *libc::c_void) -> uv_err_t {
|
|
return rustrt::rust_uv_last_error(loop_handle);
|
|
}
|
|
|
|
unsafe fn strerror(err: *uv_err_t) -> *libc::c_char {
|
|
return rustrt::rust_uv_strerror(err);
|
|
}
|
|
unsafe fn err_name(err: *uv_err_t) -> *libc::c_char {
|
|
return rustrt::rust_uv_err_name(err);
|
|
}
|
|
|
|
unsafe fn async_init(loop_handle: *libc::c_void,
|
|
async_handle: *uv_async_t,
|
|
cb: *u8) -> libc::c_int {
|
|
return rustrt::rust_uv_async_init(loop_handle,
|
|
async_handle,
|
|
cb);
|
|
}
|
|
|
|
unsafe fn async_send(async_handle: *uv_async_t) {
|
|
return rustrt::rust_uv_async_send(async_handle);
|
|
}
|
|
unsafe fn buf_init(++input: *u8, len: uint) -> uv_buf_t {
|
|
let out_buf = { base: ptr::null(), len: 0 as libc::size_t };
|
|
let out_buf_ptr = ptr::addr_of(out_buf);
|
|
log(debug, fmt!("buf_init - input %u len %u out_buf: %u",
|
|
input as uint,
|
|
len as uint,
|
|
out_buf_ptr as uint));
|
|
// yuck :/
|
|
rustrt::rust_uv_buf_init(out_buf_ptr, input, len as size_t);
|
|
//let result = rustrt::rust_uv_buf_init_2(input, len as size_t);
|
|
log(debug, ~"after rust_uv_buf_init");
|
|
let res_base = get_base_from_buf(out_buf);
|
|
let res_len = get_len_from_buf(out_buf);
|
|
//let res_base = get_base_from_buf(result);
|
|
log(debug, fmt!("buf_init - result %u len %u",
|
|
res_base as uint,
|
|
res_len as uint));
|
|
return out_buf;
|
|
//return result;
|
|
}
|
|
unsafe fn ip4_addr(ip: ~str, port: int)
|
|
-> sockaddr_in {
|
|
do str::as_c_str(ip) |ip_buf| {
|
|
rustrt::rust_uv_ip4_addr(ip_buf as *u8,
|
|
port as libc::c_int)
|
|
}
|
|
}
|
|
unsafe fn ip6_addr(ip: ~str, port: int)
|
|
-> sockaddr_in6 {
|
|
do str::as_c_str(ip) |ip_buf| {
|
|
rustrt::rust_uv_ip6_addr(ip_buf as *u8,
|
|
port as libc::c_int)
|
|
}
|
|
}
|
|
unsafe fn ip4_name(src: &sockaddr_in) -> ~str {
|
|
// ipv4 addr max size: 15 + 1 trailing null byte
|
|
let dst: ~[u8] = ~[0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
|
|
0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8];
|
|
do vec::as_imm_buf(dst) |dst_buf, size| {
|
|
rustrt::rust_uv_ip4_name(to_unsafe_ptr(src),
|
|
dst_buf, size as libc::size_t);
|
|
// seems that checking the result of uv_ip4_name
|
|
// doesn't work too well..
|
|
// you're stuck looking at the value of dst_buf
|
|
// to see if it is the string representation of
|
|
// INADDR_NONE (0xffffffff or 255.255.255.255 on
|
|
// many platforms)
|
|
str::raw::from_buf(dst_buf)
|
|
}
|
|
}
|
|
unsafe fn ip6_name(src: &sockaddr_in6) -> ~str {
|
|
// ipv6 addr max size: 45 + 1 trailing null byte
|
|
let dst: ~[u8] = ~[0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
|
|
0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
|
|
0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
|
|
0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
|
|
0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
|
|
0u8,0u8,0u8,0u8,0u8,0u8];
|
|
do vec::as_imm_buf(dst) |dst_buf, size| {
|
|
let src_unsafe_ptr = to_unsafe_ptr(src);
|
|
log(debug, fmt!("val of src *sockaddr_in6: %? sockaddr_in6: %?",
|
|
src_unsafe_ptr, src));
|
|
let result = rustrt::rust_uv_ip6_name(src_unsafe_ptr,
|
|
dst_buf, size as libc::size_t);
|
|
match result {
|
|
0i32 => str::raw::from_buf(dst_buf),
|
|
_ => ~""
|
|
}
|
|
}
|
|
}
|
|
|
|
unsafe fn timer_init(loop_ptr: *libc::c_void,
|
|
timer_ptr: *uv_timer_t) -> libc::c_int {
|
|
return rustrt::rust_uv_timer_init(loop_ptr, timer_ptr);
|
|
}
|
|
unsafe fn timer_start(timer_ptr: *uv_timer_t, cb: *u8, timeout: uint,
|
|
repeat: uint) -> libc::c_int {
|
|
return rustrt::rust_uv_timer_start(timer_ptr, cb, timeout as libc::c_uint,
|
|
repeat as libc::c_uint);
|
|
}
|
|
unsafe fn timer_stop(timer_ptr: *uv_timer_t) -> libc::c_int {
|
|
return rustrt::rust_uv_timer_stop(timer_ptr);
|
|
}
|
|
unsafe fn getaddrinfo(loop_ptr: *libc::c_void,
|
|
handle: *uv_getaddrinfo_t,
|
|
cb: *u8,
|
|
node_name_ptr: *u8,
|
|
service_name_ptr: *u8,
|
|
hints: *addrinfo) -> libc::c_int {
|
|
rustrt::rust_uv_getaddrinfo(loop_ptr,
|
|
handle,
|
|
cb,
|
|
node_name_ptr,
|
|
service_name_ptr,
|
|
hints)
|
|
}
|
|
unsafe fn freeaddrinfo(res: *addrinfo) {
|
|
rustrt::rust_uv_freeaddrinfo(res);
|
|
}
|
|
|
|
// libuv struct initializers
|
|
unsafe fn tcp_t() -> uv_tcp_t {
|
|
return uv_ll_struct_stubgen::gen_stub_uv_tcp_t();
|
|
}
|
|
unsafe fn connect_t() -> uv_connect_t {
|
|
return uv_ll_struct_stubgen::gen_stub_uv_connect_t();
|
|
}
|
|
unsafe fn write_t() -> uv_write_t {
|
|
return uv_ll_struct_stubgen::gen_stub_uv_write_t();
|
|
}
|
|
unsafe fn async_t() -> uv_async_t {
|
|
return uv_ll_struct_stubgen::gen_stub_uv_async_t();
|
|
}
|
|
unsafe fn timer_t() -> uv_timer_t {
|
|
return uv_ll_struct_stubgen::gen_stub_uv_timer_t();
|
|
}
|
|
unsafe fn getaddrinfo_t() -> uv_getaddrinfo_t {
|
|
return uv_ll_struct_stubgen::gen_stub_uv_getaddrinfo_t();
|
|
}
|
|
|
|
// data access helpers
|
|
unsafe fn get_loop_for_uv_handle<T>(handle: *T)
|
|
-> *libc::c_void {
|
|
return rustrt::rust_uv_get_loop_for_uv_handle(handle as *libc::c_void);
|
|
}
|
|
unsafe fn get_stream_handle_from_connect_req(connect: *uv_connect_t)
|
|
-> *uv_stream_t {
|
|
return rustrt::rust_uv_get_stream_handle_from_connect_req(
|
|
connect);
|
|
}
|
|
unsafe fn get_stream_handle_from_write_req(
|
|
write_req: *uv_write_t)
|
|
-> *uv_stream_t {
|
|
return rustrt::rust_uv_get_stream_handle_from_write_req(
|
|
write_req);
|
|
}
|
|
unsafe fn get_data_for_uv_loop(loop_ptr: *libc::c_void) -> *libc::c_void {
|
|
rustrt::rust_uv_get_data_for_uv_loop(loop_ptr)
|
|
}
|
|
unsafe fn set_data_for_uv_loop(loop_ptr: *libc::c_void, data: *libc::c_void) {
|
|
rustrt::rust_uv_set_data_for_uv_loop(loop_ptr, data);
|
|
}
|
|
unsafe fn get_data_for_uv_handle<T>(handle: *T) -> *libc::c_void {
|
|
return rustrt::rust_uv_get_data_for_uv_handle(handle as *libc::c_void);
|
|
}
|
|
unsafe fn set_data_for_uv_handle<T, U>(handle: *T,
|
|
data: *U) {
|
|
rustrt::rust_uv_set_data_for_uv_handle(handle as *libc::c_void,
|
|
data as *libc::c_void);
|
|
}
|
|
unsafe fn get_data_for_req<T>(req: *T) -> *libc::c_void {
|
|
return rustrt::rust_uv_get_data_for_req(req as *libc::c_void);
|
|
}
|
|
unsafe fn set_data_for_req<T, U>(req: *T,
|
|
data: *U) {
|
|
rustrt::rust_uv_set_data_for_req(req as *libc::c_void,
|
|
data as *libc::c_void);
|
|
}
|
|
unsafe fn get_base_from_buf(buf: uv_buf_t) -> *u8 {
|
|
return rustrt::rust_uv_get_base_from_buf(buf);
|
|
}
|
|
unsafe fn get_len_from_buf(buf: uv_buf_t) -> libc::size_t {
|
|
return rustrt::rust_uv_get_len_from_buf(buf);
|
|
}
|
|
unsafe fn malloc_buf_base_of(suggested_size: libc::size_t)
|
|
-> *u8 {
|
|
return rustrt::rust_uv_malloc_buf_base_of(suggested_size);
|
|
}
|
|
unsafe fn free_base_of_buf(buf: uv_buf_t) {
|
|
rustrt::rust_uv_free_base_of_buf(buf);
|
|
}
|
|
|
|
unsafe fn get_last_err_info(uv_loop: *libc::c_void) -> ~str {
|
|
let err = last_error(uv_loop);
|
|
let err_ptr = ptr::addr_of(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);
|
|
}
|
|
|
|
unsafe fn get_last_err_data(uv_loop: *libc::c_void) -> uv_err_data {
|
|
let err = last_error(uv_loop);
|
|
let err_ptr = ptr::addr_of(err);
|
|
let err_name = str::raw::from_c_str(err_name(err_ptr));
|
|
let err_msg = str::raw::from_c_str(strerror(err_ptr));
|
|
{ err_name: err_name, err_msg: err_msg }
|
|
}
|
|
|
|
type uv_err_data = {
|
|
err_name: ~str,
|
|
err_msg: ~str
|
|
};
|
|
|
|
unsafe fn is_ipv4_addrinfo(input: *addrinfo) -> bool {
|
|
rustrt::rust_uv_is_ipv4_addrinfo(input)
|
|
}
|
|
unsafe fn is_ipv6_addrinfo(input: *addrinfo) -> bool {
|
|
rustrt::rust_uv_is_ipv6_addrinfo(input)
|
|
}
|
|
unsafe fn get_INADDR_NONE() -> u32 {
|
|
rustrt::rust_uv_helper_get_INADDR_NONE()
|
|
}
|
|
unsafe fn get_next_addrinfo(input: *addrinfo) -> *addrinfo {
|
|
rustrt::rust_uv_get_next_addrinfo(input)
|
|
}
|
|
unsafe fn addrinfo_as_sockaddr_in(input: *addrinfo) -> *sockaddr_in {
|
|
rustrt::rust_uv_addrinfo_as_sockaddr_in(input)
|
|
}
|
|
unsafe fn addrinfo_as_sockaddr_in6(input: *addrinfo) -> *sockaddr_in6 {
|
|
rustrt::rust_uv_addrinfo_as_sockaddr_in6(input)
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod test {
|
|
enum tcp_read_data {
|
|
tcp_read_eof,
|
|
tcp_read_more(~[u8]),
|
|
tcp_read_error
|
|
}
|
|
|
|
type request_wrapper = {
|
|
write_req: *uv_write_t,
|
|
req_buf: *~[uv_buf_t],
|
|
read_chan: *comm::Chan<~str>
|
|
};
|
|
|
|
extern fn after_close_cb(handle: *libc::c_void) {
|
|
log(debug, fmt!("after uv_close! handle ptr: %?",
|
|
handle));
|
|
}
|
|
|
|
extern fn on_alloc_cb(handle: *libc::c_void,
|
|
++suggested_size: libc::size_t)
|
|
-> uv_buf_t unsafe {
|
|
log(debug, ~"on_alloc_cb!");
|
|
let char_ptr = malloc_buf_base_of(suggested_size);
|
|
log(debug, fmt!("on_alloc_cb h: %? char_ptr: %u sugsize: %u",
|
|
handle,
|
|
char_ptr as uint,
|
|
suggested_size as uint));
|
|
return buf_init(char_ptr, suggested_size as uint);
|
|
}
|
|
|
|
extern fn on_read_cb(stream: *uv_stream_t,
|
|
nread: libc::ssize_t,
|
|
++buf: uv_buf_t) unsafe {
|
|
let nread = nread as int;
|
|
log(debug, fmt!("CLIENT entering on_read_cb nred: %d",
|
|
nread));
|
|
if (nread > 0) {
|
|
// we have data
|
|
log(debug, fmt!("CLIENT read: data! nread: %d", nread));
|
|
read_stop(stream);
|
|
let client_data =
|
|
get_data_for_uv_handle(stream as *libc::c_void)
|
|
as *request_wrapper;
|
|
let buf_base = get_base_from_buf(buf);
|
|
let buf_len = get_len_from_buf(buf);
|
|
let bytes = vec::raw::from_buf(buf_base, buf_len as uint);
|
|
let read_chan = *((*client_data).read_chan);
|
|
let msg_from_server = str::from_bytes(bytes);
|
|
core::comm::send(read_chan, msg_from_server);
|
|
close(stream as *libc::c_void, after_close_cb)
|
|
}
|
|
else if (nread == -1) {
|
|
// err .. possibly EOF
|
|
log(debug, ~"read: eof!");
|
|
}
|
|
else {
|
|
// nread == 0 .. do nothing, just free buf as below
|
|
log(debug, ~"read: do nothing!");
|
|
}
|
|
// when we're done
|
|
free_base_of_buf(buf);
|
|
log(debug, ~"CLIENT exiting on_read_cb");
|
|
}
|
|
|
|
extern fn on_write_complete_cb(write_req: *uv_write_t,
|
|
status: libc::c_int) unsafe {
|
|
log(debug, fmt!("CLIENT beginning on_write_complete_cb status: %d",
|
|
status as int));
|
|
let stream = get_stream_handle_from_write_req(write_req);
|
|
log(debug, fmt!("CLIENT on_write_complete_cb: tcp:%d write_handle:%d",
|
|
stream as int, write_req as int));
|
|
let result = read_start(stream, on_alloc_cb, on_read_cb);
|
|
log(debug, fmt!("CLIENT ending on_write_complete_cb .. status: %d",
|
|
result as int));
|
|
}
|
|
|
|
extern fn on_connect_cb(connect_req_ptr: *uv_connect_t,
|
|
status: libc::c_int) unsafe {
|
|
log(debug, fmt!("beginning on_connect_cb .. status: %d",
|
|
status as int));
|
|
let stream =
|
|
get_stream_handle_from_connect_req(connect_req_ptr);
|
|
if (status == 0i32) {
|
|
log(debug, ~"on_connect_cb: in status=0 if..");
|
|
let client_data = get_data_for_req(
|
|
connect_req_ptr as *libc::c_void)
|
|
as *request_wrapper;
|
|
let write_handle = (*client_data).write_req;
|
|
log(debug, fmt!("on_connect_cb: tcp: %d write_hdl: %d",
|
|
stream as int, write_handle as int));
|
|
let write_result = write(write_handle,
|
|
stream as *libc::c_void,
|
|
(*client_data).req_buf,
|
|
on_write_complete_cb);
|
|
log(debug, fmt!("on_connect_cb: write() status: %d",
|
|
write_result as int));
|
|
}
|
|
else {
|
|
let test_loop = get_loop_for_uv_handle(
|
|
stream as *libc::c_void);
|
|
let err_msg = get_last_err_info(test_loop);
|
|
log(debug, err_msg);
|
|
assert false;
|
|
}
|
|
log(debug, ~"finishing on_connect_cb");
|
|
}
|
|
|
|
fn impl_uv_tcp_request(ip: ~str, port: int, req_str: ~str,
|
|
client_chan: *comm::Chan<~str>) unsafe {
|
|
let test_loop = loop_new();
|
|
let tcp_handle = tcp_t();
|
|
let tcp_handle_ptr = ptr::addr_of(tcp_handle);
|
|
let connect_handle = connect_t();
|
|
let connect_req_ptr = ptr::addr_of(connect_handle);
|
|
|
|
// this is the persistent payload of data that we
|
|
// need to pass around to get this example to work.
|
|
// In C, this would be a malloc'd or stack-allocated
|
|
// struct that we'd cast to a void* and store as the
|
|
// data field in our uv_connect_t struct
|
|
let req_str_bytes = str::to_bytes(req_str);
|
|
let req_msg_ptr: *u8 = vec::raw::to_ptr(req_str_bytes);
|
|
log(debug, fmt!("req_msg ptr: %u", req_msg_ptr as uint));
|
|
let req_msg = ~[
|
|
buf_init(req_msg_ptr, vec::len(req_str_bytes))
|
|
];
|
|
// this is the enclosing record, we'll pass a ptr to
|
|
// this to C..
|
|
let write_handle = write_t();
|
|
let write_handle_ptr = ptr::addr_of(write_handle);
|
|
log(debug, fmt!("tcp req: tcp stream: %d write_handle: %d",
|
|
tcp_handle_ptr as int,
|
|
write_handle_ptr as int));
|
|
let client_data = { writer_handle: write_handle_ptr,
|
|
req_buf: ptr::addr_of(req_msg),
|
|
read_chan: client_chan };
|
|
|
|
let tcp_init_result = tcp_init(
|
|
test_loop as *libc::c_void, tcp_handle_ptr);
|
|
if (tcp_init_result == 0i32) {
|
|
log(debug, ~"sucessful tcp_init_result");
|
|
|
|
log(debug, ~"building addr...");
|
|
let addr = ip4_addr(ip, port);
|
|
// FIXME ref #2064
|
|
let addr_ptr = ptr::addr_of(addr);
|
|
log(debug, fmt!("after build addr in rust. port: %u",
|
|
addr.sin_port as uint));
|
|
|
|
// this should set up the connection request..
|
|
log(debug, fmt!("b4 call tcp_connect connect cb: %u ",
|
|
on_connect_cb as uint));
|
|
let tcp_connect_result = tcp_connect(
|
|
connect_req_ptr, tcp_handle_ptr,
|
|
addr_ptr, on_connect_cb);
|
|
if (tcp_connect_result == 0i32) {
|
|
// not set the data on the connect_req
|
|
// until its initialized
|
|
set_data_for_req(
|
|
connect_req_ptr as *libc::c_void,
|
|
ptr::addr_of(client_data) as *libc::c_void);
|
|
set_data_for_uv_handle(
|
|
tcp_handle_ptr as *libc::c_void,
|
|
ptr::addr_of(client_data) as *libc::c_void);
|
|
log(debug, ~"before run tcp req loop");
|
|
run(test_loop);
|
|
log(debug, ~"after run tcp req loop");
|
|
}
|
|
else {
|
|
log(debug, ~"tcp_connect() failure");
|
|
assert false;
|
|
}
|
|
}
|
|
else {
|
|
log(debug, ~"tcp_init() failure");
|
|
assert false;
|
|
}
|
|
loop_delete(test_loop);
|
|
|
|
}
|
|
|
|
extern fn server_after_close_cb(handle: *libc::c_void) unsafe {
|
|
log(debug, fmt!("SERVER server stream closed, should exit.. h: %?",
|
|
handle));
|
|
}
|
|
|
|
extern fn client_stream_after_close_cb(handle: *libc::c_void)
|
|
unsafe {
|
|
log(debug,
|
|
~"SERVER: closed client stream, now closing server stream");
|
|
let client_data = get_data_for_uv_handle(
|
|
handle) as
|
|
*tcp_server_data;
|
|
close((*client_data).server as *libc::c_void,
|
|
server_after_close_cb);
|
|
}
|
|
|
|
extern fn after_server_resp_write(req: *uv_write_t) unsafe {
|
|
let client_stream_ptr =
|
|
get_stream_handle_from_write_req(req);
|
|
log(debug, ~"SERVER: resp sent... closing client stream");
|
|
close(client_stream_ptr as *libc::c_void,
|
|
client_stream_after_close_cb)
|
|
}
|
|
|
|
extern fn on_server_read_cb(client_stream_ptr: *uv_stream_t,
|
|
nread: libc::ssize_t,
|
|
++buf: uv_buf_t) unsafe {
|
|
let nread = nread as int;
|
|
if (nread > 0) {
|
|
// we have data
|
|
log(debug, fmt!("SERVER read: data! nread: %d", nread));
|
|
|
|
// pull out the contents of the write from the client
|
|
let buf_base = get_base_from_buf(buf);
|
|
let buf_len = get_len_from_buf(buf) as uint;
|
|
log(debug, fmt!("SERVER buf base: %u, len: %u, nread: %d",
|
|
buf_base as uint,
|
|
buf_len as uint,
|
|
nread));
|
|
let bytes = vec::raw::from_buf(buf_base, buf_len);
|
|
let request_str = str::from_bytes(bytes);
|
|
|
|
let client_data = get_data_for_uv_handle(
|
|
client_stream_ptr as *libc::c_void) as *tcp_server_data;
|
|
|
|
let server_kill_msg = (*client_data).server_kill_msg;
|
|
let write_req = (*client_data).server_write_req;
|
|
if (str::contains(request_str, server_kill_msg)) {
|
|
log(debug, ~"SERVER: client req contains kill_msg!");
|
|
log(debug, ~"SERVER: sending response to client");
|
|
read_stop(client_stream_ptr);
|
|
let server_chan = *((*client_data).server_chan);
|
|
core::comm::send(server_chan, request_str);
|
|
let write_result = write(
|
|
write_req,
|
|
client_stream_ptr as *libc::c_void,
|
|
(*client_data).server_resp_buf,
|
|
after_server_resp_write);
|
|
log(debug, fmt!("SERVER: resp write result: %d",
|
|
write_result as int));
|
|
if (write_result != 0i32) {
|
|
log(debug, ~"bad result for server resp write()");
|
|
log(debug, get_last_err_info(
|
|
get_loop_for_uv_handle(client_stream_ptr
|
|
as *libc::c_void)));
|
|
assert false;
|
|
}
|
|
}
|
|
else {
|
|
log(debug, ~"SERVER: client req !contain kill_msg!");
|
|
}
|
|
}
|
|
else if (nread == -1) {
|
|
// err .. possibly EOF
|
|
log(debug, ~"read: eof!");
|
|
}
|
|
else {
|
|
// nread == 0 .. do nothing, just free buf as below
|
|
log(debug, ~"read: do nothing!");
|
|
}
|
|
// when we're done
|
|
free_base_of_buf(buf);
|
|
log(debug, ~"SERVER exiting on_read_cb");
|
|
}
|
|
|
|
extern fn server_connection_cb(server_stream_ptr:
|
|
*uv_stream_t,
|
|
status: libc::c_int) unsafe {
|
|
log(debug, ~"client connecting!");
|
|
let test_loop = get_loop_for_uv_handle(
|
|
server_stream_ptr as *libc::c_void);
|
|
if status != 0i32 {
|
|
let err_msg = get_last_err_info(test_loop);
|
|
log(debug, fmt!("server_connect_cb: non-zero status: %?",
|
|
err_msg));
|
|
return;
|
|
}
|
|
let server_data = get_data_for_uv_handle(
|
|
server_stream_ptr as *libc::c_void) as *tcp_server_data;
|
|
let client_stream_ptr = (*server_data).client;
|
|
let client_init_result = tcp_init(test_loop,
|
|
client_stream_ptr);
|
|
set_data_for_uv_handle(
|
|
client_stream_ptr as *libc::c_void,
|
|
server_data as *libc::c_void);
|
|
if (client_init_result == 0i32) {
|
|
log(debug, ~"successfully initialized client stream");
|
|
let accept_result = accept(server_stream_ptr as
|
|
*libc::c_void,
|
|
client_stream_ptr as
|
|
*libc::c_void);
|
|
if (accept_result == 0i32) {
|
|
// start reading
|
|
let read_result = read_start(
|
|
client_stream_ptr as *uv_stream_t,
|
|
on_alloc_cb,
|
|
on_server_read_cb);
|
|
if (read_result == 0i32) {
|
|
log(debug, ~"successful server read start");
|
|
}
|
|
else {
|
|
log(debug, fmt!("server_connection_cb: bad read:%d",
|
|
read_result as int));
|
|
assert false;
|
|
}
|
|
}
|
|
else {
|
|
log(debug, fmt!("server_connection_cb: bad accept: %d",
|
|
accept_result as int));
|
|
assert false;
|
|
}
|
|
}
|
|
else {
|
|
log(debug, fmt!("server_connection_cb: bad client init: %d",
|
|
client_init_result as int));
|
|
assert false;
|
|
}
|
|
}
|
|
|
|
type tcp_server_data = {
|
|
client: *uv_tcp_t,
|
|
server: *uv_tcp_t,
|
|
server_kill_msg: ~str,
|
|
server_resp_buf: *~[uv_buf_t],
|
|
server_chan: *comm::Chan<~str>,
|
|
server_write_req: *uv_write_t
|
|
};
|
|
|
|
type async_handle_data = {
|
|
continue_chan: *comm::Chan<bool>
|
|
};
|
|
|
|
extern fn async_close_cb(handle: *libc::c_void) {
|
|
log(debug, fmt!("SERVER: closing async cb... h: %?",
|
|
handle));
|
|
}
|
|
|
|
extern fn continue_async_cb(async_handle: *uv_async_t,
|
|
status: libc::c_int) unsafe {
|
|
// once we're in the body of this callback,
|
|
// the tcp server's loop is set up, so we
|
|
// can continue on to let the tcp client
|
|
// do its thang
|
|
let data = get_data_for_uv_handle(
|
|
async_handle as *libc::c_void) as *async_handle_data;
|
|
let continue_chan = *((*data).continue_chan);
|
|
let should_continue = status == 0i32;
|
|
core::comm::send(continue_chan, should_continue);
|
|
close(async_handle as *libc::c_void, async_close_cb);
|
|
}
|
|
|
|
fn impl_uv_tcp_server(server_ip: ~str,
|
|
server_port: int,
|
|
kill_server_msg: ~str,
|
|
server_resp_msg: ~str,
|
|
server_chan: *comm::Chan<~str>,
|
|
continue_chan: *comm::Chan<bool>) unsafe {
|
|
let test_loop = loop_new();
|
|
let tcp_server = tcp_t();
|
|
let tcp_server_ptr = ptr::addr_of(tcp_server);
|
|
|
|
let tcp_client = tcp_t();
|
|
let tcp_client_ptr = ptr::addr_of(tcp_client);
|
|
|
|
let server_write_req = write_t();
|
|
let server_write_req_ptr = ptr::addr_of(server_write_req);
|
|
|
|
let resp_str_bytes = str::to_bytes(server_resp_msg);
|
|
let resp_msg_ptr: *u8 = vec::raw::to_ptr(resp_str_bytes);
|
|
log(debug, fmt!("resp_msg ptr: %u", resp_msg_ptr as uint));
|
|
let resp_msg = ~[
|
|
buf_init(resp_msg_ptr, vec::len(resp_str_bytes))
|
|
];
|
|
|
|
let continue_async_handle = async_t();
|
|
let continue_async_handle_ptr =
|
|
ptr::addr_of(continue_async_handle);
|
|
let async_data =
|
|
{ continue_chan: continue_chan };
|
|
let async_data_ptr = ptr::addr_of(async_data);
|
|
|
|
let server_data: tcp_server_data = {
|
|
client: tcp_client_ptr,
|
|
server: tcp_server_ptr,
|
|
server_kill_msg: kill_server_msg,
|
|
server_resp_buf: ptr::addr_of(resp_msg),
|
|
server_chan: server_chan,
|
|
server_write_req: server_write_req_ptr
|
|
};
|
|
let server_data_ptr = ptr::addr_of(server_data);
|
|
set_data_for_uv_handle(tcp_server_ptr as *libc::c_void,
|
|
server_data_ptr as *libc::c_void);
|
|
|
|
// uv_tcp_init()
|
|
let tcp_init_result = tcp_init(
|
|
test_loop as *libc::c_void, tcp_server_ptr);
|
|
if (tcp_init_result == 0i32) {
|
|
let server_addr = ip4_addr(server_ip, server_port);
|
|
// FIXME ref #2064
|
|
let server_addr_ptr = ptr::addr_of(server_addr);
|
|
|
|
// uv_tcp_bind()
|
|
let bind_result = tcp_bind(tcp_server_ptr,
|
|
server_addr_ptr);
|
|
if (bind_result == 0i32) {
|
|
log(debug, ~"successful uv_tcp_bind, listening");
|
|
|
|
// uv_listen()
|
|
let listen_result = listen(tcp_server_ptr as
|
|
*libc::c_void,
|
|
128i32,
|
|
server_connection_cb);
|
|
if (listen_result == 0i32) {
|
|
// let the test know it can set up the tcp server,
|
|
// now.. this may still present a race, not sure..
|
|
let async_result = async_init(test_loop,
|
|
continue_async_handle_ptr,
|
|
continue_async_cb);
|
|
if (async_result == 0i32) {
|
|
set_data_for_uv_handle(
|
|
continue_async_handle_ptr as *libc::c_void,
|
|
async_data_ptr as *libc::c_void);
|
|
async_send(continue_async_handle_ptr);
|
|
// uv_run()
|
|
run(test_loop);
|
|
log(debug, ~"server uv::run() has returned");
|
|
}
|
|
else {
|
|
log(debug, fmt!("uv_async_init failure: %d",
|
|
async_result as int));
|
|
assert false;
|
|
}
|
|
}
|
|
else {
|
|
log(debug, fmt!("non-zero result on uv_listen: %d",
|
|
listen_result as int));
|
|
assert false;
|
|
}
|
|
}
|
|
else {
|
|
log(debug, fmt!("non-zero result on uv_tcp_bind: %d",
|
|
bind_result as int));
|
|
assert false;
|
|
}
|
|
}
|
|
else {
|
|
log(debug, fmt!("non-zero result on uv_tcp_init: %d",
|
|
tcp_init_result as int));
|
|
assert false;
|
|
}
|
|
loop_delete(test_loop);
|
|
}
|
|
|
|
// this is the impl for a test that is (maybe) ran on a
|
|
// per-platform/arch basis below
|
|
fn impl_uv_tcp_server_and_request() unsafe {
|
|
let bind_ip = ~"0.0.0.0";
|
|
let request_ip = ~"127.0.0.1";
|
|
let port = 8887;
|
|
let kill_server_msg = ~"does a dog have buddha nature?";
|
|
let server_resp_msg = ~"mu!";
|
|
let client_port = core::comm::Port::<~str>();
|
|
let client_chan = core::comm::Chan::<~str>(client_port);
|
|
let server_port = core::comm::Port::<~str>();
|
|
let server_chan = core::comm::Chan::<~str>(server_port);
|
|
|
|
let continue_port = core::comm::Port::<bool>();
|
|
let continue_chan = core::comm::Chan::<bool>(continue_port);
|
|
let continue_chan_ptr = ptr::addr_of(continue_chan);
|
|
|
|
do task::spawn_sched(task::ManualThreads(1u)) {
|
|
impl_uv_tcp_server(bind_ip, port,
|
|
kill_server_msg,
|
|
server_resp_msg,
|
|
ptr::addr_of(server_chan),
|
|
continue_chan_ptr);
|
|
};
|
|
|
|
// block until the server up is.. possibly a race?
|
|
log(debug, ~"before receiving on server continue_port");
|
|
core::comm::recv(continue_port);
|
|
log(debug, ~"received on continue port, set up tcp client");
|
|
|
|
do task::spawn_sched(task::ManualThreads(1u)) {
|
|
impl_uv_tcp_request(request_ip, port,
|
|
kill_server_msg,
|
|
ptr::addr_of(client_chan));
|
|
};
|
|
|
|
let msg_from_client = core::comm::recv(server_port);
|
|
let msg_from_server = core::comm::recv(client_port);
|
|
|
|
assert str::contains(msg_from_client, kill_server_msg);
|
|
assert str::contains(msg_from_server, server_resp_msg);
|
|
}
|
|
|
|
// FIXME don't run on fbsd or linux 32 bit(#2064)
|
|
#[cfg(target_os="win32")]
|
|
#[cfg(target_os="darwin")]
|
|
#[cfg(target_os="linux")]
|
|
mod tcp_and_server_client_test {
|
|
#[cfg(target_arch="x86_64")]
|
|
mod impl64 {
|
|
#[test]
|
|
fn test_uv_ll_tcp_server_and_request() unsafe {
|
|
impl_uv_tcp_server_and_request();
|
|
}
|
|
}
|
|
#[cfg(target_arch="x86")]
|
|
mod impl32 {
|
|
#[test]
|
|
#[ignore(cfg(target_os = "linux"))]
|
|
fn test_uv_ll_tcp_server_and_request() unsafe {
|
|
impl_uv_tcp_server_and_request();
|
|
}
|
|
}
|
|
}
|
|
|
|
// struct size tests
|
|
#[test]
|
|
fn test_uv_ll_struct_size_uv_tcp_t() {
|
|
let foreign_handle_size = rustrt::rust_uv_helper_uv_tcp_t_size();
|
|
let rust_handle_size = sys::size_of::<uv_tcp_t>();
|
|
let output = fmt!("uv_tcp_t -- foreign: %u rust: %u",
|
|
foreign_handle_size as uint, rust_handle_size);
|
|
log(debug, output);
|
|
assert foreign_handle_size as uint == rust_handle_size;
|
|
}
|
|
#[test]
|
|
fn test_uv_ll_struct_size_uv_connect_t() {
|
|
let foreign_handle_size =
|
|
rustrt::rust_uv_helper_uv_connect_t_size();
|
|
let rust_handle_size = sys::size_of::<uv_connect_t>();
|
|
let output = fmt!("uv_connect_t -- foreign: %u rust: %u",
|
|
foreign_handle_size as uint, rust_handle_size);
|
|
log(debug, output);
|
|
assert foreign_handle_size as uint == rust_handle_size;
|
|
}
|
|
#[test]
|
|
fn test_uv_ll_struct_size_uv_buf_t() {
|
|
let foreign_handle_size =
|
|
rustrt::rust_uv_helper_uv_buf_t_size();
|
|
let rust_handle_size = sys::size_of::<uv_buf_t>();
|
|
let output = fmt!("uv_buf_t -- foreign: %u rust: %u",
|
|
foreign_handle_size as uint, rust_handle_size);
|
|
log(debug, output);
|
|
assert foreign_handle_size as uint == rust_handle_size;
|
|
}
|
|
#[test]
|
|
fn test_uv_ll_struct_size_uv_write_t() {
|
|
let foreign_handle_size =
|
|
rustrt::rust_uv_helper_uv_write_t_size();
|
|
let rust_handle_size = sys::size_of::<uv_write_t>();
|
|
let output = fmt!("uv_write_t -- foreign: %u rust: %u",
|
|
foreign_handle_size as uint, rust_handle_size);
|
|
log(debug, output);
|
|
assert foreign_handle_size as uint == rust_handle_size;
|
|
}
|
|
|
|
#[test]
|
|
fn test_uv_ll_struct_size_sockaddr_in() {
|
|
let foreign_handle_size =
|
|
rustrt::rust_uv_helper_sockaddr_in_size();
|
|
let rust_handle_size = sys::size_of::<sockaddr_in>();
|
|
let output = fmt!("sockaddr_in -- foreign: %u rust: %u",
|
|
foreign_handle_size as uint, rust_handle_size);
|
|
log(debug, output);
|
|
assert foreign_handle_size as uint == rust_handle_size;
|
|
}
|
|
#[test]
|
|
fn test_uv_ll_struct_size_sockaddr_in6() {
|
|
let foreign_handle_size =
|
|
rustrt::rust_uv_helper_sockaddr_in6_size();
|
|
let rust_handle_size = sys::size_of::<sockaddr_in6>();
|
|
let output = fmt!("sockaddr_in6 -- foreign: %u rust: %u",
|
|
foreign_handle_size as uint, rust_handle_size);
|
|
log(debug, output);
|
|
// FIXME #1645 .. rust appears to pad structs to the nearest byte..?
|
|
// .. can't get the uv::ll::sockaddr_in6 to == 28 :/
|
|
// .. so the type always appears to be 32 in size.. which is
|
|
// good, i guess.. better too big than too little
|
|
assert (4u+foreign_handle_size as uint) == rust_handle_size;
|
|
}
|
|
#[test]
|
|
#[ignore(reason = "questionable size calculations")]
|
|
fn test_uv_ll_struct_size_addr_in() {
|
|
let foreign_handle_size =
|
|
rustrt::rust_uv_helper_addr_in_size();
|
|
let rust_handle_size = sys::size_of::<addr_in>();
|
|
let output = fmt!("addr_in -- foreign: %u rust: %u",
|
|
foreign_handle_size as uint, rust_handle_size);
|
|
log(debug, output);
|
|
// FIXME #1645 .. see note above about struct padding
|
|
assert (4u+foreign_handle_size as uint) == rust_handle_size;
|
|
}
|
|
|
|
#[test]
|
|
fn test_uv_ll_struct_size_uv_async_t() {
|
|
let foreign_handle_size =
|
|
rustrt::rust_uv_helper_uv_async_t_size();
|
|
let rust_handle_size = sys::size_of::<uv_async_t>();
|
|
let output = fmt!("uv_async_t -- foreign: %u rust: %u",
|
|
foreign_handle_size as uint, rust_handle_size);
|
|
log(debug, output);
|
|
assert foreign_handle_size as uint == rust_handle_size;
|
|
}
|
|
|
|
#[test]
|
|
fn test_uv_ll_struct_size_uv_timer_t() {
|
|
let foreign_handle_size =
|
|
rustrt::rust_uv_helper_uv_timer_t_size();
|
|
let rust_handle_size = sys::size_of::<uv_timer_t>();
|
|
let output = fmt!("uv_timer_t -- foreign: %u rust: %u",
|
|
foreign_handle_size as uint, rust_handle_size);
|
|
log(debug, output);
|
|
assert foreign_handle_size as uint == rust_handle_size;
|
|
}
|
|
|
|
#[test]
|
|
#[ignore(cfg(target_os = "win32"))]
|
|
fn test_uv_ll_struct_size_uv_getaddrinfo_t() {
|
|
let foreign_handle_size =
|
|
rustrt::rust_uv_helper_uv_getaddrinfo_t_size();
|
|
let rust_handle_size = sys::size_of::<uv_getaddrinfo_t>();
|
|
let output = fmt!("uv_getaddrinfo_t -- foreign: %u rust: %u",
|
|
foreign_handle_size as uint, rust_handle_size);
|
|
log(debug, output);
|
|
assert foreign_handle_size as uint == rust_handle_size;
|
|
}
|
|
#[test]
|
|
#[ignore(cfg(target_os = "macos"))]
|
|
#[ignore(cfg(target_os = "win32"))]
|
|
fn test_uv_ll_struct_size_addrinfo() {
|
|
let foreign_handle_size =
|
|
rustrt::rust_uv_helper_addrinfo_size();
|
|
let rust_handle_size = sys::size_of::<addrinfo>();
|
|
let output = fmt!("addrinfo -- foreign: %u rust: %u",
|
|
foreign_handle_size as uint, rust_handle_size);
|
|
log(debug, output);
|
|
assert foreign_handle_size as uint == rust_handle_size;
|
|
}
|
|
}
|