diff options
| author | Jeff Olson <olson.jeffery@gmail.com> | 2013-08-15 23:54:54 -0700 |
|---|---|---|
| committer | Jeff Olson <olson.jeffery@gmail.com> | 2013-08-22 16:31:57 -0700 |
| commit | dabbac1d6c06c00f24148ffc58b42455496fdd3c (patch) | |
| tree | 06a67dbb456e735015310faaea41709249ff31d2 /src/libstd/rt | |
| parent | a901b166901601c6b132c2036882ad9754722f1c (diff) | |
| download | rust-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.rs | 119 | ||||
| -rw-r--r-- | src/libstd/rt/uv/uvll.rs | 34 |
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; |
