diff options
| author | Jeff Olson <olson.jeffery@gmail.com> | 2013-08-20 15:38:41 -0700 |
|---|---|---|
| committer | Jeff Olson <olson.jeffery@gmail.com> | 2013-08-22 16:31:57 -0700 |
| commit | 05c8cc70c90032d578606e811bbb1266cd8d2fcd (patch) | |
| tree | 26d35271abb9c78c159499477956fe2aba0d60c9 /src/libstd/rt/uv/uvio.rs | |
| parent | 48d67610285b423e806e0c44be43d01d5c1a7dbc (diff) | |
| download | rust-05c8cc70c90032d578606e811bbb1266cd8d2fcd.tar.gz rust-05c8cc70c90032d578606e811bbb1266cd8d2fcd.zip | |
std: rework file io.. support [p]read,[p]write, impl seek/tell + more tests
Diffstat (limited to 'src/libstd/rt/uv/uvio.rs')
| -rw-r--r-- | src/libstd/rt/uv/uvio.rs | 111 |
1 files changed, 79 insertions, 32 deletions
diff --git a/src/libstd/rt/uv/uvio.rs b/src/libstd/rt/uv/uvio.rs index 2acf2cccfea..2a62c782d0b 100644 --- a/src/libstd/rt/uv/uvio.rs +++ b/src/libstd/rt/uv/uvio.rs @@ -31,6 +31,7 @@ use rt::uv::idle::IdleWatcher; use rt::uv::net::{UvIpv4SocketAddr, UvIpv6SocketAddr}; use unstable::sync::Exclusive; use super::super::io::support::PathLike; +use libc::{lseek, c_long, SEEK_CUR}; #[cfg(test)] use container::Container; #[cfg(test)] use unstable::run_in_bare_thread; @@ -458,19 +459,20 @@ impl IoFactory for UvIoFactory { Ok(~UvTimer::new(watcher, home)) } - fn fs_from_raw_fd(&mut self, fd: c_int, close_on_drop: bool) -> ~RtioFileDescriptor { - ~UvFileDescriptor { + fn fs_from_raw_fd(&mut self, fd: c_int, close_on_drop: bool) -> ~RtioFileStream { + ~UvFileStream { loop_: Loop{handle:self.uv_loop().native_handle()}, fd: file::FileDescriptor(fd), - close_on_drop: close_on_drop - } as ~RtioFileDescriptor + close_on_drop: close_on_drop, + } as ~RtioFileStream } fn fs_open<P: PathLike>(&mut self, path: &P, flags: int, mode: int) - -> Result<~RtioFileDescriptor, IoError> { + -> Result<~RtioFileStream, IoError> { let loop_ = Loop {handle: self.uv_loop().native_handle()}; let result_cell = Cell::new_empty(); - let result_cell_ptr: *Cell<Result<~RtioFileDescriptor, IoError>> = &result_cell; + let result_cell_ptr: *Cell<Result<~RtioFileStream, + IoError>> = &result_cell; let path_cell = Cell::new(path); let scheduler = Local::take::<Scheduler>(); do scheduler.deschedule_running_task_and_then |_, task| { @@ -478,10 +480,10 @@ impl IoFactory for UvIoFactory { let path = path_cell.take(); do file::FileDescriptor::open(loop_, path, flags, mode) |req,err| { if err.is_none() { - let res = Ok(~UvFileDescriptor { + let res = Ok(~UvFileStream { loop_: loop_, fd: file::FileDescriptor(req.get_result()), - close_on_drop: true} as ~RtioFileDescriptor); + close_on_drop: true} as ~RtioFileStream); unsafe { (*result_cell_ptr).put_back(res); } let scheduler = Local::take::<Scheduler>(); scheduler.resume_blocked_task_immediately(task_cell.take()); @@ -1056,32 +1058,14 @@ impl RtioTimer for UvTimer { } } -pub struct UvFileDescriptor { +pub struct UvFileStream { loop_: Loop, fd: file::FileDescriptor, close_on_drop: bool } -impl UvFileDescriptor { -} - -impl Drop for UvFileDescriptor { - fn drop(&self) { - if self.close_on_drop { - let scheduler = Local::take::<Scheduler>(); - do scheduler.deschedule_running_task_and_then |_, task| { - let task_cell = Cell::new(task); - do self.fd.close(self.loop_) |_,_| { - let scheduler = Local::take::<Scheduler>(); - scheduler.resume_blocked_task_immediately(task_cell.take()); - }; - }; - } - } -} - -impl RtioFileDescriptor for UvFileDescriptor { - fn read(&mut self, buf: &mut [u8], offset: i64) -> Result<int, IoError> { +impl UvFileStream { + fn base_read(&mut self, buf: &mut [u8], offset: i64) -> Result<int, IoError> { let scheduler = Local::take::<Scheduler>(); let result_cell = Cell::new_empty(); let result_cell_ptr: *Cell<Result<int, IoError>> = &result_cell; @@ -1101,7 +1085,7 @@ impl RtioFileDescriptor for UvFileDescriptor { }; result_cell.take() } - fn write(&mut self, buf: &[u8], offset: i64) -> Result<(), IoError> { + fn base_write(&mut self, buf: &[u8], offset: i64) -> Result<(), IoError> { let scheduler = Local::take::<Scheduler>(); let result_cell = Cell::new_empty(); let result_cell_ptr: *Cell<Result<(), IoError>> = &result_cell; @@ -1123,6 +1107,69 @@ impl RtioFileDescriptor for UvFileDescriptor { } } +impl Drop for UvFileStream { + fn drop(&self) { + if self.close_on_drop { + let scheduler = Local::take::<Scheduler>(); + do scheduler.deschedule_running_task_and_then |_, task| { + let task_cell = Cell::new(task); + do self.fd.close(self.loop_) |_,_| { + let scheduler = Local::take::<Scheduler>(); + scheduler.resume_blocked_task_immediately(task_cell.take()); + }; + }; + } + } +} + +impl RtioFileStream for UvFileStream { + fn read(&mut self, buf: &mut [u8]) -> Result<int, IoError> { + self.base_read(buf, -1) + } + fn write(&mut self, buf: &[u8]) -> Result<(), IoError> { + self.base_write(buf, -1) + } + fn pread(&mut self, buf: &mut [u8], offset: u64) -> Result<int, IoError> { + self.base_read(buf, offset as i64) + } + fn pwrite(&mut self, buf: &[u8], offset: u64) -> Result<(), IoError> { + self.base_write(buf, offset as i64) + } + fn seek(&mut self, pos: i64, whence: i64) -> Result<(), IoError> { + #[fixed_stack_segment]; #[inline(never)]; + unsafe { + match lseek((*self.fd), pos as c_long, whence as c_int) { + -1 => { + Err(IoError { + kind: OtherIoError, + desc: "Failed to lseek.", + detail: None + }) + }, + _ => Ok(()) + } + } + } + fn tell(&self) -> Result<u64, IoError> { + #[fixed_stack_segment]; #[inline(never)]; + unsafe { + match lseek((*self.fd), 0, SEEK_CUR) { + -1 => { + Err(IoError { + kind: OtherIoError, + desc: "Failed to lseek, needed to tell().", + detail: None + }) + }, + n=> Ok(n as u64) + } + } + } + fn flush(&mut self) -> Result<(), IoError> { + Ok(()) + } +} + #[test] fn test_simple_io_no_connect() { do run_in_newsched_task { @@ -1647,12 +1694,12 @@ fn file_test_uvio_full_simple_impl() { { let mut fd = (*io).fs_open(&Path(path), create_flags as int, mode as int).unwrap(); let write_buf = write_val.as_bytes(); - fd.write(write_buf, 0); + fd.write(write_buf); } { let mut fd = (*io).fs_open(&Path(path), ro_flags as int, mode as int).unwrap(); let mut read_vec = [0, .. 1028]; - let nread = fd.read(read_vec, 0).unwrap(); + let nread = fd.read(read_vec).unwrap(); let read_val = str::from_bytes(read_vec.slice(0, nread as uint)); assert!(read_val == write_val.to_owned()); } |
