]> git.lizzy.rs Git - rust.git/blob - src/libstd/uv_ll.rs
778daf131c4b0e78f6a14c9df19adbc0419ae285
[rust.git] / src / libstd / uv_ll.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  * 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
20  * representations.
21  *
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).
25  *
26  * As new functionality, existant in uv.h, is added to the rust stdlib,
27  * the mappings should be added in this module.
28  *
29  * This module's implementation will hopefully be, eventually, replaced
30  * with per-platform, generated source files from rust-bindgen.
31  */
32
33 #[allow(non_camel_case_types)]; // C types
34
35 use core::libc::size_t;
36 use core::libc;
37 use core::prelude::*;
38 use core::ptr::to_unsafe_ptr;
39 use core::ptr;
40 use core::str;
41 use core::vec;
42
43 // libuv struct mappings
44 pub type uv_ip4_addr = {
45     ip: ~[u8],
46     port: int
47 };
48 pub type uv_ip6_addr = uv_ip4_addr;
49
50 pub enum uv_handle_type {
51     UNKNOWN_HANDLE = 0,
52     UV_TCP,
53     UV_UDP,
54     UV_NAMED_PIPE,
55     UV_TTY,
56     UV_FILE,
57     UV_TIMER,
58     UV_PREPARE,
59     UV_CHECK,
60     UV_IDLE,
61     UV_ASYNC,
62     UV_ARES_TASK,
63     UV_ARES_EVENT,
64     UV_PROCESS,
65     UV_FS_EVENT
66 }
67
68 pub type handle_type = libc::c_uint;
69
70 pub type uv_handle_fields = {
71    loop_handle: *libc::c_void,
72    type_: handle_type,
73    close_cb: *u8,
74    mut data: *libc::c_void,
75 };
76
77 // unix size: 8
78 pub type uv_err_t = {
79     code: libc::c_int,
80     sys_errno_: libc::c_int
81 };
82
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
90 };
91
92 // 64bit unix size: 272
93 #[cfg(unix)]
94 pub type uv_tcp_t = {
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,
103     a28: *u8,
104     a30: uv_tcp_t_32bit_unix_riders
105 };
106 // 32bit unix size: 328 (164)
107 #[cfg(target_arch="x86_64")]
108 pub type uv_tcp_t_32bit_unix_riders = {
109     a29: *u8
110 };
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,
115     a35: *u8, a36: *u8
116 };
117
118 // 32bit win32 size: 240 (120)
119 #[cfg(windows)]
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,
128     a24: *u8, a25: *u8
129 };
130
131 // unix size: 48
132 #[cfg(unix)]
133 pub type uv_connect_t = {
134     a00: *u8, a01: *u8, a02: *u8, a03: *u8,
135     a04: *u8, a05: *u8
136 };
137 // win32 size: 88 (44)
138 #[cfg(windows)]
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
143 };
144
145 // unix size: 16
146 pub type uv_buf_t = {
147     base: *u8,
148     len: libc::size_t
149 };
150 // no gen stub method.. should create
151 // it via uv::direct::buf_init()
152
153 // unix size: 144
154 #[cfg(unix)]
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,
160     a12: *u8,
161     a14: uv_write_t_32bit_unix_riders
162 };
163 #[cfg(target_arch="x86_64")]
164 pub type uv_write_t_32bit_unix_riders = {
165     a13: *u8
166 };
167 #[cfg(target_arch="x86")]
168 pub type uv_write_t_32bit_unix_riders = {
169     a13: *u8, a14: *u8
170 };
171 // win32 size: 136 (68)
172 #[cfg(windows)]
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,
178     a12: *u8
179 };
180 // 64bit unix size: 120
181 // 32bit unix size: 152 (76)
182 #[cfg(unix)]
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,
187     a08: *u8, a09: *u8,
188     a11: uv_async_t_32bit_unix_riders
189 };
190 #[cfg(target_arch="x86_64")]
191 pub type uv_async_t_32bit_unix_riders = {
192     a10: *u8
193 };
194 #[cfg(target_arch="x86")]
195 pub type uv_async_t_32bit_unix_riders = {
196     a10: *u8, a11: *u8, a12: *u8, a13: *u8
197 };
198 // win32 size 132 (68)
199 #[cfg(windows)]
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,
205     a12: *u8
206 };
207
208 // 64bit unix size: 128
209 // 32bit unix size: 84
210 #[cfg(unix)]
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,
215     a08: *u8, a09: *u8,
216     a11: uv_timer_t_32bit_unix_riders
217 };
218 #[cfg(target_arch="x86_64")]
219 pub type uv_timer_t_32bit_unix_riders = {
220     a10: *u8, a11: *u8
221 };
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
226 };
227 // win32 size: 64
228 #[cfg(windows)]
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
234 };
235
236 // unix size: 16
237 pub type sockaddr_in = {
238     mut sin_family: u16,
239     mut sin_port: u16,
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)
242 };
243
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 = {
248     a0: *u8, a1: *u8,
249     a2: *u8, a3: *u8
250 };
251 #[cfg(target_arch="x86")]
252 pub type sockaddr_in6 = {
253     a0: *u8, a1: *u8,
254     a2: *u8, a3: *u8,
255     a4: *u8, a5: *u8,
256     a6: *u8, a7: *u8
257 };
258
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;
262 #[cfg(unix)]
263 pub mod addr_in_impl {
264     #[cfg(target_arch="x86_64")]
265     pub type addr_in = {
266         a0: *u8, a1: *u8,
267         a2: *u8, a3: *u8
268     };
269     #[cfg(target_arch="x86")]
270     pub type addr_in = {
271         a0: *u8, a1: *u8,
272         a2: *u8, a3: *u8,
273         a4: *u8, a5: *u8,
274         a6: *u8, a7: *u8,
275     };
276 }
277 #[cfg(windows)]
278 pub mod addr_in_impl {
279     pub type addr_in = {
280         a0: *u8, a1: *u8,
281         a2: *u8, a3: *u8
282     };
283 }
284
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,
292         a04: *u8, a05: *u8
293     };
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
298     };
299 }
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,
305         a04: *u8, a05: *u8
306     };
307 }
308 #[cfg(windows)]
309 pub mod addrinfo_impl {
310     pub type addrinfo = {
311         a00: *u8, a01: *u8, a02: *u8, a03: *u8,
312         a04: *u8, a05: *u8
313     };
314 }
315
316 // unix size: 72
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
320 };
321
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};
325
326     use core::ptr;
327
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,
341                     a03: 0 as *u8,
342                     a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
343                     a07: 0 as *u8,
344                     a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
345                     a11: 0 as *u8,
346                     a12: 0 as *u8, a13: 0 as *u8, a14: 0 as *u8,
347                     a15: 0 as *u8,
348                     a16: 0 as *u8, a17: 0 as *u8, a18: 0 as *u8,
349                     a19: 0 as *u8,
350                     a20: 0 as *u8, a21: 0 as *u8, a22: 0 as *u8,
351                     a23: 0 as *u8,
352                     a24: 0 as *u8, a25: 0 as *u8, a26: 0 as *u8,
353                     a27: 0 as *u8,
354                     a28: 0 as *u8,
355                     a30: {
356                         a29: 0 as *u8
357                     }
358                 };
359             }
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,
366                     a03: 0 as *u8,
367                     a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
368                     a07: 0 as *u8,
369                     a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
370                     a11: 0 as *u8,
371                     a12: 0 as *u8, a13: 0 as *u8, a14: 0 as *u8,
372                     a15: 0 as *u8,
373                     a16: 0 as *u8, a17: 0 as *u8, a18: 0 as *u8,
374                     a19: 0 as *u8,
375                     a20: 0 as *u8, a21: 0 as *u8, a22: 0 as *u8,
376                     a23: 0 as *u8,
377                     a24: 0 as *u8, a25: 0 as *u8, a26: 0 as *u8,
378                     a27: 0 as *u8,
379                     a28: 0 as *u8,
380                     a30: {
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
384                     }
385                 };
386             }
387         }
388         #[cfg(windows)]
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,
394                 a03: 0 as *u8,
395                 a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
396                 a07: 0 as *u8,
397                 a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
398                 a11: 0 as *u8,
399                 a12: 0 as *u8, a13: 0 as *u8, a14: 0 as *u8,
400                 a15: 0 as *u8,
401                 a16: 0 as *u8, a17: 0 as *u8, a18: 0 as *u8,
402                 a19: 0 as *u8,
403                 a20: 0 as *u8, a21: 0 as *u8, a22: 0 as *u8,
404                 a23: 0 as *u8,
405                 a24: 0 as *u8, a25: 0 as *u8
406             };
407         }
408     }
409     #[cfg(unix)]
410     pub fn gen_stub_uv_connect_t() -> uv_connect_t {
411         return {
412             a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
413             a03: 0 as *u8,
414             a04: 0 as *u8, a05: 0 as *u8
415         };
416     }
417     #[cfg(windows)]
418     pub fn gen_stub_uv_connect_t() -> uv_connect_t {
419         return {
420             a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
421             a03: 0 as *u8,
422             a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
423             a07: 0 as *u8,
424             a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8
425         };
426     }
427     #[cfg(unix)]
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,
436                 a03: 0 as *u8,
437                 a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
438                 a07: 0 as *u8,
439                 a08: 0 as *u8, a09: 0 as *u8,
440                 a11: {
441                     a10: 0 as *u8
442                 }
443             };
444         }
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,
451                 a03: 0 as *u8,
452                 a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
453                 a07: 0 as *u8,
454                 a08: 0 as *u8, a09: 0 as *u8,
455                 a11: {
456                     a10: 0 as *u8, a11: 0 as *u8,
457                     a12: 0 as *u8, a13: 0 as *u8
458                 }
459             };
460         }
461     }
462     #[cfg(windows)]
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,
468             a03: 0 as *u8,
469             a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
470             a07: 0 as *u8,
471             a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
472             a11: 0 as *u8,
473             a12: 0 as *u8
474         };
475     }
476     #[cfg(unix)]
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,
485                 a03: 0 as *u8,
486                 a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
487                 a07: 0 as *u8,
488                 a08: 0 as *u8, a09: 0 as *u8,
489                 a11: {
490                     a10: 0 as *u8, a11: 0 as *u8
491                 }
492             };
493         }
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,
500                 a03: 0 as *u8,
501                 a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
502                 a07: 0 as *u8,
503                 a08: 0 as *u8, a09: 0 as *u8,
504                 a11: {
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,
508                     a16: 0 as *u8
509                 }
510             };
511         }
512     }
513     #[cfg(windows)]
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,
519             a03: 0 as *u8,
520             a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
521             a07: 0 as *u8,
522             a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
523             a11: 0 as *u8
524         };
525     }
526     #[cfg(unix)]
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,
535                 a03: 0 as *u8,
536                 a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
537                 a07: 0 as *u8,
538                 a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
539                 a11: 0 as *u8,
540                 a12: 0 as *u8, a14: { a13: 0 as *u8 }
541             };
542         }
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,
549                 a03: 0 as *u8,
550                 a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
551                 a07: 0 as *u8,
552                 a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
553                 a11: 0 as *u8,
554                 a12: 0 as *u8, a14: { a13: 0 as *u8, a14: 0 as *u8 }
555             };
556         }
557     }
558     #[cfg(windows)]
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,
564             a03: 0 as *u8,
565             a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
566             a07: 0 as *u8,
567             a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
568             a11: 0 as *u8,
569             a12: 0 as *u8
570         };
571     }
572     pub fn gen_stub_uv_getaddrinfo_t() -> uv_getaddrinfo_t {
573         {
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,
576             a08: 0 as *u8
577         }
578     }
579 }
580
581 #[nolink]
582 extern mod rustrt {
583     // libuv public API
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,
598                         len: libc::size_t);
599     unsafe fn rust_uv_last_error(loop_handle: *libc::c_void) -> uv_err_t;
600     // FIXME ref #2064
601     unsafe fn rust_uv_strerror(err: *uv_err_t) -> *libc::c_char;
602     // FIXME ref #2064
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)
605         -> sockaddr_in;
606     unsafe fn rust_uv_ip6_addr(ip: *u8, port: libc::c_int)
607         -> sockaddr_in6;
608     unsafe fn rust_uv_ip4_name(src: *sockaddr_in,
609                                dst: *u8,
610                                size: libc::size_t)
611                             -> libc::c_int;
612     unsafe fn rust_uv_ip6_name(src: *sockaddr_in6,
613                                dst: *u8,
614                                size: libc::size_t)
615                             -> libc::c_int;
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;
618     // FIXME ref #2064
619     unsafe fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t,
620                                   tcp_handle_ptr: *uv_tcp_t,
621                                   ++after_cb: *u8,
622                                   ++addr: *sockaddr_in) -> libc::c_int;
623     // FIXME ref #2064
624     unsafe fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t,
625                                ++addr: *sockaddr_in) -> libc::c_int;
626     // FIXME ref #2064
627     unsafe fn rust_uv_tcp_connect6(connect_ptr: *uv_connect_t,
628                                    tcp_handle_ptr: *uv_tcp_t,
629                                    ++after_cb: *u8,
630                                    ++addr: *sockaddr_in6) -> libc::c_int;
631     // FIXME ref #2064
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)
642                           -> libc::c_int;
643     unsafe fn rust_uv_write(req: *libc::c_void,
644                             stream: *libc::c_void,
645                             ++buf_in: *uv_buf_t,
646                             buf_cnt: libc::c_int,
647                             cb: *u8)
648                          -> libc::c_int;
649     unsafe fn rust_uv_read_start(stream: *libc::c_void,
650                                  on_alloc: *u8,
651                                  on_read: *u8)
652                               -> libc::c_int;
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)
656                               -> libc::c_int;
657     unsafe fn rust_uv_timer_start(
658         timer_handle: *uv_timer_t,
659         cb: *u8,
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;
663
664     unsafe fn rust_uv_getaddrinfo(loop_ptr: *libc::c_void,
665                                   handle: *uv_getaddrinfo_t,
666                                   cb: *u8,
667                                   node_name_ptr: *u8,
668                                   service_name_ptr: *u8,
669                                   // should probably only pass ptr::null()
670                                   hints: *addrinfo)
671                                -> libc::c_int;
672     unsafe fn rust_uv_freeaddrinfo(res: *addrinfo);
673
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)
680                                            -> *sockaddr_in;
681     unsafe fn rust_uv_addrinfo_as_sockaddr_in6(input: *addrinfo)
682                                             -> *sockaddr_in6;
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)
687         -> *uv_stream_t;
688     unsafe fn rust_uv_get_stream_handle_from_write_req(
689         write_req: *uv_write_t)
690         -> *uv_stream_t;
691     unsafe fn rust_uv_get_loop_for_uv_handle(handle: *libc::c_void)
692         -> *libc::c_void;
693     unsafe fn rust_uv_get_data_for_uv_loop(loop_ptr: *libc::c_void)
694                                         -> *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)
698                                           -> *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;
706
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;
720 }
721
722 pub unsafe fn loop_new() -> *libc::c_void {
723     return rustrt::rust_uv_loop_new();
724 }
725
726 pub unsafe fn loop_delete(loop_handle: *libc::c_void) {
727     rustrt::rust_uv_loop_delete(loop_handle);
728 }
729
730 pub unsafe fn loop_refcount(loop_ptr: *libc::c_void) -> libc::c_int {
731     return rustrt::rust_uv_loop_refcount(loop_ptr);
732 }
733
734 pub unsafe fn run(loop_handle: *libc::c_void) {
735     rustrt::rust_uv_run(loop_handle);
736 }
737
738 pub unsafe fn close<T>(handle: *T, cb: *u8) {
739     rustrt::rust_uv_close(handle as *libc::c_void, cb);
740 }
741
742 pub unsafe fn tcp_init(loop_handle: *libc::c_void, handle: *uv_tcp_t)
743     -> libc::c_int {
744     return rustrt::rust_uv_tcp_init(loop_handle, handle);
745 }
746 // FIXME ref #2064
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)
751 -> libc::c_int {
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);
756 }
757 // FIXME ref #2064
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)
762 -> libc::c_int {
763     return rustrt::rust_uv_tcp_connect6(connect_ptr, tcp_handle_ptr,
764                                     after_connect_cb, addr_ptr);
765 }
766 // FIXME ref #2064
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,
770                                  addr_ptr);
771 }
772 // FIXME ref #2064
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,
776                                  addr_ptr);
777 }
778
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);
782 }
783
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);
787 }
788
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);
792 }
793
794 pub unsafe fn accept(server: *libc::c_void, client: *libc::c_void)
795     -> libc::c_int {
796     return rustrt::rust_uv_accept(server as *libc::c_void,
797                                client as *libc::c_void);
798 }
799
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);
807 }
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,
811                                    on_alloc, on_read);
812 }
813
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);
816 }
817
818 pub unsafe fn last_error(loop_handle: *libc::c_void) -> uv_err_t {
819     return rustrt::rust_uv_last_error(loop_handle);
820 }
821
822 pub unsafe fn strerror(err: *uv_err_t) -> *libc::c_char {
823     return rustrt::rust_uv_strerror(err);
824 }
825 pub unsafe fn err_name(err: *uv_err_t) -> *libc::c_char {
826     return rustrt::rust_uv_err_name(err);
827 }
828
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,
833                                    async_handle,
834                                    cb);
835 }
836
837 pub unsafe fn async_send(async_handle: *uv_async_t) {
838     return rustrt::rust_uv_async_send(async_handle);
839 }
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",
844                      input as uint,
845                      len as uint,
846                      out_buf_ptr as uint));
847     // yuck :/
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",
855                      res_base as uint,
856                      res_len as uint));
857     return out_buf;
858     //return result;
859 }
860 pub unsafe fn ip4_addr(ip: &str, port: int)
861 -> sockaddr_in {
862     do str::as_c_str(ip) |ip_buf| {
863         rustrt::rust_uv_ip4_addr(ip_buf as *u8,
864                                  port as libc::c_int)
865     }
866 }
867 pub unsafe fn ip6_addr(ip: &str, port: int)
868 -> sockaddr_in6 {
869     do str::as_c_str(ip) |ip_buf| {
870         rustrt::rust_uv_ip6_addr(ip_buf as *u8,
871                                  port as libc::c_int)
872     }
873 }
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
886         // many platforms)
887         str::raw::from_buf(dst_buf)
888     }
889 }
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);
904         match result {
905           0i32 => str::raw::from_buf(dst_buf),
906           _ => ~""
907         }
908     }
909 }
910 pub unsafe fn ip4_port(src: &sockaddr_in) -> uint {
911     rustrt::rust_uv_ip4_port(to_unsafe_ptr(src)) as uint
912 }
913 pub unsafe fn ip6_port(src: &sockaddr_in6) -> uint {
914     rustrt::rust_uv_ip6_port(to_unsafe_ptr(src)) as uint
915 }
916
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);
920 }
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);
925 }
926 pub unsafe fn timer_stop(timer_ptr: *uv_timer_t) -> libc::c_int {
927     return rustrt::rust_uv_timer_stop(timer_ptr);
928 }
929 pub unsafe fn getaddrinfo(loop_ptr: *libc::c_void,
930                            handle: *uv_getaddrinfo_t,
931                            cb: *u8,
932                            node_name_ptr: *u8,
933                            service_name_ptr: *u8,
934                            hints: *addrinfo) -> libc::c_int {
935     rustrt::rust_uv_getaddrinfo(loop_ptr,
936                            handle,
937                            cb,
938                            node_name_ptr,
939                            service_name_ptr,
940                            hints)
941 }
942 pub unsafe fn freeaddrinfo(res: *addrinfo) {
943     rustrt::rust_uv_freeaddrinfo(res);
944 }
945
946 // libuv struct initializers
947 pub unsafe fn tcp_t() -> uv_tcp_t {
948     return uv_ll_struct_stubgen::gen_stub_uv_tcp_t();
949 }
950 pub unsafe fn connect_t() -> uv_connect_t {
951     return uv_ll_struct_stubgen::gen_stub_uv_connect_t();
952 }
953 pub unsafe fn write_t() -> uv_write_t {
954     return uv_ll_struct_stubgen::gen_stub_uv_write_t();
955 }
956 pub unsafe fn async_t() -> uv_async_t {
957     return uv_ll_struct_stubgen::gen_stub_uv_async_t();
958 }
959 pub unsafe fn timer_t() -> uv_timer_t {
960     return uv_ll_struct_stubgen::gen_stub_uv_timer_t();
961 }
962 pub unsafe fn getaddrinfo_t() -> uv_getaddrinfo_t {
963     return uv_ll_struct_stubgen::gen_stub_uv_getaddrinfo_t();
964 }
965
966 // data access helpers
967 pub unsafe fn get_loop_for_uv_handle<T>(handle: *T)
968     -> *libc::c_void {
969     return rustrt::rust_uv_get_loop_for_uv_handle(handle as *libc::c_void);
970 }
971 pub unsafe fn get_stream_handle_from_connect_req(connect: *uv_connect_t)
972     -> *uv_stream_t {
973     return rustrt::rust_uv_get_stream_handle_from_connect_req(
974         connect);
975 }
976 pub unsafe fn get_stream_handle_from_write_req(
977     write_req: *uv_write_t)
978     -> *uv_stream_t {
979     return rustrt::rust_uv_get_stream_handle_from_write_req(
980         write_req);
981 }
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)
984 }
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);
988 }
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);
991 }
992 pub unsafe fn set_data_for_uv_handle<T, U>(handle: *T,
993                     data: *U) {
994     rustrt::rust_uv_set_data_for_uv_handle(handle as *libc::c_void,
995                                            data as *libc::c_void);
996 }
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);
999 }
1000 pub unsafe fn set_data_for_req<T, U>(req: *T,
1001                     data: *U) {
1002     rustrt::rust_uv_set_data_for_req(req as *libc::c_void,
1003                                      data as *libc::c_void);
1004 }
1005 pub unsafe fn get_base_from_buf(buf: uv_buf_t) -> *u8 {
1006     return rustrt::rust_uv_get_base_from_buf(buf);
1007 }
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);
1010 }
1011 pub unsafe fn malloc_buf_base_of(suggested_size: libc::size_t)
1012     -> *u8 {
1013     return rustrt::rust_uv_malloc_buf_base_of(suggested_size);
1014 }
1015 pub unsafe fn free_base_of_buf(buf: uv_buf_t) {
1016     rustrt::rust_uv_free_base_of_buf(buf);
1017 }
1018
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",
1025                     err_name, err_msg);
1026 }
1027
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 }
1034 }
1035
1036 pub type uv_err_data = {
1037     err_name: ~str,
1038     err_msg: ~str
1039 };
1040
1041 pub unsafe fn is_ipv4_addrinfo(input: *addrinfo) -> bool {
1042     rustrt::rust_uv_is_ipv4_addrinfo(input)
1043 }
1044 pub unsafe fn is_ipv6_addrinfo(input: *addrinfo) -> bool {
1045     rustrt::rust_uv_is_ipv6_addrinfo(input)
1046 }
1047 pub unsafe fn get_INADDR_NONE() -> u32 {
1048     rustrt::rust_uv_helper_get_INADDR_NONE()
1049 }
1050 pub unsafe fn get_next_addrinfo(input: *addrinfo) -> *addrinfo {
1051     rustrt::rust_uv_get_next_addrinfo(input)
1052 }
1053 pub unsafe fn addrinfo_as_sockaddr_in(input: *addrinfo) -> *sockaddr_in {
1054     rustrt::rust_uv_addrinfo_as_sockaddr_in(input)
1055 }
1056 pub unsafe fn addrinfo_as_sockaddr_in6(input: *addrinfo) -> *sockaddr_in6 {
1057     rustrt::rust_uv_addrinfo_as_sockaddr_in6(input)
1058 }
1059
1060 #[cfg(test)]
1061 pub mod test {
1062     use core::prelude::*;
1063
1064     use uv_ll::*;
1065
1066     use core::libc;
1067     use core::oldcomm;
1068     use core::ptr;
1069     use core::str;
1070     use core::sys;
1071     use core::task;
1072     use core::vec;
1073
1074     enum tcp_read_data {
1075         tcp_read_eof,
1076         tcp_read_more(~[u8]),
1077         tcp_read_error
1078     }
1079
1080     type request_wrapper = {
1081         write_req: *uv_write_t,
1082         req_buf: *~[uv_buf_t],
1083         read_chan: *oldcomm::Chan<~str>
1084     };
1085
1086     extern fn after_close_cb(handle: *libc::c_void) {
1087         log(debug, fmt!("after uv_close! handle ptr: %?",
1088                         handle));
1089     }
1090
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",
1097                          handle,
1098                          char_ptr as uint,
1099                          suggested_size as uint));
1100         return buf_init(char_ptr, suggested_size as uint);
1101     }
1102
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",
1108                         nread));
1109         if (nread > 0) {
1110             // we have data
1111             log(debug, fmt!("CLIENT read: data! nread: %d", nread));
1112             read_stop(stream);
1113             let client_data =
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)
1123         }
1124         else if (nread == -1) {
1125             // err .. possibly EOF
1126             log(debug, ~"read: eof!");
1127         }
1128         else {
1129             // nread == 0 .. do nothing, just free buf as below
1130             log(debug, ~"read: do nothing!");
1131         }
1132         // when we're done
1133         free_base_of_buf(buf);
1134         log(debug, ~"CLIENT exiting on_read_cb");
1135     }
1136
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",
1140                          status as int));
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",
1146                          result as int));
1147     }
1148
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",
1152                          status as int));
1153         let stream =
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));
1169         }
1170         else {
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);
1175             assert false;
1176         }
1177         log(debug, ~"finishing on_connect_cb");
1178     }
1179
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);
1187
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));
1196         let req_msg = ~[
1197             buf_init(req_msg_ptr, vec::len(req_str_bytes))
1198         ];
1199         // this is the enclosing record, we'll pass a ptr to
1200         // this to C..
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 };
1209
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");
1214
1215             log(debug, ~"building addr...");
1216             let addr = ip4_addr(ip, port);
1217             // FIXME ref #2064
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));
1221
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
1231                 set_data_for_req(
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");
1238                 run(test_loop);
1239                 log(debug, ~"after run tcp req loop");
1240             }
1241             else {
1242                log(debug, ~"tcp_connect() failure");
1243                assert false;
1244             }
1245         }
1246         else {
1247             log(debug, ~"tcp_init() failure");
1248             assert false;
1249         }
1250         loop_delete(test_loop);
1251
1252     }
1253
1254     extern fn server_after_close_cb(handle: *libc::c_void) unsafe {
1255         log(debug, fmt!("SERVER server stream closed, should exit.. h: %?",
1256                    handle));
1257     }
1258
1259     extern fn client_stream_after_close_cb(handle: *libc::c_void)
1260         unsafe {
1261         log(debug,
1262             ~"SERVER: closed client stream, now closing server stream");
1263         let client_data = get_data_for_uv_handle(
1264             handle) as
1265             *tcp_server_data;
1266         close((*client_data).server as *libc::c_void,
1267                       server_after_close_cb);
1268     }
1269
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)
1276     }
1277
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;
1282         if (nread > 0) {
1283             // we have data
1284             log(debug, fmt!("SERVER read: data! nread: %d", nread));
1285
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",
1290                             buf_base as uint,
1291                             buf_len as uint,
1292                             nread));
1293             let bytes = vec::from_buf(buf_base, buf_len);
1294             let request_str = str::from_bytes(bytes);
1295
1296             let client_data = get_data_for_uv_handle(
1297                 client_stream_ptr as *libc::c_void) as *tcp_server_data;
1298
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(
1308                     write_req,
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)));
1319                     assert false;
1320                 }
1321             }
1322             else {
1323                 log(debug, ~"SERVER: client req !contain kill_msg!");
1324             }
1325         }
1326         else if (nread == -1) {
1327             // err .. possibly EOF
1328             log(debug, ~"read: eof!");
1329         }
1330         else {
1331             // nread == 0 .. do nothing, just free buf as below
1332             log(debug, ~"read: do nothing!");
1333         }
1334         // when we're done
1335         free_base_of_buf(buf);
1336         log(debug, ~"SERVER exiting on_read_cb");
1337     }
1338
1339     extern fn server_connection_cb(server_stream_ptr:
1340                                     *uv_stream_t,
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);
1345         if status != 0i32 {
1346             let err_msg = get_last_err_info(test_loop);
1347             log(debug, fmt!("server_connect_cb: non-zero status: %?",
1348                          err_msg));
1349             return;
1350         }
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,
1355                                                   client_stream_ptr);
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
1362                                                  *libc::c_void,
1363                                                client_stream_ptr as
1364                                                  *libc::c_void);
1365             if (accept_result == 0i32) {
1366                 // start reading
1367                 let read_result = read_start(
1368                     client_stream_ptr as *uv_stream_t,
1369                                                      on_alloc_cb,
1370                                                      on_server_read_cb);
1371                 if (read_result == 0i32) {
1372                     log(debug, ~"successful server read start");
1373                 }
1374                 else {
1375                     log(debug, fmt!("server_connection_cb: bad read:%d",
1376                                     read_result as int));
1377                     assert false;
1378                 }
1379             }
1380             else {
1381                 log(debug, fmt!("server_connection_cb: bad accept: %d",
1382                             accept_result as int));
1383                 assert false;
1384             }
1385         }
1386         else {
1387             log(debug, fmt!("server_connection_cb: bad client init: %d",
1388                         client_init_result as int));
1389             assert false;
1390         }
1391     }
1392
1393     type tcp_server_data = {
1394         client: *uv_tcp_t,
1395         server: *uv_tcp_t,
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
1400     };
1401
1402     type async_handle_data = {
1403         continue_chan: *oldcomm::Chan<bool>
1404     };
1405
1406     extern fn async_close_cb(handle: *libc::c_void) {
1407         log(debug, fmt!("SERVER: closing async cb... h: %?",
1408                    handle));
1409     }
1410
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
1416         // do its thang
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);
1423     }
1424
1425     fn impl_uv_tcp_server(server_ip: &str,
1426                           server_port: int,
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);
1434
1435         let tcp_client = tcp_t();
1436         let tcp_client_ptr = ptr::addr_of(&tcp_client);
1437
1438         let server_write_req = write_t();
1439         let server_write_req_ptr = ptr::addr_of(&server_write_req);
1440
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));
1444         let resp_msg = ~[
1445             buf_init(resp_msg_ptr, vec::len(resp_str_bytes))
1446         ];
1447
1448         let continue_async_handle = async_t();
1449         let continue_async_handle_ptr =
1450             ptr::addr_of(&continue_async_handle);
1451         let async_data =
1452             { continue_chan: continue_chan };
1453         let async_data_ptr = ptr::addr_of(&async_data);
1454
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
1462         };
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);
1466
1467         // uv_tcp_init()
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);
1472             // FIXME ref #2064
1473             let server_addr_ptr = ptr::addr_of(&server_addr);
1474
1475             // uv_tcp_bind()
1476             let bind_result = tcp_bind(tcp_server_ptr,
1477                                                server_addr_ptr);
1478             if (bind_result == 0i32) {
1479                 log(debug, ~"successful uv_tcp_bind, listening");
1480
1481                 // uv_listen()
1482                 let listen_result = listen(tcp_server_ptr as
1483                                                      *libc::c_void,
1484                                                    128i32,
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,
1491                                        continue_async_cb);
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);
1497                         // uv_run()
1498                         run(test_loop);
1499                         log(debug, ~"server uv::run() has returned");
1500                     }
1501                     else {
1502                         log(debug, fmt!("uv_async_init failure: %d",
1503                                 async_result as int));
1504                         assert false;
1505                     }
1506                 }
1507                 else {
1508                     log(debug, fmt!("non-zero result on uv_listen: %d",
1509                                 listen_result as int));
1510                     assert false;
1511                 }
1512             }
1513             else {
1514                 log(debug, fmt!("non-zero result on uv_tcp_bind: %d",
1515                             bind_result as int));
1516                 assert false;
1517             }
1518         }
1519         else {
1520             log(debug, fmt!("non-zero result on uv_tcp_init: %d",
1521                         tcp_init_result as int));
1522             assert false;
1523         }
1524         loop_delete(test_loop);
1525     }
1526
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";
1532         let port = 8886;
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);
1539
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);
1543
1544         do task::spawn_sched(task::ManualThreads(1)) {
1545             impl_uv_tcp_server(bind_ip, port,
1546                                kill_server_msg,
1547                                server_resp_msg,
1548                                ptr::addr_of(&server_chan),
1549                                continue_chan_ptr);
1550         };
1551
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");
1556
1557         do task::spawn_sched(task::ManualThreads(1u)) {
1558             impl_uv_tcp_request(request_ip, port,
1559                                kill_server_msg,
1560                                ptr::addr_of(&client_chan));
1561         };
1562
1563         let msg_from_client = oldcomm::recv(server_port);
1564         let msg_from_server = oldcomm::recv(client_port);
1565
1566         assert str::contains(msg_from_client, kill_server_msg);
1567         assert str::contains(msg_from_server, server_resp_msg);
1568     }
1569
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")]
1576         pub mod impl64 {
1577             use uv_ll::test::*;
1578             #[test]
1579             pub fn test_uv_ll_tcp_server_and_request() unsafe {
1580                 impl_uv_tcp_server_and_request();
1581             }
1582         }
1583         #[cfg(target_arch="x86")]
1584         pub mod impl32 {
1585             use uv_ll::test::*;
1586             #[test]
1587             #[ignore(cfg(target_os = "linux"))]
1588             pub fn test_uv_ll_tcp_server_and_request() unsafe {
1589                 impl_uv_tcp_server_and_request();
1590             }
1591         }
1592     }
1593
1594     // struct size tests
1595     #[test]
1596     fn test_uv_ll_struct_size_uv_tcp_t() {
1597         unsafe {
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);
1603             log(debug, output);
1604             assert foreign_handle_size as uint == rust_handle_size;
1605         }
1606     }
1607     #[test]
1608     fn test_uv_ll_struct_size_uv_connect_t() {
1609         unsafe {
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);
1615             log(debug, output);
1616             assert foreign_handle_size as uint == rust_handle_size;
1617         }
1618     }
1619     #[test]
1620     fn test_uv_ll_struct_size_uv_buf_t() {
1621         unsafe {
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);
1627             log(debug, output);
1628             assert foreign_handle_size as uint == rust_handle_size;
1629         }
1630     }
1631     #[test]
1632     fn test_uv_ll_struct_size_uv_write_t() {
1633         unsafe {
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);
1639             log(debug, output);
1640             assert foreign_handle_size as uint == rust_handle_size;
1641         }
1642     }
1643
1644     #[test]
1645     fn test_uv_ll_struct_size_sockaddr_in() {
1646         unsafe {
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);
1652             log(debug, output);
1653             assert foreign_handle_size as uint == rust_handle_size;
1654         }
1655     }
1656     #[test]
1657     fn test_uv_ll_struct_size_sockaddr_in6() {
1658         unsafe {
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);
1664             log(debug, output);
1665             // FIXME #1645 .. rust appears to pad structs to the nearest
1666             // byte..?
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;
1671         }
1672     }
1673     #[test]
1674     #[ignore(reason = "questionable size calculations")]
1675     fn test_uv_ll_struct_size_addr_in() {
1676         unsafe {
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);
1682             log(debug, output);
1683             // FIXME #1645 .. see note above about struct padding
1684             assert (4u+foreign_handle_size as uint) == rust_handle_size;
1685         }
1686     }
1687
1688     #[test]
1689     fn test_uv_ll_struct_size_uv_async_t() {
1690         unsafe {
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);
1696             log(debug, output);
1697             assert foreign_handle_size as uint == rust_handle_size;
1698         }
1699     }
1700
1701     #[test]
1702     fn test_uv_ll_struct_size_uv_timer_t() {
1703         unsafe {
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);
1709             log(debug, output);
1710             assert foreign_handle_size as uint == rust_handle_size;
1711         }
1712     }
1713
1714     #[test]
1715     #[ignore(cfg(target_os = "win32"))]
1716     fn test_uv_ll_struct_size_uv_getaddrinfo_t() {
1717         unsafe {
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);
1723             log(debug, output);
1724             assert foreign_handle_size as uint == rust_handle_size;
1725         }
1726     }
1727     #[test]
1728     #[ignore(cfg(target_os = "macos"))]
1729     #[ignore(cfg(target_os = "win32"))]
1730     fn test_uv_ll_struct_size_addrinfo() {
1731         unsafe {
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);
1737             log(debug, output);
1738             assert foreign_handle_size as uint == rust_handle_size;
1739         }
1740     }
1741 }