diff options
| author | Jeff Olson <olson.jeffery@gmail.com> | 2013-09-16 13:25:10 -0700 |
|---|---|---|
| committer | Jeff Olson <olson.jeffery@gmail.com> | 2013-09-16 23:19:24 -0700 |
| commit | bf399d558e755b5964666892e9f95440ad6f8ef2 (patch) | |
| tree | 60bba6e534cf70e65b84058dfeb8a4433579d165 /src/libstd/rt/uv | |
| parent | 25b4d8c1d7de70bab8eca8a57fdfb703e5e281c9 (diff) | |
| download | rust-bf399d558e755b5964666892e9f95440ad6f8ef2.tar.gz rust-bf399d558e755b5964666892e9f95440ad6f8ef2.zip | |
std: bind uv_fs_readdir(), flesh out DirectoryInfo and docs/cleanup
Diffstat (limited to 'src/libstd/rt/uv')
| -rw-r--r-- | src/libstd/rt/uv/file.rs | 50 | ||||
| -rw-r--r-- | src/libstd/rt/uv/uvio.rs | 38 | ||||
| -rw-r--r-- | src/libstd/rt/uv/uvll.rs | 14 |
3 files changed, 94 insertions, 8 deletions
diff --git a/src/libstd/rt/uv/file.rs b/src/libstd/rt/uv/file.rs index 34f87e3601e..cd0a217cc45 100644 --- a/src/libstd/rt/uv/file.rs +++ b/src/libstd/rt/uv/file.rs @@ -17,6 +17,7 @@ use rt::uv::uvll; use rt::uv::uvll::*; use super::super::io::support::PathLike; use cast::transmute; +use libc; use libc::{c_int}; use option::{None, Some, Option}; @@ -28,14 +29,6 @@ pub struct RequestData { } impl FsRequest { - pub fn new_REFACTOR_ME(cb: Option<FsCallback>) -> FsRequest { - let fs_req = unsafe { malloc_req(UV_FS) }; - assert!(fs_req.is_not_null()); - let fs_req: FsRequest = NativeHandle::from_native_handle(fs_req); - fs_req.install_req_data(cb); - fs_req - } - pub fn new() -> FsRequest { let fs_req = unsafe { malloc_req(UV_FS) }; assert!(fs_req.is_not_null()); @@ -180,6 +173,17 @@ impl FsRequest { }); } + pub fn readdir<P: PathLike>(self, loop_: &Loop, path: &P, + flags: c_int, cb: FsCallback) { + let complete_cb_ptr = self.req_boilerplate(Some(cb)); + path.path_as_str(|p| { + p.to_c_str().with_ref(|p| unsafe { + uvll::fs_readdir(loop_.native_handle(), + self.native_handle(), p, flags, complete_cb_ptr) + }) + }); + } + // accessors/utility funcs fn sync_cleanup(self, result: c_int) -> Result<c_int, UvError> { @@ -235,6 +239,36 @@ impl FsRequest { stat } + pub fn get_ptr(&self) -> *libc::c_void { + unsafe { + uvll::get_ptr_from_fs_req(self.native_handle()) + } + } + + pub fn get_paths(&mut self) -> ~[~str] { + use str; + let ptr = self.get_ptr(); + match self.get_result() { + n if (n <= 0) => { + ~[] + }, + n => { + let n_len = n as uint; + // we pass in the len that uv tells us is there + // for the entries and we don't continue past that.. + // it appears that sometimes the multistring isn't + // correctly delimited and we stray into garbage memory? + // in any case, passing Some(n_len) fixes it and ensures + // good results + let raw_path_strs = unsafe { + str::raw::from_c_multistring(ptr as *libc::c_char, Some(n_len)) }; + let raw_len = raw_path_strs.len(); + assert_eq!(raw_len, n_len); + raw_path_strs + } + } + } + fn cleanup_and_delete(self) { unsafe { let data = uvll::get_data_for_req(self.native_handle()); diff --git a/src/libstd/rt/uv/uvio.rs b/src/libstd/rt/uv/uvio.rs index d701a87004c..2d024f04e1d 100644 --- a/src/libstd/rt/uv/uvio.rs +++ b/src/libstd/rt/uv/uvio.rs @@ -704,6 +704,44 @@ impl IoFactory for UvIoFactory { }; } } + fn fs_readdir<P: PathLike>(&mut self, path: &P, flags: c_int) -> + Result<~[Path], IoError> { + use str::StrSlice; + let result_cell = Cell::new_empty(); + let result_cell_ptr: *Cell<Result<~[Path], + IoError>> = &result_cell; + let path_cell = Cell::new(path); + do task::unkillable { // FIXME(#8674) + let scheduler: ~Scheduler = Local::take(); + let stat_req = file::FsRequest::new(); + do scheduler.deschedule_running_task_and_then |_, task| { + let task_cell = Cell::new(task); + let path = path_cell.take(); + let path_str = path.path_as_str(|p| p.to_owned()); + do stat_req.readdir(self.uv_loop(), path, flags) + |req,err| { + let res = match err { + None => { + let rel_paths = req.get_paths(); + let mut paths = ~[]; + for r in rel_paths.iter() { + paths.push(Path(path_str+"/"+*r)); + } + Ok(paths) + }, + Some(e) => { + Err(uv_error_to_io_error(e)) + } + }; + unsafe { (*result_cell_ptr).put_back(res); } + let scheduler: ~Scheduler = Local::take(); + scheduler.resume_blocked_task_immediately(task_cell.take()); + }; + }; + }; + assert!(!result_cell.is_empty()); + return result_cell.take(); + } } pub struct UvTcpListener { diff --git a/src/libstd/rt/uv/uvll.rs b/src/libstd/rt/uv/uvll.rs index a2d1c48c3e1..42102a52e2e 100644 --- a/src/libstd/rt/uv/uvll.rs +++ b/src/libstd/rt/uv/uvll.rs @@ -811,6 +811,12 @@ pub unsafe fn fs_rmdir(loop_ptr: *uv_loop_t, req: *uv_fs_t, path: *c_char, rust_uv_fs_rmdir(loop_ptr, req, path, cb) } +pub unsafe fn fs_readdir(loop_ptr: *uv_loop_t, req: *uv_fs_t, path: *c_char, + flags: c_int, cb: *u8) -> c_int { + #[fixed_stack_segment]; #[inline(never)]; + + rust_uv_fs_readdir(loop_ptr, req, path, flags, cb) +} pub unsafe fn populate_stat(req_in: *uv_fs_t, stat_out: *uv_stat_t) { #[fixed_stack_segment]; #[inline(never)]; @@ -828,6 +834,11 @@ pub unsafe fn get_result_from_fs_req(req: *uv_fs_t) -> c_int { rust_uv_get_result_from_fs_req(req) } +pub unsafe fn get_ptr_from_fs_req(req: *uv_fs_t) -> *libc::c_void { + #[fixed_stack_segment]; #[inline(never)]; + + rust_uv_get_ptr_from_fs_req(req) +} pub unsafe fn get_loop_from_fs_req(req: *uv_fs_t) -> *uv_loop_t { #[fixed_stack_segment]; #[inline(never)]; @@ -1014,9 +1025,12 @@ extern { mode: c_int, cb: *u8) -> c_int; fn rust_uv_fs_rmdir(loop_ptr: *c_void, req: *uv_fs_t, path: *c_char, cb: *u8) -> c_int; + fn rust_uv_fs_readdir(loop_ptr: *c_void, req: *uv_fs_t, path: *c_char, + flags: c_int, cb: *u8) -> c_int; fn rust_uv_fs_req_cleanup(req: *uv_fs_t); fn rust_uv_populate_uv_stat(req_in: *uv_fs_t, stat_out: *uv_stat_t); fn rust_uv_get_result_from_fs_req(req: *uv_fs_t) -> c_int; + fn rust_uv_get_ptr_from_fs_req(req: *uv_fs_t) -> *libc::c_void; fn rust_uv_get_loop_from_fs_req(req: *uv_fs_t) -> *uv_loop_t; fn rust_uv_get_loop_from_getaddrinfo_req(req: *uv_fs_t) -> *uv_loop_t; |
