about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorJeff Olson <olson.jeffery@gmail.com>2012-03-22 21:15:39 -0700
committerBrian Anderson <banderson@mozilla.com>2012-04-06 15:35:48 -0700
commite5ccc76bc4e32538f8b2cb5f6745f42ce50ac232 (patch)
treea9f275b248045f076a13b8a2bc193b68b3849b64 /src
parent43c82bdb453523be57512c91d267bac05018ed19 (diff)
downloadrust-e5ccc76bc4e32538f8b2cb5f6745f42ce50ac232.tar.gz
rust-e5ccc76bc4e32538f8b2cb5f6745f42ce50ac232.zip
fixed by-val from rust->c, use ++ sigil in native fn sig <-- NEVAR FORGET
have to use ++ sigil in rust-side extern fn decls in order to have rust
actually copy the struct, by value, onto the C stack. gotcha, indeed.

also adding a helper method to verify/remind how to pass a struct by-val
into C... check out the rust fn sig for rust_uv_ip4_test_verify_port_val()
for more infos
Diffstat (limited to 'src')
-rw-r--r--src/libstd/uv.rs46
-rw-r--r--src/rt/rust_uv.cpp17
2 files changed, 43 insertions, 20 deletions
diff --git a/src/libstd/uv.rs b/src/libstd/uv.rs
index 30c8cbd9c4e..e52b1121a6f 100644
--- a/src/libstd/uv.rs
+++ b/src/libstd/uv.rs
@@ -217,17 +217,15 @@ fn gen_stub_uv_write_t() -> uv_write_t {
     ret { loop_handle: ptr::null() };
 }
 
-// not going to use this type, for now, because of
-// github issue #1402
 // unix size: 16
 #[cfg(target_os = "linux")]
 #[cfg(target_os = "macos")]
 #[cfg(target_os = "freebsd")]
 type sockaddr_in = {
-    sin_family: u16,
-    sin_port: u16,
-    sin_addr: u32, // in_addr: this is an opaque, per-platform struct
-    sin_zero: *u8
+    mut sin_family: u16,
+    mut sin_port: u16,
+    mut sin_addr: u32, // in_addr: this is an opaque, per-platform struct
+    mut sin_zero: (u8, u8, u8, u8, u8, u8, u8, u8)
 };
 
 // unix size: 28 .. make due w/ 32
