about summary refs log tree commit diff
path: root/src/libstd/rt
diff options
context:
space:
mode:
authorJeff Olson <olson.jeffery@gmail.com>2013-08-15 23:54:54 -0700
committerJeff Olson <olson.jeffery@gmail.com>2013-08-22 16:31:57 -0700
commitdabbac1d6c06c00f24148ffc58b42455496fdd3c (patch)
tree06a67dbb456e735015310faaea41709249ff31d2 /src/libstd/rt
parenta901b166901601c6b132c2036882ad9754722f1c (diff)
downloadrust-dabbac1d6c06c00f24148ffc58b42455496fdd3c.tar.gz
rust-dabbac1d6c06c00f24148ffc58b42455496fdd3c.zip
std: working tests for low-level libuv open, write and close operations
Diffstat (limited to 'src/libstd/rt')
-rw-r--r--src/libstd/rt/uv/file.rs119
-rw-r--r--src/libstd/rt/uv/uvll.rs34
2 files changed, 126 insertions, 27 deletions
diff --git a/src/libstd/rt/uv/file.rs b/src/libstd/rt/uv/file.rs
index cab27ee29c1..2a16a34070d 100644
--- a/src/libstd/rt/uv/file.rs
+++ b/src/libstd/rt/uv/file.rs
@@ -11,8 +11,9 @@
 use prelude::*;
 use ptr::null;
 use libc::c_void;
-use rt::uv::{Request, NativeHandle, Loop, FsCallback,
-             status_to_maybe_uv_error_with_loop};
+use rt::uv::{Request, NativeHandle, Loop, FsCallback, Buf,
+             status_to_maybe_uv_error_with_loop,
+             vec_to_uv_buf};//, vec_from_uv_buf};
 use rt::uv::uvll;
 use rt::uv::uvll::*;
 use path::Path;
@@ -30,6 +31,14 @@ pub enum UvFileFlag {
     O_CREAT,
     O_TRUNC
 }
