--- /dev/null
- static fn from_native_handle(
+ // 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 prelude::*;
+ use libc::{size_t, ssize_t, c_int, c_void};
+ use cast::{transmute, transmute_mut_region};
+ use super::super::uvll;
+ use super::super::uvll::*;
+ use super::{Loop, Watcher, Request, UvError, Buf, Callback, NativeHandle, NullCallback,
+ loop_from_watcher, status_to_maybe_uv_error,
+ install_watcher_data, get_watcher_data, drop_watcher_data,
+ vec_to_uv_buf, vec_from_uv_buf};
+ use super::super::rtio::{IpAddr, Ipv4, Ipv6};
+
+ #[cfg(test)]
+ use unstable::run_in_bare_thread;
+ #[cfg(test)]
+ use super::super::thread::Thread;
+ #[cfg(test)]
+ use cell::Cell;
+
+ fn ip4_as_uv_ip4(addr: IpAddr, f: &fn(*sockaddr_in)) {
+ match addr {
+ Ipv4(a, b, c, d, p) => {
+ unsafe {
+ let addr = malloc_ip4_addr(fmt!("%u.%u.%u.%u",
+ a as uint,
+ b as uint,
+ c as uint,
+ d as uint), p as int);
+ do (|| {
+ f(addr);
+ }).finally {
+ free_ip4_addr(addr);
+ }
+ }
+ }
+ Ipv6 => fail!()
+ }
+ }
+
+ // uv_stream t is the parent class of uv_tcp_t, uv_pipe_t, uv_tty_t
+ // and uv_file_t
+ pub struct StreamWatcher(*uvll::uv_stream_t);
+
+ impl Watcher for StreamWatcher {
+ fn event_loop(&self) -> Loop {
+ loop_from_watcher(self)
+ }
+ }
+
+ pub type ReadCallback = ~fn(StreamWatcher, int, Buf, Option<UvError>);
+ impl Callback for ReadCallback { }
+
+ // XXX: The uv alloc callback also has a *uv_handle_t arg
+ pub type AllocCallback = ~fn(uint) -> Buf;
+ impl Callback for AllocCallback { }
+
+ pub impl StreamWatcher {
+
+ fn read_start(&mut self, alloc: AllocCallback, cb: ReadCallback) {
+ // XXX: Borrowchk problems
+ let data = get_watcher_data(unsafe { transmute_mut_region(self) });
+ data.alloc_cb = Some(alloc);
+ data.read_cb = Some(cb);
+
+ let handle = self.native_handle();
+ unsafe { uvll::read_start(handle, alloc_cb, read_cb); }
+
+ extern fn alloc_cb(stream: *uvll::uv_stream_t, suggested_size: size_t) -> Buf {
+ let mut stream_watcher: StreamWatcher = NativeHandle::from_native_handle(stream);
+ let data = get_watcher_data(&mut stream_watcher);
+ let alloc_cb = data.alloc_cb.get_ref();
+ return (*alloc_cb)(suggested_size as uint);
+ }
+
+ extern fn read_cb(stream: *uvll::uv_stream_t, nread: ssize_t, ++buf: Buf) {
+ rtdebug!("buf addr: %x", buf.base as uint);
+ rtdebug!("buf len: %d", buf.len as int);
+ let mut stream_watcher: StreamWatcher = NativeHandle::from_native_handle(stream);
+ let data = get_watcher_data(&mut stream_watcher);
+ let cb = data.read_cb.get_ref();
+ let status = status_to_maybe_uv_error(stream, nread as c_int);
+ (*cb)(stream_watcher, nread as int, buf, status);
+ }
+ }
+
+ fn read_stop(&mut self) {
+ // It would be nice to drop the alloc and read callbacks here,
+ // but read_stop may be called from inside one of them and we
+ // would end up freeing the in-use environment
+ let handle = self.native_handle();
+ unsafe { uvll::read_stop(handle); }
+ }
+
+ // XXX: Needs to take &[u8], not ~[u8]
+ fn write(&mut self, msg: ~[u8], cb: ConnectionCallback) {
+ // XXX: Borrowck
+ let data = get_watcher_data(unsafe { transmute_mut_region(self) });
+ fail_unless!(data.write_cb.is_none());
+ data.write_cb = Some(cb);
+
+ let req = WriteRequest::new();
+ let buf = vec_to_uv_buf(msg);
+ // XXX: Allocation
+ let bufs = ~[buf];
+ unsafe {
+ fail_unless!(0 == uvll::write(req.native_handle(),
+ self.native_handle(),
+ &bufs, write_cb));
+ }
+ // XXX: Freeing immediately after write. Is this ok?
+ let _v = vec_from_uv_buf(buf);
+
+ extern fn write_cb(req: *uvll::uv_write_t, status: c_int) {
+ let write_request: WriteRequest = NativeHandle::from_native_handle(req);
+ let mut stream_watcher = write_request.stream();
+ write_request.delete();
+ let cb = get_watcher_data(&mut stream_watcher).write_cb.swap_unwrap();
+ let status = status_to_maybe_uv_error(stream_watcher.native_handle(), status);
+ cb(stream_watcher, status);
+ }
+ }
+
+ fn accept(&mut self, stream: StreamWatcher) {
+ let self_handle = self.native_handle() as *c_void;
+ let stream_handle = stream.native_handle() as *c_void;
+ unsafe {
+ fail_unless!(0 == uvll::accept(self_handle, stream_handle));
+ }
+ }
+
+ fn close(self, cb: NullCallback) {
+ {
+ let mut self = self;
+ let data = get_watcher_data(&mut self);
+ fail_unless!(data.close_cb.is_none());
+ data.close_cb = Some(cb);
+ }
+
+ unsafe { uvll::close(self.native_handle(), close_cb); }
+
+ extern fn close_cb(handle: *uvll::uv_stream_t) {
+ let mut stream_watcher: StreamWatcher = NativeHandle::from_native_handle(handle);
+ {
+ let mut data = get_watcher_data(&mut stream_watcher);
+ data.close_cb.swap_unwrap()();
+ }
+ drop_watcher_data(&mut stream_watcher);
+ unsafe { free_handle(handle as *c_void) }
+ }
+ }
+ }
+
+ impl NativeHandle<*uvll::uv_stream_t> for StreamWatcher {
- static fn new(loop_: &mut Loop) -> TcpWatcher {
++ fn from_native_handle(
+ handle: *uvll::uv_stream_t) -> StreamWatcher {
+ StreamWatcher(handle)
+ }
+ fn native_handle(&self) -> *uvll::uv_stream_t {
+ match self { &StreamWatcher(ptr) => ptr }
+ }
+ }
+
+ pub struct TcpWatcher(*uvll::uv_tcp_t);
+
+ impl Watcher for TcpWatcher {
+ fn event_loop(&self) -> Loop {
+ loop_from_watcher(self)
+ }
+ }
+
+ pub type ConnectionCallback = ~fn(StreamWatcher, Option<UvError>);
+ impl Callback for ConnectionCallback { }
+
+ pub impl TcpWatcher {
- const BACKLOG: c_int = 128; // XXX should be configurable
++ fn new(loop_: &mut Loop) -> TcpWatcher {
+ unsafe {
+ let handle = malloc_handle(UV_TCP);
+ fail_unless!(handle.is_not_null());
+ fail_unless!(0 == uvll::tcp_init(loop_.native_handle(), handle));
+ let mut watcher = NativeHandle::from_native_handle(handle);
+ install_watcher_data(&mut watcher);
+ return watcher;
+ }
+ }
+
+ fn bind(&mut self, address: IpAddr) {
+ match address {
+ Ipv4(*) => {
+ do ip4_as_uv_ip4(address) |addr| {
+ let result = unsafe {
+ uvll::tcp_bind(self.native_handle(), addr)
+ };
+ // XXX: bind is likely to fail. need real error handling
+ fail_unless!(result == 0);
+ }
+ }
+ _ => fail!()
+ }
+ }
+
+ fn connect(&mut self, address: IpAddr, cb: ConnectionCallback) {
+ unsafe {
+ fail_unless!(get_watcher_data(self).connect_cb.is_none());
+ get_watcher_data(self).connect_cb = Some(cb);
+
+ let mut connect_watcher = ConnectRequest::new();
+ let connect_handle = connect_watcher.native_handle();
+ match address {
+ Ipv4(*) => {
+ do ip4_as_uv_ip4(address) |addr| {
+ rtdebug!("connect_t: %x", connect_handle as uint);
+ fail_unless!(0 == uvll::tcp_connect(connect_handle,
+ self.native_handle(),
+ addr, connect_cb));
+ }
+ }
+ _ => fail!()
+ }
+
+ extern fn connect_cb(req: *uvll::uv_connect_t, status: c_int) {
+ rtdebug!("connect_t: %x", req as uint);
+ let connect_request: ConnectRequest = NativeHandle::from_native_handle(req);
+ let mut stream_watcher = connect_request.stream();
+ connect_request.delete();
+ let cb: ConnectionCallback = {
+ let data = get_watcher_data(&mut stream_watcher);
+ data.connect_cb.swap_unwrap()
+ };
+ let status = status_to_maybe_uv_error(stream_watcher.native_handle(), status);
+ cb(stream_watcher, status);
+ }
+ }
+ }
+
+ fn listen(&mut self, cb: ConnectionCallback) {
+ // XXX: Borrowck
+ let data = get_watcher_data(unsafe { transmute_mut_region(self) });
+ fail_unless!(data.connect_cb.is_none());
+ data.connect_cb = Some(cb);
+
+ unsafe {
- static fn from_native_handle(handle: *uvll::uv_tcp_t) -> TcpWatcher {
++ static BACKLOG: c_int = 128; // XXX should be configurable
+ // XXX: This can probably fail
+ fail_unless!(0 == uvll::listen(self.native_handle(),
+ BACKLOG, connection_cb));
+ }
+
+ extern fn connection_cb(handle: *uvll::uv_stream_t, status: c_int) {
+ rtdebug!("connection_cb");
+ let mut stream_watcher: StreamWatcher = NativeHandle::from_native_handle(handle);
+ let cb = get_watcher_data(&mut stream_watcher).connect_cb.swap_unwrap();
+ let status = status_to_maybe_uv_error(stream_watcher.native_handle(), status);
+ cb(stream_watcher, status);
+ }
+ }
+
+ fn as_stream(&self) -> StreamWatcher {
+ NativeHandle::from_native_handle(self.native_handle() as *uvll::uv_stream_t)
+ }
+ }
+
+ impl NativeHandle<*uvll::uv_tcp_t> for TcpWatcher {
- static fn new() -> ConnectRequest {
++ fn from_native_handle(handle: *uvll::uv_tcp_t) -> TcpWatcher {
+ TcpWatcher(handle)
+ }
+ fn native_handle(&self) -> *uvll::uv_tcp_t {
+ match self { &TcpWatcher(ptr) => ptr }
+ }
+ }
+
+ pub type ConnectCallback = ~fn(ConnectRequest, Option<UvError>);
+ impl Callback for ConnectCallback { }
+
+ // uv_connect_t is a subclass of uv_req_t
+ struct ConnectRequest(*uvll::uv_connect_t);
+
+ impl Request for ConnectRequest { }
+
+ impl ConnectRequest {
+
- static fn from_native_handle(
++ fn new() -> ConnectRequest {
+ let connect_handle = unsafe {
+ malloc_req(UV_CONNECT)
+ };
+ fail_unless!(connect_handle.is_not_null());
+ let connect_handle = connect_handle as *uvll::uv_connect_t;
+ ConnectRequest(connect_handle)
+ }
+
+ fn stream(&self) -> StreamWatcher {
+ unsafe {
+ let stream_handle = uvll::get_stream_handle_from_connect_req(self.native_handle());
+ NativeHandle::from_native_handle(stream_handle)
+ }
+ }
+
+ fn delete(self) {
+ unsafe { free_req(self.native_handle() as *c_void) }
+ }
+ }
+
+ impl NativeHandle<*uvll::uv_connect_t> for ConnectRequest {
- static fn new() -> WriteRequest {
++ fn from_native_handle(
+ handle: *uvll:: uv_connect_t) -> ConnectRequest {
+ ConnectRequest(handle)
+ }
+ fn native_handle(&self) -> *uvll::uv_connect_t {
+ match self { &ConnectRequest(ptr) => ptr }
+ }
+ }
+
+ pub struct WriteRequest(*uvll::uv_write_t);
+
+ impl Request for WriteRequest { }
+
+ pub impl WriteRequest {
+
- static fn from_native_handle(handle: *uvll:: uv_write_t) -> WriteRequest {
++ fn new() -> WriteRequest {
+ let write_handle = unsafe {
+ malloc_req(UV_WRITE)
+ };
+ fail_unless!(write_handle.is_not_null());
+ let write_handle = write_handle as *uvll::uv_write_t;
+ WriteRequest(write_handle)
+ }
+
+ fn stream(&self) -> StreamWatcher {
+ unsafe {
+ let stream_handle = uvll::get_stream_handle_from_write_req(self.native_handle());
+ NativeHandle::from_native_handle(stream_handle)
+ }
+ }
+
+ fn delete(self) {
+ unsafe { free_req(self.native_handle() as *c_void) }
+ }
+ }
+
+ impl NativeHandle<*uvll::uv_write_t> for WriteRequest {
- const MAX: int = 10;
++ fn from_native_handle(handle: *uvll:: uv_write_t) -> WriteRequest {
+ WriteRequest(handle)
+ }
+ fn native_handle(&self) -> *uvll::uv_write_t {
+ match self { &WriteRequest(ptr) => ptr }
+ }
+ }
+
+
+ #[test]
+ #[ignore(reason = "ffi struct issues")]
+ fn connect_close() {
+ do run_in_bare_thread() {
+ let mut loop_ = Loop::new();
+ let mut tcp_watcher = { TcpWatcher::new(&mut loop_) };
+ // Connect to a port where nobody is listening
+ let addr = Ipv4(127, 0, 0, 1, 2923);
+ do tcp_watcher.connect(addr) |stream_watcher, status| {
+ rtdebug!("tcp_watcher.connect!");
+ fail_unless!(status.is_some());
+ fail_unless!(status.get().name() == ~"ECONNREFUSED");
+ stream_watcher.close(||());
+ }
+ loop_.run();
+ loop_.close();
+ }
+ }
+
+ #[test]
+ #[ignore(reason = "need a server to connect to")]
+ fn connect_read() {
+ do run_in_bare_thread() {
+ let mut loop_ = Loop::new();
+ let mut tcp_watcher = { TcpWatcher::new(&mut loop_) };
+ let addr = Ipv4(127, 0, 0, 1, 2924);
+ do tcp_watcher.connect(addr) |stream_watcher, status| {
+ let mut stream_watcher = stream_watcher;
+ rtdebug!("tcp_watcher.connect!");
+ fail_unless!(status.is_none());
+ let alloc: AllocCallback = |size| {
+ vec_to_uv_buf(vec::from_elem(size, 0))
+ };
+ do stream_watcher.read_start(alloc)
+ |stream_watcher, nread, buf, status| {
+
+ let buf = vec_from_uv_buf(buf);
+ rtdebug!("read cb!");
+ if status.is_none() {
+ let bytes = buf.unwrap();
+ rtdebug!("%s", bytes.slice(0, nread as uint).to_str());
+ } else {
+ rtdebug!("status after read: %s", status.get().to_str());
+ rtdebug!("closing");
+ stream_watcher.close(||());
+ }
+ }
+ }
+ loop_.run();
+ loop_.close();
+ }
+ }
+
+ #[test]
+ #[ignore(reason = "ffi struct issues")]
+ fn listen() {
+ do run_in_bare_thread() {
- for buf.view(0, nread as uint).each |byte| {
++ static MAX: int = 10;
+ let mut loop_ = Loop::new();
+ let mut server_tcp_watcher = { TcpWatcher::new(&mut loop_) };
+ let addr = Ipv4(127, 0, 0, 1, 2925);
+ server_tcp_watcher.bind(addr);
+ let loop_ = loop_;
+ rtdebug!("listening");
+ do server_tcp_watcher.listen |server_stream_watcher, status| {
+ rtdebug!("listened!");
+ fail_unless!(status.is_none());
+ let mut server_stream_watcher = server_stream_watcher;
+ let mut loop_ = loop_;
+ let mut client_tcp_watcher = TcpWatcher::new(&mut loop_);
+ let mut client_tcp_watcher = client_tcp_watcher.as_stream();
+ server_stream_watcher.accept(client_tcp_watcher);
+ let count_cell = Cell(0);
+ let server_stream_watcher = server_stream_watcher;
+ rtdebug!("starting read");
+ let alloc: AllocCallback = |size| {
+ vec_to_uv_buf(vec::from_elem(size, 0))
+ };
+ do client_tcp_watcher.read_start(alloc)
+ |stream_watcher, nread, buf, status| {
+
+ rtdebug!("i'm reading!");
+ let buf = vec_from_uv_buf(buf);
+ let mut count = count_cell.take();
+ if status.is_none() {
+ rtdebug!("got %d bytes", nread);
+ let buf = buf.unwrap();
++ for buf.slice(0, nread as uint).each |byte| {
+ fail_unless!(*byte == count as u8);
+ rtdebug!("%u", *byte as uint);
+ count += 1;
+ }
+ } else {
+ fail_unless!(count == MAX);
+ do stream_watcher.close {
+ server_stream_watcher.close(||());
+ }
+ }
+ count_cell.put_back(count);
+ }
+ }
+
+ let _client_thread = do Thread::start {
+ rtdebug!("starting client thread");
+ let mut loop_ = Loop::new();
+ let mut tcp_watcher = { TcpWatcher::new(&mut loop_) };
+ do tcp_watcher.connect(addr) |stream_watcher, status| {
+ rtdebug!("connecting");
+ fail_unless!(status.is_none());
+ let mut stream_watcher = stream_watcher;
+ let msg = ~[0, 1, 2, 3, 4, 5, 6 ,7 ,8, 9];
+ do stream_watcher.write(msg) |stream_watcher, status| {
+ rtdebug!("writing");
+ fail_unless!(status.is_none());
+ stream_watcher.close(||());
+ }
+ }
+ loop_.run();
+ loop_.close();
+ };
+
+ let mut loop_ = loop_;
+ loop_.run();
+ loop_.close();
+ }
+ }
--- /dev/null
-#[deriving_eq]
+ // Copyright 2012 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.
+
+ /*!
+ * Low-level bindings to the libuv library.
+ *
+ * This module contains a set of direct, 'bare-metal' wrappers around
+ * the libuv C-API.
+ *
+ * We're not bothering yet to redefine uv's structs as Rust structs
+ * because they are quite large and change often between versions.
+ * The maintenance burden is just too high. Instead we use the uv's
+ * `uv_handle_size` and `uv_req_size` to find the correct size of the
+ * structs and allocate them on the heap. This can be revisited later.
+ *
+ * There are also a collection of helper functions to ease interacting
+ * with the low-level API.
+ *
+ * As new functionality, existant in uv.h, is added to the rust stdlib,
+ * the mappings should be added in this module.
+ */
+
+ #[allow(non_camel_case_types)]; // C types
+
+ use libc::{size_t, c_int, c_uint, c_void, c_char, uintptr_t};
+ use libc::{malloc, free};
+ use prelude::*;
+ use ptr::to_unsafe_ptr;
+
+ pub struct uv_err_t {
+ code: c_int,
+ sys_errno_: c_int
+ }
+
+ pub struct uv_buf_t {
+ base: *u8,
+ len: libc::size_t,
+ }
+
+ pub type uv_handle_t = c_void;
+ pub type uv_loop_t = c_void;
+ pub type uv_idle_t = c_void;
+ pub type uv_tcp_t = c_void;
+ pub type uv_connect_t = c_void;
+ pub type uv_write_t = c_void;
+ pub type uv_async_t = c_void;
+ pub type uv_timer_t = c_void;
+ pub type uv_stream_t = c_void;
+ pub type uv_fs_t = c_void;
+
+ pub type uv_idle_cb = *u8;
+
+ pub type sockaddr_in = c_void;
+ pub type sockaddr_in6 = c_void;
+
-#[deriving_eq]
++#[deriving(Eq)]
+ pub enum uv_handle_type {
+ UV_UNKNOWN_HANDLE,
+ UV_ASYNC,
+ UV_CHECK,
+ UV_FS_EVENT,
+ UV_FS_POLL,
+ UV_HANDLE,
+ UV_IDLE,
+ UV_NAMED_PIPE,
+ UV_POLL,
+ UV_PREPARE,
+ UV_PROCESS,
+ UV_STREAM,
+ UV_TCP,
+ UV_TIMER,
+ UV_TTY,
+ UV_UDP,
+ UV_SIGNAL,
+ UV_FILE,
+ UV_HANDLE_TYPE_MAX
+ }
+
++#[deriving(Eq)]
+ pub enum uv_req_type {
+ UV_UNKNOWN_REQ,
+ UV_REQ,
+ UV_CONNECT,
+ UV_WRITE,
+ UV_SHUTDOWN,
+ UV_UDP_SEND,
+ UV_FS,
+ UV_WORK,
+ UV_GETADDRINFO,
+ UV_REQ_TYPE_MAX
+ }
+
+ pub unsafe fn malloc_handle(handle: uv_handle_type) -> *c_void {
+ fail_unless!(handle != UV_UNKNOWN_HANDLE && handle != UV_HANDLE_TYPE_MAX);
+ let size = unsafe { rust_uv_handle_size(handle as uint) };
+ let p = malloc(size);
+ fail_unless!(p.is_not_null());
+ return p;
+ }
+
+ pub unsafe fn free_handle(v: *c_void) {
+ free(v)
+ }
+
+ pub unsafe fn malloc_req(req: uv_req_type) -> *c_void {
+ fail_unless!(req != UV_UNKNOWN_REQ && req != UV_REQ_TYPE_MAX);
+ let size = unsafe { rust_uv_req_size(req as uint) };
+ let p = malloc(size);
+ fail_unless!(p.is_not_null());
+ return p;
+ }
+
+ pub unsafe fn free_req(v: *c_void) {
+ free(v)
+ }
+
+ #[test]
+ fn handle_sanity_check() {
+ unsafe {
+ fail_unless!(UV_HANDLE_TYPE_MAX as uint == rust_uv_handle_type_max());
+ }
+ }
+
+ #[test]
+ fn request_sanity_check() {
+ unsafe {
+ fail_unless!(UV_REQ_TYPE_MAX as uint == rust_uv_req_type_max());
+ }
+ }
+
+ pub unsafe fn loop_new() -> *c_void {
+ return rust_uv_loop_new();
+ }
+
+ pub unsafe fn loop_delete(loop_handle: *c_void) {
+ rust_uv_loop_delete(loop_handle);
+ }
+
+ pub unsafe fn run(loop_handle: *c_void) {
+ rust_uv_run(loop_handle);
+ }
+
+ pub unsafe fn close<T>(handle: *T, cb: *u8) {
+ rust_uv_close(handle as *c_void, cb);
+ }
+
+ pub unsafe fn walk(loop_handle: *c_void, cb: *u8, arg: *c_void) {
+ rust_uv_walk(loop_handle, cb, arg);
+ }
+
+ pub unsafe fn idle_new() -> *uv_idle_t {
+ rust_uv_idle_new()
+ }
+
+ pub unsafe fn idle_delete(handle: *uv_idle_t) {
+ rust_uv_idle_delete(handle)
+ }
+
+ pub unsafe fn idle_init(loop_handle: *uv_loop_t, handle: *uv_idle_t) -> c_int {
+ rust_uv_idle_init(loop_handle, handle)
+ }
+
+ pub unsafe fn idle_start(handle: *uv_idle_t, cb: uv_idle_cb) -> c_int {
+ rust_uv_idle_start(handle, cb)
+ }
+
+ pub unsafe fn idle_stop(handle: *uv_idle_t) -> c_int {
+ rust_uv_idle_stop(handle)
+ }
+
+ pub unsafe fn tcp_init(loop_handle: *c_void, handle: *uv_tcp_t) -> c_int {
+ return rust_uv_tcp_init(loop_handle, handle);
+ }
+
+ // FIXME ref #2064
+ pub unsafe fn tcp_connect(connect_ptr: *uv_connect_t,
+ tcp_handle_ptr: *uv_tcp_t,
+ addr_ptr: *sockaddr_in,
+ after_connect_cb: *u8) -> c_int {
+ return rust_uv_tcp_connect(connect_ptr, tcp_handle_ptr,
+ after_connect_cb, addr_ptr);
+ }
+ // FIXME ref #2064
+ pub unsafe fn tcp_connect6(connect_ptr: *uv_connect_t,
+ tcp_handle_ptr: *uv_tcp_t,
+ addr_ptr: *sockaddr_in6,
+ after_connect_cb: *u8) -> c_int {
+ return rust_uv_tcp_connect6(connect_ptr, tcp_handle_ptr,
+ after_connect_cb, addr_ptr);
+ }
+ // FIXME ref #2064
+ pub unsafe fn tcp_bind(tcp_server_ptr: *uv_tcp_t, addr_ptr: *sockaddr_in) -> c_int {
+ return rust_uv_tcp_bind(tcp_server_ptr, addr_ptr);
+ }
+ // FIXME ref #2064
+ pub unsafe fn tcp_bind6(tcp_server_ptr: *uv_tcp_t, addr_ptr: *sockaddr_in6) -> c_int {
+ return rust_uv_tcp_bind6(tcp_server_ptr, addr_ptr);
+ }
+
+ pub unsafe fn tcp_getpeername(tcp_handle_ptr: *uv_tcp_t, name: *sockaddr_in) -> c_int {
+ return rust_uv_tcp_getpeername(tcp_handle_ptr, name);
+ }
+
+ pub unsafe fn tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t, name: *sockaddr_in6) ->c_int {
+ return rust_uv_tcp_getpeername6(tcp_handle_ptr, name);
+ }
+
+ pub unsafe fn listen<T>(stream: *T, backlog: c_int, cb: *u8) -> c_int {
+ return rust_uv_listen(stream as *c_void, backlog, cb);
+ }
+
+ pub unsafe fn accept(server: *c_void, client: *c_void) -> c_int {
+ return rust_uv_accept(server as *c_void, client as *c_void);
+ }
+
+ pub unsafe fn write<T>(req: *uv_write_t, stream: *T, buf_in: *~[uv_buf_t], cb: *u8) -> c_int {
+ let buf_ptr = vec::raw::to_ptr(*buf_in);
+ let buf_cnt = vec::len(*buf_in) as i32;
+ return rust_uv_write(req as *c_void, stream as *c_void, buf_ptr, buf_cnt, cb);
+ }
+ pub unsafe fn read_start(stream: *uv_stream_t, on_alloc: *u8, on_read: *u8) -> c_int {
+ return rust_uv_read_start(stream as *c_void, on_alloc, on_read);
+ }
+
+ 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 {
+ return rust_uv_last_error(loop_handle);
+ }
+
+ pub unsafe fn strerror(err: *uv_err_t) -> *c_char {
+ return rust_uv_strerror(err);
+ }
+ pub unsafe fn err_name(err: *uv_err_t) -> *c_char {
+ return rust_uv_err_name(err);
+ }
+
+ pub unsafe fn async_init(loop_handle: *c_void, async_handle: *uv_async_t, cb: *u8) -> c_int {
+ return rust_uv_async_init(loop_handle, async_handle, cb);
+ }
+
+ pub unsafe fn async_send(async_handle: *uv_async_t) {
+ return rust_uv_async_send(async_handle);
+ }
+ pub unsafe fn buf_init(input: *u8, len: uint) -> uv_buf_t {
+ let out_buf = uv_buf_t { base: ptr::null(), len: 0 as size_t };
+ let out_buf_ptr = ptr::addr_of(&out_buf);
+ rust_uv_buf_init(out_buf_ptr, input, len as size_t);
+ return out_buf;
+ }
+
+ pub unsafe fn timer_init(loop_ptr: *c_void, timer_ptr: *uv_timer_t) -> c_int {
+ return rust_uv_timer_init(loop_ptr, timer_ptr);
+ }
+ pub unsafe fn timer_start(timer_ptr: *uv_timer_t, cb: *u8, timeout: uint,
+ repeat: uint) -> c_int {
+ return rust_uv_timer_start(timer_ptr, cb, timeout as c_uint, repeat as c_uint);
+ }
+ pub unsafe fn timer_stop(timer_ptr: *uv_timer_t) -> c_int {
+ return rust_uv_timer_stop(timer_ptr);
+ }
+
+ pub unsafe fn malloc_ip4_addr(ip: &str, port: int) -> *sockaddr_in {
+ do str::as_c_str(ip) |ip_buf| {
+ rust_uv_ip4_addrp(ip_buf as *u8, port as libc::c_int)
+ }
+ }
+ pub unsafe fn malloc_ip6_addr(ip: &str, port: int) -> *sockaddr_in6 {
+ do str::as_c_str(ip) |ip_buf| {
+ rust_uv_ip6_addrp(ip_buf as *u8, port as libc::c_int)
+ }
+ }
+
+ pub unsafe fn free_ip4_addr(addr: *sockaddr_in) {
+ rust_uv_free_ip4_addr(addr);
+ }
+
+ pub unsafe fn free_ip6_addr(addr: *sockaddr_in6) {
+ rust_uv_free_ip6_addr(addr);
+ }
+
+ // data access helpers
+ pub unsafe fn get_loop_for_uv_handle<T>(handle: *T) -> *c_void {
+ return rust_uv_get_loop_for_uv_handle(handle as *c_void);
+ }
+ pub unsafe fn get_stream_handle_from_connect_req(connect: *uv_connect_t) -> *uv_stream_t {
+ return rust_uv_get_stream_handle_from_connect_req(connect);
+ }
+ pub unsafe fn get_stream_handle_from_write_req(write_req: *uv_write_t) -> *uv_stream_t {
+ return rust_uv_get_stream_handle_from_write_req(write_req);
+ }
+ pub unsafe fn get_data_for_uv_loop(loop_ptr: *c_void) -> *c_void {
+ rust_uv_get_data_for_uv_loop(loop_ptr)
+ }
+ pub unsafe fn set_data_for_uv_loop(loop_ptr: *c_void, data: *c_void) {
+ rust_uv_set_data_for_uv_loop(loop_ptr, data);
+ }
+ pub unsafe fn get_data_for_uv_handle<T>(handle: *T) -> *c_void {
+ return rust_uv_get_data_for_uv_handle(handle as *c_void);
+ }
+ pub unsafe fn set_data_for_uv_handle<T, U>(handle: *T, data: *U) {
+ rust_uv_set_data_for_uv_handle(handle as *c_void, data as *c_void);
+ }
+ pub unsafe fn get_data_for_req<T>(req: *T) -> *c_void {
+ return rust_uv_get_data_for_req(req as *c_void);
+ }
+ pub unsafe fn set_data_for_req<T, U>(req: *T, data: *U) {
+ rust_uv_set_data_for_req(req as *c_void, data as *c_void);
+ }
+ pub unsafe fn get_base_from_buf(buf: uv_buf_t) -> *u8 {
+ return rust_uv_get_base_from_buf(buf);
+ }
+ pub unsafe fn get_len_from_buf(buf: uv_buf_t) -> size_t {
+ return rust_uv_get_len_from_buf(buf);
+ }
+ pub unsafe fn malloc_buf_base_of(suggested_size: size_t) -> *u8 {
+ return rust_uv_malloc_buf_base_of(suggested_size);
+ }
+ pub unsafe fn free_base_of_buf(buf: uv_buf_t) {
+ rust_uv_free_base_of_buf(buf);
+ }
+
+ pub unsafe fn get_last_err_info(uv_loop: *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);
+ }
+
+ pub unsafe fn get_last_err_data(uv_loop: *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));
+ uv_err_data { err_name: err_name, err_msg: err_msg }
+ }
+
+ pub struct uv_err_data {
+ err_name: ~str,
+ err_msg: ~str,
+ }
+
+ extern {
+
+ fn rust_uv_handle_size(type_: uintptr_t) -> size_t;
+ fn rust_uv_req_size(type_: uintptr_t) -> size_t;
+ fn rust_uv_handle_type_max() -> uintptr_t;
+ fn rust_uv_req_type_max() -> uintptr_t;
+
+ // libuv public API
+ fn rust_uv_loop_new() -> *c_void;
+ fn rust_uv_loop_delete(lp: *c_void);
+ fn rust_uv_run(loop_handle: *c_void);
+ fn rust_uv_close(handle: *c_void, cb: *u8);
+ fn rust_uv_walk(loop_handle: *c_void, cb: *u8, arg: *c_void);
+
+ fn rust_uv_idle_new() -> *uv_idle_t;
+ fn rust_uv_idle_delete(handle: *uv_idle_t);
+ fn rust_uv_idle_init(loop_handle: *uv_loop_t, handle: *uv_idle_t) -> c_int;
+ fn rust_uv_idle_start(handle: *uv_idle_t, cb: uv_idle_cb) -> c_int;
+ fn rust_uv_idle_stop(handle: *uv_idle_t) -> c_int;
+
+ fn rust_uv_async_send(handle: *uv_async_t);
+ fn rust_uv_async_init(loop_handle: *c_void,
+ async_handle: *uv_async_t,
+ cb: *u8) -> c_int;
+ fn rust_uv_tcp_init(loop_handle: *c_void, handle_ptr: *uv_tcp_t) -> c_int;
+ // FIXME ref #2604 .. ?
+ 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;
+ // FIXME ref #2064
+ fn rust_uv_strerror(err: *uv_err_t) -> *c_char;
+ // FIXME ref #2064
+ fn rust_uv_err_name(err: *uv_err_t) -> *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);
+ fn rust_uv_free_ip6_addr(addr: *sockaddr_in6);
+ fn rust_uv_ip4_name(src: *sockaddr_in, dst: *u8, size: size_t) -> c_int;
+ fn rust_uv_ip6_name(src: *sockaddr_in6, dst: *u8, size: size_t) -> c_int;
+ fn rust_uv_ip4_port(src: *sockaddr_in) -> c_uint;
+ fn rust_uv_ip6_port(src: *sockaddr_in6) -> c_uint;
+ // 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) -> c_int;
+ // FIXME ref #2064
+ fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t, ++addr: *sockaddr_in) -> 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) -> c_int;
+ // FIXME ref #2064
+ fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t, ++addr: *sockaddr_in6) -> c_int;
+ fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t, ++name: *sockaddr_in) -> c_int;
+ fn rust_uv_tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t, ++name: *sockaddr_in6) ->c_int;
+ fn rust_uv_listen(stream: *c_void, backlog: c_int, cb: *u8) -> c_int;
+ fn rust_uv_accept(server: *c_void, client: *c_void) -> c_int;
+ fn rust_uv_write(req: *c_void,
+ stream: *c_void,
+ ++buf_in: *uv_buf_t,
+ buf_cnt: c_int,
+ cb: *u8) -> c_int;
+ fn rust_uv_read_start(stream: *c_void,
+ on_alloc: *u8,
+ on_read: *u8) -> c_int;
+ fn rust_uv_read_stop(stream: *c_void) -> c_int;
+ fn rust_uv_timer_init(loop_handle: *c_void,
+ timer_handle: *uv_timer_t) -> c_int;
+ fn rust_uv_timer_start(timer_handle: *uv_timer_t,
+ cb: *u8,
+ timeout: c_uint,
+ repeat: c_uint) -> c_int;
+ fn rust_uv_timer_stop(handle: *uv_timer_t) -> c_int;
+
+ fn rust_uv_malloc_buf_base_of(sug_size: 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: *c_void) -> *c_void;
+ fn rust_uv_get_data_for_uv_loop(loop_ptr: *c_void) -> *c_void;
+ fn rust_uv_set_data_for_uv_loop(loop_ptr: *c_void, data: *c_void);
+ fn rust_uv_get_data_for_uv_handle(handle: *c_void) -> *c_void;
+ fn rust_uv_set_data_for_uv_handle(handle: *c_void, data: *c_void);
+ fn rust_uv_get_data_for_req(req: *c_void) -> *c_void;
+ 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;
+ }
--- /dev/null
- use prelude::*;
+ // Copyright 2012 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.
+
+ /*!
+ * 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 core::libc::size_t;
+ use core::libc::c_void;
+ use core::prelude::*;
+ use core::ptr::to_unsafe_ptr;
+
+ pub type uv_handle_t = c_void;
+ pub type uv_loop_t = c_void;
+ pub type uv_idle_t = c_void;
+ pub type uv_idle_cb = *u8;
+
+ // libuv struct mappings
+ pub struct uv_ip4_addr {
+ ip: ~[u8],
+ port: int,
+ }
+ pub type uv_ip6_addr = uv_ip4_addr;
+
+ pub 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
+ }
+
+ pub type handle_type = libc::c_uint;
+
+ pub struct uv_handle_fields {
+ loop_handle: *libc::c_void,
+ type_: handle_type,
+ close_cb: *u8,
+ data: *libc::c_void,
+ }
+
+ // unix size: 8
+ pub struct 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..)
+ pub struct uv_stream_t {
+ fields: uv_handle_fields,
+ }
+
+ // 64bit unix size: 216
+ #[cfg(target_os="macos")]
+ pub struct 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: uv_tcp_t_osx_riders
+ }
+ #[cfg(target_arch="x86_64")]
+ pub struct uv_tcp_t_osx_riders {
+ a23: *u8,
+ }
+ #[cfg(target_arch="x86")]
+ #[cfg(target_arch="arm")]
+ pub struct uv_tcp_t_osx_riders {
+ a23: *u8,
+ a24: *u8, a25: *u8,
+ }
+ #[cfg(target_os="linux")]
+ #[cfg(target_os="freebsd")]
+ #[cfg(target_os="android")]
+ pub struct 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: uv_tcp_t_32bit_unix_riders,
+ }
+ // 32bit unix size: 328 (164)
+ #[cfg(target_arch="x86_64")]
+ pub struct uv_tcp_t_32bit_unix_riders {
+ a29: *u8,
+ }
+ #[cfg(target_arch="x86")]
+ #[cfg(target_arch="arm")]
+ #[cfg(target_arch="mips")]
+ pub struct uv_tcp_t_32bit_unix_riders {
+ a29: *u8, a30: *u8, a31: *u8,
+ }
+
+ // 32bit win32 size: 240 (120)
+ #[cfg(windows)]
+ pub struct 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: 64
+ #[cfg(unix)]
+ pub struct uv_connect_t {
+ a00: *u8, a01: *u8, a02: *u8, a03: *u8,
+ a04: *u8, a05: *u8, a06: *u8, a07: *u8
+ }
+ // win32 size: 88 (44)
+ #[cfg(windows)]
+ pub struct 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
+ pub struct uv_buf_t {
+ base: *u8,
+ len: libc::size_t,
+ }
+ // no gen stub method.. should create
+ // it via uv::direct::buf_init()
+
+ // unix size: 160
+ #[cfg(unix)]
+ pub struct 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")]
+ pub struct uv_write_t_32bit_unix_riders {
+ a13: *u8, a14: *u8, a15: *u8
+ }
+ #[cfg(target_arch="x86")]
+ #[cfg(target_arch="arm")]
+ #[cfg(target_arch="mips")]
+ pub struct uv_write_t_32bit_unix_riders {
+ a13: *u8, a14: *u8, a15: *u8,
+ a16: *u8,
+ }
+ // win32 size: 136 (68)
+ #[cfg(windows)]
+ pub struct 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: 96
+ // 32bit unix size: 152 (76)
+ #[cfg(unix)]
+ pub struct uv_async_t {
+ fields: uv_handle_fields,
+ a00: *u8, a01: *u8, a02: *u8, a03: *u8,
+ a04: *u8, a05: *u8, a06: *u8,
+ a07: uv_async_t_32bit_unix_riders,
+ }
+ #[cfg(target_arch="x86_64")]
+ pub struct uv_async_t_32bit_unix_riders {
+ a10: *u8,
+ }
+ #[cfg(target_arch="x86")]
+ #[cfg(target_arch="arm")]
+ #[cfg(target_arch="mips")]
+ pub struct uv_async_t_32bit_unix_riders {
+ a10: *u8,
+ }
+ // win32 size 132 (68)
+ #[cfg(windows)]
+ pub struct 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: 120
+ // 32bit unix size: 84
+ #[cfg(unix)]
+ pub struct 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")]
+ pub struct uv_timer_t_32bit_unix_riders {
+ a10: *u8,
+ }
+ #[cfg(target_arch="x86")]
+ #[cfg(target_arch="arm")]
+ #[cfg(target_arch="mips")]
+ pub struct uv_timer_t_32bit_unix_riders {
+ a10: *u8, a11: *u8, a12: *u8
+ }
+ // win32 size: 64
+ #[cfg(windows)]
+ pub struct 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
+ pub struct sockaddr_in {
+ sin_family: u16,
+ sin_port: u16,
+ sin_addr: u32, // in_addr: this is an opaque, per-platform struct
+ 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")]
+ pub struct sockaddr_in6 {
+ a0: *u8, a1: *u8,
+ a2: *u8, a3: *u8,
+ }
+ #[cfg(target_arch="x86")]
+ #[cfg(target_arch="arm")]
+ #[cfg(target_arch="mips")]
+ pub struct 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?
+ pub type addr_in = addr_in_impl::addr_in;
+ #[cfg(unix)]
+ pub mod addr_in_impl {
+ #[cfg(target_arch="x86_64")]
+ pub struct addr_in {
+ a0: *u8, a1: *u8,
+ a2: *u8, a3: *u8,
+ }
+ #[cfg(target_arch="x86")]
+ #[cfg(target_arch="arm")]
+ #[cfg(target_arch="mips")]
+ pub struct addr_in {
+ a0: *u8, a1: *u8,
+ a2: *u8, a3: *u8,
+ a4: *u8, a5: *u8,
+ a6: *u8, a7: *u8,
+ }
+ }
+ #[cfg(windows)]
+ pub mod addr_in_impl {
+ pub struct addr_in {
+ a0: *u8, a1: *u8,
+ a2: *u8, a3: *u8,
+ }
+ }
+
+ // unix size: 48, 32bit: 32
+ pub type addrinfo = addrinfo_impl::addrinfo;
+ #[cfg(target_os="linux")]
+ #[cfg(target_os="android")]
+ pub mod addrinfo_impl {
+ #[cfg(target_arch="x86_64")]
+ pub struct addrinfo {
+ a00: *u8, a01: *u8, a02: *u8, a03: *u8,
+ a04: *u8, a05: *u8,
+ }
+ #[cfg(target_arch="x86")]
+ #[cfg(target_arch="arm")]
+ #[cfg(target_arch="mips")]
+ pub struct 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")]
+ pub mod addrinfo_impl {
+ pub struct addrinfo {
+ a00: *u8, a01: *u8, a02: *u8, a03: *u8,
+ a04: *u8, a05: *u8,
+ }
+ }
+ #[cfg(windows)]
+ pub mod addrinfo_impl {
+ pub struct addrinfo {
+ a00: *u8, a01: *u8, a02: *u8, a03: *u8,
+ a04: *u8, a05: *u8,
+ }
+ }
+
+ // unix size: 72
+ pub struct uv_getaddrinfo_t {
+ 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
+ }
+
+ pub mod uv_ll_struct_stubgen {
+
+ use core::ptr;
+
+ use super::{
+ uv_async_t,
+ uv_connect_t,
+ uv_getaddrinfo_t,
+ uv_handle_fields,
+ uv_tcp_t,
+ uv_timer_t,
+ uv_write_t,
+ };
+
+ #[cfg(target_os = "linux")]
+ #[cfg(target_os = "android")]
+ #[cfg(target_os = "macos")]
+ #[cfg(target_os = "freebsd")]
+ use super::{
+ uv_async_t_32bit_unix_riders,
+ uv_tcp_t_32bit_unix_riders,
+ uv_timer_t_32bit_unix_riders,
+ uv_write_t_32bit_unix_riders,
+ };
+
+ pub fn gen_stub_uv_tcp_t() -> uv_tcp_t {
+ return gen_stub_os();
+ #[cfg(target_os = "linux")]
+ #[cfg(target_os = "android")]
+ #[cfg(target_os = "freebsd")]
+ pub fn gen_stub_os() -> uv_tcp_t {
+ return gen_stub_arch();
+ #[cfg(target_arch="x86_64")]
+ pub fn gen_stub_arch() -> uv_tcp_t {
+ uv_tcp_t {
+ fields: uv_handle_fields {
+ loop_handle: ptr::null(), type_: 0u32,
+ close_cb: ptr::null(),
+ 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: uv_tcp_t_32bit_unix_riders { a29: 0 as *u8 },
+ }
+ }
+ #[cfg(target_arch="x86")]
+ #[cfg(target_arch="arm")]
+ #[cfg(target_arch="mips")]
+ pub fn gen_stub_arch() -> uv_tcp_t {
+ uv_tcp_t {
+ fields: uv_handle_fields {
+ loop_handle: ptr::null(), type_: 0u32,
+ close_cb: ptr::null(),
+ 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: uv_tcp_t_32bit_unix_riders {
+ a29: 0 as *u8, a30: 0 as *u8, a31: 0 as *u8,
+ },
+ }
+ }
+ }
+ #[cfg(windows)]
+ pub fn gen_stub_os() -> uv_tcp_t {
+ uv_tcp_t {
+ fields: uv_handle_fields {
+ loop_handle: ptr::null(), type_: 0u32,
+ close_cb: ptr::null(),
+ 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(target_os = "macos")]
+ pub fn gen_stub_os() -> uv_tcp_t {
+ use super::uv_tcp_t_osx_riders;
+
+ return gen_stub_arch();
+
+ #[cfg(target_arch = "x86_64")]
+ fn gen_stub_arch() -> uv_tcp_t {
+ uv_tcp_t {
+ fields: uv_handle_fields {
+ loop_handle: ptr::null(), type_: 0u32,
+ close_cb: ptr::null(),
+ 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: uv_tcp_t_osx_riders {
+ a23: 0 as *u8,
+ }
+ }
+ }
+
+ #[cfg(target_arch = "x86")]
+ #[cfg(target_arch = "arm")]
+ fn gen_stub_arch() -> uv_tcp_t {
+ uv_tcp_t {
+ fields: uv_handle_fields {
+ loop_handle: ptr::null(), type_: 0u32,
+ close_cb: ptr::null(),
+ 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: uv_tcp_t_osx_riders {
+ a23: 0 as *u8,
+ a24: 0 as *u8, a25: 0 as *u8,
+ }
+ }
+ }
+ }
+ }
+ #[cfg(unix)]
+ pub fn gen_stub_uv_connect_t() -> uv_connect_t {
+ uv_connect_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
+ }
+ }
+ #[cfg(windows)]
+ pub fn gen_stub_uv_connect_t() -> uv_connect_t {
+ uv_connect_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, a09: 0 as *u8, a10: 0 as *u8,
+ }
+ }
+ #[cfg(unix)]
+ pub fn gen_stub_uv_async_t() -> uv_async_t {
+ return gen_stub_arch();
+ #[cfg(target_arch = "x86_64")]
+ pub fn gen_stub_arch() -> uv_async_t {
+ uv_async_t {
+ fields: uv_handle_fields {
+ loop_handle: ptr::null(), type_: 0u32,
+ close_cb: ptr::null(),
+ 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: uv_async_t_32bit_unix_riders { a10: 0 as *u8 },
+ }
+ }
+ #[cfg(target_arch = "x86")]
+ #[cfg(target_arch="arm")]
+ #[cfg(target_arch="mips")]
+ pub fn gen_stub_arch() -> uv_async_t {
+ uv_async_t {
+ fields: uv_handle_fields {
+ loop_handle: ptr::null(), type_: 0u32,
+ close_cb: ptr::null(),
+ 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: uv_async_t_32bit_unix_riders {
+ a10: 0 as *u8,
+ }
+ }
+ }
+ }
+ #[cfg(windows)]
+ pub fn gen_stub_uv_async_t() -> uv_async_t {
+ uv_async_t {
+ fields: uv_handle_fields {
+ loop_handle: ptr::null(), type_: 0u32,
+ close_cb: ptr::null(),
+ 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)]
+ pub fn gen_stub_uv_timer_t() -> uv_timer_t {
+ return gen_stub_arch();
+ #[cfg(target_arch = "x86_64")]
+ pub fn gen_stub_arch() -> uv_timer_t {
+ uv_timer_t {
+ fields: uv_handle_fields {
+ loop_handle: ptr::null(), type_: 0u32,
+ close_cb: ptr::null(),
+ 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: uv_timer_t_32bit_unix_riders {
+ a10: 0 as *u8
+ },
+ }
+ }
+ #[cfg(target_arch = "x86")]
+ #[cfg(target_arch="arm")]
+ #[cfg(target_arch="mips")]
+ pub fn gen_stub_arch() -> uv_timer_t {
+ uv_timer_t {
+ fields: uv_handle_fields {
+ loop_handle: ptr::null(), type_: 0u32,
+ close_cb: ptr::null(),
+ 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: uv_timer_t_32bit_unix_riders {
+ a10: 0 as *u8, a11: 0 as *u8,
+ a12: 0 as *u8,
+ },
+ }
+ }
+ }
+ #[cfg(windows)]
+ pub fn gen_stub_uv_timer_t() -> uv_timer_t {
+ uv_timer_t {
+ fields: uv_handle_fields {
+ loop_handle: ptr::null(), type_: 0u32,
+ close_cb: ptr::null(),
+ 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)]
+ pub fn gen_stub_uv_write_t() -> uv_write_t {
+ return gen_stub_arch();
+ #[cfg(target_arch="x86_64")]
+ pub fn gen_stub_arch() -> uv_write_t {
+ uv_write_t {
+ fields: uv_handle_fields {
+ loop_handle: ptr::null(), type_: 0u32,
+ close_cb: ptr::null(),
+ 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: uv_write_t_32bit_unix_riders { a13: 0 as *u8,
+ a14: 0 as *u8,
+ a15: 0 as *u8},
+ }
+ }
+ #[cfg(target_arch="x86")]
+ #[cfg(target_arch="arm")]
+ #[cfg(target_arch="mips")]
+ pub fn gen_stub_arch() -> uv_write_t {
+ uv_write_t {
+ fields: uv_handle_fields {
+ loop_handle: ptr::null(), type_: 0u32,
+ close_cb: ptr::null(),
+ 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: uv_write_t_32bit_unix_riders {
+ a13: 0 as *u8,
+ a14: 0 as *u8,
+ a15: 0 as *u8,
+ a16: 0 as *u8,
+ }
+ }
+ }
+ }
+ #[cfg(windows)]
+ pub fn gen_stub_uv_write_t() -> uv_write_t {
+ uv_write_t {
+ fields: uv_handle_fields {
+ loop_handle: ptr::null(), type_: 0u32,
+ close_cb: ptr::null(),
+ 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
+ }
+ }
+ pub fn gen_stub_uv_getaddrinfo_t() -> 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, a09: 0 as *u8,
+ a10: 1 as *u8, a11: 1 as *u8, a12: 1 as *u8, a13: 1 as *u8,
+ a14: 1 as *u8, a15: 1 as *u8
+ }
+ }
+ }
+
+ #[nolink]
+ extern mod rustrt {
+
+ // libuv public API
+ unsafe fn rust_uv_loop_new() -> *libc::c_void;
+ unsafe fn rust_uv_loop_delete(lp: *libc::c_void);
+ unsafe fn rust_uv_run(loop_handle: *libc::c_void);
+ unsafe fn rust_uv_close(handle: *libc::c_void, cb: *u8);
+ unsafe fn rust_uv_walk(loop_handle: *libc::c_void, cb: *u8,
+ arg: *libc::c_void);
+
+ unsafe fn rust_uv_idle_new() -> *uv_idle_t;
+ unsafe fn rust_uv_idle_delete(handle: *uv_idle_t);
+ unsafe fn rust_uv_idle_init(loop_handle: *uv_loop_t,
+ handle: *uv_idle_t) -> libc::c_int;
+ unsafe fn rust_uv_idle_start(handle: *uv_idle_t,
+ cb: uv_idle_cb) -> libc::c_int;
+ unsafe fn rust_uv_idle_stop(handle: *uv_idle_t) -> libc::c_int;
+
+ unsafe fn rust_uv_async_send(handle: *uv_async_t);
+ unsafe fn rust_uv_async_init(loop_handle: *libc::c_void,
+ async_handle: *uv_async_t,
+ cb: *u8) -> libc::c_int;
+ unsafe fn rust_uv_tcp_init(
+ loop_handle: *libc::c_void,
+ handle_ptr: *uv_tcp_t) -> libc::c_int;
+ // FIXME ref #2604 .. ?
+ unsafe fn rust_uv_buf_init(out_buf: *uv_buf_t, base: *u8,
+ len: libc::size_t);
+ unsafe fn rust_uv_last_error(loop_handle: *libc::c_void) -> uv_err_t;
+ // FIXME ref #2064
+ unsafe fn rust_uv_strerror(err: *uv_err_t) -> *libc::c_char;
+ // FIXME ref #2064
+ unsafe fn rust_uv_err_name(err: *uv_err_t) -> *libc::c_char;
+ unsafe fn rust_uv_ip4_addr(ip: *u8, port: libc::c_int)
+ -> sockaddr_in;
+ unsafe fn rust_uv_ip6_addr(ip: *u8, port: libc::c_int)
+ -> sockaddr_in6;
+ unsafe fn rust_uv_ip4_name(src: *sockaddr_in,
+ dst: *u8,
+ size: libc::size_t)
+ -> libc::c_int;
+ unsafe fn rust_uv_ip6_name(src: *sockaddr_in6,
+ dst: *u8,
+ size: libc::size_t)
+ -> libc::c_int;
+ unsafe fn rust_uv_ip4_port(src: *sockaddr_in) -> libc::c_uint;
+ unsafe fn rust_uv_ip6_port(src: *sockaddr_in6) -> libc::c_uint;
+ // FIXME ref #2064
+ unsafe 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
+ unsafe fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t,
+ ++addr: *sockaddr_in) -> libc::c_int;
+ // FIXME ref #2064
+ unsafe 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
+ unsafe fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t,
+ ++addr: *sockaddr_in6) -> libc::c_int;
+ unsafe fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t,
+ ++name: *sockaddr_in) -> libc::c_int;
+ unsafe fn rust_uv_tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t,
+ ++name: *sockaddr_in6) ->libc::c_int;
+ unsafe fn rust_uv_listen(stream: *libc::c_void,
+ backlog: libc::c_int,
+ cb: *u8) -> libc::c_int;
+ unsafe fn rust_uv_accept(server: *libc::c_void, client: *libc::c_void)
+ -> libc::c_int;
+ unsafe 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;
+ unsafe fn rust_uv_read_start(stream: *libc::c_void,
+ on_alloc: *u8,
+ on_read: *u8)
+ -> libc::c_int;
+ unsafe fn rust_uv_read_stop(stream: *libc::c_void) -> libc::c_int;
+ unsafe fn rust_uv_timer_init(loop_handle: *libc::c_void,
+ timer_handle: *uv_timer_t)
+ -> libc::c_int;
+ unsafe fn rust_uv_timer_start(
+ timer_handle: *uv_timer_t,
+ cb: *u8,
+ timeout: libc::c_uint,
+ repeat: libc::c_uint) -> libc::c_int;
+ unsafe fn rust_uv_timer_stop(handle: *uv_timer_t) -> libc::c_int;
+
+ unsafe 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;
+ unsafe fn rust_uv_freeaddrinfo(res: *addrinfo);
+
+ // data accessors/helpers for rust-mapped uv structs
+ unsafe fn rust_uv_helper_get_INADDR_NONE() -> u32;
+ unsafe fn rust_uv_is_ipv4_addrinfo(input: *addrinfo) -> bool;
+ unsafe fn rust_uv_is_ipv6_addrinfo(input: *addrinfo) -> bool;
+ unsafe fn rust_uv_get_next_addrinfo(input: *addrinfo) -> *addrinfo;
+ unsafe fn rust_uv_addrinfo_as_sockaddr_in(input: *addrinfo)
+ -> *sockaddr_in;
+ unsafe fn rust_uv_addrinfo_as_sockaddr_in6(input: *addrinfo)
+ -> *sockaddr_in6;
+ unsafe fn rust_uv_malloc_buf_base_of(sug_size: libc::size_t) -> *u8;
+ unsafe fn rust_uv_free_base_of_buf(++buf: uv_buf_t);
+ unsafe fn rust_uv_get_stream_handle_from_connect_req(
+ connect_req: *uv_connect_t)
+ -> *uv_stream_t;
+ unsafe fn rust_uv_get_stream_handle_from_write_req(
+ write_req: *uv_write_t)
+ -> *uv_stream_t;
+ unsafe fn rust_uv_get_loop_for_uv_handle(handle: *libc::c_void)
+ -> *libc::c_void;
+ unsafe fn rust_uv_get_data_for_uv_loop(loop_ptr: *libc::c_void)
+ -> *libc::c_void;
+ unsafe fn rust_uv_set_data_for_uv_loop(loop_ptr: *libc::c_void,
+ data: *libc::c_void);
+ unsafe fn rust_uv_get_data_for_uv_handle(handle: *libc::c_void)
+ -> *libc::c_void;
+ unsafe fn rust_uv_set_data_for_uv_handle(handle: *libc::c_void,
+ data: *libc::c_void);
+ unsafe fn rust_uv_get_data_for_req(req: *libc::c_void)
+ -> *libc::c_void;
+ unsafe fn rust_uv_set_data_for_req(req: *libc::c_void,
+ data: *libc::c_void);
+ unsafe fn rust_uv_get_base_from_buf(++buf: uv_buf_t) -> *u8;
+ unsafe fn rust_uv_get_len_from_buf(++buf: uv_buf_t) -> libc::size_t;
+
+ // sizeof testing helpers
+ unsafe fn rust_uv_helper_uv_tcp_t_size() -> libc::c_uint;
+ unsafe fn rust_uv_helper_uv_connect_t_size() -> libc::c_uint;
+ unsafe fn rust_uv_helper_uv_buf_t_size() -> libc::c_uint;
+ unsafe fn rust_uv_helper_uv_write_t_size() -> libc::c_uint;
+ unsafe fn rust_uv_helper_uv_err_t_size() -> libc::c_uint;
+ unsafe fn rust_uv_helper_sockaddr_in_size() -> libc::c_uint;
+ unsafe fn rust_uv_helper_sockaddr_in6_size() -> libc::c_uint;
+ unsafe fn rust_uv_helper_uv_async_t_size() -> libc::c_uint;
+ unsafe fn rust_uv_helper_uv_timer_t_size() -> libc::c_uint;
+ unsafe fn rust_uv_helper_uv_getaddrinfo_t_size() -> libc::c_uint;
+ unsafe fn rust_uv_helper_addrinfo_size() -> libc::c_uint;
+ unsafe fn rust_uv_helper_addr_in_size() -> libc::c_uint;
+ }
+
+ pub unsafe fn loop_new() -> *libc::c_void {
+ return rustrt::rust_uv_loop_new();
+ }
+
+ pub unsafe fn loop_delete(loop_handle: *libc::c_void) {
+ rustrt::rust_uv_loop_delete(loop_handle);
+ }
+
+ pub unsafe fn run(loop_handle: *libc::c_void) {
+ rustrt::rust_uv_run(loop_handle);
+ }
+
+ pub unsafe fn close<T>(handle: *T, cb: *u8) {
+ rustrt::rust_uv_close(handle as *libc::c_void, cb);
+ }
+
+ pub unsafe fn walk(loop_handle: *libc::c_void, cb: *u8, arg: *libc::c_void) {
+ rustrt::rust_uv_walk(loop_handle, cb, arg);
+ }
+
+ pub unsafe fn idle_new() -> *uv_idle_t {
+ rustrt::rust_uv_idle_new()
+ }
+
+ pub unsafe fn idle_delete(handle: *uv_idle_t) {
+ rustrt::rust_uv_idle_delete(handle)
+ }
+
+ pub unsafe fn idle_init(loop_handle: *uv_loop_t,
+ handle: *uv_idle_t) -> libc::c_int {
+ rustrt::rust_uv_idle_init(loop_handle, handle)
+ }
+
+ pub unsafe fn idle_start(handle: *uv_idle_t, cb: uv_idle_cb) -> libc::c_int {
+ rustrt::rust_uv_idle_start(handle, cb)
+ }
+
+ pub unsafe fn idle_stop(handle: *uv_idle_t) -> libc::c_int {
+ rustrt::rust_uv_idle_stop(handle)
+ }
+
+ pub 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
+ pub 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 {
+ return rustrt::rust_uv_tcp_connect(connect_ptr, tcp_handle_ptr,
+ after_connect_cb, addr_ptr);
+ }
+ // FIXME ref #2064
+ pub 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
+ pub 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
+ pub 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);
+ }
+
+ pub unsafe fn tcp_getpeername(tcp_handle_ptr: *uv_tcp_t,
+ name: *sockaddr_in) -> libc::c_int {
+ return rustrt::rust_uv_tcp_getpeername(tcp_handle_ptr, name);
+ }
+
+ pub unsafe fn tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t,
+ name: *sockaddr_in6) ->libc::c_int {
+ return rustrt::rust_uv_tcp_getpeername6(tcp_handle_ptr, name);
+ }
+
+ pub 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);
+ }
+
+ pub 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);
+ }
+
+ pub 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);
+ }
+ pub 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);
+ }
+
+ pub unsafe fn read_stop(stream: *uv_stream_t) -> libc::c_int {
+ return rustrt::rust_uv_read_stop(stream as *libc::c_void);
+ }
+
+ pub unsafe fn last_error(loop_handle: *libc::c_void) -> uv_err_t {
+ return rustrt::rust_uv_last_error(loop_handle);
+ }
+
+ pub unsafe fn strerror(err: *uv_err_t) -> *libc::c_char {
+ return rustrt::rust_uv_strerror(err);
+ }
+ pub unsafe fn err_name(err: *uv_err_t) -> *libc::c_char {
+ return rustrt::rust_uv_err_name(err);
+ }
+
+ pub 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);
+ }
+
+ pub unsafe fn async_send(async_handle: *uv_async_t) {
+ return rustrt::rust_uv_async_send(async_handle);
+ }
+ pub unsafe fn buf_init(input: *u8, len: uint) -> uv_buf_t {
+ let out_buf = uv_buf_t { base: ptr::null(), len: 0 as libc::size_t };
+ let out_buf_ptr = ptr::addr_of(&out_buf);
+ rustrt::rust_uv_buf_init(out_buf_ptr, input, len as size_t);
+ return out_buf;
+ }
+ pub 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)
+ }
+ }
+ pub 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)
+ }
+ }
+ pub 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)
+ }
+ }
+ pub 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);
+ 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),
+ _ => ~""
+ }
+ }
+ }
+ pub unsafe fn ip4_port(src: &sockaddr_in) -> uint {
+ rustrt::rust_uv_ip4_port(to_unsafe_ptr(src)) as uint
+ }
+ pub unsafe fn ip6_port(src: &sockaddr_in6) -> uint {
+ rustrt::rust_uv_ip6_port(to_unsafe_ptr(src)) as uint
+ }
+
+ pub 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);
+ }
+ pub 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);
+ }
+ pub unsafe fn timer_stop(timer_ptr: *uv_timer_t) -> libc::c_int {
+ return rustrt::rust_uv_timer_stop(timer_ptr);
+ }
+ pub 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)
+ }
+ pub unsafe fn freeaddrinfo(res: *addrinfo) {
+ rustrt::rust_uv_freeaddrinfo(res);
+ }
+
+ // libuv struct initializers
+ pub unsafe fn tcp_t() -> uv_tcp_t {
+ return uv_ll_struct_stubgen::gen_stub_uv_tcp_t();
+ }
+ pub unsafe fn connect_t() -> uv_connect_t {
+ return uv_ll_struct_stubgen::gen_stub_uv_connect_t();
+ }
+ pub unsafe fn write_t() -> uv_write_t {
+ return uv_ll_struct_stubgen::gen_stub_uv_write_t();
+ }
+ pub unsafe fn async_t() -> uv_async_t {
+ return uv_ll_struct_stubgen::gen_stub_uv_async_t();
+ }
+ pub unsafe fn timer_t() -> uv_timer_t {
+ return uv_ll_struct_stubgen::gen_stub_uv_timer_t();
+ }
+ pub unsafe fn getaddrinfo_t() -> uv_getaddrinfo_t {
+ return uv_ll_struct_stubgen::gen_stub_uv_getaddrinfo_t();
+ }
+
+ // data access helpers
+ pub 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);
+ }
+ pub 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);
+ }
+ pub 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);
+ }
+ pub 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)
+ }
+ pub 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);
+ }
+ pub 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);
+ }
+ pub 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);
+ }
+ pub 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);
+ }
+ pub 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);
+ }
+ pub unsafe fn get_base_from_buf(buf: uv_buf_t) -> *u8 {
+ return rustrt::rust_uv_get_base_from_buf(buf);
+ }
+ pub unsafe fn get_len_from_buf(buf: uv_buf_t) -> libc::size_t {
+ return rustrt::rust_uv_get_len_from_buf(buf);
+ }
+ pub unsafe fn malloc_buf_base_of(suggested_size: libc::size_t)
+ -> *u8 {
+ return rustrt::rust_uv_malloc_buf_base_of(suggested_size);
+ }
+ pub unsafe fn free_base_of_buf(buf: uv_buf_t) {
+ rustrt::rust_uv_free_base_of_buf(buf);
+ }
+
+ pub 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);
+ }
+
+ pub 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));
+ uv_err_data { err_name: err_name, err_msg: err_msg }
+ }
+
+ pub struct uv_err_data {
+ err_name: ~str,
+ err_msg: ~str,
+ }
+
+ pub unsafe fn is_ipv4_addrinfo(input: *addrinfo) -> bool {
+ rustrt::rust_uv_is_ipv4_addrinfo(input)
+ }
+ pub unsafe fn is_ipv6_addrinfo(input: *addrinfo) -> bool {
+ rustrt::rust_uv_is_ipv6_addrinfo(input)
+ }
+ pub unsafe fn get_INADDR_NONE() -> u32 {
+ rustrt::rust_uv_helper_get_INADDR_NONE()
+ }
+ pub unsafe fn get_next_addrinfo(input: *addrinfo) -> *addrinfo {
+ rustrt::rust_uv_get_next_addrinfo(input)
+ }
+ pub unsafe fn addrinfo_as_sockaddr_in(input: *addrinfo) -> *sockaddr_in {
+ rustrt::rust_uv_addrinfo_as_sockaddr_in(input)
+ }
+ pub unsafe fn addrinfo_as_sockaddr_in6(input: *addrinfo) -> *sockaddr_in6 {
+ rustrt::rust_uv_addrinfo_as_sockaddr_in6(input)
+ }
+
+ #[cfg(test)]
+ pub mod test {
- use comm::{SharedChan, stream, GenericChan, GenericPort};
++ use core::prelude::*;
++ use core::comm::{SharedChan, stream, GenericChan, GenericPort};
+ use super::*;
- log(debug, fmt!("after uv_close! handle ptr: %?",
- handle));
+
+ enum tcp_read_data {
+ tcp_read_eof,
+ tcp_read_more(~[u8]),
+ tcp_read_error
+ }
+
+ struct request_wrapper {
+ write_req: *uv_write_t,
+ req_buf: *~[uv_buf_t],
+ read_chan: SharedChan<~str>,
+ }
+
+ extern fn after_close_cb(handle: *libc::c_void) {
- log(debug, ~"on_alloc_cb!");
++ debug!("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, fmt!("on_alloc_cb h: %? char_ptr: %u sugsize: %u",
++ debug!(~"on_alloc_cb!");
+ let char_ptr = malloc_buf_base_of(suggested_size);
- suggested_size as uint));
++ debug!("on_alloc_cb h: %? char_ptr: %u sugsize: %u",
+ handle,
+ char_ptr as uint,
- log(debug, fmt!("CLIENT entering on_read_cb nred: %d",
- nread));
++ 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 read: data! nread: %d", nread));
++ debug!("CLIENT entering on_read_cb nred: %d",
++ nread);
+ if (nread > 0) {
+ // we have data
- log(debug, ~"read: eof!");
++ debug!("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 bytes = vec::from_buf(buf_base, nread as uint);
+ let read_chan = (*client_data).read_chan.clone();
+ let msg_from_server = str::from_bytes(bytes);
+ read_chan.send(msg_from_server);
+ close(stream as *libc::c_void, after_close_cb)
+ }
+ else if (nread == -1) {
+ // err .. possibly EOF
- log(debug, ~"read: do nothing!");
++ debug!(~"read: eof!");
+ }
+ else {
+ // nread == 0 .. do nothing, just free buf as below
- log(debug, ~"CLIENT exiting on_read_cb");
++ debug!(~"read: do nothing!");
+ }
+ // when we're done
+ free_base_of_buf(buf);
- log(debug,
- fmt!("CLIENT beginning on_write_complete_cb status: %d",
- status as int));
++ 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 on_write_complete_cb: tcp:%d write_handle:%d",
- stream as int, write_req as int));
++ debug!(
++ "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 ending on_write_complete_cb .. status: %d",
- result as int));
++ debug!(
++ "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!("beginning on_connect_cb .. status: %d",
- status as int));
++ debug!("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, ~"on_connect_cb: in status=0 if..");
++ debug!("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, fmt!("on_connect_cb: tcp: %d write_hdl: %d",
- stream as int, write_handle as int));
++ 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: write() status: %d",
- write_result as int));
++ debug!("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, err_msg);
++ debug!("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, ~"finishing on_connect_cb");
++ debug!(err_msg);
+ fail_unless!(false);
+ }
- log(debug, fmt!("req_msg ptr: %u", req_msg_ptr as uint));
++ debug!(~"finishing on_connect_cb");
+ }
+ }
+
+ fn impl_uv_tcp_request(ip: &str, port: int, req_str: &str,
+ client_chan: SharedChan<~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!("tcp req: tcp stream: %d write_handle: %d",
++ debug!("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);
- write_handle_ptr as int));
++ debug!("tcp req: tcp stream: %d write_handle: %d",
+ tcp_handle_ptr as int,
- log(debug, ~"sucessful tcp_init_result");
++ write_handle_ptr as int);
+ let client_data = request_wrapper {
+ write_req: 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, ~"building addr...");
++ debug!(~"sucessful tcp_init_result");
+
- log(debug, fmt!("after build addr in rust. port: %u",
- addr.sin_port as uint));
++ debug!(~"building addr...");
+ let addr = ip4_addr(ip, port);
+ // FIXME ref #2064
+ let addr_ptr = ptr::addr_of(&addr);
- log(debug, fmt!("b4 call tcp_connect connect cb: %u ",
- on_connect_cb as uint));
++ debug!("after build addr in rust. port: %u",
++ addr.sin_port as uint);
+
+ // this should set up the connection request..
- log(debug, ~"before run tcp req loop");
++ debug!("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, ~"after run tcp req loop");
++ debug!(~"before run tcp req loop");
+ run(test_loop);
- log(debug, ~"tcp_connect() failure");
++ debug!(~"after run tcp req loop");
+ }
+ else {
- log(debug, ~"tcp_init() failure");
++ debug!(~"tcp_connect() failure");
+ fail_unless!(false);
+ }
+ }
+ else {
- log(debug, fmt!("SERVER server stream closed, should exit. h: %?",
- handle));
++ debug!(~"tcp_init() failure");
+ fail_unless!(false);
+ }
+ loop_delete(test_loop);
+ }
+ }
+
+ extern fn server_after_close_cb(handle: *libc::c_void) {
+ unsafe {
- log(debug,
- ~"SERVER: closed client stream, now closing server stream");
++ debug!("SERVER server stream closed, should exit. h: %?",
++ handle);
+ }
+ }
+
+ extern fn client_stream_after_close_cb(handle: *libc::c_void) {
+ unsafe {
- log(debug, ~"SERVER: resp sent... closing client stream");
++ 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, fmt!("SERVER read: data! nread: %d", nread));
++ 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 buf base: %u, len: %u, nread: %d",
++ debug!("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;
- nread));
++ debug!("SERVER buf base: %u, len: %u, nread: %d",
+ buf_base as uint,
+ buf_len as uint,
- log(debug, ~"SERVER: client req contains kill_msg!");
- log(debug, ~"SERVER: sending response to client");
++ nread);
+ let bytes = vec::from_buf(buf_base, nread as uint);
+ 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 = copy (*client_data).server_kill_msg;
+ let write_req = (*client_data).server_write_req;
+ if str::contains(request_str, server_kill_msg) {
- log(debug, fmt!("SERVER: resp write result: %d",
- write_result as int));
++ debug!(~"SERVER: client req contains kill_msg!");
++ debug!(~"SERVER: sending response to client");
+ read_stop(client_stream_ptr);
+ let server_chan = (*client_data).server_chan.clone();
+ server_chan.send(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, ~"bad result for server resp write()");
- log(debug, get_last_err_info(
++ debug!("SERVER: resp write result: %d",
++ write_result as int);
+ if (write_result != 0i32) {
- log(debug, ~"SERVER: client req !contain kill_msg!");
++ debug!(~"bad result for server resp write()");
++ debug!(get_last_err_info(
+ get_loop_for_uv_handle(client_stream_ptr
+ as *libc::c_void)));
+ fail_unless!(false);
+ }
+ }
+ else {
- log(debug, ~"read: eof!");
++ debug!(~"SERVER: client req !contain kill_msg!");
+ }
+ }
+ else if (nread == -1) {
+ // err .. possibly EOF
- log(debug, ~"read: do nothing!");
++ debug!(~"read: eof!");
+ }
+ else {
+ // nread == 0 .. do nothing, just free buf as below
- log(debug, ~"SERVER exiting on_read_cb");
++ debug!(~"read: do nothing!");
+ }
+ // when we're done
+ free_base_of_buf(buf);
- log(debug, ~"client connecting!");
++ debug!(~"SERVER exiting on_read_cb");
+ }
+ }
+
+ extern fn server_connection_cb(server_stream_ptr:
+ *uv_stream_t,
+ status: libc::c_int) {
+ unsafe {
- log(debug, fmt!("server_connect_cb: non-zero status: %?",
- err_msg));
++ 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, ~"successfully initialized client stream");
++ debug!("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, ~"successful server read start");
++ 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, fmt!("server_connection_cb: bad read:%d",
- read_result as int));
++ debug!(~"successful server read start");
+ }
+ else {
- log(debug, fmt!("server_connection_cb: bad accept: %d",
- accept_result as int));
++ debug!("server_connection_cb: bad read:%d",
++ read_result as int);
+ fail_unless!(false);
+ }
+ }
+ else {
- log(debug, fmt!("server_connection_cb: bad client init: %d",
- client_init_result as int));
++ debug!("server_connection_cb: bad accept: %d",
++ accept_result as int);
+ fail_unless!(false);
+ }
+ }
+ else {
- log(debug, fmt!("SERVER: closing async cb... h: %?",
- handle));
++ debug!("server_connection_cb: bad client init: %d",
++ client_init_result as int);
+ fail_unless!(false);
+ }
+ }
+ }
+
+ struct tcp_server_data {
+ client: *uv_tcp_t,
+ server: *uv_tcp_t,
+ server_kill_msg: ~str,
+ server_resp_buf: *~[uv_buf_t],
+ server_chan: SharedChan<~str>,
+ server_write_req: *uv_write_t,
+ }
+
+ struct async_handle_data {
+ continue_chan: SharedChan<bool>,
+ }
+
+ extern fn async_close_cb(handle: *libc::c_void) {
- log(debug, fmt!("resp_msg ptr: %u", resp_msg_ptr as uint));
++ debug!("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.clone();
+ let should_continue = status == 0i32;
+ continue_chan.send(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: SharedChan<~str>,
+ continue_chan: SharedChan<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, ~"successful uv_tcp_bind, listening");
++ debug!("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 =
+ async_handle_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, ~"server uv::run() has returned");
++ 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, fmt!("uv_async_init failure: %d",
- async_result as int));
++ debug!(~"server uv::run() has returned");
+ }
+ else {
- log(debug, fmt!("non-zero result on uv_listen: %d",
- listen_result as int));
++ debug!("uv_async_init failure: %d",
++ async_result as int);
+ fail_unless!(false);
+ }
+ }
+ else {
- log(debug, fmt!("non-zero result on uv_tcp_bind: %d",
- bind_result as int));
++ debug!("non-zero result on uv_listen: %d",
++ listen_result as int);
+ fail_unless!(false);
+ }
+ }
+ else {
- log(debug, fmt!("non-zero result on uv_tcp_init: %d",
- tcp_init_result as int));
++ debug!("non-zero result on uv_tcp_bind: %d",
++ bind_result as int);
+ fail_unless!(false);
+ }
+ }
+ else {
- log(debug, ~"before receiving on server continue_port");
++ debug!("non-zero result on uv_tcp_init: %d",
++ tcp_init_result as int);
+ fail_unless!(false);
+ }
+ loop_delete(test_loop);
+ }
+ }
+
+ // this is the impl for a test that is (maybe) ran on a
+ // per-platform/arch basis below
+ pub fn impl_uv_tcp_server_and_request() {
+ unsafe {
+ let bind_ip = ~"0.0.0.0";
+ let request_ip = ~"127.0.0.1";
+ let port = 8886;
+ let kill_server_msg = ~"does a dog have buddha nature?";
+ let server_resp_msg = ~"mu!";
+ let (client_port, client_chan) = stream::<~str>();
+ let client_chan = SharedChan(client_chan);
+ let (server_port, server_chan) = stream::<~str>();
+ let server_chan = SharedChan(server_chan);
+
+ let (continue_port, continue_chan) = stream::<bool>();
+ let continue_chan = SharedChan(continue_chan);
+
+ let kill_server_msg_copy = copy kill_server_msg;
+ let server_resp_msg_copy = copy server_resp_msg;
+ do task::spawn_sched(task::ManualThreads(1)) {
+ impl_uv_tcp_server(bind_ip, port,
+ copy kill_server_msg_copy,
+ copy server_resp_msg_copy,
+ server_chan.clone(),
+ continue_chan.clone());
+ };
+
+ // block until the server up is.. possibly a race?
- log(debug, ~"received on continue port, set up tcp client");
++ debug!(~"before receiving on server continue_port");
+ continue_port.recv();
- log(debug, output);
++ debug!(~"received on continue port, set up tcp client");
+
+ let kill_server_msg_copy = copy kill_server_msg;
+ do task::spawn_sched(task::ManualThreads(1u)) {
+ impl_uv_tcp_request(request_ip, port,
+ kill_server_msg_copy,
+ client_chan.clone());
+ };
+
+ let msg_from_client = server_port.recv();
+ let msg_from_server = client_port.recv();
+
+ fail_unless!(str::contains(msg_from_client, kill_server_msg));
+ fail_unless!(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")]
+ #[cfg(target_os="android")]
+ pub mod tcp_and_server_client_test {
+ #[cfg(target_arch="x86_64")]
+ pub mod impl64 {
+ #[test]
+ pub fn test_uv_ll_tcp_server_and_request() {
+ unsafe {
+ super::super::impl_uv_tcp_server_and_request();
+ }
+ }
+ }
+ #[cfg(target_arch="x86")]
+ #[cfg(target_arch="arm")]
+ #[cfg(target_arch="mips")]
+ pub mod impl32 {
+ #[test]
+ #[ignore(cfg(target_os = "linux"))]
+ pub fn test_uv_ll_tcp_server_and_request() {
+ unsafe {
+ super::super::impl_uv_tcp_server_and_request();
+ }
+ }
+ }
+ }
+
+ fn struct_size_check_common<TStruct>(t_name: ~str,
+ foreign_size: libc::c_uint) {
+ unsafe {
+ let rust_size = sys::size_of::<TStruct>();
+ let sizes_match = foreign_size as uint == rust_size;
+ if !sizes_match {
+ let output = fmt!(
+ "STRUCT_SIZE FAILURE: %s -- actual: %u expected: %u",
+ t_name, rust_size, foreign_size as uint);
- log(debug, output);
++ debug!(output);
+ }
+ fail_unless!(sizes_match);
+ }
+ }
+
+ // struct size tests
+ #[test]
+ fn test_uv_ll_struct_size_uv_tcp_t() {
+ unsafe {
+ struct_size_check_common::<uv_tcp_t>(
+ ~"uv_tcp_t",
+ super::rustrt::rust_uv_helper_uv_tcp_t_size()
+ );
+ }
+ }
+ #[test]
+ fn test_uv_ll_struct_size_uv_connect_t() {
+ unsafe {
+ struct_size_check_common::<uv_connect_t>(
+ ~"uv_connect_t",
+ super::rustrt::rust_uv_helper_uv_connect_t_size()
+ );
+ }
+ }
+ #[test]
+ fn test_uv_ll_struct_size_uv_buf_t() {
+ unsafe {
+ struct_size_check_common::<uv_buf_t>(
+ ~"uv_buf_t",
+ super::rustrt::rust_uv_helper_uv_buf_t_size()
+ );
+ }
+ }
+ #[test]
+ fn test_uv_ll_struct_size_uv_write_t() {
+ unsafe {
+ struct_size_check_common::<uv_write_t>(
+ ~"uv_write_t",
+ super::rustrt::rust_uv_helper_uv_write_t_size()
+ );
+ }
+ }
+
+ #[test]
+ fn test_uv_ll_struct_size_sockaddr_in() {
+ unsafe {
+ struct_size_check_common::<sockaddr_in>(
+ ~"sockaddr_in",
+ super::rustrt::rust_uv_helper_sockaddr_in_size()
+ );
+ }
+ }
+ #[test]
+ fn test_uv_ll_struct_size_sockaddr_in6() {
+ unsafe {
+ let foreign_handle_size =
+ super::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);
++ 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
+ fail_unless!((4u+foreign_handle_size as uint) ==
+ rust_handle_size);
+ }
+ }
+ #[test]
+ #[ignore(reason = "questionable size calculations")]
+ fn test_uv_ll_struct_size_addr_in() {
+ unsafe {
+ let foreign_handle_size =
+ super::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);
++ debug!(output);
+ // FIXME #1645 .. see note above about struct padding
+ fail_unless!((4u+foreign_handle_size as uint) ==
+ rust_handle_size);
+ }
+ }
+
+ #[test]
+ fn test_uv_ll_struct_size_uv_async_t() {
+ unsafe {
+ struct_size_check_common::<uv_async_t>(
+ ~"uv_async_t",
+ super::rustrt::rust_uv_helper_uv_async_t_size()
+ );
+ }
+ }
+
+ #[test]
+ fn test_uv_ll_struct_size_uv_timer_t() {
+ unsafe {
+ struct_size_check_common::<uv_timer_t>(
+ ~"uv_timer_t",
+ super::rustrt::rust_uv_helper_uv_timer_t_size()
+ );
+ }
+ }
+
+ #[test]
+ #[ignore(cfg(target_os = "win32"))]
+ fn test_uv_ll_struct_size_uv_getaddrinfo_t() {
+ unsafe {
+ struct_size_check_common::<uv_getaddrinfo_t>(
+ ~"uv_getaddrinfo_t",
+ super::rustrt::rust_uv_helper_uv_getaddrinfo_t_size()
+ );
+ }
+ }
+ #[test]
+ #[ignore(cfg(target_os = "macos"))]
+ #[ignore(cfg(target_os = "win32"))]
+ fn test_uv_ll_struct_size_addrinfo() {
+ unsafe {
+ struct_size_check_common::<uv_timer_t>(
+ ~"addrinfo",
+ super::rustrt::rust_uv_helper_uv_timer_t_size()
+ );
+ }
+ }
+ }