Skip to content

Commit 8d997fb

Browse files
committed
std: put FileMode/Access->whence-mask in uvio, open/unlink as fns in file::
1 parent 6311856 commit 8d997fb

File tree

4 files changed

+109
-100
lines changed

4 files changed

+109
-100
lines changed

src/libstd/rt/io/file.rs

Lines changed: 51 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -13,34 +13,45 @@ use super::support::PathLike;
1313
use super::{Reader, Writer, Seek};
1414
use super::{SeekSet, SeekCur, SeekEnd, SeekStyle};
1515
use rt::rtio::{RtioFileStream, IoFactory, IoFactoryObject};
16-
use rt::io::{io_error, read_error, EndOfFile};
16+
use rt::io::{io_error, read_error, EndOfFile,
17+
FileMode, FileAccess, Open, Read, Create, ReadWrite};
1718
use rt::local::Local;
1819
use rt::test::*;
19-
use libc::{O_RDWR, O_RDONLY, O_WRONLY, S_IWUSR, S_IRUSR,
20-
O_CREAT, O_TRUNC, O_APPEND};
2120

22-
/// Instructions on how to open a file and return a `FileStream`.
23-
enum FileMode {
24-
/// Opens an existing file. IoError if file does not exist.
25-
Open,
26-
/// Creates a file. IoError if file exists.
27-
Create,
28-
/// Opens an existing file or creates a new one.
29-
OpenOrCreate,
30-
/// Opens an existing file or creates a new one, positioned at EOF.
31-
Append,
32-
/// Opens an existing file, truncating it to 0 bytes.
33-
Truncate,
34-
/// Opens an existing file or creates a new one, truncating it to 0 bytes.
35-
CreateOrTruncate,
21+
/// Open a file for reading/writing, as indicated by `path`.
22+
pub fn open<P: PathLike>(path: &P,
23+
mode: FileMode,
24+
access: FileAccess
25+
) -> Option<FileStream> {
26+
let open_result = unsafe {
27+
let io = Local::unsafe_borrow::<IoFactoryObject>();
28+
(*io).fs_open(path, mode, access)
29+
};
30+
match open_result {
31+
Ok(fd) => Some(FileStream {
32+
fd: fd,
33+
last_nread: -1
34+
}),
35+
Err(ioerr) => {
36+
io_error::cond.raise(ioerr);
37+
None
38+
}
39+
}
3640
}
3741

38-
/// How should the file be opened? `FileStream`s opened with `Read` will
39-
/// raise an `io_error` condition if written to.
40-
enum FileAccess {
41-
Read,
42-
Write,
43-
ReadWrite
42+
/// Unlink (remove) a file from the filesystem, as indicated
43+
/// by `path`.
44+
pub fn unlink<P: PathLike>(path: &P) {
45+
let unlink_result = unsafe {
46+
let io = Local::unsafe_borrow::<IoFactoryObject>();
47+
(*io).fs_unlink(path)
48+
};
49+
match unlink_result {
50+
Ok(_) => (),
51+
Err(ioerr) => {
52+
io_error::cond.raise(ioerr);
53+
}
54+
}
4455
}
4556

4657
/// Abstraction representing *positional* access to a file. In this case,
@@ -61,55 +72,6 @@ pub struct FileStream {
6172
}
6273

6374
impl FileStream {
64-
pub fn open<P: PathLike>(path: &P,
65-
mode: FileMode,
66-
access: FileAccess
67-
) -> Option<FileStream> {
68-
let open_result = unsafe {
69-
let io = Local::unsafe_borrow::<IoFactoryObject>();
70-
let mut flags = match mode {
71-
Open => 0,
72-
Create => O_CREAT,
73-
OpenOrCreate => O_CREAT,
74-
Append => O_APPEND,
75-
Truncate => O_TRUNC,
76-
CreateOrTruncate => O_TRUNC | O_CREAT
77-
};
78-
flags = match access {
79-
Read => flags | O_RDONLY,
80-
Write => flags | O_WRONLY,
81-
ReadWrite => flags | O_RDWR
82-
};
83-
let create_mode = match mode {
84-
Create|OpenOrCreate|CreateOrTruncate =>
85-
S_IRUSR | S_IWUSR,
86-
_ => 0
87-
};
88-
(*io).fs_open(path, flags as int, create_mode as int)
89-
};
90-
match open_result {
91-
Ok(fd) => Some(FileStream {
92-
fd: fd,
93-
last_nread: -1
94-
}),
95-
Err(ioerr) => {
96-
io_error::cond.raise(ioerr);
97-
None
98-
}
99-
}
100-
}
101-
fn unlink<P: PathLike>(path: &P) {
102-
let unlink_result = unsafe {
103-
let io = Local::unsafe_borrow::<IoFactoryObject>();
104-
(*io).fs_unlink(path)
105-
};
106-
match unlink_result {
107-
Ok(_) => (),
108-
Err(ioerr) => {
109-
io_error::cond.raise(ioerr);
110-
}
111-
}
112-
}
11375
}
11476

11577
impl Reader for FileStream {
@@ -188,20 +150,20 @@ fn file_test_smoke_test_impl() {
188150
let message = "it's alright. have a good time";
189151
let filename = &Path("./tmp/file_rt_io_file_test.txt");
190152
{
191-
let mut write_stream = FileStream::open(filename, Create, ReadWrite).unwrap();
153+
let mut write_stream = open(filename, Create, ReadWrite).unwrap();
192154
write_stream.write(message.as_bytes());
193155
}
194156
{
195157
use str;
196-
let mut read_stream = FileStream::open(filename, Open, Read).unwrap();
158+
let mut read_stream = open(filename, Open, Read).unwrap();
197159
let mut read_buf = [0, .. 1028];
198160
let read_str = match read_stream.read(read_buf).unwrap() {
199161
-1|0 => fail!("shouldn't happen"),
200162
n => str::from_bytes(read_buf.slice_to(n))
201163
};
202164
assert!(read_str == message.to_owned());
203165
}
204-
FileStream::unlink(filename);
166+
unlink(filename);
205167
}
206168
}
207169

@@ -217,7 +179,7 @@ fn file_test_invalid_path_opened_without_create_should_raise_condition_impl() {
217179
do io_error::cond.trap(|_| {
218180
called = true;
219181
}).inside {
220-
let result = FileStream::open(filename, Open, Read);
182+
let result = open(filename, Open, Read);
221183
assert!(result.is_none());
222184
}
223185
assert!(called);
@@ -235,7 +197,7 @@ fn file_test_unlinking_invalid_path_should_raise_condition_impl() {
235197
do io_error::cond.trap(|_| {
236198
called = true;
237199
}).inside {
238-
FileStream::unlink(filename);
200+
unlink(filename);
239201
}
240202
assert!(called);
241203
}
@@ -252,11 +214,11 @@ fn file_test_io_non_positional_read_impl() {
252214
let mut read_mem = [0, .. 8];
253215
let filename = &Path("./tmp/file_rt_io_file_test_positional.txt");
254216
{
255-
let mut rw_stream = FileStream::open(filename, Create, ReadWrite).unwrap();
217+
let mut rw_stream = open(filename, Create, ReadWrite).unwrap();
256218
rw_stream.write(message.as_bytes());
257219
}
258220
{
259-
let mut read_stream = FileStream::open(filename, Open, Read).unwrap();
221+
let mut read_stream = open(filename, Open, Read).unwrap();
260222
{
261223
let read_buf = read_mem.mut_slice(0, 4);
262224
read_stream.read(read_buf);
@@ -266,7 +228,7 @@ fn file_test_io_non_positional_read_impl() {
266228
read_stream.read(read_buf);
267229
}
268230
}
269-
FileStream::unlink(filename);
231+
unlink(filename);
270232
let read_str = str::from_bytes(read_mem);
271233
assert!(read_str == message.to_owned());
272234
}
@@ -287,17 +249,17 @@ fn file_test_io_seeking_impl() {
287249
let mut tell_pos_post_read;
288250
let filename = &Path("./tmp/file_rt_io_file_test_seeking.txt");
289251
{
290-
let mut rw_stream = FileStream::open(filename, Create, ReadWrite).unwrap();
252+
let mut rw_stream = open(filename, Create, ReadWrite).unwrap();
291253
rw_stream.write(message.as_bytes());
292254
}
293255
{
294-
let mut read_stream = FileStream::open(filename, Open, Read).unwrap();
256+
let mut read_stream = open(filename, Open, Read).unwrap();
295257
read_stream.seek(set_cursor as i64, SeekSet);
296258
tell_pos_pre_read = read_stream.tell();
297259
read_stream.read(read_mem);
298260
tell_pos_post_read = read_stream.tell();
299261
}
300-
FileStream::unlink(filename);
262+
unlink(filename);
301263
let read_str = str::from_bytes(read_mem);
302264
assert!(read_str == message.slice(4, 8).to_owned());
303265
assert!(tell_pos_pre_read == set_cursor);
@@ -320,16 +282,16 @@ fn file_test_io_seek_and_write_impl() {
320282
let mut read_mem = [0, .. 13];
321283
let filename = &Path("./tmp/file_rt_io_file_test_seek_and_write.txt");
322284
{
323-
let mut rw_stream = FileStream::open(filename, Create, ReadWrite).unwrap();
285+
let mut rw_stream = open(filename, Create, ReadWrite).unwrap();
324286
rw_stream.write(initial_msg.as_bytes());
325287
rw_stream.seek(seek_idx as i64, SeekSet);
326288
rw_stream.write(overwrite_msg.as_bytes());
327289
}
328290
{
329-
let mut read_stream = FileStream::open(filename, Open, Read).unwrap();
291+
let mut read_stream = open(filename, Open, Read).unwrap();
330292
read_stream.read(read_mem);
331293
}
332-
FileStream::unlink(filename);
294+
unlink(filename);
333295
let read_str = str::from_bytes(read_mem);
334296
io::println(fmt!("read_str: '%?' final_msg: '%?'", read_str, final_msg));
335297
assert!(read_str == final_msg.to_owned());
@@ -350,11 +312,11 @@ fn file_test_io_seek_shakedown_impl() {
350312
let mut read_mem = [0, .. 4];
351313
let filename = &Path("./tmp/file_rt_io_file_test_seek_shakedown.txt");
352314
{
353-
let mut rw_stream = FileStream::open(filename, Create, ReadWrite).unwrap();
315+
let mut rw_stream = open(filename, Create, ReadWrite).unwrap();
354316
rw_stream.write(initial_msg.as_bytes());
355317
}
356318
{
357-
let mut read_stream = FileStream::open(filename, Open, Read).unwrap();
319+
let mut read_stream = open(filename, Open, Read).unwrap();
358320

359321
read_stream.seek(-4, SeekEnd);
360322
read_stream.read(read_mem);
@@ -371,7 +333,7 @@ fn file_test_io_seek_shakedown_impl() {
371333
let read_str = str::from_bytes(read_mem);
372334
assert!(read_str == chunk_one.to_owned());
373335
}
374-
FileStream::unlink(filename);
336+
unlink(filename);
375337
}
376338
}
377339
#[test]

src/libstd/rt/io/mod.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,3 +540,27 @@ pub fn placeholder_error() -> IoError {
540540
detail: None
541541
}
542542
}
543+
544+
/// Instructions on how to open a file and return a `FileStream`.
545+
pub enum FileMode {
546+
/// Opens an existing file. IoError if file does not exist.
547+
Open,
548+
/// Creates a file. IoError if file exists.
549+
Create,
550+
/// Opens an existing file or creates a new one.
551+
OpenOrCreate,
552+
/// Opens an existing file or creates a new one, positioned at EOF.
553+
Append,
554+
/// Opens an existing file, truncating it to 0 bytes.
555+
Truncate,
556+
/// Opens an existing file or creates a new one, truncating it to 0 bytes.
557+
CreateOrTruncate,
558+
}
559+
560+
/// Access permissions with which the file should be opened.
561+
/// `FileStream`s opened with `Read` will raise an `io_error` condition if written to.
562+
pub enum FileAccess {
563+
Read,
564+
Write,
565+
ReadWrite
566+
}

src/libstd/rt/rtio.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use rt::uv::uvio;
1818
use path::Path;
1919
use super::io::support::PathLike;
2020
use super::io::{SeekStyle};
21+
use super::io::{FileMode, FileAccess};
2122

2223
// XXX: ~object doesn't work currently so these are some placeholder
2324
// types to use instead
@@ -68,7 +69,7 @@ pub trait IoFactory {
6869
fn udp_bind(&mut self, addr: SocketAddr) -> Result<~RtioUdpSocketObject, IoError>;
6970
fn timer_init(&mut self) -> Result<~RtioTimerObject, IoError>;
7071
fn fs_from_raw_fd(&mut self, fd: c_int, close_on_drop: bool) -> ~RtioFileStream;
71-
fn fs_open<P: PathLike>(&mut self, path: &P, flags: int, mode:int)
72+
fn fs_open<P: PathLike>(&mut self, path: &P, fm: FileMode, fa: FileAccess)
7273
-> Result<~RtioFileStream, IoError>;
7374
fn fs_unlink<P: PathLike>(&mut self, path: &P) -> Result<(), IoError>;
7475
}

src/libstd/rt/uv/uvio.rs

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ use rt::uv::idle::IdleWatcher;
3131
use rt::uv::net::{UvIpv4SocketAddr, UvIpv6SocketAddr};
3232
use unstable::sync::Exclusive;
3333
use super::super::io::support::PathLike;
34-
use libc::{lseek, c_long};
34+
use libc::{lseek, c_long, O_CREAT, O_APPEND, O_TRUNC, O_RDWR, O_RDONLY, O_WRONLY,
35+
S_IRUSR, S_IWUSR};
36+
use rt::io::{FileMode, FileAccess, OpenOrCreate, Open, Create,
37+
CreateOrTruncate, Append, Truncate, Read, Write, ReadWrite};
3538

3639
#[cfg(test)] use container::Container;
3740
#[cfg(test)] use unstable::run_in_bare_thread;
@@ -466,8 +469,26 @@ impl IoFactory for UvIoFactory {
466469
~UvFileStream::new(loop_, fd, close_on_drop, home) as ~RtioFileStream
467470
}
468471

469-
fn fs_open<P: PathLike>(&mut self, path: &P, flags: int, mode: int)
472+
fn fs_open<P: PathLike>(&mut self, path: &P, fm: FileMode, fa: FileAccess)
470473
-> Result<~RtioFileStream, IoError> {
474+
let mut flags = match fm {
475+
Open => 0,
476+
Create => O_CREAT,
477+
OpenOrCreate => O_CREAT,
478+
Append => O_APPEND,
479+
Truncate => O_TRUNC,
480+
CreateOrTruncate => O_TRUNC | O_CREAT
481+
};
482+
flags = match fa {
483+
Read => flags | O_RDONLY,
484+
Write => flags | O_WRONLY,
485+
ReadWrite => flags | O_RDWR
486+
};
487+
let create_mode = match fm {
488+
Create|OpenOrCreate|CreateOrTruncate =>
489+
S_IRUSR | S_IWUSR,
490+
_ => 0
491+
};
471492
let result_cell = Cell::new_empty();
472493
let result_cell_ptr: *Cell<Result<~RtioFileStream,
473494
IoError>> = &result_cell;
@@ -476,7 +497,8 @@ impl IoFactory for UvIoFactory {
476497
do scheduler.deschedule_running_task_and_then |_, task| {
477498
let task_cell = Cell::new(task);
478499
let path = path_cell.take();
479-
do file::FsRequest::open(self.uv_loop(), path, flags, mode) |req,err| {
500+
do file::FsRequest::open(self.uv_loop(), path, flags as int, create_mode as int)
501+
|req,err| {
480502
if err.is_none() {
481503
let loop_ = Loop {handle: req.get_loop().native_handle()};
482504
let home = get_handle_to_current_scheduler!();
@@ -1699,26 +1721,26 @@ fn test_timer_sleep_simple() {
16991721
}
17001722

17011723
fn file_test_uvio_full_simple_impl() {
1702-
use libc::{O_CREAT, O_RDWR, O_RDONLY,
1703-
S_IWUSR, S_IRUSR};
17041724
use str::StrSlice; // why does this have to be explicitly imported to work?
17051725
// compiler was complaining about no trait for str that
17061726
// does .as_bytes() ..
17071727
use path::Path;
1728+
use rt::io::{Open, Create, ReadWrite, Read};
17081729
unsafe {
17091730
let io = Local::unsafe_borrow::<IoFactoryObject>();
1710-
let create_flags = O_RDWR | O_CREAT;
1711-
let ro_flags = O_RDONLY;
17121731
let write_val = "hello uvio!";
1713-
let mode = S_IWUSR | S_IRUSR;
17141732
let path = "./tmp/file_test_uvio_full.txt";
17151733
{
1716-
let mut fd = (*io).fs_open(&Path(path), create_flags as int, mode as int).unwrap();
1734+
let create_fm = Create;
1735+
let create_fa = ReadWrite;
1736+
let mut fd = (*io).fs_open(&Path(path), create_fm, create_fa).unwrap();
17171737
let write_buf = write_val.as_bytes();
17181738
fd.write(write_buf);
17191739
}
17201740
{
1721-
let mut fd = (*io).fs_open(&Path(path), ro_flags as int, mode as int).unwrap();
1741+
let ro_fm = Open;
1742+
let ro_fa = Read;
1743+
let mut fd = (*io).fs_open(&Path(path), ro_fm, ro_fa).unwrap();
17221744
let mut read_vec = [0, .. 1028];
17231745
let nread = fd.read(read_vec).unwrap();
17241746
let read_val = str::from_bytes(read_vec.slice(0, nread as uint));

0 commit comments

Comments
 (0)