]> git.lizzy.rs Git - rust.git/blob - src/libstd/rt/uv/uvll.rs
08e9bc062ce4e8b75b2fbcd592d9d549f7b0b606
[rust.git] / src / libstd / rt / uv / uvll.rs
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.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 /*!
12  * Low-level bindings to the libuv library.
13  *
14  * This module contains a set of direct, 'bare-metal' wrappers around
15  * the libuv C-API.
16  *
17  * We're not bothering yet to redefine uv's structs as Rust structs
18  * because they are quite large and change often between versions.
19  * The maintenance burden is just too high. Instead we use the uv's
20  * `uv_handle_size` and `uv_req_size` to find the correct size of the
21  * structs and allocate them on the heap. This can be revisited later.
22  *
23  * There are also a collection of helper functions to ease interacting
24  * with the low-level API.
25  *
26  * As new functionality, existent in uv.h, is added to the rust stdlib,
27  * the mappings should be added in this module.
28  */
29
30 #[allow(non_camel_case_types)]; // C types
31
32 use c_str::ToCStr;
33 use libc::{size_t, c_int, c_uint, c_void, c_char, uintptr_t};
34 #[cfg(not(stage0))]
35 use libc::ssize_t;
36 use libc::{malloc, free};
37 use libc;
38 use prelude::*;
39 use ptr;
40 use str;
41 use vec;
42
43 pub static UNKNOWN: c_int = -1;
44 pub static OK: c_int = 0;
45 pub static EOF: c_int = 1;
46 pub static EADDRINFO: c_int = 2;
47 pub static EACCES: c_int = 3;
48 pub static ECONNREFUSED: c_int = 12;
49 pub static ECONNRESET: c_int = 13;
50 pub static EPIPE: c_int = 36;
51
52 pub struct uv_err_t {
53     code: c_int,
54     sys_errno_: c_int
55 }
56
57 pub struct uv_buf_t {
58     base: *u8,
59     len: libc::size_t,
60 }
61
62 pub type uv_handle_t = c_void;
63 pub type uv_loop_t = c_void;
64 pub type uv_idle_t = c_void;
65 pub type uv_tcp_t = c_void;
66 pub type uv_udp_t = c_void;
67 pub type uv_connect_t = c_void;
68 pub type uv_connection_t = c_void;
69 pub type uv_write_t = c_void;
70 pub type uv_async_t = c_void;
71 pub type uv_timer_t = c_void;
72 pub type uv_stream_t = c_void;
73 pub type uv_fs_t = c_void;
74 pub type uv_udp_send_t = c_void;
75 pub type uv_getaddrinfo_t = c_void;
76
77 #[cfg(stage0)]
78 pub type uv_idle_cb = *u8;
79 #[cfg(stage0)]
80 pub type uv_alloc_cb = *u8;
81 #[cfg(stage0)]
82 pub type uv_read_cb = *u8;
83 #[cfg(stage0)]
84 pub type uv_udp_send_cb = *u8;
85 #[cfg(stage0)]
86 pub type uv_udp_recv_cb = *u8;
87 #[cfg(stage0)]
88 pub type uv_close_cb = *u8;
89 #[cfg(stage0)]
90 pub type uv_walk_cb = *u8;
91 #[cfg(stage0)]
92 pub type uv_async_cb = *u8;
93 #[cfg(stage0)]
94 pub type uv_connect_cb = *u8;
95 #[cfg(stage0)]
96 pub type uv_connection_cb = *u8;
97 #[cfg(stage0)]
98 pub type uv_timer_cb = *u8;
99 #[cfg(stage0)]
100 pub type uv_write_cb = *u8;
101 #[cfg(stage0)]
102 pub type uv_getaddrinfo_cb = *u8;
103
104 #[cfg(not(stage0))]
105 pub type uv_idle_cb = extern "C" fn(handle: *uv_idle_t,
106                                     status: c_int);
107 #[cfg(not(stage0))]
108 pub type uv_alloc_cb = extern "C" fn(stream: *uv_stream_t,
109                                      suggested_size: size_t) -> uv_buf_t;
110 #[cfg(not(stage0))]
111 pub type uv_read_cb = extern "C" fn(stream: *uv_stream_t,
112                                     nread: ssize_t,
113                                     buf: uv_buf_t);
114 #[cfg(not(stage0))]
115 pub type uv_udp_send_cb = extern "C" fn(req: *uv_udp_send_t,
116                                         status: c_int);
117 #[cfg(not(stage0))]
118 pub type uv_udp_recv_cb = extern "C" fn(handle: *uv_udp_t,
119                                         nread: ssize_t,
120                                         buf: uv_buf_t,
121                                         addr: *sockaddr,
122                                         flags: c_uint);
123 #[cfg(not(stage0))]
124 pub type uv_close_cb = extern "C" fn(handle: *uv_handle_t);
125 #[cfg(not(stage0))]
126 pub type uv_walk_cb = extern "C" fn(handle: *uv_handle_t,
127                                     arg: *c_void);
128 #[cfg(not(stage0))]
129 pub type uv_async_cb = extern "C" fn(handle: *uv_async_t,
130                                      status: c_int);
131 #[cfg(not(stage0))]
132 pub type uv_connect_cb = extern "C" fn(handle: *uv_connect_t,
133                                        status: c_int);
134 #[cfg(not(stage0))]
135 pub type uv_connection_cb = extern "C" fn(handle: *uv_connection_t,
136                                           status: c_int);
137 #[cfg(not(stage0))]
138 pub type uv_timer_cb = extern "C" fn(handle: *uv_timer_t,
139                                      status: c_int);
140 #[cfg(not(stage0))]
141 pub type uv_write_cb = extern "C" fn(handle: *uv_write_t,
142                                      status: c_int);
143 #[cfg(not(stage0))]
144 pub type uv_getaddrinfo_cb = extern "C" fn(req: *uv_getaddrinfo_t,
145                                            status: c_int,
146                                            res: *addrinfo);
147
148 pub type sockaddr = c_void;
149 pub type sockaddr_in = c_void;
150 pub type sockaddr_in6 = c_void;
151 pub type sockaddr_storage = c_void;
152
153 #[cfg(unix)]
154 pub type socklen_t = c_int;
155
156 // XXX: This is a standard C type. Could probably be defined in libc
157 #[cfg(target_os = "android")]
158 #[cfg(target_os = "linux")]
159 pub struct addrinfo {
160     ai_flags: c_int,
161     ai_family: c_int,
162     ai_socktype: c_int,
163     ai_protocol: c_int,
164     ai_addrlen: socklen_t,
165     ai_addr: *sockaddr,
166     ai_canonname: *char,
167     ai_next: *addrinfo
168 }
169
170 #[cfg(target_os = "macos")]
171 #[cfg(target_os = "freebsd")]
172 pub struct addrinfo {
173     ai_flags: c_int,
174     ai_family: c_int,
175     ai_socktype: c_int,
176     ai_protocol: c_int,
177     ai_addrlen: socklen_t,
178     ai_canonname: *char,
179     ai_addr: *sockaddr,
180     ai_next: *addrinfo
181 }
182
183 #[cfg(windows)]
184 pub struct addrinfo {
185     ai_flags: c_int,
186     ai_family: c_int,
187     ai_socktype: c_int,
188     ai_protocol: c_int,
189     ai_addrlen: size_t,
190     ai_canonname: *char,
191     ai_addr: *sockaddr,
192     ai_next: *addrinfo
193 }
194
195 #[deriving(Eq)]
196 pub enum uv_handle_type {
197     UV_UNKNOWN_HANDLE,
198     UV_ASYNC,
199     UV_CHECK,
200     UV_FS_EVENT,
201     UV_FS_POLL,
202     UV_HANDLE,
203     UV_IDLE,
204     UV_NAMED_PIPE,
205     UV_POLL,
206     UV_PREPARE,
207     UV_PROCESS,
208     UV_STREAM,
209     UV_TCP,
210     UV_TIMER,
211     UV_TTY,
212     UV_UDP,
213     UV_SIGNAL,
214     UV_FILE,
215     UV_HANDLE_TYPE_MAX
216 }
217
218 #[deriving(Eq)]
219 pub enum uv_req_type {
220     UV_UNKNOWN_REQ,
221     UV_REQ,
222     UV_CONNECT,
223     UV_WRITE,
224     UV_SHUTDOWN,
225     UV_UDP_SEND,
226     UV_FS,
227     UV_WORK,
228     UV_GETADDRINFO,
229     UV_REQ_TYPE_MAX
230 }
231
232 #[deriving(Eq)]
233 pub enum uv_membership {
234     UV_LEAVE_GROUP,
235     UV_JOIN_GROUP
236 }
237
238 pub unsafe fn malloc_handle(handle: uv_handle_type) -> *c_void {
239     #[fixed_stack_segment]; #[inline(never)];
240
241     assert!(handle != UV_UNKNOWN_HANDLE && handle != UV_HANDLE_TYPE_MAX);
242     let size = rust_uv_handle_size(handle as uint);
243     let p = malloc(size);
244     assert!(p.is_not_null());
245     return p;
246 }
247
248 pub unsafe fn free_handle(v: *c_void) {
249     #[fixed_stack_segment]; #[inline(never)];
250
251     free(v)
252 }
253
254 pub unsafe fn malloc_req(req: uv_req_type) -> *c_void {
255     #[fixed_stack_segment]; #[inline(never)];
256
257     assert!(req != UV_UNKNOWN_REQ && req != UV_REQ_TYPE_MAX);
258     let size = rust_uv_req_size(req as uint);
259     let p = malloc(size);
260     assert!(p.is_not_null());
261     return p;
262 }
263
264 pub unsafe fn free_req(v: *c_void) {
265     #[fixed_stack_segment]; #[inline(never)];
266
267     free(v)
268 }
269
270 #[test]
271 fn handle_sanity_check() {
272     #[fixed_stack_segment]; #[inline(never)];
273     unsafe {
274         assert_eq!(UV_HANDLE_TYPE_MAX as uint, rust_uv_handle_type_max());
275     }
276 }
277
278 #[test]
279 #[ignore(cfg(windows))] // FIXME #8817
280 #[fixed_stack_segment]
281 #[inline(never)]
282 fn request_sanity_check() {
283     unsafe {
284         assert_eq!(UV_REQ_TYPE_MAX as uint, rust_uv_req_type_max());
285     }
286 }
287
288 // XXX Event loops ignore SIGPIPE by default.
289 pub unsafe fn loop_new() -> *c_void {
290     #[fixed_stack_segment]; #[inline(never)];
291
292     return rust_uv_loop_new();
293 }
294
295 pub unsafe fn loop_delete(loop_handle: *c_void) {
296     #[fixed_stack_segment]; #[inline(never)];
297
298     rust_uv_loop_delete(loop_handle);
299 }
300
301 pub unsafe fn run(loop_handle: *c_void) {
302     #[fixed_stack_segment]; #[inline(never)];
303
304     rust_uv_run(loop_handle);
305 }
306
307 pub unsafe fn close<T>(handle: *T, cb: uv_close_cb) {
308     #[fixed_stack_segment]; #[inline(never)];
309
310     rust_uv_close(handle as *c_void, cb);
311 }
312
313 pub unsafe fn walk(loop_handle: *c_void, cb: uv_walk_cb, arg: *c_void) {
314     #[fixed_stack_segment]; #[inline(never)];
315
316     rust_uv_walk(loop_handle, cb, arg);
317 }
318
319 pub unsafe fn idle_new() -> *uv_idle_t {
320     #[fixed_stack_segment]; #[inline(never)];
321
322     rust_uv_idle_new()
323 }
324
325 pub unsafe fn idle_delete(handle: *uv_idle_t) {
326     #[fixed_stack_segment]; #[inline(never)];
327
328     rust_uv_idle_delete(handle)
329 }
330
331 pub unsafe fn idle_init(loop_handle: *uv_loop_t, handle: *uv_idle_t) -> c_int {
332     #[fixed_stack_segment]; #[inline(never)];
333
334     rust_uv_idle_init(loop_handle, handle)
335 }
336
337 pub unsafe fn idle_start(handle: *uv_idle_t, cb: uv_idle_cb) -> c_int {
338     #[fixed_stack_segment]; #[inline(never)];
339
340     rust_uv_idle_start(handle, cb)
341 }
342
343 pub unsafe fn idle_stop(handle: *uv_idle_t) -> c_int {
344     #[fixed_stack_segment]; #[inline(never)];
345
346     rust_uv_idle_stop(handle)
347 }
348
349 pub unsafe fn udp_init(loop_handle: *uv_loop_t, handle: *uv_udp_t) -> c_int {
350     #[fixed_stack_segment]; #[inline(never)];
351
352     return rust_uv_udp_init(loop_handle, handle);
353 }
354
355 pub unsafe fn udp_bind(server: *uv_udp_t, addr: *sockaddr_in, flags: c_uint) -> c_int {
356     #[fixed_stack_segment]; #[inline(never)];
357
358     return rust_uv_udp_bind(server, addr, flags);
359 }
360
361 pub unsafe fn udp_bind6(server: *uv_udp_t, addr: *sockaddr_in6, flags: c_uint) -> c_int {
362     #[fixed_stack_segment]; #[inline(never)];
363
364     return rust_uv_udp_bind6(server, addr, flags);
365 }
366
367 pub unsafe fn udp_send<T>(req: *uv_udp_send_t, handle: *T, buf_in: &[uv_buf_t],
368                           addr: *sockaddr_in, cb: uv_udp_send_cb) -> c_int {
369     #[fixed_stack_segment]; #[inline(never)];
370
371     let buf_ptr = vec::raw::to_ptr(buf_in);
372     let buf_cnt = buf_in.len() as i32;
373     return rust_uv_udp_send(req, handle as *c_void, buf_ptr, buf_cnt, addr, cb);
374 }
375
376 pub unsafe fn udp_send6<T>(req: *uv_udp_send_t, handle: *T, buf_in: &[uv_buf_t],
377                           addr: *sockaddr_in6, cb: uv_udp_send_cb) -> c_int {
378     #[fixed_stack_segment]; #[inline(never)];
379
380     let buf_ptr = vec::raw::to_ptr(buf_in);
381     let buf_cnt = buf_in.len() as i32;
382     return rust_uv_udp_send6(req, handle as *c_void, buf_ptr, buf_cnt, addr, cb);
383 }
384
385 pub unsafe fn udp_recv_start(server: *uv_udp_t, on_alloc: uv_alloc_cb,
386                              on_recv: uv_udp_recv_cb) -> c_int {
387     #[fixed_stack_segment]; #[inline(never)];
388
389     return rust_uv_udp_recv_start(server, on_alloc, on_recv);
390 }
391
392 pub unsafe fn udp_recv_stop(server: *uv_udp_t) -> c_int {
393     #[fixed_stack_segment]; #[inline(never)];
394
395     return rust_uv_udp_recv_stop(server);
396 }
397
398 pub unsafe fn get_udp_handle_from_send_req(send_req: *uv_udp_send_t) -> *uv_udp_t {
399     #[fixed_stack_segment]; #[inline(never)];
400
401     return rust_uv_get_udp_handle_from_send_req(send_req);
402 }
403
404 pub unsafe fn udp_getsockname(handle: *uv_udp_t, name: *sockaddr_storage) -> c_int {
405     #[fixed_stack_segment]; #[inline(never)];
406
407     return rust_uv_udp_getsockname(handle, name);
408 }
409
410 pub unsafe fn udp_set_membership(handle: *uv_udp_t, multicast_addr: *c_char,
411                                  interface_addr: *c_char, membership: uv_membership) -> c_int {
412     #[fixed_stack_segment]; #[inline(never)];
413
414     return rust_uv_udp_set_membership(handle, multicast_addr, interface_addr, membership as c_int);
415 }
416
417 pub unsafe fn udp_set_multicast_loop(handle: *uv_udp_t, on: c_int) -> c_int {
418     #[fixed_stack_segment]; #[inline(never)];
419
420     return rust_uv_udp_set_multicast_loop(handle, on);
421 }
422
423 pub unsafe fn udp_set_multicast_ttl(handle: *uv_udp_t, ttl: c_int) -> c_int {
424     #[fixed_stack_segment]; #[inline(never)];
425
426     return rust_uv_udp_set_multicast_ttl(handle, ttl);
427 }
428
429 pub unsafe fn udp_set_ttl(handle: *uv_udp_t, ttl: c_int) -> c_int {
430     #[fixed_stack_segment]; #[inline(never)];
431
432     return rust_uv_udp_set_ttl(handle, ttl);
433 }
434
435 pub unsafe fn udp_set_broadcast(handle: *uv_udp_t, on: c_int) -> c_int {
436     #[fixed_stack_segment]; #[inline(never)];
437
438     return rust_uv_udp_set_broadcast(handle, on);
439 }
440
441 pub unsafe fn tcp_init(loop_handle: *c_void, handle: *uv_tcp_t) -> c_int {
442     #[fixed_stack_segment]; #[inline(never)];
443
444     return rust_uv_tcp_init(loop_handle, handle);
445 }
446
447 pub unsafe fn tcp_connect(connect_ptr: *uv_connect_t, tcp_handle_ptr: *uv_tcp_t,
448                           addr_ptr: *sockaddr_in, after_connect_cb: uv_connect_cb) -> c_int {
449     #[fixed_stack_segment]; #[inline(never)];
450
451     return rust_uv_tcp_connect(connect_ptr, tcp_handle_ptr, after_connect_cb, addr_ptr);
452 }
453
454 pub unsafe fn tcp_connect6(connect_ptr: *uv_connect_t, tcp_handle_ptr: *uv_tcp_t,
455                            addr_ptr: *sockaddr_in6, after_connect_cb: uv_connect_cb) -> c_int {
456     #[fixed_stack_segment]; #[inline(never)];
457
458     return rust_uv_tcp_connect6(connect_ptr, tcp_handle_ptr, after_connect_cb, addr_ptr);
459 }
460
461 pub unsafe fn tcp_bind(tcp_server_ptr: *uv_tcp_t, addr_ptr: *sockaddr_in) -> c_int {
462     #[fixed_stack_segment]; #[inline(never)];
463
464     return rust_uv_tcp_bind(tcp_server_ptr, addr_ptr);
465 }
466
467 pub unsafe fn tcp_bind6(tcp_server_ptr: *uv_tcp_t, addr_ptr: *sockaddr_in6) -> c_int {
468     #[fixed_stack_segment]; #[inline(never)];
469
470     return rust_uv_tcp_bind6(tcp_server_ptr, addr_ptr);
471 }
472
473 pub unsafe fn tcp_getpeername(tcp_handle_ptr: *uv_tcp_t, name: *sockaddr_storage) -> c_int {
474     #[fixed_stack_segment]; #[inline(never)];
475
476     return rust_uv_tcp_getpeername(tcp_handle_ptr, name);
477 }
478
479 pub unsafe fn tcp_getsockname(handle: *uv_tcp_t, name: *sockaddr_storage) -> c_int {
480     #[fixed_stack_segment]; #[inline(never)];
481
482     return rust_uv_tcp_getsockname(handle, name);
483 }
484
485 pub unsafe fn tcp_nodelay(handle: *uv_tcp_t, enable: c_int) -> c_int {
486     #[fixed_stack_segment]; #[inline(never)];
487
488     return rust_uv_tcp_nodelay(handle, enable);
489 }
490
491 pub unsafe fn tcp_keepalive(handle: *uv_tcp_t, enable: c_int, delay: c_uint) -> c_int {
492     #[fixed_stack_segment]; #[inline(never)];
493
494     return rust_uv_tcp_keepalive(handle, enable, delay);
495 }
496
497 pub unsafe fn tcp_simultaneous_accepts(handle: *uv_tcp_t, enable: c_int) -> c_int {
498     #[fixed_stack_segment]; #[inline(never)];
499
500     return rust_uv_tcp_simultaneous_accepts(handle, enable);
501 }
502
503 pub unsafe fn listen<T>(stream: *T, backlog: c_int,
504                         cb: uv_connection_cb) -> c_int {
505     #[fixed_stack_segment]; #[inline(never)];
506
507     return rust_uv_listen(stream as *c_void, backlog, cb);
508 }
509
510 pub unsafe fn accept(server: *c_void, client: *c_void) -> c_int {
511     #[fixed_stack_segment]; #[inline(never)];
512
513     return rust_uv_accept(server as *c_void, client as *c_void);
514 }
515
516 pub unsafe fn write<T>(req: *uv_write_t,
517                        stream: *T,
518                        buf_in: &[uv_buf_t],
519                        cb: uv_write_cb) -> c_int {
520     #[fixed_stack_segment]; #[inline(never)];
521
522     let buf_ptr = vec::raw::to_ptr(buf_in);
523     let buf_cnt = buf_in.len() as i32;
524     return rust_uv_write(req as *c_void, stream as *c_void, buf_ptr, buf_cnt, cb);
525 }
526 pub unsafe fn read_start(stream: *uv_stream_t,
527                          on_alloc: uv_alloc_cb,
528                          on_read: uv_read_cb) -> c_int {
529     #[fixed_stack_segment]; #[inline(never)];
530
531     return rust_uv_read_start(stream as *c_void, on_alloc, on_read);
532 }
533
534 pub unsafe fn read_stop(stream: *uv_stream_t) -> c_int {
535     #[fixed_stack_segment]; #[inline(never)];
536
537     return rust_uv_read_stop(stream as *c_void);
538 }
539
540 pub unsafe fn last_error(loop_handle: *c_void) -> uv_err_t {
541     #[fixed_stack_segment]; #[inline(never)];
542
543     return rust_uv_last_error(loop_handle);
544 }
545
546 pub unsafe fn strerror(err: *uv_err_t) -> *c_char {
547     #[fixed_stack_segment]; #[inline(never)];
548
549     return rust_uv_strerror(err);
550 }
551 pub unsafe fn err_name(err: *uv_err_t) -> *c_char {
552     #[fixed_stack_segment]; #[inline(never)];
553
554     return rust_uv_err_name(err);
555 }
556
557 pub unsafe fn async_init(loop_handle: *c_void,
558                          async_handle: *uv_async_t,
559                          cb: uv_async_cb) -> c_int {
560     #[fixed_stack_segment]; #[inline(never)];
561
562     return rust_uv_async_init(loop_handle, async_handle, cb);
563 }
564
565 pub unsafe fn async_send(async_handle: *uv_async_t) {
566     #[fixed_stack_segment]; #[inline(never)];
567
568     return rust_uv_async_send(async_handle);
569 }
570 pub unsafe fn buf_init(input: *u8, len: uint) -> uv_buf_t {
571     #[fixed_stack_segment]; #[inline(never)];
572
573     let out_buf = uv_buf_t { base: ptr::null(), len: 0 as size_t };
574     let out_buf_ptr = ptr::to_unsafe_ptr(&out_buf);
575     rust_uv_buf_init(out_buf_ptr, input, len as size_t);
576     return out_buf;
577 }
578
579 pub unsafe fn timer_init(loop_ptr: *c_void, timer_ptr: *uv_timer_t) -> c_int {
580     #[fixed_stack_segment]; #[inline(never)];
581
582     return rust_uv_timer_init(loop_ptr, timer_ptr);
583 }
584 pub unsafe fn timer_start(timer_ptr: *uv_timer_t,
585                           cb: uv_timer_cb, timeout: u64,
586                           repeat: u64) -> c_int {
587     #[fixed_stack_segment]; #[inline(never)];
588
589     return rust_uv_timer_start(timer_ptr, cb, timeout, repeat);
590 }
591 pub unsafe fn timer_stop(timer_ptr: *uv_timer_t) -> c_int {
592     #[fixed_stack_segment]; #[inline(never)];
593
594     return rust_uv_timer_stop(timer_ptr);
595 }
596
597 pub unsafe fn is_ip4_addr(addr: *sockaddr) -> bool {
598     #[fixed_stack_segment]; #[inline(never)];
599
600     match rust_uv_is_ipv4_sockaddr(addr) { 0 => false, _ => true }
601 }
602
603 pub unsafe fn is_ip6_addr(addr: *sockaddr) -> bool {
604     #[fixed_stack_segment]; #[inline(never)];
605
606     match rust_uv_is_ipv6_sockaddr(addr) { 0 => false, _ => true }
607 }
608
609 pub unsafe fn malloc_ip4_addr(ip: &str, port: int) -> *sockaddr_in {
610     #[fixed_stack_segment]; #[inline(never)];
611     do ip.with_c_str |ip_buf| {
612         rust_uv_ip4_addrp(ip_buf as *u8, port as libc::c_int)
613     }
614 }
615 pub unsafe fn malloc_ip6_addr(ip: &str, port: int) -> *sockaddr_in6 {
616     #[fixed_stack_segment]; #[inline(never)];
617     do ip.with_c_str |ip_buf| {
618         rust_uv_ip6_addrp(ip_buf as *u8, port as libc::c_int)
619     }
620 }
621
622 pub unsafe fn malloc_sockaddr_storage() -> *sockaddr_storage {
623     #[fixed_stack_segment]; #[inline(never)];
624
625     rust_uv_malloc_sockaddr_storage()
626 }
627
628 pub unsafe fn free_sockaddr_storage(ss: *sockaddr_storage) {
629     #[fixed_stack_segment]; #[inline(never)];
630
631     rust_uv_free_sockaddr_storage(ss);
632 }
633
634 pub unsafe fn free_ip4_addr(addr: *sockaddr_in) {
635     #[fixed_stack_segment]; #[inline(never)];
636
637     rust_uv_free_ip4_addr(addr);
638 }
639
640 pub unsafe fn free_ip6_addr(addr: *sockaddr_in6) {
641     #[fixed_stack_segment]; #[inline(never)];
642
643     rust_uv_free_ip6_addr(addr);
644 }
645
646 pub unsafe fn ip4_name(addr: *sockaddr_in, dst: *u8, size: size_t) -> c_int {
647     #[fixed_stack_segment]; #[inline(never)];
648
649     return rust_uv_ip4_name(addr, dst, size);
650 }
651
652 pub unsafe fn ip6_name(addr: *sockaddr_in6, dst: *u8, size: size_t) -> c_int {
653     #[fixed_stack_segment]; #[inline(never)];
654
655     return rust_uv_ip6_name(addr, dst, size);
656 }
657
658 pub unsafe fn ip4_port(addr: *sockaddr_in) -> c_uint {
659     #[fixed_stack_segment]; #[inline(never)];
660
661    return rust_uv_ip4_port(addr);
662 }
663
664 pub unsafe fn ip6_port(addr: *sockaddr_in6) -> c_uint {
665     #[fixed_stack_segment]; #[inline(never)];
666
667     return rust_uv_ip6_port(addr);
668 }
669
670 pub unsafe fn fs_open(loop_ptr: *uv_loop_t, req: *uv_fs_t, path: *c_char, flags: int, mode: int,
671                 cb: *u8) -> c_int {
672     #[fixed_stack_segment]; #[inline(never)];
673
674     rust_uv_fs_open(loop_ptr, req, path, flags as c_int, mode as c_int, cb)
675 }
676
677 pub unsafe fn fs_unlink(loop_ptr: *uv_loop_t, req: *uv_fs_t, path: *c_char,
678                 cb: *u8) -> c_int {
679     #[fixed_stack_segment]; #[inline(never)];
680
681     rust_uv_fs_unlink(loop_ptr, req, path, cb)
682 }
683 pub unsafe fn fs_write(loop_ptr: *uv_loop_t, req: *uv_fs_t, fd: c_int, buf: *c_void,
684                        len: uint, offset: i64, cb: *u8) -> c_int {
685     #[fixed_stack_segment]; #[inline(never)];
686
687     rust_uv_fs_write(loop_ptr, req, fd, buf, len as c_uint, offset, cb)
688 }
689 pub unsafe fn fs_read(loop_ptr: *uv_loop_t, req: *uv_fs_t, fd: c_int, buf: *c_void,
690                        len: uint, offset: i64, cb: *u8) -> c_int {
691     #[fixed_stack_segment]; #[inline(never)];
692
693     rust_uv_fs_read(loop_ptr, req, fd, buf, len as c_uint, offset, cb)
694 }
695 pub unsafe fn fs_close(loop_ptr: *uv_loop_t, req: *uv_fs_t, fd: c_int,
696                 cb: *u8) -> c_int {
697     #[fixed_stack_segment]; #[inline(never)];
698
699     rust_uv_fs_close(loop_ptr, req, fd, cb)
700 }
701 pub unsafe fn fs_req_cleanup(req: *uv_fs_t) {
702     #[fixed_stack_segment]; #[inline(never)];
703
704     rust_uv_fs_req_cleanup(req);
705 }
706
707 // data access helpers
708 pub unsafe fn get_result_from_fs_req(req: *uv_fs_t) -> c_int {
709     #[fixed_stack_segment]; #[inline(never)];
710
711     rust_uv_get_result_from_fs_req(req)
712 }
713 pub unsafe fn get_loop_from_fs_req(req: *uv_fs_t) -> *uv_loop_t {
714     #[fixed_stack_segment]; #[inline(never)];
715
716     rust_uv_get_loop_from_fs_req(req)
717 }
718 pub unsafe fn get_loop_from_getaddrinfo_req(req: *uv_getaddrinfo_t) -> *uv_loop_t {
719     #[fixed_stack_segment]; #[inline(never)];
720
721     rust_uv_get_loop_from_getaddrinfo_req(req)
722 }
723 pub unsafe fn get_loop_for_uv_handle<T>(handle: *T) -> *c_void {
724     #[fixed_stack_segment]; #[inline(never)];
725
726     return rust_uv_get_loop_for_uv_handle(handle as *c_void);
727 }
728 pub unsafe fn get_stream_handle_from_connect_req(connect: *uv_connect_t) -> *uv_stream_t {
729     #[fixed_stack_segment]; #[inline(never)];
730
731     return rust_uv_get_stream_handle_from_connect_req(connect);
732 }
733 pub unsafe fn get_stream_handle_from_write_req(write_req: *uv_write_t) -> *uv_stream_t {
734     #[fixed_stack_segment]; #[inline(never)];
735
736     return rust_uv_get_stream_handle_from_write_req(write_req);
737 }
738 pub unsafe fn get_data_for_uv_loop(loop_ptr: *c_void) -> *c_void {
739     #[fixed_stack_segment]; #[inline(never)];
740
741     rust_uv_get_data_for_uv_loop(loop_ptr)
742 }
743 pub unsafe fn set_data_for_uv_loop(loop_ptr: *c_void, data: *c_void) {
744     #[fixed_stack_segment]; #[inline(never)];
745
746     rust_uv_set_data_for_uv_loop(loop_ptr, data);
747 }
748 pub unsafe fn get_data_for_uv_handle<T>(handle: *T) -> *c_void {
749     #[fixed_stack_segment]; #[inline(never)];
750
751     return rust_uv_get_data_for_uv_handle(handle as *c_void);
752 }
753 pub unsafe fn set_data_for_uv_handle<T, U>(handle: *T, data: *U) {
754     #[fixed_stack_segment]; #[inline(never)];
755
756     rust_uv_set_data_for_uv_handle(handle as *c_void, data as *c_void);
757 }
758 pub unsafe fn get_data_for_req<T>(req: *T) -> *c_void {
759     #[fixed_stack_segment]; #[inline(never)];
760
761     return rust_uv_get_data_for_req(req as *c_void);
762 }
763 pub unsafe fn set_data_for_req<T, U>(req: *T, data: *U) {
764     #[fixed_stack_segment]; #[inline(never)];
765
766     rust_uv_set_data_for_req(req as *c_void, data as *c_void);
767 }
768 pub unsafe fn get_base_from_buf(buf: uv_buf_t) -> *u8 {
769     #[fixed_stack_segment]; #[inline(never)];
770
771     return rust_uv_get_base_from_buf(buf);
772 }
773 pub unsafe fn get_len_from_buf(buf: uv_buf_t) -> size_t {
774     #[fixed_stack_segment]; #[inline(never)];
775
776     return rust_uv_get_len_from_buf(buf);
777 }
778 pub unsafe fn getaddrinfo(loop_: *uv_loop_t, req: *uv_getaddrinfo_t,
779                getaddrinfo_cb: uv_getaddrinfo_cb,
780                node: *c_char, service: *c_char,
781                hints: *addrinfo) -> c_int {
782     #[fixed_stack_segment]; #[inline(never)];
783     return rust_uv_getaddrinfo(loop_, req, getaddrinfo_cb, node, service, hints);
784 }
785 pub unsafe fn freeaddrinfo(ai: *addrinfo) {
786     #[fixed_stack_segment]; #[inline(never)];
787     rust_uv_freeaddrinfo(ai);
788 }
789
790 pub unsafe fn get_last_err_info(uv_loop: *c_void) -> ~str {
791     let err = last_error(uv_loop);
792     let err_ptr = ptr::to_unsafe_ptr(&err);
793     let err_name = str::raw::from_c_str(err_name(err_ptr));
794     let err_msg = str::raw::from_c_str(strerror(err_ptr));
795     return fmt!("LIBUV ERROR: name: %s msg: %s",
796                     err_name, err_msg);
797 }
798
799 pub unsafe fn get_last_err_data(uv_loop: *c_void) -> uv_err_data {
800     let err = last_error(uv_loop);
801     let err_ptr = ptr::to_unsafe_ptr(&err);
802     let err_name = str::raw::from_c_str(err_name(err_ptr));
803     let err_msg = str::raw::from_c_str(strerror(err_ptr));
804     uv_err_data { err_name: err_name, err_msg: err_msg }
805 }
806
807 pub struct uv_err_data {
808     err_name: ~str,
809     err_msg: ~str,
810 }
811
812 extern {
813
814     fn rust_uv_handle_size(type_: uintptr_t) -> size_t;
815     fn rust_uv_req_size(type_: uintptr_t) -> size_t;
816     fn rust_uv_handle_type_max() -> uintptr_t;
817     fn rust_uv_req_type_max() -> uintptr_t;
818
819     // libuv public API
820     fn rust_uv_loop_new() -> *c_void;
821     fn rust_uv_loop_delete(lp: *c_void);
822     fn rust_uv_run(loop_handle: *c_void);
823     fn rust_uv_close(handle: *c_void, cb: uv_close_cb);
824     fn rust_uv_walk(loop_handle: *c_void, cb: uv_walk_cb, arg: *c_void);
825
826     fn rust_uv_idle_new() -> *uv_idle_t;
827     fn rust_uv_idle_delete(handle: *uv_idle_t);
828     fn rust_uv_idle_init(loop_handle: *uv_loop_t, handle: *uv_idle_t) -> c_int;
829     fn rust_uv_idle_start(handle: *uv_idle_t, cb: uv_idle_cb) -> c_int;
830     fn rust_uv_idle_stop(handle: *uv_idle_t) -> c_int;
831
832     fn rust_uv_async_send(handle: *uv_async_t);
833     fn rust_uv_async_init(loop_handle: *c_void,
834                           async_handle: *uv_async_t,
835                           cb: uv_async_cb) -> c_int;
836     fn rust_uv_tcp_init(loop_handle: *c_void, handle_ptr: *uv_tcp_t) -> c_int;
837     fn rust_uv_buf_init(out_buf: *uv_buf_t, base: *u8, len: size_t);
838     fn rust_uv_last_error(loop_handle: *c_void) -> uv_err_t;
839     fn rust_uv_strerror(err: *uv_err_t) -> *c_char;
840     fn rust_uv_err_name(err: *uv_err_t) -> *c_char;
841     fn rust_uv_ip4_addrp(ip: *u8, port: c_int) -> *sockaddr_in;
842     fn rust_uv_ip6_addrp(ip: *u8, port: c_int) -> *sockaddr_in6;
843     fn rust_uv_free_ip4_addr(addr: *sockaddr_in);
844     fn rust_uv_free_ip6_addr(addr: *sockaddr_in6);
845     fn rust_uv_ip4_name(src: *sockaddr_in, dst: *u8, size: size_t) -> c_int;
846     fn rust_uv_ip6_name(src: *sockaddr_in6, dst: *u8, size: size_t) -> c_int;
847     fn rust_uv_ip4_port(src: *sockaddr_in) -> c_uint;
848     fn rust_uv_ip6_port(src: *sockaddr_in6) -> c_uint;
849     fn rust_uv_tcp_connect(req: *uv_connect_t, handle: *uv_tcp_t,
850                            cb: uv_connect_cb,
851                            addr: *sockaddr_in) -> c_int;
852     fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t, addr: *sockaddr_in) -> c_int;
853     fn rust_uv_tcp_connect6(req: *uv_connect_t, handle: *uv_tcp_t,
854                             cb: uv_connect_cb,
855                             addr: *sockaddr_in6) -> c_int;
856     fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t, addr: *sockaddr_in6) -> c_int;
857     fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t, name: *sockaddr_storage) -> c_int;
858     fn rust_uv_tcp_getsockname(handle: *uv_tcp_t, name: *sockaddr_storage) -> c_int;
859     fn rust_uv_tcp_nodelay(handle: *uv_tcp_t, enable: c_int) -> c_int;
860     fn rust_uv_tcp_keepalive(handle: *uv_tcp_t, enable: c_int, delay: c_uint) -> c_int;
861     fn rust_uv_tcp_simultaneous_accepts(handle: *uv_tcp_t, enable: c_int) -> c_int;
862
863     fn rust_uv_udp_init(loop_handle: *uv_loop_t, handle_ptr: *uv_udp_t) -> c_int;
864     fn rust_uv_udp_bind(server: *uv_udp_t, addr: *sockaddr_in, flags: c_uint) -> c_int;
865     fn rust_uv_udp_bind6(server: *uv_udp_t, addr: *sockaddr_in6, flags: c_uint) -> c_int;
866     fn rust_uv_udp_send(req: *uv_udp_send_t, handle: *uv_udp_t, buf_in: *uv_buf_t,
867                         buf_cnt: c_int, addr: *sockaddr_in, cb: uv_udp_send_cb) -> c_int;
868     fn rust_uv_udp_send6(req: *uv_udp_send_t, handle: *uv_udp_t, buf_in: *uv_buf_t,
869                          buf_cnt: c_int, addr: *sockaddr_in6, cb: uv_udp_send_cb) -> c_int;
870     fn rust_uv_udp_recv_start(server: *uv_udp_t,
871                               on_alloc: uv_alloc_cb,
872                               on_recv: uv_udp_recv_cb) -> c_int;
873     fn rust_uv_udp_recv_stop(server: *uv_udp_t) -> c_int;
874     fn rust_uv_get_udp_handle_from_send_req(req: *uv_udp_send_t) -> *uv_udp_t;
875     fn rust_uv_udp_getsockname(handle: *uv_udp_t, name: *sockaddr_storage) -> c_int;
876     fn rust_uv_udp_set_membership(handle: *uv_udp_t, multicast_addr: *c_char,
877                                   interface_addr: *c_char, membership: c_int) -> c_int;
878     fn rust_uv_udp_set_multicast_loop(handle: *uv_udp_t, on: c_int) -> c_int;
879     fn rust_uv_udp_set_multicast_ttl(handle: *uv_udp_t, ttl: c_int) -> c_int;
880     fn rust_uv_udp_set_ttl(handle: *uv_udp_t, ttl: c_int) -> c_int;
881     fn rust_uv_udp_set_broadcast(handle: *uv_udp_t, on: c_int) -> c_int;
882
883     fn rust_uv_is_ipv4_sockaddr(addr: *sockaddr) -> c_int;
884     fn rust_uv_is_ipv6_sockaddr(addr: *sockaddr) -> c_int;
885     fn rust_uv_malloc_sockaddr_storage() -> *sockaddr_storage;
886     fn rust_uv_free_sockaddr_storage(ss: *sockaddr_storage);
887
888     fn rust_uv_listen(stream: *c_void, backlog: c_int,
889                       cb: uv_connection_cb) -> c_int;
890     fn rust_uv_accept(server: *c_void, client: *c_void) -> c_int;
891     fn rust_uv_write(req: *c_void, stream: *c_void, buf_in: *uv_buf_t, buf_cnt: c_int,
892                      cb: uv_write_cb) -> c_int;
893     fn rust_uv_read_start(stream: *c_void,
894                           on_alloc: uv_alloc_cb,
895                           on_read: uv_read_cb) -> c_int;
896     fn rust_uv_read_stop(stream: *c_void) -> c_int;
897     fn rust_uv_timer_init(loop_handle: *c_void, timer_handle: *uv_timer_t) -> c_int;
898     fn rust_uv_timer_start(timer_handle: *uv_timer_t, cb: uv_timer_cb, timeout: libc::uint64_t,
899                            repeat: libc::uint64_t) -> c_int;
900     fn rust_uv_timer_stop(handle: *uv_timer_t) -> c_int;
901     fn rust_uv_fs_open(loop_ptr: *c_void, req: *uv_fs_t, path: *c_char,
902                        flags: c_int, mode: c_int, cb: *u8) -> c_int;
903     fn rust_uv_fs_unlink(loop_ptr: *c_void, req: *uv_fs_t, path: *c_char,
904                        cb: *u8) -> c_int;
905     fn rust_uv_fs_write(loop_ptr: *c_void, req: *uv_fs_t, fd: c_int,
906                        buf: *c_void, len: c_uint, offset: i64, cb: *u8) -> c_int;
907     fn rust_uv_fs_read(loop_ptr: *c_void, req: *uv_fs_t, fd: c_int,
908                        buf: *c_void, len: c_uint, offset: i64, cb: *u8) -> c_int;
909     fn rust_uv_fs_close(loop_ptr: *c_void, req: *uv_fs_t, fd: c_int,
910                         cb: *u8) -> c_int;
911     fn rust_uv_fs_req_cleanup(req: *uv_fs_t);
912     fn rust_uv_get_result_from_fs_req(req: *uv_fs_t) -> c_int;
913     fn rust_uv_get_loop_from_fs_req(req: *uv_fs_t) -> *uv_loop_t;
914     fn rust_uv_get_loop_from_getaddrinfo_req(req: *uv_fs_t) -> *uv_loop_t;
915
916     fn rust_uv_get_stream_handle_from_connect_req(connect_req: *uv_connect_t) -> *uv_stream_t;
917     fn rust_uv_get_stream_handle_from_write_req(write_req: *uv_write_t) -> *uv_stream_t;
918     fn rust_uv_get_loop_for_uv_handle(handle: *c_void) -> *c_void;
919     fn rust_uv_get_data_for_uv_loop(loop_ptr: *c_void) -> *c_void;
920     fn rust_uv_set_data_for_uv_loop(loop_ptr: *c_void, data: *c_void);
921     fn rust_uv_get_data_for_uv_handle(handle: *c_void) -> *c_void;
922     fn rust_uv_set_data_for_uv_handle(handle: *c_void, data: *c_void);
923     fn rust_uv_get_data_for_req(req: *c_void) -> *c_void;
924     fn rust_uv_set_data_for_req(req: *c_void, data: *c_void);
925     fn rust_uv_get_base_from_buf(buf: uv_buf_t) -> *u8;
926     fn rust_uv_get_len_from_buf(buf: uv_buf_t) -> size_t;
927     fn rust_uv_getaddrinfo(loop_: *uv_loop_t, req: *uv_getaddrinfo_t,
928                            getaddrinfo_cb: uv_getaddrinfo_cb,
929                            node: *c_char, service: *c_char,
930                            hints: *addrinfo) -> c_int;
931     fn rust_uv_freeaddrinfo(ai: *addrinfo);
932 }