std: put FileMode/Access->whence-mask in uvio, open/unlink as fns in file::
This commit is contained in:
parent
6311856bf4
commit
8d997fba1a
@ -13,34 +13,45 @@ use super::support::PathLike;
|
||||
use super::{Reader, Writer, Seek};
|
||||
use super::{SeekSet, SeekCur, SeekEnd, SeekStyle};
|
||||
use rt::rtio::{RtioFileStream, IoFactory, IoFactoryObject};
|
||||
use rt::io::{io_error, read_error, EndOfFile};
|
||||
use rt::io::{io_error, read_error, EndOfFile,
|
||||
FileMode, FileAccess, Open, Read, Create, ReadWrite};
|
||||
use rt::local::Local;
|
||||
use rt::test::*;
|
||||
use libc::{O_RDWR, O_RDONLY, O_WRONLY, S_IWUSR, S_IRUSR,
|
||||
O_CREAT, O_TRUNC, O_APPEND};
|
||||
|
||||
/// Instructions on how to open a file and return a `FileStream`.
|
||||
enum FileMode {
|
||||
/// Opens an existing file. IoError if file does not exist.
|
||||
Open,
|
||||
/// Creates a file. IoError if file exists.
|
||||
Create,
|
||||
/// Opens an existing file or creates a new one.
|
||||
OpenOrCreate,
|
||||
/// Opens an existing file or creates a new one, positioned at EOF.
|
||||
Append,
|
||||
/// Opens an existing file, truncating it to 0 bytes.
|
||||
Truncate,
|
||||
/// Opens an existing file or creates a new one, truncating it to 0 bytes.
|
||||
CreateOrTruncate,
|
||||
/// Open a file for reading/writing, as indicated by `path`.
|
||||
pub fn open<P: PathLike>(path: &P,
|
||||
mode: FileMode,
|
||||
access: FileAccess
|
||||
) -> Option<FileStream> {
|
||||
let open_result = unsafe {
|
||||
let io = Local::unsafe_borrow::<IoFactoryObject>();
|
||||
(*io).fs_open(path, mode, access)
|
||||
};
|
||||
match open_result {
|
||||
Ok(fd) => Some(FileStream {
|
||||
fd: fd,
|
||||
last_nread: -1
|
||||
}),
|
||||
Err(ioerr) => {
|
||||
io_error::cond.raise(ioerr);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// How should the file be opened? `FileStream`s opened with `Read` will
|
||||
/// raise an `io_error` condition if written to.
|
||||
enum FileAccess {
|
||||
Read,
|
||||
Write,
|
||||
ReadWrite
|
||||
/// Unlink (remove) a file from the filesystem, as indicated
|
||||
/// by `path`.
|
||||
pub fn unlink<P: PathLike>(path: &P) {
|
||||
let unlink_result = unsafe {
|
||||
let io = Local::unsafe_borrow::<IoFactoryObject>();
|
||||
(*io).fs_unlink(path)
|
||||
};
|
||||
match unlink_result {
|
||||
Ok(_) => (),
|
||||
Err(ioerr) => {
|
||||
io_error::cond.raise(ioerr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Abstraction representing *positional* access to a file. In this case,
|
||||
@ -61,55 +72,6 @@ pub struct FileStream {
|
||||
}
|
||||
|
||||
impl FileStream {
|
||||
pub fn open<P: PathLike>(path: &P,
|
||||
mode: FileMode,
|
||||
access: FileAccess
|
||||
) -> Option<FileStream> {
|
||||
let open_result = unsafe {
|
||||
let io = Local::unsafe_borrow::<IoFactoryObject>();
|
||||
let mut flags = match mode {
|
||||
Open => 0,
|
||||
Create => O_CREAT,
|
||||
OpenOrCreate => O_CREAT,
|
||||
Append => O_APPEND,
|
||||
Truncate => O_TRUNC,
|
||||
CreateOrTruncate => O_TRUNC | O_CREAT
|
||||
};
|
||||
flags = match access {
|
||||
Read => flags | O_RDONLY,
|
||||
Write => flags | O_WRONLY,
|
||||
ReadWrite => flags | O_RDWR
|
||||
};
|
||||
let create_mode = match mode {
|
||||
Create|OpenOrCreate|CreateOrTruncate =>
|
||||
S_IRUSR | S_IWUSR,
|
||||
_ => 0
|
||||
};
|
||||
(*io).fs_open(path, flags as int, create_mode as int)
|
||||
};
|
||||
match open_result {
|
||||
Ok(fd) => Some(FileStream {
|
||||
fd: fd,
|
||||
last_nread: -1
|
||||
}),
|
||||
Err(ioerr) => {
|
||||
io_error::cond.raise(ioerr);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
fn unlink<P: PathLike>(path: &P) {
|
||||
let unlink_result = unsafe {
|
||||
let io = Local::unsafe_borrow::<IoFactoryObject>();
|
||||
(*io).fs_unlink(path)
|
||||
};
|
||||
match unlink_result {
|
||||
Ok(_) => (),
|
||||
Err(ioerr) => {
|
||||
io_error::cond.raise(ioerr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Reader for FileStream {
|
||||
@ -188,12 +150,12 @@ fn file_test_smoke_test_impl() {
|
||||
let message = "it's alright. have a good time";
|
||||
let filename = &Path("./tmp/file_rt_io_file_test.txt");
|
||||
{
|
||||
let mut write_stream = FileStream::open(filename, Create, ReadWrite).unwrap();
|
||||
let mut write_stream = open(filename, Create, ReadWrite).unwrap();
|
||||
write_stream.write(message.as_bytes());
|
||||
}
|
||||
{
|
||||
use str;
|
||||
let mut read_stream = FileStream::open(filename, Open, Read).unwrap();
|
||||
let mut read_stream = open(filename, Open, Read).unwrap();
|
||||
let mut read_buf = [0, .. 1028];
|
||||
let read_str = match read_stream.read(read_buf).unwrap() {
|
||||
-1|0 => fail!("shouldn't happen"),
|
||||
@ -201,7 +163,7 @@ fn file_test_smoke_test_impl() {
|
||||
};
|
||||
assert!(read_str == message.to_owned());
|
||||
}
|
||||
FileStream::unlink(filename);
|
||||
unlink(filename);
|
||||
}
|
||||
}
|
||||
|
||||
@ -217,7 +179,7 @@ fn file_test_invalid_path_opened_without_create_should_raise_condition_impl() {
|
||||
do io_error::cond.trap(|_| {
|
||||
called = true;
|
||||
}).inside {
|
||||
let result = FileStream::open(filename, Open, Read);
|
||||
let result = open(filename, Open, Read);
|
||||
assert!(result.is_none());
|
||||
}
|
||||
assert!(called);
|
||||
@ -235,7 +197,7 @@ fn file_test_unlinking_invalid_path_should_raise_condition_impl() {
|
||||
do io_error::cond.trap(|_| {
|
||||
called = true;
|
||||
}).inside {
|
||||
FileStream::unlink(filename);
|
||||
unlink(filename);
|
||||
}
|
||||
assert!(called);
|
||||
}
|
||||
@ -252,11 +214,11 @@ fn file_test_io_non_positional_read_impl() {
|
||||
let mut read_mem = [0, .. 8];
|
||||
let filename = &Path("./tmp/file_rt_io_file_test_positional.txt");
|
||||
{
|
||||
let mut rw_stream = FileStream::open(filename, Create, ReadWrite).unwrap();
|
||||
let mut rw_stream = open(filename, Create, ReadWrite).unwrap();
|
||||
rw_stream.write(message.as_bytes());
|
||||
}
|
||||
{
|
||||
let mut read_stream = FileStream::open(filename, Open, Read).unwrap();
|
||||
let mut read_stream = open(filename, Open, Read).unwrap();
|
||||
{
|
||||
let read_buf = read_mem.mut_slice(0, 4);
|
||||
read_stream.read(read_buf);
|
||||
@ -266,7 +228,7 @@ fn file_test_io_non_positional_read_impl() {
|
||||
read_stream.read(read_buf);
|
||||
}
|
||||
}
|
||||
FileStream::unlink(filename);
|
||||
unlink(filename);
|
||||
let read_str = str::from_bytes(read_mem);
|
||||
assert!(read_str == message.to_owned());
|
||||
}
|
||||
@ -287,17 +249,17 @@ fn file_test_io_seeking_impl() {
|
||||
let mut tell_pos_post_read;
|
||||
let filename = &Path("./tmp/file_rt_io_file_test_seeking.txt");
|
||||
{
|
||||
let mut rw_stream = FileStream::open(filename, Create, ReadWrite).unwrap();
|
||||
let mut rw_stream = open(filename, Create, ReadWrite).unwrap();
|
||||
rw_stream.write(message.as_bytes());
|
||||
}
|
||||
{
|
||||
let mut read_stream = FileStream::open(filename, Open, Read).unwrap();
|
||||
let mut read_stream = open(filename, Open, Read).unwrap();
|
||||
read_stream.seek(set_cursor as i64, SeekSet);
|
||||
tell_pos_pre_read = read_stream.tell();
|
||||
read_stream.read(read_mem);
|
||||
tell_pos_post_read = read_stream.tell();
|
||||
}
|
||||
FileStream::unlink(filename);
|
||||
unlink(filename);
|
||||
let read_str = str::from_bytes(read_mem);
|
||||
assert!(read_str == message.slice(4, 8).to_owned());
|
||||
assert!(tell_pos_pre_read == set_cursor);
|
||||
@ -320,16 +282,16 @@ fn file_test_io_seek_and_write_impl() {
|
||||
let mut read_mem = [0, .. 13];
|
||||
let filename = &Path("./tmp/file_rt_io_file_test_seek_and_write.txt");
|
||||
{
|
||||
let mut rw_stream = FileStream::open(filename, Create, ReadWrite).unwrap();
|
||||
let mut rw_stream = open(filename, Create, ReadWrite).unwrap();
|
||||
rw_stream.write(initial_msg.as_bytes());
|
||||
rw_stream.seek(seek_idx as i64, SeekSet);
|
||||
rw_stream.write(overwrite_msg.as_bytes());
|
||||
}
|
||||
{
|
||||
let mut read_stream = FileStream::open(filename, Open, Read).unwrap();
|
||||
let mut read_stream = open(filename, Open, Read).unwrap();
|
||||
read_stream.read(read_mem);
|
||||
}
|
||||
FileStream::unlink(filename);
|
||||
unlink(filename);
|
||||
let read_str = str::from_bytes(read_mem);
|
||||
io::println(fmt!("read_str: '%?' final_msg: '%?'", read_str, final_msg));
|
||||
assert!(read_str == final_msg.to_owned());
|
||||
@ -350,11 +312,11 @@ fn file_test_io_seek_shakedown_impl() {
|
||||
let mut read_mem = [0, .. 4];
|
||||
let filename = &Path("./tmp/file_rt_io_file_test_seek_shakedown.txt");
|
||||
{
|
||||
let mut rw_stream = FileStream::open(filename, Create, ReadWrite).unwrap();
|
||||
let mut rw_stream = open(filename, Create, ReadWrite).unwrap();
|
||||
rw_stream.write(initial_msg.as_bytes());
|
||||
}
|
||||
{
|
||||
let mut read_stream = FileStream::open(filename, Open, Read).unwrap();
|
||||
let mut read_stream = open(filename, Open, Read).unwrap();
|
||||
|
||||
read_stream.seek(-4, SeekEnd);
|
||||
read_stream.read(read_mem);
|
||||
@ -371,7 +333,7 @@ fn file_test_io_seek_shakedown_impl() {
|
||||
let read_str = str::from_bytes(read_mem);
|
||||
assert!(read_str == chunk_one.to_owned());
|
||||
}
|
||||
FileStream::unlink(filename);
|
||||
unlink(filename);
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
|
@ -540,3 +540,27 @@ pub fn placeholder_error() -> IoError {
|
||||
detail: None
|
||||
}
|
||||
}
|
||||
|
||||
/// Instructions on how to open a file and return a `FileStream`.
|
||||
pub enum FileMode {
|
||||
/// Opens an existing file. IoError if file does not exist.
|
||||
Open,
|
||||
/// Creates a file. IoError if file exists.
|
||||
Create,
|
||||
/// Opens an existing file or creates a new one.
|
||||
OpenOrCreate,
|
||||
/// Opens an existing file or creates a new one, positioned at EOF.
|
||||
Append,
|
||||
/// Opens an existing file, truncating it to 0 bytes.
|
||||
Truncate,
|
||||
/// Opens an existing file or creates a new one, truncating it to 0 bytes.
|
||||
CreateOrTruncate,
|
||||
}
|
||||
|
||||
/// Access permissions with which the file should be opened.
|
||||
/// `FileStream`s opened with `Read` will raise an `io_error` condition if written to.
|
||||
pub enum FileAccess {
|
||||
Read,
|
||||
Write,
|
||||
ReadWrite
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ use rt::uv::uvio;
|
||||
use path::Path;
|
||||
use super::io::support::PathLike;
|
||||
use super::io::{SeekStyle};
|
||||
use super::io::{FileMode, FileAccess};
|
||||
|
||||
// XXX: ~object doesn't work currently so these are some placeholder
|
||||
// types to use instead
|
||||
@ -68,7 +69,7 @@ pub trait IoFactory {
|
||||
fn udp_bind(&mut self, addr: SocketAddr) -> Result<~RtioUdpSocketObject, IoError>;
|
||||
fn timer_init(&mut self) -> Result<~RtioTimerObject, IoError>;
|
||||
fn fs_from_raw_fd(&mut self, fd: c_int, close_on_drop: bool) -> ~RtioFileStream;
|
||||
fn fs_open<P: PathLike>(&mut self, path: &P, flags: int, mode:int)
|
||||
fn fs_open<P: PathLike>(&mut self, path: &P, fm: FileMode, fa: FileAccess)
|
||||
-> Result<~RtioFileStream, IoError>;
|
||||
fn fs_unlink<P: PathLike>(&mut self, path: &P) -> Result<(), IoError>;
|
||||
}
|
||||
|
@ -31,7 +31,10 @@ 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};
|
||||
use libc::{lseek, c_long, O_CREAT, O_APPEND, O_TRUNC, O_RDWR, O_RDONLY, O_WRONLY,
|
||||
S_IRUSR, S_IWUSR};
|
||||
use rt::io::{FileMode, FileAccess, OpenOrCreate, Open, Create,
|
||||
CreateOrTruncate, Append, Truncate, Read, Write, ReadWrite};
|
||||
|
||||
#[cfg(test)] use container::Container;
|
||||
#[cfg(test)] use unstable::run_in_bare_thread;
|
||||
@ -466,8 +469,26 @@ impl IoFactory for UvIoFactory {
|
||||
~UvFileStream::new(loop_, fd, close_on_drop, home) as ~RtioFileStream
|
||||
}
|
||||
|
||||
fn fs_open<P: PathLike>(&mut self, path: &P, flags: int, mode: int)
|
||||
fn fs_open<P: PathLike>(&mut self, path: &P, fm: FileMode, fa: FileAccess)
|
||||
-> Result<~RtioFileStream, IoError> {
|
||||
let mut flags = match fm {
|
||||
Open => 0,
|
||||
Create => O_CREAT,
|
||||
OpenOrCreate => O_CREAT,
|
||||
Append => O_APPEND,
|
||||
Truncate => O_TRUNC,
|
||||
CreateOrTruncate => O_TRUNC | O_CREAT
|
||||
};
|
||||
flags = match fa {
|
||||
Read => flags | O_RDONLY,
|
||||
Write => flags | O_WRONLY,
|
||||
ReadWrite => flags | O_RDWR
|
||||
};
|
||||
let create_mode = match fm {
|
||||
Create|OpenOrCreate|CreateOrTruncate =>
|
||||
S_IRUSR | S_IWUSR,
|
||||
_ => 0
|
||||
};
|
||||
let result_cell = Cell::new_empty();
|
||||
let result_cell_ptr: *Cell<Result<~RtioFileStream,
|
||||
IoError>> = &result_cell;
|
||||
@ -476,7 +497,8 @@ impl IoFactory for UvIoFactory {
|
||||
do scheduler.deschedule_running_task_and_then |_, task| {
|
||||
let task_cell = Cell::new(task);
|
||||
let path = path_cell.take();
|
||||
do file::FsRequest::open(self.uv_loop(), path, flags, mode) |req,err| {
|
||||
do file::FsRequest::open(self.uv_loop(), path, flags as int, create_mode as int)
|
||||
|req,err| {
|
||||
if err.is_none() {
|
||||
let loop_ = Loop {handle: req.get_loop().native_handle()};
|
||||
let home = get_handle_to_current_scheduler!();
|
||||
@ -1699,26 +1721,26 @@ fn test_timer_sleep_simple() {
|
||||
}
|
||||
|
||||
fn file_test_uvio_full_simple_impl() {
|
||||
use libc::{O_CREAT, O_RDWR, O_RDONLY,
|
||||
S_IWUSR, S_IRUSR};
|
||||
use str::StrSlice; // why does this have to be explicitly imported to work?
|
||||
// compiler was complaining about no trait for str that
|
||||
// does .as_bytes() ..
|
||||
use path::Path;
|
||||
use rt::io::{Open, Create, ReadWrite, Read};
|
||||
unsafe {
|
||||
let io = Local::unsafe_borrow::<IoFactoryObject>();
|
||||
let create_flags = O_RDWR | O_CREAT;
|
||||
let ro_flags = O_RDONLY;
|
||||
let write_val = "hello uvio!";
|
||||
let mode = S_IWUSR | S_IRUSR;
|
||||
let path = "./tmp/file_test_uvio_full.txt";
|
||||
{
|
||||
let mut fd = (*io).fs_open(&Path(path), create_flags as int, mode as int).unwrap();
|
||||
let create_fm = Create;
|
||||
let create_fa = ReadWrite;
|
||||
let mut fd = (*io).fs_open(&Path(path), create_fm, create_fa).unwrap();
|
||||
let write_buf = write_val.as_bytes();
|
||||
fd.write(write_buf);
|
||||
}
|
||||
{
|
||||
let mut fd = (*io).fs_open(&Path(path), ro_flags as int, mode as int).unwrap();
|
||||
let ro_fm = Open;
|
||||
let ro_fa = Read;
|
||||
let mut fd = (*io).fs_open(&Path(path), ro_fm, ro_fa).unwrap();
|
||||
let mut read_vec = [0, .. 1028];
|
||||
let nread = fd.read(read_vec).unwrap();
|
||||
let read_val = str::from_bytes(read_vec.slice(0, nread as uint));
|
||||
|
Loading…
Reference in New Issue
Block a user