1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
12 * Low-level bindings to the libuv library.
14 * This module contains a set of direct, 'bare-metal' wrappers around
17 * Also contained herein are a set of rust records that map, in
18 * approximate memory-size, to the libuv data structures. The record
19 * implementations are adjusted, per-platform, to match their respective
22 * There are also a collection of helper functions to ease interacting
23 * with the low-level API (such as a function to return the latest
24 * libuv error as a rust-formatted string).
26 * As new functionality, existant in uv.h, is added to the rust stdlib,
27 * the mappings should be added in this module.
29 * This module's implementation will hopefully be, eventually, replaced
30 * with per-platform, generated source files from rust-bindgen.
33 #[allow(non_camel_case_types)]; // C types
35 use core::libc::size_t;
38 use core::ptr::to_unsafe_ptr;
43 // libuv struct mappings
44 pub type uv_ip4_addr = {
48 pub type uv_ip6_addr = uv_ip4_addr;
50 pub enum uv_handle_type {
68 pub type handle_type = libc::c_uint;
70 pub type uv_handle_fields = {
71 loop_handle: *libc::c_void,
74 mut data: *libc::c_void,
80 sys_errno_: libc::c_int
83 // don't create one of these directly. instead,
84 // count on it appearing in libuv callbacks or embedded
85 // in other types as a pointer to be used in other
86 // operations (so mostly treat it as opaque, once you
87 // have it in this form..)
88 pub type uv_stream_t = {
89 fields: uv_handle_fields
92 // 64bit unix size: 272
95 fields: uv_handle_fields,
96 a00: *u8, a01: *u8, a02: *u8, a03: *u8,
97 a04: *u8, a05: *u8, a06: *u8, a07: *u8,
98 a08: *u8, a09: *u8, a10: *u8, a11: *u8,
99 a12: *u8, a13: *u8, a14: *u8, a15: *u8,
100 a16: *u8, a17: *u8, a18: *u8, a19: *u8,
101 a20: *u8, a21: *u8, a22: *u8, a23: *u8,
102 a24: *u8, a25: *u8, a26: *u8, a27: *u8,
104 a30: uv_tcp_t_32bit_unix_riders
106 // 32bit unix size: 328 (164)
107 #[cfg(target_arch="x86_64")]
108 pub type uv_tcp_t_32bit_unix_riders = {
111 #[cfg(target_arch="x86")]
112 pub type uv_tcp_t_32bit_unix_riders = {
113 a29: *u8, a30: *u8, a31: *u8,
114 a32: *u8, a33: *u8, a34: *u8,
118 // 32bit win32 size: 240 (120)
120 pub type uv_tcp_t = {
121 fields: uv_handle_fields,
122 a00: *u8, a01: *u8, a02: *u8, a03: *u8,
123 a04: *u8, a05: *u8, a06: *u8, a07: *u8,
124 a08: *u8, a09: *u8, a10: *u8, a11: *u8,
125 a12: *u8, a13: *u8, a14: *u8, a15: *u8,
126 a16: *u8, a17: *u8, a18: *u8, a19: *u8,
127 a20: *u8, a21: *u8, a22: *u8, a23: *u8,
133 pub type uv_connect_t = {
134 a00: *u8, a01: *u8, a02: *u8, a03: *u8,
137 // win32 size: 88 (44)
139 pub type uv_connect_t = {
140 a00: *u8, a01: *u8, a02: *u8, a03: *u8,
141 a04: *u8, a05: *u8, a06: *u8, a07: *u8,
142 a08: *u8, a09: *u8, a10: *u8
146 pub type uv_buf_t = {
150 // no gen stub method.. should create
151 // it via uv::direct::buf_init()
155 pub type uv_write_t = {
156 fields: uv_handle_fields,
157 a00: *u8, a01: *u8, a02: *u8, a03: *u8,
158 a04: *u8, a05: *u8, a06: *u8, a07: *u8,
159 a08: *u8, a09: *u8, a10: *u8, a11: *u8,
161 a14: uv_write_t_32bit_unix_riders
163 #[cfg(target_arch="x86_64")]
164 pub type uv_write_t_32bit_unix_riders = {
167 #[cfg(target_arch="x86")]
168 pub type uv_write_t_32bit_unix_riders = {
171 // win32 size: 136 (68)
173 pub type uv_write_t = {
174 fields: uv_handle_fields,
175 a00: *u8, a01: *u8, a02: *u8, a03: *u8,
176 a04: *u8, a05: *u8, a06: *u8, a07: *u8,
177 a08: *u8, a09: *u8, a10: *u8, a11: *u8,
180 // 64bit unix size: 120
181 // 32bit unix size: 152 (76)
183 pub type uv_async_t = {
184 fields: uv_handle_fields,
185 a00: *u8, a01: *u8, a02: *u8, a03: *u8,
186 a04: *u8, a05: *u8, a06: *u8, a07: *u8,
188 a11: uv_async_t_32bit_unix_riders
190 #[cfg(target_arch="x86_64")]
191 pub type uv_async_t_32bit_unix_riders = {
194 #[cfg(target_arch="x86")]
195 pub type uv_async_t_32bit_unix_riders = {
196 a10: *u8, a11: *u8, a12: *u8, a13: *u8
198 // win32 size 132 (68)
200 pub type uv_async_t = {
201 fields: uv_handle_fields,
202 a00: *u8, a01: *u8, a02: *u8, a03: *u8,
203 a04: *u8, a05: *u8, a06: *u8, a07: *u8,
204 a08: *u8, a09: *u8, a10: *u8, a11: *u8,
208 // 64bit unix size: 128
209 // 32bit unix size: 84
211 pub type uv_timer_t = {
212 fields: uv_handle_fields,
213 a00: *u8, a01: *u8, a02: *u8, a03: *u8,
214 a04: *u8, a05: *u8, a06: *u8, a07: *u8,
216 a11: uv_timer_t_32bit_unix_riders
218 #[cfg(target_arch="x86_64")]
219 pub type uv_timer_t_32bit_unix_riders = {
222 #[cfg(target_arch="x86")]
223 pub type uv_timer_t_32bit_unix_riders = {
224 a10: *u8, a11: *u8, a12: *u8, a13: *u8,
225 a14: *u8, a15: *u8, a16: *u8
229 pub type uv_timer_t = {
230 fields: uv_handle_fields,
231 a00: *u8, a01: *u8, a02: *u8, a03: *u8,
232 a04: *u8, a05: *u8, a06: *u8, a07: *u8,
233 a08: *u8, a09: *u8, a10: *u8, a11: *u8
237 pub type sockaddr_in = {
240 mut sin_addr: u32, // in_addr: this is an opaque, per-platform struct
241 mut sin_zero: (u8, u8, u8, u8, u8, u8, u8, u8)
244 // unix size: 28 .. FIXME #1645
245 // stuck with 32 becuse of rust padding structs?
246 #[cfg(target_arch="x86_64")]
247 pub type sockaddr_in6 = {
251 #[cfg(target_arch="x86")]
252 pub type sockaddr_in6 = {
259 // unix size: 28 .. FIXME #1645
260 // stuck with 32 becuse of rust padding structs?
261 pub type addr_in = addr_in_impl::addr_in;
263 pub mod addr_in_impl {
264 #[cfg(target_arch="x86_64")]
269 #[cfg(target_arch="x86")]
278 pub mod addr_in_impl {
285 // unix size: 48, 32bit: 32
286 pub type addrinfo = addrinfo_impl::addrinfo;
287 #[cfg(target_os="linux")]
288 pub mod addrinfo_impl {
289 #[cfg(target_arch="x86_64")]
290 pub type addrinfo = {
291 a00: *u8, a01: *u8, a02: *u8, a03: *u8,
294 #[cfg(target_arch="x86")]
295 pub type addrinfo = {
296 a00: *u8, a01: *u8, a02: *u8, a03: *u8,
297 a04: *u8, a05: *u8, a06: *u8, a07: *u8
300 #[cfg(target_os="macos")]
301 #[cfg(target_os="freebsd")]
302 pub mod addrinfo_impl {
303 pub type addrinfo = {
304 a00: *u8, a01: *u8, a02: *u8, a03: *u8,
309 pub mod addrinfo_impl {
310 pub type addrinfo = {
311 a00: *u8, a01: *u8, a02: *u8, a03: *u8,
317 pub type uv_getaddrinfo_t = {
318 a00: *u8, a01: *u8, a02: *u8, a03: *u8, a04: *u8, a05: *u8,
319 a06: *u8, a07: *u8, a08: *u8
322 pub mod uv_ll_struct_stubgen {
323 use uv_ll::{uv_async_t, uv_connect_t, uv_getaddrinfo_t, uv_tcp_t};
324 use uv_ll::{uv_timer_t, uv_write_t};
328 pub fn gen_stub_uv_tcp_t() -> uv_tcp_t {
329 return gen_stub_os();
330 #[cfg(target_os = "linux")]
331 #[cfg(target_os = "macos")]
332 #[cfg(target_os = "freebsd")]
333 pub fn gen_stub_os() -> uv_tcp_t {
334 return gen_stub_arch();
335 #[cfg(target_arch="x86_64")]
336 pub fn gen_stub_arch() -> uv_tcp_t {
337 return { fields: { loop_handle: ptr::null(), type_: 0u32,
338 close_cb: ptr::null(),
339 mut data: ptr::null() },
340 a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
342 a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
344 a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
346 a12: 0 as *u8, a13: 0 as *u8, a14: 0 as *u8,
348 a16: 0 as *u8, a17: 0 as *u8, a18: 0 as *u8,
350 a20: 0 as *u8, a21: 0 as *u8, a22: 0 as *u8,
352 a24: 0 as *u8, a25: 0 as *u8, a26: 0 as *u8,
360 #[cfg(target_arch="x86")]
361 pub fn gen_stub_arch() -> uv_tcp_t {
362 return { fields: { loop_handle: ptr::null(), type_: 0u32,
363 close_cb: ptr::null(),
364 mut data: ptr::null() },
365 a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
367 a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
369 a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
371 a12: 0 as *u8, a13: 0 as *u8, a14: 0 as *u8,
373 a16: 0 as *u8, a17: 0 as *u8, a18: 0 as *u8,
375 a20: 0 as *u8, a21: 0 as *u8, a22: 0 as *u8,
377 a24: 0 as *u8, a25: 0 as *u8, a26: 0 as *u8,
381 a29: 0 as *u8, a30: 0 as *u8, a31: 0 as *u8,
382 a32: 0 as *u8, a33: 0 as *u8, a34: 0 as *u8,
383 a35: 0 as *u8, a36: 0 as *u8
389 pub fn gen_stub_os() -> uv_tcp_t {
390 return { fields: { loop_handle: ptr::null(), type_: 0u32,
391 close_cb: ptr::null(),
392 mut data: ptr::null() },
393 a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
395 a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
397 a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
399 a12: 0 as *u8, a13: 0 as *u8, a14: 0 as *u8,
401 a16: 0 as *u8, a17: 0 as *u8, a18: 0 as *u8,
403 a20: 0 as *u8, a21: 0 as *u8, a22: 0 as *u8,
405 a24: 0 as *u8, a25: 0 as *u8
410 pub fn gen_stub_uv_connect_t() -> uv_connect_t {
412 a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
414 a04: 0 as *u8, a05: 0 as *u8
418 pub fn gen_stub_uv_connect_t() -> uv_connect_t {
420 a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
422 a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
424 a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8
428 pub fn gen_stub_uv_async_t() -> uv_async_t {
429 return gen_stub_arch();
430 #[cfg(target_arch = "x86_64")]
431 pub fn gen_stub_arch() -> uv_async_t {
432 return { fields: { loop_handle: ptr::null(), type_: 0u32,
433 close_cb: ptr::null(),
434 mut data: ptr::null() },
435 a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
437 a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
439 a08: 0 as *u8, a09: 0 as *u8,
445 #[cfg(target_arch = "x86")]
446 pub fn gen_stub_arch() -> uv_async_t {
447 return { fields: { loop_handle: ptr::null(), type_: 0u32,
448 close_cb: ptr::null(),
449 mut data: ptr::null() },
450 a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
452 a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
454 a08: 0 as *u8, a09: 0 as *u8,
456 a10: 0 as *u8, a11: 0 as *u8,
457 a12: 0 as *u8, a13: 0 as *u8
463 pub fn gen_stub_uv_async_t() -> uv_async_t {
464 return { fields: { loop_handle: ptr::null(), type_: 0u32,
465 close_cb: ptr::null(),
466 mut data: ptr::null() },
467 a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
469 a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
471 a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
477 pub fn gen_stub_uv_timer_t() -> uv_timer_t {
478 return gen_stub_arch();
479 #[cfg(target_arch = "x86_64")]
480 pub fn gen_stub_arch() -> uv_timer_t {
481 return { fields: { loop_handle: ptr::null(), type_: 0u32,
482 close_cb: ptr::null(),
483 mut data: ptr::null() },
484 a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
486 a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
488 a08: 0 as *u8, a09: 0 as *u8,
490 a10: 0 as *u8, a11: 0 as *u8
494 #[cfg(target_arch = "x86")]
495 pub fn gen_stub_arch() -> uv_timer_t {
496 return { fields: { loop_handle: ptr::null(), type_: 0u32,
497 close_cb: ptr::null(),
498 mut data: ptr::null() },
499 a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
501 a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
503 a08: 0 as *u8, a09: 0 as *u8,
505 a10: 0 as *u8, a11: 0 as *u8,
506 a12: 0 as *u8, a13: 0 as *u8,
507 a14: 0 as *u8, a15: 0 as *u8,
514 pub fn gen_stub_uv_timer_t() -> uv_timer_t {
515 return { fields: { loop_handle: ptr::null(), type_: 0u32,
516 close_cb: ptr::null(),
517 mut data: ptr::null() },
518 a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
520 a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
522 a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
527 pub fn gen_stub_uv_write_t() -> uv_write_t {
528 return gen_stub_arch();
529 #[cfg(target_arch="x86_64")]
530 pub fn gen_stub_arch() -> uv_write_t {
531 return { fields: { loop_handle: ptr::null(), type_: 0u32,
532 close_cb: ptr::null(),
533 mut data: ptr::null() },
534 a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
536 a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
538 a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
540 a12: 0 as *u8, a14: { a13: 0 as *u8 }
543 #[cfg(target_arch="x86")]
544 pub fn gen_stub_arch() -> uv_write_t {
545 return { fields: { loop_handle: ptr::null(), type_: 0u32,
546 close_cb: ptr::null(),
547 mut data: ptr::null() },
548 a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
550 a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
552 a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
554 a12: 0 as *u8, a14: { a13: 0 as *u8, a14: 0 as *u8 }
559 pub fn gen_stub_uv_write_t() -> uv_write_t {
560 return { fields: { loop_handle: ptr::null(), type_: 0u32,
561 close_cb: ptr::null(),
562 mut data: ptr::null() },
563 a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
565 a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
567 a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
572 pub fn gen_stub_uv_getaddrinfo_t() -> uv_getaddrinfo_t {
574 a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8, a03: 0 as *u8,
575 a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8, a07: 0 as *u8,
584 unsafe fn rust_uv_loop_new() -> *libc::c_void;
585 unsafe fn rust_uv_loop_delete(lp: *libc::c_void);
586 unsafe fn rust_uv_loop_refcount(loop_ptr: *libc::c_void) -> libc::c_int;
587 unsafe fn rust_uv_run(loop_handle: *libc::c_void);
588 unsafe fn rust_uv_close(handle: *libc::c_void, cb: *u8);
589 unsafe fn rust_uv_async_send(handle: *uv_async_t);
590 unsafe fn rust_uv_async_init(loop_handle: *libc::c_void,
591 async_handle: *uv_async_t,
592 cb: *u8) -> libc::c_int;
593 unsafe fn rust_uv_tcp_init(
594 loop_handle: *libc::c_void,
595 handle_ptr: *uv_tcp_t) -> libc::c_int;
596 // FIXME ref #2604 .. ?
597 unsafe fn rust_uv_buf_init(out_buf: *uv_buf_t, base: *u8,
599 unsafe fn rust_uv_last_error(loop_handle: *libc::c_void) -> uv_err_t;
601 unsafe fn rust_uv_strerror(err: *uv_err_t) -> *libc::c_char;
603 unsafe fn rust_uv_err_name(err: *uv_err_t) -> *libc::c_char;
604 unsafe fn rust_uv_ip4_addr(ip: *u8, port: libc::c_int)
606 unsafe fn rust_uv_ip6_addr(ip: *u8, port: libc::c_int)
608 unsafe fn rust_uv_ip4_name(src: *sockaddr_in,
612 unsafe fn rust_uv_ip6_name(src: *sockaddr_in6,
616 unsafe fn rust_uv_ip4_port(src: *sockaddr_in) -> libc::c_uint;
617 unsafe fn rust_uv_ip6_port(src: *sockaddr_in6) -> libc::c_uint;
619 unsafe fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t,
620 tcp_handle_ptr: *uv_tcp_t,
622 ++addr: *sockaddr_in) -> libc::c_int;
624 unsafe fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t,
625 ++addr: *sockaddr_in) -> libc::c_int;
627 unsafe fn rust_uv_tcp_connect6(connect_ptr: *uv_connect_t,
628 tcp_handle_ptr: *uv_tcp_t,
630 ++addr: *sockaddr_in6) -> libc::c_int;
632 unsafe fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t,
633 ++addr: *sockaddr_in6) -> libc::c_int;
634 unsafe fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t,
635 ++name: *sockaddr_in) -> libc::c_int;
636 unsafe fn rust_uv_tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t,
637 ++name: *sockaddr_in6) ->libc::c_int;
638 unsafe fn rust_uv_listen(stream: *libc::c_void,
639 backlog: libc::c_int,
640 cb: *u8) -> libc::c_int;
641 unsafe fn rust_uv_accept(server: *libc::c_void, client: *libc::c_void)
643 unsafe fn rust_uv_write(req: *libc::c_void,
644 stream: *libc::c_void,
646 buf_cnt: libc::c_int,
649 unsafe fn rust_uv_read_start(stream: *libc::c_void,
653 unsafe fn rust_uv_read_stop(stream: *libc::c_void) -> libc::c_int;
654 unsafe fn rust_uv_timer_init(loop_handle: *libc::c_void,
655 timer_handle: *uv_timer_t)
657 unsafe fn rust_uv_timer_start(
658 timer_handle: *uv_timer_t,
660 timeout: libc::c_uint,
661 repeat: libc::c_uint) -> libc::c_int;
662 unsafe fn rust_uv_timer_stop(handle: *uv_timer_t) -> libc::c_int;
664 unsafe fn rust_uv_getaddrinfo(loop_ptr: *libc::c_void,
665 handle: *uv_getaddrinfo_t,
668 service_name_ptr: *u8,
669 // should probably only pass ptr::null()
672 unsafe fn rust_uv_freeaddrinfo(res: *addrinfo);
674 // data accessors/helpers for rust-mapped uv structs
675 unsafe fn rust_uv_helper_get_INADDR_NONE() -> u32;
676 unsafe fn rust_uv_is_ipv4_addrinfo(input: *addrinfo) -> bool;
677 unsafe fn rust_uv_is_ipv6_addrinfo(input: *addrinfo) -> bool;
678 unsafe fn rust_uv_get_next_addrinfo(input: *addrinfo) -> *addrinfo;
679 unsafe fn rust_uv_addrinfo_as_sockaddr_in(input: *addrinfo)
681 unsafe fn rust_uv_addrinfo_as_sockaddr_in6(input: *addrinfo)
683 unsafe fn rust_uv_malloc_buf_base_of(sug_size: libc::size_t) -> *u8;
684 unsafe fn rust_uv_free_base_of_buf(++buf: uv_buf_t);
685 unsafe fn rust_uv_get_stream_handle_from_connect_req(
686 connect_req: *uv_connect_t)
688 unsafe fn rust_uv_get_stream_handle_from_write_req(
689 write_req: *uv_write_t)
691 unsafe fn rust_uv_get_loop_for_uv_handle(handle: *libc::c_void)
693 unsafe fn rust_uv_get_data_for_uv_loop(loop_ptr: *libc::c_void)
695 unsafe fn rust_uv_set_data_for_uv_loop(loop_ptr: *libc::c_void,
696 data: *libc::c_void);
697 unsafe fn rust_uv_get_data_for_uv_handle(handle: *libc::c_void)
699 unsafe fn rust_uv_set_data_for_uv_handle(handle: *libc::c_void,
700 data: *libc::c_void);
701 unsafe fn rust_uv_get_data_for_req(req: *libc::c_void) -> *libc::c_void;
702 unsafe fn rust_uv_set_data_for_req(req: *libc::c_void,
703 data: *libc::c_void);
704 unsafe fn rust_uv_get_base_from_buf(++buf: uv_buf_t) -> *u8;
705 unsafe fn rust_uv_get_len_from_buf(++buf: uv_buf_t) -> libc::size_t;
707 // sizeof testing helpers
708 unsafe fn rust_uv_helper_uv_tcp_t_size() -> libc::c_uint;
709 unsafe fn rust_uv_helper_uv_connect_t_size() -> libc::c_uint;
710 unsafe fn rust_uv_helper_uv_buf_t_size() -> libc::c_uint;
711 unsafe fn rust_uv_helper_uv_write_t_size() -> libc::c_uint;
712 unsafe fn rust_uv_helper_uv_err_t_size() -> libc::c_uint;
713 unsafe fn rust_uv_helper_sockaddr_in_size() -> libc::c_uint;
714 unsafe fn rust_uv_helper_sockaddr_in6_size() -> libc::c_uint;
715 unsafe fn rust_uv_helper_uv_async_t_size() -> libc::c_uint;
716 unsafe fn rust_uv_helper_uv_timer_t_size() -> libc::c_uint;
717 unsafe fn rust_uv_helper_uv_getaddrinfo_t_size() -> libc::c_uint;
718 unsafe fn rust_uv_helper_addrinfo_size() -> libc::c_uint;
719 unsafe fn rust_uv_helper_addr_in_size() -> libc::c_uint;
722 pub unsafe fn loop_new() -> *libc::c_void {
723 return rustrt::rust_uv_loop_new();
726 pub unsafe fn loop_delete(loop_handle: *libc::c_void) {
727 rustrt::rust_uv_loop_delete(loop_handle);
730 pub unsafe fn loop_refcount(loop_ptr: *libc::c_void) -> libc::c_int {
731 return rustrt::rust_uv_loop_refcount(loop_ptr);
734 pub unsafe fn run(loop_handle: *libc::c_void) {
735 rustrt::rust_uv_run(loop_handle);
738 pub unsafe fn close<T>(handle: *T, cb: *u8) {
739 rustrt::rust_uv_close(handle as *libc::c_void, cb);
742 pub unsafe fn tcp_init(loop_handle: *libc::c_void, handle: *uv_tcp_t)
744 return rustrt::rust_uv_tcp_init(loop_handle, handle);
747 pub unsafe fn tcp_connect(connect_ptr: *uv_connect_t,
748 tcp_handle_ptr: *uv_tcp_t,
749 addr_ptr: *sockaddr_in,
750 after_connect_cb: *u8)
752 log(debug, fmt!("b4 foreign tcp_connect--addr port: %u cb: %u",
753 (*addr_ptr).sin_port as uint, after_connect_cb as uint));
754 return rustrt::rust_uv_tcp_connect(connect_ptr, tcp_handle_ptr,
755 after_connect_cb, addr_ptr);
758 pub unsafe fn tcp_connect6(connect_ptr: *uv_connect_t,
759 tcp_handle_ptr: *uv_tcp_t,
760 addr_ptr: *sockaddr_in6,
761 after_connect_cb: *u8)
763 return rustrt::rust_uv_tcp_connect6(connect_ptr, tcp_handle_ptr,
764 after_connect_cb, addr_ptr);
767 pub unsafe fn tcp_bind(tcp_server_ptr: *uv_tcp_t,
768 addr_ptr: *sockaddr_in) -> libc::c_int {
769 return rustrt::rust_uv_tcp_bind(tcp_server_ptr,
773 pub unsafe fn tcp_bind6(tcp_server_ptr: *uv_tcp_t,
774 addr_ptr: *sockaddr_in6) -> libc::c_int {
775 return rustrt::rust_uv_tcp_bind6(tcp_server_ptr,
779 pub unsafe fn tcp_getpeername(tcp_handle_ptr: *uv_tcp_t,
780 name: *sockaddr_in) -> libc::c_int {
781 return rustrt::rust_uv_tcp_getpeername(tcp_handle_ptr, name);
784 pub unsafe fn tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t,
785 name: *sockaddr_in6) ->libc::c_int {
786 return rustrt::rust_uv_tcp_getpeername6(tcp_handle_ptr, name);
789 pub unsafe fn listen<T>(stream: *T, backlog: libc::c_int,
790 cb: *u8) -> libc::c_int {
791 return rustrt::rust_uv_listen(stream as *libc::c_void, backlog, cb);
794 pub unsafe fn accept(server: *libc::c_void, client: *libc::c_void)
796 return rustrt::rust_uv_accept(server as *libc::c_void,
797 client as *libc::c_void);
800 pub unsafe fn write<T>(req: *uv_write_t, stream: *T,
801 buf_in: *~[uv_buf_t], cb: *u8) -> libc::c_int {
802 let buf_ptr = vec::raw::to_ptr(*buf_in);
803 let buf_cnt = vec::len(*buf_in) as i32;
804 return rustrt::rust_uv_write(req as *libc::c_void,
805 stream as *libc::c_void,
806 buf_ptr, buf_cnt, cb);
808 pub unsafe fn read_start(stream: *uv_stream_t, on_alloc: *u8,
809 on_read: *u8) -> libc::c_int {
810 return rustrt::rust_uv_read_start(stream as *libc::c_void,
814 pub unsafe fn read_stop(stream: *uv_stream_t) -> libc::c_int {
815 return rustrt::rust_uv_read_stop(stream as *libc::c_void);
818 pub unsafe fn last_error(loop_handle: *libc::c_void) -> uv_err_t {
819 return rustrt::rust_uv_last_error(loop_handle);
822 pub unsafe fn strerror(err: *uv_err_t) -> *libc::c_char {
823 return rustrt::rust_uv_strerror(err);
825 pub unsafe fn err_name(err: *uv_err_t) -> *libc::c_char {
826 return rustrt::rust_uv_err_name(err);
829 pub unsafe fn async_init(loop_handle: *libc::c_void,
830 async_handle: *uv_async_t,
831 cb: *u8) -> libc::c_int {
832 return rustrt::rust_uv_async_init(loop_handle,
837 pub unsafe fn async_send(async_handle: *uv_async_t) {
838 return rustrt::rust_uv_async_send(async_handle);
840 pub unsafe fn buf_init(input: *u8, len: uint) -> uv_buf_t {
841 let out_buf = { base: ptr::null(), len: 0 as libc::size_t };
842 let out_buf_ptr = ptr::addr_of(&out_buf);
843 log(debug, fmt!("buf_init - input %u len %u out_buf: %u",
846 out_buf_ptr as uint));
848 rustrt::rust_uv_buf_init(out_buf_ptr, input, len as size_t);
849 //let result = rustrt::rust_uv_buf_init_2(input, len as size_t);
850 log(debug, ~"after rust_uv_buf_init");
851 let res_base = get_base_from_buf(out_buf);
852 let res_len = get_len_from_buf(out_buf);
853 //let res_base = get_base_from_buf(result);
854 log(debug, fmt!("buf_init - result %u len %u",
860 pub unsafe fn ip4_addr(ip: &str, port: int)
862 do str::as_c_str(ip) |ip_buf| {
863 rustrt::rust_uv_ip4_addr(ip_buf as *u8,
867 pub unsafe fn ip6_addr(ip: &str, port: int)
869 do str::as_c_str(ip) |ip_buf| {
870 rustrt::rust_uv_ip6_addr(ip_buf as *u8,
874 pub unsafe fn ip4_name(src: &sockaddr_in) -> ~str {
875 // ipv4 addr max size: 15 + 1 trailing null byte
876 let dst: ~[u8] = ~[0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
877 0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8];
878 do vec::as_imm_buf(dst) |dst_buf, size| {
879 rustrt::rust_uv_ip4_name(to_unsafe_ptr(src),
880 dst_buf, size as libc::size_t);
881 // seems that checking the result of uv_ip4_name
882 // doesn't work too well..
883 // you're stuck looking at the value of dst_buf
884 // to see if it is the string representation of
885 // INADDR_NONE (0xffffffff or 255.255.255.255 on
887 str::raw::from_buf(dst_buf)
890 pub unsafe fn ip6_name(src: &sockaddr_in6) -> ~str {
891 // ipv6 addr max size: 45 + 1 trailing null byte
892 let dst: ~[u8] = ~[0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
893 0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
894 0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
895 0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
896 0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
897 0u8,0u8,0u8,0u8,0u8,0u8];
898 do vec::as_imm_buf(dst) |dst_buf, size| {
899 let src_unsafe_ptr = to_unsafe_ptr(src);
900 log(debug, fmt!("val of src *sockaddr_in6: %? sockaddr_in6: %?",
901 src_unsafe_ptr, src));
902 let result = rustrt::rust_uv_ip6_name(src_unsafe_ptr,
903 dst_buf, size as libc::size_t);
905 0i32 => str::raw::from_buf(dst_buf),
910 pub unsafe fn ip4_port(src: &sockaddr_in) -> uint {
911 rustrt::rust_uv_ip4_port(to_unsafe_ptr(src)) as uint
913 pub unsafe fn ip6_port(src: &sockaddr_in6) -> uint {
914 rustrt::rust_uv_ip6_port(to_unsafe_ptr(src)) as uint
917 pub unsafe fn timer_init(loop_ptr: *libc::c_void,
918 timer_ptr: *uv_timer_t) -> libc::c_int {
919 return rustrt::rust_uv_timer_init(loop_ptr, timer_ptr);
921 pub unsafe fn timer_start(timer_ptr: *uv_timer_t, cb: *u8, timeout: uint,
922 repeat: uint) -> libc::c_int {
923 return rustrt::rust_uv_timer_start(timer_ptr, cb, timeout as libc::c_uint,
924 repeat as libc::c_uint);
926 pub unsafe fn timer_stop(timer_ptr: *uv_timer_t) -> libc::c_int {
927 return rustrt::rust_uv_timer_stop(timer_ptr);
929 pub unsafe fn getaddrinfo(loop_ptr: *libc::c_void,
930 handle: *uv_getaddrinfo_t,
933 service_name_ptr: *u8,
934 hints: *addrinfo) -> libc::c_int {
935 rustrt::rust_uv_getaddrinfo(loop_ptr,
942 pub unsafe fn freeaddrinfo(res: *addrinfo) {
943 rustrt::rust_uv_freeaddrinfo(res);
946 // libuv struct initializers
947 pub unsafe fn tcp_t() -> uv_tcp_t {
948 return uv_ll_struct_stubgen::gen_stub_uv_tcp_t();
950 pub unsafe fn connect_t() -> uv_connect_t {
951 return uv_ll_struct_stubgen::gen_stub_uv_connect_t();
953 pub unsafe fn write_t() -> uv_write_t {
954 return uv_ll_struct_stubgen::gen_stub_uv_write_t();
956 pub unsafe fn async_t() -> uv_async_t {
957 return uv_ll_struct_stubgen::gen_stub_uv_async_t();
959 pub unsafe fn timer_t() -> uv_timer_t {
960 return uv_ll_struct_stubgen::gen_stub_uv_timer_t();
962 pub unsafe fn getaddrinfo_t() -> uv_getaddrinfo_t {
963 return uv_ll_struct_stubgen::gen_stub_uv_getaddrinfo_t();
966 // data access helpers
967 pub unsafe fn get_loop_for_uv_handle<T>(handle: *T)
969 return rustrt::rust_uv_get_loop_for_uv_handle(handle as *libc::c_void);
971 pub unsafe fn get_stream_handle_from_connect_req(connect: *uv_connect_t)
973 return rustrt::rust_uv_get_stream_handle_from_connect_req(
976 pub unsafe fn get_stream_handle_from_write_req(
977 write_req: *uv_write_t)
979 return rustrt::rust_uv_get_stream_handle_from_write_req(
982 pub unsafe fn get_data_for_uv_loop(loop_ptr: *libc::c_void) -> *libc::c_void {
983 rustrt::rust_uv_get_data_for_uv_loop(loop_ptr)
985 pub unsafe fn set_data_for_uv_loop(loop_ptr: *libc::c_void,
986 data: *libc::c_void) {
987 rustrt::rust_uv_set_data_for_uv_loop(loop_ptr, data);
989 pub unsafe fn get_data_for_uv_handle<T>(handle: *T) -> *libc::c_void {
990 return rustrt::rust_uv_get_data_for_uv_handle(handle as *libc::c_void);
992 pub unsafe fn set_data_for_uv_handle<T, U>(handle: *T,
994 rustrt::rust_uv_set_data_for_uv_handle(handle as *libc::c_void,
995 data as *libc::c_void);
997 pub unsafe fn get_data_for_req<T>(req: *T) -> *libc::c_void {
998 return rustrt::rust_uv_get_data_for_req(req as *libc::c_void);
1000 pub unsafe fn set_data_for_req<T, U>(req: *T,
1002 rustrt::rust_uv_set_data_for_req(req as *libc::c_void,
1003 data as *libc::c_void);
1005 pub unsafe fn get_base_from_buf(buf: uv_buf_t) -> *u8 {
1006 return rustrt::rust_uv_get_base_from_buf(buf);
1008 pub unsafe fn get_len_from_buf(buf: uv_buf_t) -> libc::size_t {
1009 return rustrt::rust_uv_get_len_from_buf(buf);
1011 pub unsafe fn malloc_buf_base_of(suggested_size: libc::size_t)
1013 return rustrt::rust_uv_malloc_buf_base_of(suggested_size);
1015 pub unsafe fn free_base_of_buf(buf: uv_buf_t) {
1016 rustrt::rust_uv_free_base_of_buf(buf);
1019 pub unsafe fn get_last_err_info(uv_loop: *libc::c_void) -> ~str {
1020 let err = last_error(uv_loop);
1021 let err_ptr = ptr::addr_of(&err);
1022 let err_name = str::raw::from_c_str(err_name(err_ptr));
1023 let err_msg = str::raw::from_c_str(strerror(err_ptr));
1024 return fmt!("LIBUV ERROR: name: %s msg: %s",
1028 pub unsafe fn get_last_err_data(uv_loop: *libc::c_void) -> uv_err_data {
1029 let err = last_error(uv_loop);
1030 let err_ptr = ptr::addr_of(&err);
1031 let err_name = str::raw::from_c_str(err_name(err_ptr));
1032 let err_msg = str::raw::from_c_str(strerror(err_ptr));
1033 { err_name: err_name, err_msg: err_msg }
1036 pub type uv_err_data = {
1041 pub unsafe fn is_ipv4_addrinfo(input: *addrinfo) -> bool {
1042 rustrt::rust_uv_is_ipv4_addrinfo(input)
1044 pub unsafe fn is_ipv6_addrinfo(input: *addrinfo) -> bool {
1045 rustrt::rust_uv_is_ipv6_addrinfo(input)
1047 pub unsafe fn get_INADDR_NONE() -> u32 {
1048 rustrt::rust_uv_helper_get_INADDR_NONE()
1050 pub unsafe fn get_next_addrinfo(input: *addrinfo) -> *addrinfo {
1051 rustrt::rust_uv_get_next_addrinfo(input)
1053 pub unsafe fn addrinfo_as_sockaddr_in(input: *addrinfo) -> *sockaddr_in {
1054 rustrt::rust_uv_addrinfo_as_sockaddr_in(input)
1056 pub unsafe fn addrinfo_as_sockaddr_in6(input: *addrinfo) -> *sockaddr_in6 {
1057 rustrt::rust_uv_addrinfo_as_sockaddr_in6(input)
1062 use core::prelude::*;
1074 enum tcp_read_data {
1076 tcp_read_more(~[u8]),
1080 type request_wrapper = {
1081 write_req: *uv_write_t,
1082 req_buf: *~[uv_buf_t],
1083 read_chan: *oldcomm::Chan<~str>
1086 extern fn after_close_cb(handle: *libc::c_void) {
1087 log(debug, fmt!("after uv_close! handle ptr: %?",
1091 extern fn on_alloc_cb(handle: *libc::c_void,
1092 suggested_size: libc::size_t)
1093 -> uv_buf_t unsafe {
1094 log(debug, ~"on_alloc_cb!");
1095 let char_ptr = malloc_buf_base_of(suggested_size);
1096 log(debug, fmt!("on_alloc_cb h: %? char_ptr: %u sugsize: %u",
1099 suggested_size as uint));
1100 return buf_init(char_ptr, suggested_size as uint);
1103 extern fn on_read_cb(stream: *uv_stream_t,
1104 nread: libc::ssize_t,
1105 ++buf: uv_buf_t) unsafe {
1106 let nread = nread as int;
1107 log(debug, fmt!("CLIENT entering on_read_cb nred: %d",
1111 log(debug, fmt!("CLIENT read: data! nread: %d", nread));
1114 get_data_for_uv_handle(stream as *libc::c_void)
1115 as *request_wrapper;
1116 let buf_base = get_base_from_buf(buf);
1117 let buf_len = get_len_from_buf(buf);
1118 let bytes = vec::from_buf(buf_base, buf_len as uint);
1119 let read_chan = *((*client_data).read_chan);
1120 let msg_from_server = str::from_bytes(bytes);
1121 oldcomm::send(read_chan, msg_from_server);
1122 close(stream as *libc::c_void, after_close_cb)
1124 else if (nread == -1) {
1125 // err .. possibly EOF
1126 log(debug, ~"read: eof!");
1129 // nread == 0 .. do nothing, just free buf as below
1130 log(debug, ~"read: do nothing!");
1133 free_base_of_buf(buf);
1134 log(debug, ~"CLIENT exiting on_read_cb");
1137 extern fn on_write_complete_cb(write_req: *uv_write_t,
1138 status: libc::c_int) unsafe {
1139 log(debug, fmt!("CLIENT beginning on_write_complete_cb status: %d",
1141 let stream = get_stream_handle_from_write_req(write_req);
1142 log(debug, fmt!("CLIENT on_write_complete_cb: tcp:%d write_handle:%d",
1143 stream as int, write_req as int));
1144 let result = read_start(stream, on_alloc_cb, on_read_cb);
1145 log(debug, fmt!("CLIENT ending on_write_complete_cb .. status: %d",
1149 extern fn on_connect_cb(connect_req_ptr: *uv_connect_t,
1150 status: libc::c_int) unsafe {
1151 log(debug, fmt!("beginning on_connect_cb .. status: %d",
1154 get_stream_handle_from_connect_req(connect_req_ptr);
1155 if (status == 0i32) {
1156 log(debug, ~"on_connect_cb: in status=0 if..");
1157 let client_data = get_data_for_req(
1158 connect_req_ptr as *libc::c_void)
1159 as *request_wrapper;
1160 let write_handle = (*client_data).write_req;
1161 log(debug, fmt!("on_connect_cb: tcp: %d write_hdl: %d",
1162 stream as int, write_handle as int));
1163 let write_result = write(write_handle,
1164 stream as *libc::c_void,
1165 (*client_data).req_buf,
1166 on_write_complete_cb);
1167 log(debug, fmt!("on_connect_cb: write() status: %d",
1168 write_result as int));
1171 let test_loop = get_loop_for_uv_handle(
1172 stream as *libc::c_void);
1173 let err_msg = get_last_err_info(test_loop);
1174 log(debug, err_msg);
1177 log(debug, ~"finishing on_connect_cb");
1180 fn impl_uv_tcp_request(ip: &str, port: int, req_str: &str,
1181 client_chan: *oldcomm::Chan<~str>) unsafe {
1182 let test_loop = loop_new();
1183 let tcp_handle = tcp_t();
1184 let tcp_handle_ptr = ptr::addr_of(&tcp_handle);
1185 let connect_handle = connect_t();
1186 let connect_req_ptr = ptr::addr_of(&connect_handle);
1188 // this is the persistent payload of data that we
1189 // need to pass around to get this example to work.
1190 // In C, this would be a malloc'd or stack-allocated
1191 // struct that we'd cast to a void* and store as the
1192 // data field in our uv_connect_t struct
1193 let req_str_bytes = str::to_bytes(req_str);
1194 let req_msg_ptr: *u8 = vec::raw::to_ptr(req_str_bytes);
1195 log(debug, fmt!("req_msg ptr: %u", req_msg_ptr as uint));
1197 buf_init(req_msg_ptr, vec::len(req_str_bytes))
1199 // this is the enclosing record, we'll pass a ptr to
1201 let write_handle = write_t();
1202 let write_handle_ptr = ptr::addr_of(&write_handle);
1203 log(debug, fmt!("tcp req: tcp stream: %d write_handle: %d",
1204 tcp_handle_ptr as int,
1205 write_handle_ptr as int));
1206 let client_data = { writer_handle: write_handle_ptr,
1207 req_buf: ptr::addr_of(&req_msg),
1208 read_chan: client_chan };
1210 let tcp_init_result = tcp_init(
1211 test_loop as *libc::c_void, tcp_handle_ptr);
1212 if (tcp_init_result == 0i32) {
1213 log(debug, ~"sucessful tcp_init_result");
1215 log(debug, ~"building addr...");
1216 let addr = ip4_addr(ip, port);
1218 let addr_ptr = ptr::addr_of(&addr);
1219 log(debug, fmt!("after build addr in rust. port: %u",
1220 addr.sin_port as uint));
1222 // this should set up the connection request..
1223 log(debug, fmt!("b4 call tcp_connect connect cb: %u ",
1224 on_connect_cb as uint));
1225 let tcp_connect_result = tcp_connect(
1226 connect_req_ptr, tcp_handle_ptr,
1227 addr_ptr, on_connect_cb);
1228 if (tcp_connect_result == 0i32) {
1229 // not set the data on the connect_req
1230 // until its initialized
1232 connect_req_ptr as *libc::c_void,
1233 ptr::addr_of(&client_data) as *libc::c_void);
1234 set_data_for_uv_handle(
1235 tcp_handle_ptr as *libc::c_void,
1236 ptr::addr_of(&client_data) as *libc::c_void);
1237 log(debug, ~"before run tcp req loop");
1239 log(debug, ~"after run tcp req loop");
1242 log(debug, ~"tcp_connect() failure");
1247 log(debug, ~"tcp_init() failure");
1250 loop_delete(test_loop);
1254 extern fn server_after_close_cb(handle: *libc::c_void) unsafe {
1255 log(debug, fmt!("SERVER server stream closed, should exit.. h: %?",
1259 extern fn client_stream_after_close_cb(handle: *libc::c_void)
1262 ~"SERVER: closed client stream, now closing server stream");
1263 let client_data = get_data_for_uv_handle(
1266 close((*client_data).server as *libc::c_void,
1267 server_after_close_cb);
1270 extern fn after_server_resp_write(req: *uv_write_t) unsafe {
1271 let client_stream_ptr =
1272 get_stream_handle_from_write_req(req);
1273 log(debug, ~"SERVER: resp sent... closing client stream");
1274 close(client_stream_ptr as *libc::c_void,
1275 client_stream_after_close_cb)
1278 extern fn on_server_read_cb(client_stream_ptr: *uv_stream_t,
1279 nread: libc::ssize_t,
1280 ++buf: uv_buf_t) unsafe {
1281 let nread = nread as int;
1284 log(debug, fmt!("SERVER read: data! nread: %d", nread));
1286 // pull out the contents of the write from the client
1287 let buf_base = get_base_from_buf(buf);
1288 let buf_len = get_len_from_buf(buf) as uint;
1289 log(debug, fmt!("SERVER buf base: %u, len: %u, nread: %d",
1293 let bytes = vec::from_buf(buf_base, buf_len);
1294 let request_str = str::from_bytes(bytes);
1296 let client_data = get_data_for_uv_handle(
1297 client_stream_ptr as *libc::c_void) as *tcp_server_data;
1299 let server_kill_msg = (*client_data).server_kill_msg;
1300 let write_req = (*client_data).server_write_req;
1301 if (str::contains(request_str, server_kill_msg)) {
1302 log(debug, ~"SERVER: client req contains kill_msg!");
1303 log(debug, ~"SERVER: sending response to client");
1304 read_stop(client_stream_ptr);
1305 let server_chan = *((*client_data).server_chan);
1306 oldcomm::send(server_chan, request_str);
1307 let write_result = write(
1309 client_stream_ptr as *libc::c_void,
1310 (*client_data).server_resp_buf,
1311 after_server_resp_write);
1312 log(debug, fmt!("SERVER: resp write result: %d",
1313 write_result as int));
1314 if (write_result != 0i32) {
1315 log(debug, ~"bad result for server resp write()");
1316 log(debug, get_last_err_info(
1317 get_loop_for_uv_handle(client_stream_ptr
1318 as *libc::c_void)));
1323 log(debug, ~"SERVER: client req !contain kill_msg!");
1326 else if (nread == -1) {
1327 // err .. possibly EOF
1328 log(debug, ~"read: eof!");
1331 // nread == 0 .. do nothing, just free buf as below
1332 log(debug, ~"read: do nothing!");
1335 free_base_of_buf(buf);
1336 log(debug, ~"SERVER exiting on_read_cb");
1339 extern fn server_connection_cb(server_stream_ptr:
1341 status: libc::c_int) unsafe {
1342 log(debug, ~"client connecting!");
1343 let test_loop = get_loop_for_uv_handle(
1344 server_stream_ptr as *libc::c_void);
1346 let err_msg = get_last_err_info(test_loop);
1347 log(debug, fmt!("server_connect_cb: non-zero status: %?",
1351 let server_data = get_data_for_uv_handle(
1352 server_stream_ptr as *libc::c_void) as *tcp_server_data;
1353 let client_stream_ptr = (*server_data).client;
1354 let client_init_result = tcp_init(test_loop,
1356 set_data_for_uv_handle(
1357 client_stream_ptr as *libc::c_void,
1358 server_data as *libc::c_void);
1359 if (client_init_result == 0i32) {
1360 log(debug, ~"successfully initialized client stream");
1361 let accept_result = accept(server_stream_ptr as
1363 client_stream_ptr as
1365 if (accept_result == 0i32) {
1367 let read_result = read_start(
1368 client_stream_ptr as *uv_stream_t,
1371 if (read_result == 0i32) {
1372 log(debug, ~"successful server read start");
1375 log(debug, fmt!("server_connection_cb: bad read:%d",
1376 read_result as int));
1381 log(debug, fmt!("server_connection_cb: bad accept: %d",
1382 accept_result as int));
1387 log(debug, fmt!("server_connection_cb: bad client init: %d",
1388 client_init_result as int));
1393 type tcp_server_data = {
1396 server_kill_msg: ~str,
1397 server_resp_buf: *~[uv_buf_t],
1398 server_chan: *oldcomm::Chan<~str>,
1399 server_write_req: *uv_write_t
1402 type async_handle_data = {
1403 continue_chan: *oldcomm::Chan<bool>
1406 extern fn async_close_cb(handle: *libc::c_void) {
1407 log(debug, fmt!("SERVER: closing async cb... h: %?",
1411 extern fn continue_async_cb(async_handle: *uv_async_t,
1412 status: libc::c_int) unsafe {
1413 // once we're in the body of this callback,
1414 // the tcp server's loop is set up, so we
1415 // can continue on to let the tcp client
1417 let data = get_data_for_uv_handle(
1418 async_handle as *libc::c_void) as *async_handle_data;
1419 let continue_chan = *((*data).continue_chan);
1420 let should_continue = status == 0i32;
1421 oldcomm::send(continue_chan, should_continue);
1422 close(async_handle as *libc::c_void, async_close_cb);
1425 fn impl_uv_tcp_server(server_ip: &str,
1427 +kill_server_msg: ~str,
1428 +server_resp_msg: ~str,
1429 server_chan: *oldcomm::Chan<~str>,
1430 continue_chan: *oldcomm::Chan<bool>) unsafe {
1431 let test_loop = loop_new();
1432 let tcp_server = tcp_t();
1433 let tcp_server_ptr = ptr::addr_of(&tcp_server);
1435 let tcp_client = tcp_t();
1436 let tcp_client_ptr = ptr::addr_of(&tcp_client);
1438 let server_write_req = write_t();
1439 let server_write_req_ptr = ptr::addr_of(&server_write_req);
1441 let resp_str_bytes = str::to_bytes(server_resp_msg);
1442 let resp_msg_ptr: *u8 = vec::raw::to_ptr(resp_str_bytes);
1443 log(debug, fmt!("resp_msg ptr: %u", resp_msg_ptr as uint));
1445 buf_init(resp_msg_ptr, vec::len(resp_str_bytes))
1448 let continue_async_handle = async_t();
1449 let continue_async_handle_ptr =
1450 ptr::addr_of(&continue_async_handle);
1452 { continue_chan: continue_chan };
1453 let async_data_ptr = ptr::addr_of(&async_data);
1455 let server_data: tcp_server_data = {
1456 client: tcp_client_ptr,
1457 server: tcp_server_ptr,
1458 server_kill_msg: kill_server_msg,
1459 server_resp_buf: ptr::addr_of(&resp_msg),
1460 server_chan: server_chan,
1461 server_write_req: server_write_req_ptr
1463 let server_data_ptr = ptr::addr_of(&server_data);
1464 set_data_for_uv_handle(tcp_server_ptr as *libc::c_void,
1465 server_data_ptr as *libc::c_void);
1468 let tcp_init_result = tcp_init(
1469 test_loop as *libc::c_void, tcp_server_ptr);
1470 if (tcp_init_result == 0i32) {
1471 let server_addr = ip4_addr(server_ip, server_port);
1473 let server_addr_ptr = ptr::addr_of(&server_addr);
1476 let bind_result = tcp_bind(tcp_server_ptr,
1478 if (bind_result == 0i32) {
1479 log(debug, ~"successful uv_tcp_bind, listening");
1482 let listen_result = listen(tcp_server_ptr as
1485 server_connection_cb);
1486 if (listen_result == 0i32) {
1487 // let the test know it can set up the tcp server,
1488 // now.. this may still present a race, not sure..
1489 let async_result = async_init(test_loop,
1490 continue_async_handle_ptr,
1492 if (async_result == 0i32) {
1493 set_data_for_uv_handle(
1494 continue_async_handle_ptr as *libc::c_void,
1495 async_data_ptr as *libc::c_void);
1496 async_send(continue_async_handle_ptr);
1499 log(debug, ~"server uv::run() has returned");
1502 log(debug, fmt!("uv_async_init failure: %d",
1503 async_result as int));
1508 log(debug, fmt!("non-zero result on uv_listen: %d",
1509 listen_result as int));
1514 log(debug, fmt!("non-zero result on uv_tcp_bind: %d",
1515 bind_result as int));
1520 log(debug, fmt!("non-zero result on uv_tcp_init: %d",
1521 tcp_init_result as int));
1524 loop_delete(test_loop);
1527 // this is the impl for a test that is (maybe) ran on a
1528 // per-platform/arch basis below
1529 fn impl_uv_tcp_server_and_request() unsafe {
1530 let bind_ip = ~"0.0.0.0";
1531 let request_ip = ~"127.0.0.1";
1533 let kill_server_msg = ~"does a dog have buddha nature?";
1534 let server_resp_msg = ~"mu!";
1535 let client_port = oldcomm::Port::<~str>();
1536 let client_chan = oldcomm::Chan::<~str>(&client_port);
1537 let server_port = oldcomm::Port::<~str>();
1538 let server_chan = oldcomm::Chan::<~str>(&server_port);
1540 let continue_port = oldcomm::Port::<bool>();
1541 let continue_chan = oldcomm::Chan::<bool>(&continue_port);
1542 let continue_chan_ptr = ptr::addr_of(&continue_chan);
1544 do task::spawn_sched(task::ManualThreads(1)) {
1545 impl_uv_tcp_server(bind_ip, port,
1548 ptr::addr_of(&server_chan),
1552 // block until the server up is.. possibly a race?
1553 log(debug, ~"before receiving on server continue_port");
1554 oldcomm::recv(continue_port);
1555 log(debug, ~"received on continue port, set up tcp client");
1557 do task::spawn_sched(task::ManualThreads(1u)) {
1558 impl_uv_tcp_request(request_ip, port,
1560 ptr::addr_of(&client_chan));
1563 let msg_from_client = oldcomm::recv(server_port);
1564 let msg_from_server = oldcomm::recv(client_port);
1566 assert str::contains(msg_from_client, kill_server_msg);
1567 assert str::contains(msg_from_server, server_resp_msg);
1570 // FIXME don't run on fbsd or linux 32 bit(#2064)
1571 #[cfg(target_os="win32")]
1572 #[cfg(target_os="darwin")]
1573 #[cfg(target_os="linux")]
1574 pub mod tcp_and_server_client_test {
1575 #[cfg(target_arch="x86_64")]
1579 pub fn test_uv_ll_tcp_server_and_request() unsafe {
1580 impl_uv_tcp_server_and_request();
1583 #[cfg(target_arch="x86")]
1587 #[ignore(cfg(target_os = "linux"))]
1588 pub fn test_uv_ll_tcp_server_and_request() unsafe {
1589 impl_uv_tcp_server_and_request();
1594 // struct size tests
1596 fn test_uv_ll_struct_size_uv_tcp_t() {
1598 let foreign_handle_size =
1599 ::uv_ll::rustrt::rust_uv_helper_uv_tcp_t_size();
1600 let rust_handle_size = sys::size_of::<uv_tcp_t>();
1601 let output = fmt!("uv_tcp_t -- foreign: %u rust: %u",
1602 foreign_handle_size as uint, rust_handle_size);
1604 assert foreign_handle_size as uint == rust_handle_size;
1608 fn test_uv_ll_struct_size_uv_connect_t() {
1610 let foreign_handle_size =
1611 ::uv_ll::rustrt::rust_uv_helper_uv_connect_t_size();
1612 let rust_handle_size = sys::size_of::<uv_connect_t>();
1613 let output = fmt!("uv_connect_t -- foreign: %u rust: %u",
1614 foreign_handle_size as uint, rust_handle_size);
1616 assert foreign_handle_size as uint == rust_handle_size;
1620 fn test_uv_ll_struct_size_uv_buf_t() {
1622 let foreign_handle_size =
1623 ::uv_ll::rustrt::rust_uv_helper_uv_buf_t_size();
1624 let rust_handle_size = sys::size_of::<uv_buf_t>();
1625 let output = fmt!("uv_buf_t -- foreign: %u rust: %u",
1626 foreign_handle_size as uint, rust_handle_size);
1628 assert foreign_handle_size as uint == rust_handle_size;
1632 fn test_uv_ll_struct_size_uv_write_t() {
1634 let foreign_handle_size =
1635 ::uv_ll::rustrt::rust_uv_helper_uv_write_t_size();
1636 let rust_handle_size = sys::size_of::<uv_write_t>();
1637 let output = fmt!("uv_write_t -- foreign: %u rust: %u",
1638 foreign_handle_size as uint, rust_handle_size);
1640 assert foreign_handle_size as uint == rust_handle_size;
1645 fn test_uv_ll_struct_size_sockaddr_in() {
1647 let foreign_handle_size =
1648 ::uv_ll::rustrt::rust_uv_helper_sockaddr_in_size();
1649 let rust_handle_size = sys::size_of::<sockaddr_in>();
1650 let output = fmt!("sockaddr_in -- foreign: %u rust: %u",
1651 foreign_handle_size as uint, rust_handle_size);
1653 assert foreign_handle_size as uint == rust_handle_size;
1657 fn test_uv_ll_struct_size_sockaddr_in6() {
1659 let foreign_handle_size =
1660 ::uv_ll::rustrt::rust_uv_helper_sockaddr_in6_size();
1661 let rust_handle_size = sys::size_of::<sockaddr_in6>();
1662 let output = fmt!("sockaddr_in6 -- foreign: %u rust: %u",
1663 foreign_handle_size as uint, rust_handle_size);
1665 // FIXME #1645 .. rust appears to pad structs to the nearest
1667 // .. can't get the uv::ll::sockaddr_in6 to == 28 :/
1668 // .. so the type always appears to be 32 in size.. which is
1669 // good, i guess.. better too big than too little
1670 assert (4u+foreign_handle_size as uint) == rust_handle_size;
1674 #[ignore(reason = "questionable size calculations")]
1675 fn test_uv_ll_struct_size_addr_in() {
1677 let foreign_handle_size =
1678 ::uv_ll::rustrt::rust_uv_helper_addr_in_size();
1679 let rust_handle_size = sys::size_of::<addr_in>();
1680 let output = fmt!("addr_in -- foreign: %u rust: %u",
1681 foreign_handle_size as uint, rust_handle_size);
1683 // FIXME #1645 .. see note above about struct padding
1684 assert (4u+foreign_handle_size as uint) == rust_handle_size;
1689 fn test_uv_ll_struct_size_uv_async_t() {
1691 let foreign_handle_size =
1692 ::uv_ll::rustrt::rust_uv_helper_uv_async_t_size();
1693 let rust_handle_size = sys::size_of::<uv_async_t>();
1694 let output = fmt!("uv_async_t -- foreign: %u rust: %u",
1695 foreign_handle_size as uint, rust_handle_size);
1697 assert foreign_handle_size as uint == rust_handle_size;
1702 fn test_uv_ll_struct_size_uv_timer_t() {
1704 let foreign_handle_size =
1705 ::uv_ll::rustrt::rust_uv_helper_uv_timer_t_size();
1706 let rust_handle_size = sys::size_of::<uv_timer_t>();
1707 let output = fmt!("uv_timer_t -- foreign: %u rust: %u",
1708 foreign_handle_size as uint, rust_handle_size);
1710 assert foreign_handle_size as uint == rust_handle_size;
1715 #[ignore(cfg(target_os = "win32"))]
1716 fn test_uv_ll_struct_size_uv_getaddrinfo_t() {
1718 let foreign_handle_size =
1719 ::uv_ll::rustrt::rust_uv_helper_uv_getaddrinfo_t_size();
1720 let rust_handle_size = sys::size_of::<uv_getaddrinfo_t>();
1721 let output = fmt!("uv_getaddrinfo_t -- foreign: %u rust: %u",
1722 foreign_handle_size as uint, rust_handle_size);
1724 assert foreign_handle_size as uint == rust_handle_size;
1728 #[ignore(cfg(target_os = "macos"))]
1729 #[ignore(cfg(target_os = "win32"))]
1730 fn test_uv_ll_struct_size_addrinfo() {
1732 let foreign_handle_size =
1733 ::uv_ll::rustrt::rust_uv_helper_addrinfo_size();
1734 let rust_handle_size = sys::size_of::<addrinfo>();
1735 let output = fmt!("addrinfo -- foreign: %u rust: %u",
1736 foreign_handle_size as uint, rust_handle_size);
1738 assert foreign_handle_size as uint == rust_handle_size;