@@ -275,11 +273,14 @@ native mod rustrt {
     fn rust_uv_buf_init(base: *u8, len: libc::size_t)
         -> *libc::c_void;
     fn rust_uv_last_error(loop_handle: *libc::c_void) -> uv_err_t;
+    fn rust_uv_ip4_test_verify_port_val(++addr: sockaddr_in,
+                                        expected: libc::c_uint)
+        -> bool;
     fn rust_uv_ip4_addr(ip: *u8, port: libc::c_int)
         -> sockaddr_in;
     fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t,
                            tcp_handle_ptr: *uv_tcp_t,
-                           addr: *libc::c_void,
+                           ++addr: sockaddr_in,
                            after_cb: *u8) -> libc::c_int;
     fn rust_uv_write(req: *libc::c_void, stream: *libc::c_void,
              buf_in: **libc::c_void, buf_cnt: libc::c_int,
@@ -329,9 +330,10 @@ mod direct {
     }
     unsafe fn tcp_connect(connect_ptr: *uv_connect_t,
                           tcp_handle_ptr: *uv_tcp_t,
-                          address: *libc::c_void,
+                          address: sockaddr_in,
                           after_connect_cb: *u8)
     -> libc::c_int {
+        io::println(#fmt("before native tcp_connect -- addr port: %u", address.sin_port as uint));
         ret rustrt::rust_uv_tcp_connect(connect_ptr, tcp_handle_ptr,
                                     address, after_connect_cb);
     }
@@ -380,15 +382,15 @@ mod direct {
     unsafe fn buf_init(input: *u8, len: uint) -> *libc::c_void {
         ret rustrt::rust_uv_buf_init(input, len);
     }
-    // TODO: see github issue #1402
-    unsafe fn ip4_addr(ip: str, port: libc::c_int)
+    unsafe fn ip4_addr(ip: str, port: int)
     -> sockaddr_in {
         let mut addr_vec = str::bytes(ip);
         addr_vec += [0u8]; // add null terminator
         let addr_vec_ptr = vec::unsafe::to_ptr(addr_vec);
         let ip_back = str::from_bytes(addr_vec);
         io::println(#fmt("vec val: '%s' length: %u",ip_back, vec::len(addr_vec)));
-        ret rustrt::rust_uv_ip4_addr(addr_vec_ptr, port);
+        ret rustrt::rust_uv_ip4_addr(addr_vec_ptr,
+                                     port as libc::c_int);
     }
     // this is lame.
     // TODO: see github issue #1402
@@ -1032,11 +1034,11 @@ fn impl_uv_tcp_request() unsafe {
         io::println("sucessful tcp_init_result");
         
         io::println("building addr...");
-        let addr_val = direct::ip4_addr("173.194.33.40", 80i32);
+        let addr = direct::ip4_addr("173.194.33.40", 80);
         io::println(#fmt("after build addr in rust. port: %u",
-                         addr_val.sin_port as uint));
-        let addr: *libc::c_void = ptr::addr_of(addr_val) as
-                                    *libc::c_void;
+                         addr.sin_port as uint));
+        //let addr: *libc::c_void = ptr::addr_of(addr_val) as
+        //                            *libc::c_void;
         
         // this should set up the connection request..
         let tcp_connect_result = direct::tcp_connect(
@@ -1128,3 +1130,17 @@ fn test_uv_struct_size_sockaddr_in() {
     io::println(output);
     assert native_handle_size as uint == rust_handle_size;
 }
+
+fn impl_uv_byval_test() unsafe {
+    let addr = direct::ip4_addr("173.194.33.111", 80);
+    io::println(#fmt("after build addr in rust. port: %u",
+                     addr.sin_port as uint));
+    assert rustrt::rust_uv_ip4_test_verify_port_val(addr,
+                                   addr.sin_port as libc::c_uint);
+    io::println(#fmt("after build addr in rust. port: %u",
+                     addr.sin_port as uint));
+}
+#[test]
+fn test_uv_ip4_byval_passing_test() {
+    impl_uv_byval_test();
+}
diff --git a/src/rt/rust_uv.cpp b/src/rt/rust_uv.cpp
index c62af8edf40..cfe3b78b108 100644
--- a/src/rt/rust_uv.cpp
+++ b/src/rt/rust_uv.cpp
@@ -287,12 +287,12 @@ rust_uv_last_error(uv_loop_t* loop) {
 extern "C" int
 rust_uv_tcp_connect(uv_connect_t* connect_ptr,
 					uv_tcp_t* tcp_ptr,
-					void* addr_ptr,
+					struct sockaddr_in addr,
 					uv_connect_cb cb) {
 	//return uv_tcp_connect(connect_ptr, tcp_ptr, addr, cb);
 	printf("inside rust_uv_tcp_connect\n");
-	sockaddr_in addr_tmp = *((sockaddr_in*)addr_ptr);
-	sockaddr_in addr = addr_tmp;
+	//sockaddr_in addr_tmp = *((sockaddr_in*)addr_ptr);
+	//sockaddr_in addr = addr_tmp;
 	printf("before tcp_connect .. port: %d\n", addr.sin_port);
 	int result = uv_tcp_connect(connect_ptr, tcp_ptr, addr, cb);
 	printf ("leaving rust_uv_tcp_connect.. and result: %d\n",
@@ -313,10 +313,17 @@ rust_uv_write(uv_write_t* req, uv_stream_t* handle,
 	return uv_write(req, handle, buf_vals, buf_cnt, cb);
 }
 
-extern "C" sockaddr_in
+extern "C" struct sockaddr_in
 rust_uv_ip4_addr(const char* ip, int port) {
 	printf("before creating addr_ptr.. ip %s port %d\n", ip, port);
-	sockaddr_in addr = uv_ip4_addr("173.194.33.40", 80);
+	struct sockaddr_in addr = uv_ip4_addr(ip, port);
 	printf("after creating .. port: %d\n", addr.sin_port);
 	return addr;
 }
+
+extern "C" bool
+rust_uv_ip4_test_verify_port_val(struct sockaddr_in addr,
+								 unsigned int expected) {
+	printf("inside c++ ip4_test .. port: %u\n", addr.sin_port);
+	return addr.sin_port == expected;
+}