+// just want enough to get 0644
+#[allow(non_camel_case_types)]
+pub enum UvFileMode {
+    S_IWUSR,
+    S_IRUSR,
+    S_IRGRP,
+    S_IROTH
+}
 pub fn map_flag(v: UvFileFlag) -> int {
     unsafe {
         match v {
@@ -41,9 +50,21 @@ pub fn map_flag(v: UvFileFlag) -> int {
         }
     }
 }
+pub fn map_mode(v: UvFileMode) -> int {
+    unsafe {
+        match v {
+            S_IWUSR => uvll::get_S_IWUSR() as int,
+            S_IRUSR => uvll::get_S_IRUSR() as int,
+            S_IRGRP => uvll::get_S_IRGRP() as int,
+            S_IROTH => uvll::get_S_IROTH() as int
+        }
+    }
+}
 
 pub struct RequestData {
-    complete_cb: Option<FsCallback>
+    complete_cb: Option<FsCallback>,
+    buf: Option<Buf>,
+    raw_fd: Option<c_int>
 }
 
 impl FsRequest {
@@ -58,7 +79,9 @@ impl FsRequest {
     pub fn install_req_data(&self, cb: Option<FsCallback>) {
         let fs_req = (self.native_handle()) as *uvll::uv_write_t;
         let data = ~RequestData {
-            complete_cb: cb
+            complete_cb: cb,
+            buf: None,
+            raw_fd: None
         };
         unsafe {
             let data = transmute::<~RequestData, *c_void>(data);
@@ -86,10 +109,10 @@ impl FsRequest {
 
     fn cleanup_and_delete(self) {
         unsafe {
-            uvll::fs_req_cleanup(self.native_handle());
-            let data = uvll::get_data_for_uv_handle(self.native_handle());
+            let data = uvll::get_data_for_req(self.native_handle());
             let _data = transmute::<*c_void, ~RequestData>(data);
-            uvll::set_data_for_uv_handle(self.native_handle(), null::<()>());
+            uvll::set_data_for_req(self.native_handle(), null::<()>());
+            uvll::fs_req_cleanup(self.native_handle());
             free_req(self.native_handle() as *c_void)
         }
     }
@@ -121,10 +144,24 @@ impl FileDescriptor {
             uvll::fs_open(loop_.native_handle(),
                           req.native_handle(), p, flags, mode, complete_cb) as int
         })
+    }
 
+    pub fn write(&self, loop_: Loop, buf: ~[u8], offset: i64, cb: FsCallback)
+          -> int {
+        let mut req = FsRequest::new(Some(cb));
+        let len = buf.len();
+        let buf = vec_to_uv_buf(buf);
+        let base_ptr = buf.base as *c_void;
+        req.get_req_data().buf = Some(buf);
+        req.get_req_data().raw_fd = Some(self.native_handle());
+        unsafe {
+            uvll::fs_write(loop_.native_handle(), req.native_handle(),
+                           self.native_handle(), base_ptr,
+                           len, offset, complete_cb) as int
+        }
     }
 
-    fn close(self, loop_: Loop, cb: FsCallback) -> int {
+    pub fn close(self, loop_: Loop, cb: FsCallback) -> int {
         let req = FsRequest::new(Some(cb));
         unsafe {
             uvll::fs_close(loop_.native_handle(), req.native_handle(),
@@ -170,17 +207,22 @@ mod test {
     //use rt::test::*;
     use unstable::run_in_bare_thread;
     use path::Path;
-    use rt::uv::Loop;
+    use rt::uv::{Loop};//, slice_to_uv_buf};
 
     // this is equiv to touch, i guess?
     fn file_test_touch_impl() {
         debug!("hello?")
         do run_in_bare_thread {
             debug!("In bare thread")
-            let loop_ = Loop::new();
+            let mut loop_ = Loop::new();
             let flags = map_flag(O_RDWR) |
-                map_flag(O_CREAT) | map_flag(O_TRUNC);
-            do FileDescriptor::open(loop_, Path("./foo.txt"), flags, 0644)
+                map_flag(O_CREAT);
+            // 0644
+            let mode = map_mode(S_IWUSR) |
+                map_mode(S_IRUSR) |
+                map_mode(S_IRGRP) |
+                map_mode(S_IROTH);
+            do FileDescriptor::open(loop_, Path("./foo.txt"), flags, mode)
             |req, uverr| {
                 let loop_ = req.get_loop();
                 assert!(uverr.is_none());
@@ -189,6 +231,7 @@ mod test {
                     assert!(uverr.is_none());
                 };
             };
+            loop_.run();
         }
     }
 
@@ -196,4 +239,56 @@ mod test {
     fn file_test_touch() {
         file_test_touch_impl();
     }
+
+    fn file_test_tee_impl() {
+        debug!("hello?")
+        do run_in_bare_thread {
+            debug!("In bare thread")
+            let mut loop_ = Loop::new();
+            let flags = map_flag(O_RDWR) |
+                map_flag(O_CREAT);
+            // 0644
+            let mode = map_mode(S_IWUSR) |
+                map_mode(S_IRUSR) |
+                map_mode(S_IRGRP) |
+                map_mode(S_IROTH);
+            do FileDescriptor::open(loop_, Path("./file_tee_test.txt"), flags, mode)
+            |req, uverr| {
+                let loop_ = req.get_loop();
+                assert!(uverr.is_none());
+                let fd = FileDescriptor::from_open_req(req);
+                let msg: ~[u8] = "hello world".as_bytes().to_owned();
+                let raw_fd = fd.native_handle();
+                do fd.write(loop_, msg, -1) |_, uverr| {
+                    let fd = FileDescriptor(raw_fd);
+                    do fd.close(loop_) |_, _| {
+                        assert!(uverr.is_none());
+                    };
+                };
+            };
+            loop_.run();
+        }
+    }
+
+    #[test]
+    fn file_test_tee() {
+        file_test_tee_impl();
+    }
+
+    fn naive_print(input: ~str) {
+        do run_in_bare_thread {
+            let mut loop_ = Loop::new();
+            let stdout = FileDescriptor(1);
+            let msg = input.as_bytes().to_owned();
+            do stdout.write(loop_, msg, -1) |_, uverr| {
+                assert!(uverr.is_none());
+            };
+            loop_.run();
+        }
+    }
+
+    #[test]
+    fn file_test_println() {
+        naive_print(~"oh yeah.\n");
+    }
 }
diff --git a/src/libstd/rt/uv/uvll.rs b/src/libstd/rt/uv/uvll.rs
index b6cffa754c1..0fbf45fca97 100644
--- a/src/libstd/rt/uv/uvll.rs
+++ b/src/libstd/rt/uv/uvll.rs
@@ -621,6 +621,10 @@ pub unsafe fn fs_open(loop_ptr: *uv_loop_t, req: *uv_fs_t, path: *c_char, flags:
                 cb: *u8) -> c_int {
     rust_uv_fs_open(loop_ptr, req, path, flags as c_int, mode as c_int, cb)
 }
+pub unsafe fn fs_write(loop_ptr: *uv_loop_t, req: *uv_fs_t, fd: c_int, buf: *c_void,
+                       len: uint, offset: i64, cb: *u8) -> c_int {
+    rust_uv_fs_write(loop_ptr, req, fd, buf, len as c_uint, offset, cb)
+}
 pub unsafe fn fs_close(loop_ptr: *uv_loop_t, req: *uv_fs_t, fd: c_int,
                 cb: *u8) -> c_int {
     rust_uv_fs_close(loop_ptr, req, fd, cb)
@@ -630,21 +634,15 @@ pub unsafe fn fs_req_cleanup(req: *uv_fs_t) {
 }
 
 // data access helpers
-pub unsafe fn get_O_RDONLY() -> c_int {
-    rust_uv_get_O_RDONLY()
-}
-pub unsafe fn get_O_WRONLY() -> c_int {
-    rust_uv_get_O_WRONLY()
-}
-pub unsafe fn get_O_RDWR() -> c_int {
-    rust_uv_get_O_RDWR()
-}
-pub unsafe fn get_O_CREAT() -> c_int {
-    rust_uv_get_O_CREAT()
-}
-pub unsafe fn get_O_TRUNC() -> c_int {
-    rust_uv_get_O_TRUNC()
-}
+pub unsafe fn get_O_RDONLY() -> c_int { rust_uv_get_O_RDONLY() }
+pub unsafe fn get_O_WRONLY() -> c_int { rust_uv_get_O_WRONLY() }
+pub unsafe fn get_O_RDWR() -> c_int { rust_uv_get_O_RDWR() }
+pub unsafe fn get_O_CREAT() -> c_int { rust_uv_get_O_CREAT() }
+pub unsafe fn get_O_TRUNC() -> c_int { rust_uv_get_O_TRUNC() }
+pub unsafe fn get_S_IWUSR() -> c_int { rust_uv_get_S_IWUSR() }
+pub unsafe fn get_S_IRUSR() -> c_int { rust_uv_get_S_IRUSR() }
+pub unsafe fn get_S_IRGRP() -> c_int { rust_uv_get_S_IRGRP() }
+pub unsafe fn get_S_IROTH() -> c_int { rust_uv_get_S_IROTH() }
 pub unsafe fn get_result_from_fs_req(req: *uv_fs_t) -> c_int {
     rust_uv_get_result_from_fs_req(req)
 }
@@ -819,6 +817,8 @@ extern {
     fn rust_uv_timer_stop(handle: *uv_timer_t) -> c_int;
     fn rust_uv_fs_open(loop_ptr: *c_void, req: *uv_fs_t, path: *c_char,
                        flags: c_int, mode: c_int, cb: *u8) -> c_int;
+    fn rust_uv_fs_write(loop_ptr: *c_void, req: *uv_fs_t, fd: c_int,
+                       buf: *c_void, len: c_uint, offset: i64, cb: *u8) -> c_int;
     fn rust_uv_fs_close(loop_ptr: *c_void, req: *uv_fs_t, fd: c_int,
                         cb: *u8) -> c_int;
     fn rust_uv_fs_req_cleanup(req: *uv_fs_t);
@@ -827,6 +827,10 @@ extern {
     fn rust_uv_get_O_RDWR() -> c_int;
     fn rust_uv_get_O_CREAT() -> c_int;
     fn rust_uv_get_O_TRUNC() -> c_int;
+    fn rust_uv_get_S_IWUSR() -> c_int;
+    fn rust_uv_get_S_IRUSR() -> c_int;
+    fn rust_uv_get_S_IRGRP() -> c_int;
+    fn rust_uv_get_S_IROTH() -> c_int;
     fn rust_uv_get_result_from_fs_req(req: *uv_fs_t) -> c_int;
     fn rust_uv_get_loop_from_fs_req(req: *uv_fs_t) -> *uv_loop_t;