Skip to content

Commit da2293c

Browse files
committed
std: Deal with fallout of rtio changes
1 parent 5ec36c3 commit da2293c

File tree

21 files changed

+453
-210
lines changed

21 files changed

+453
-210
lines changed

src/libstd/comm/shared.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ use option::{Some, None, Option};
2727
use owned::Box;
2828
use result::{Ok, Err, Result};
2929
use rt::local::Local;
30+
use rt::mutex::NativeMutex;
3031
use rt::task::{Task, BlockedTask};
3132
use rt::thread::Thread;
3233
use sync::atomics;
33-
use unstable::mutex::NativeMutex;
3434

3535
use mpsc = sync::mpsc_queue;
3636

src/libstd/comm/sync.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,10 @@ use owned::Box;
4343
use ptr::RawPtr;
4444
use result::{Result, Ok, Err};
4545
use rt::local::Local;
46+
use rt::mutex::{NativeMutex, LockGuard};
4647
use rt::task::{Task, BlockedTask};
4748
use sync::atomics;
4849
use ty::Unsafe;
49-
use unstable::mutex::{NativeMutex, LockGuard};
5050
use vec::Vec;
5151

5252
pub struct Packet<T> {

src/libstd/io/fs.rs

Lines changed: 112 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -52,19 +52,22 @@ fs::unlink(&path);
5252
use c_str::ToCStr;
5353
use clone::Clone;
5454
use container::Container;
55+
use io;
5556
use iter::Iterator;
5657
use kinds::Send;
57-
use super::{Reader, Writer, Seek};
58-
use super::{SeekStyle, Read, Write, Open, IoError, Truncate};
59-
use super::{FileMode, FileAccess, FileStat, IoResult, FilePermission};
60-
use rt::rtio::{RtioFileStream, IoFactory, LocalIo};
61-
use io;
58+
use libc;
6259
use option::{Some, None, Option};
6360
use owned::Box;
64-
use result::{Ok, Err};
65-
use path;
6661
use path::{Path, GenericPath};
62+
use path;
63+
use result::{Ok, Err};
64+
use rt::rtio::{RtioFileStream, IoFactory, LocalIo};
65+
use rt::rtio;
6766
use slice::{OwnedVector, ImmutableVector};
67+
use super::UnstableFileStat;
68+
use super::{FileMode, FileAccess, FileStat, IoResult, FilePermission};
69+
use super::{Reader, Writer, Seek, Append, SeekCur, SeekEnd, SeekSet};
70+
use super::{SeekStyle, Read, Write, ReadWrite, Open, IoError, Truncate};
6871
use vec::Vec;
6972

7073
/// Unconstrained file access type that exposes read and write operations
@@ -126,6 +129,16 @@ impl File {
126129
pub fn open_mode(path: &Path,
127130
mode: FileMode,
128131
access: FileAccess) -> IoResult<File> {
132+
let mode = match mode {
133+
Open => rtio::Open,
134+
Append => rtio::Append,
135+
Truncate => rtio::Truncate,
136+
};
137+
let access = match access {
138+
Read => rtio::Read,
139+
Write => rtio::Write,
140+
ReadWrite => rtio::ReadWrite,
141+
};
129142
LocalIo::maybe_raise(|io| {
130143
io.fs_open(&path.to_c_str(), mode, access).map(|fd| {
131144
File {
@@ -134,7 +147,7 @@ impl File {
134147
last_nread: -1
135148
}
136149
})
137-
})
150+
}).map_err(IoError::from_rtio_error)
138151
}
139152

140153
/// Attempts to open a file in read-only mode. This function is equivalent to
@@ -184,15 +197,15 @@ impl File {
184197
/// device. This will flush any internal buffers necessary to perform this
185198
/// operation.
186199
pub fn fsync(&mut self) -> IoResult<()> {
187-
self.fd.fsync()
200+
self.fd.fsync().map_err(IoError::from_rtio_error)
188201
}
189202

190203
/// This function is similar to `fsync`, except that it may not synchronize
191204
/// file metadata to the filesystem. This is intended for use case which
192205
/// must synchronize content, but don't need the metadata on disk. The goal
193206
/// of this method is to reduce disk operations.
194207
pub fn datasync(&mut self) -> IoResult<()> {
195-
self.fd.datasync()
208+
self.fd.datasync().map_err(IoError::from_rtio_error)
196209
}
197210

198211
/// Either truncates or extends the underlying file, updating the size of
@@ -204,7 +217,7 @@ impl File {
204217
/// will be extended to `size` and have all of the intermediate data filled
205218
/// in with 0s.
206219
pub fn truncate(&mut self, size: i64) -> IoResult<()> {
207-
self.fd.truncate(size)
220+
self.fd.truncate(size).map_err(IoError::from_rtio_error)
208221
}
209222

210223
/// Tests whether this stream has reached EOF.
@@ -217,7 +230,10 @@ impl File {
217230

218231
/// Queries information about the underlying file.
219232
pub fn stat(&mut self) -> IoResult<FileStat> {
220-
self.fd.fstat()
233+
match self.fd.fstat() {
234+
Ok(s) => Ok(from_rtio(s)),
235+
Err(e) => Err(IoError::from_rtio_error(e)),
236+
}
221237
}
222238
}
223239

@@ -243,7 +259,9 @@ impl File {
243259
/// user lacks permissions to remove the file, or if some other filesystem-level
244260
/// error occurs.
245261
pub fn unlink(path: &Path) -> IoResult<()> {
246-
LocalIo::maybe_raise(|io| io.fs_unlink(&path.to_c_str()))
262+
LocalIo::maybe_raise(|io| {
263+
io.fs_unlink(&path.to_c_str())
264+
}).map_err(IoError::from_rtio_error)
247265
}
248266

249267
/// Given a path, query the file system to get information about a file,
@@ -268,9 +286,10 @@ pub fn unlink(path: &Path) -> IoResult<()> {
268286
/// to perform a `stat` call on the given path or if there is no entry in the
269287
/// filesystem at the provided path.
270288
pub fn stat(path: &Path) -> IoResult<FileStat> {
271-
LocalIo::maybe_raise(|io| {
272-
io.fs_stat(&path.to_c_str())
273-
})
289+
match LocalIo::maybe_raise(|io| io.fs_stat(&path.to_c_str())) {
290+
Ok(s) => Ok(from_rtio(s)),
291+
Err(e) => Err(IoError::from_rtio_error(e)),
292+
}
274293
}
275294

276295
/// Perform the same operation as the `stat` function, except that this
@@ -282,9 +301,46 @@ pub fn stat(path: &Path) -> IoResult<FileStat> {
282301
///
283302
/// See `stat`
284303
pub fn lstat(path: &Path) -> IoResult<FileStat> {
285-
LocalIo::maybe_raise(|io| {
286-
io.fs_lstat(&path.to_c_str())
287-
})
304+
match LocalIo::maybe_raise(|io| io.fs_lstat(&path.to_c_str())) {
305+
Ok(s) => Ok(from_rtio(s)),
306+
Err(e) => Err(IoError::from_rtio_error(e)),
307+
}
308+
}
309+
310+
fn from_rtio(s: rtio::FileStat) -> FileStat {
311+
let rtio::FileStat {
312+
size, kind, perm, created, modified,
313+
accessed, device, inode, rdev,
314+
nlink, uid, gid, blksize, blocks, flags, gen
315+
} = s;
316+
317+
FileStat {
318+
size: size,
319+
kind: match (kind as libc::c_int) & libc::S_IFMT {
320+
libc::S_IFREG => io::TypeFile,
321+
libc::S_IFDIR => io::TypeDirectory,
322+
libc::S_IFIFO => io::TypeNamedPipe,
323+
libc::S_IFBLK => io::TypeBlockSpecial,
324+
libc::S_IFLNK => io::TypeSymlink,
325+
_ => io::TypeUnknown,
326+
},
327+
perm: FilePermission::from_bits_truncate(perm as u32),
328+
created: created,
329+
modified: modified,
330+
accessed: accessed,
331+
unstable: UnstableFileStat {
332+
device: device,
333+
inode: inode,
334+
rdev: rdev,
335+
nlink: nlink,
336+
uid: uid,
337+
gid: gid,
338+
blksize: blksize,
339+
blocks: blocks,
340+
flags: flags,
341+
gen: gen,
342+
},
343+
}
288344
}
289345

290346
/// Rename a file or directory to a new name.
@@ -304,7 +360,9 @@ pub fn lstat(path: &Path) -> IoResult<FileStat> {
304360
/// permissions to view the contents, or if some other intermittent I/O error
305361
/// occurs.
306362
pub fn rename(from: &Path, to: &Path) -> IoResult<()> {
307-
LocalIo::maybe_raise(|io| io.fs_rename(&from.to_c_str(), &to.to_c_str()))
363+
LocalIo::maybe_raise(|io| {
364+
io.fs_rename(&from.to_c_str(), &to.to_c_str())
365+
}).map_err(IoError::from_rtio_error)
308366
}
309367

310368
/// Copies the contents of one file to another. This function will also
@@ -382,25 +440,33 @@ pub fn copy(from: &Path, to: &Path) -> IoResult<()> {
382440
/// Some possible error situations are not having the permission to
383441
/// change the attributes of a file or the file not existing.
384442
pub fn chmod(path: &Path, mode: io::FilePermission) -> IoResult<()> {
385-
LocalIo::maybe_raise(|io| io.fs_chmod(&path.to_c_str(), mode))
443+
LocalIo::maybe_raise(|io| {
444+
io.fs_chmod(&path.to_c_str(), mode.bits() as uint)
445+
}).map_err(IoError::from_rtio_error)
386446
}
387447

388448
/// Change the user and group owners of a file at the specified path.
389449
pub fn chown(path: &Path, uid: int, gid: int) -> IoResult<()> {
390-
LocalIo::maybe_raise(|io| io.fs_chown(&path.to_c_str(), uid, gid))
450+
LocalIo::maybe_raise(|io| {
451+
io.fs_chown(&path.to_c_str(), uid, gid)
452+
}).map_err(IoError::from_rtio_error)
391453
}
392454

393455
/// Creates a new hard link on the filesystem. The `dst` path will be a
394456
/// link pointing to the `src` path. Note that systems often require these
395457
/// two paths to both be located on the same filesystem.
396458
pub fn link(src: &Path, dst: &Path) -> IoResult<()> {
397-
LocalIo::maybe_raise(|io| io.fs_link(&src.to_c_str(), &dst.to_c_str()))
459+
LocalIo::maybe_raise(|io| {
460+
io.fs_link(&src.to_c_str(), &dst.to_c_str())
461+
}).map_err(IoError::from_rtio_error)
398462
}
399463

400464
/// Creates a new symbolic link on the filesystem. The `dst` path will be a
401465
/// symlink pointing to the `src` path.
402466
pub fn symlink(src: &Path, dst: &Path) -> IoResult<()> {
403-
LocalIo::maybe_raise(|io| io.fs_symlink(&src.to_c_str(), &dst.to_c_str()))
467+
LocalIo::maybe_raise(|io| {
468+
io.fs_symlink(&src.to_c_str(), &dst.to_c_str())
469+
}).map_err(IoError::from_rtio_error)
404470
}
405471

406472
/// Reads a symlink, returning the file that the symlink points to.
@@ -412,7 +478,7 @@ pub fn symlink(src: &Path, dst: &Path) -> IoResult<()> {
412478
pub fn readlink(path: &Path) -> IoResult<Path> {
413479
LocalIo::maybe_raise(|io| {
414480
Ok(Path::new(try!(io.fs_readlink(&path.to_c_str()))))
415-
})
481+
}).map_err(IoError::from_rtio_error)
416482
}
417483

418484
/// Create a new, empty directory at the provided path
@@ -433,7 +499,9 @@ pub fn readlink(path: &Path) -> IoResult<Path> {
433499
/// This call will return an error if the user lacks permissions to make a new
434500
/// directory at the provided path, or if the directory already exists.
435501
pub fn mkdir(path: &Path, mode: FilePermission) -> IoResult<()> {
436-
LocalIo::maybe_raise(|io| io.fs_mkdir(&path.to_c_str(), mode))
502+
LocalIo::maybe_raise(|io| {
503+
io.fs_mkdir(&path.to_c_str(), mode.bits() as uint)
504+
}).map_err(IoError::from_rtio_error)
437505
}
438506

439507
/// Remove an existing, empty directory
@@ -453,7 +521,9 @@ pub fn mkdir(path: &Path, mode: FilePermission) -> IoResult<()> {
453521
/// This call will return an error if the user lacks permissions to remove the
454522
/// directory at the provided path, or if the directory isn't empty.
455523
pub fn rmdir(path: &Path) -> IoResult<()> {
456-
LocalIo::maybe_raise(|io| io.fs_rmdir(&path.to_c_str()))
524+
LocalIo::maybe_raise(|io| {
525+
io.fs_rmdir(&path.to_c_str())
526+
}).map_err(IoError::from_rtio_error)
457527
}
458528

459529
/// Retrieve a vector containing all entries within a provided directory
@@ -492,7 +562,7 @@ pub fn readdir(path: &Path) -> IoResult<Vec<Path>> {
492562
Ok(try!(io.fs_readdir(&path.to_c_str(), 0)).move_iter().map(|a| {
493563
Path::new(a)
494564
}).collect())
495-
})
565+
}).map_err(IoError::from_rtio_error)
496566
}
497567

498568
/// Returns an iterator which will recursively walk the directory structure
@@ -616,7 +686,9 @@ pub fn rmdir_recursive(path: &Path) -> IoResult<()> {
616686
/// be in milliseconds.
617687
// FIXME(#10301) these arguments should not be u64
618688
pub fn change_file_times(path: &Path, atime: u64, mtime: u64) -> IoResult<()> {
619-
LocalIo::maybe_raise(|io| io.fs_utime(&path.to_c_str(), atime, mtime))
689+
LocalIo::maybe_raise(|io| {
690+
io.fs_utime(&path.to_c_str(), atime, mtime)
691+
}).map_err(IoError::from_rtio_error)
620692
}
621693

622694
impl Reader for File {
@@ -629,28 +701,35 @@ impl Reader for File {
629701
_ => Ok(read as uint)
630702
}
631703
},
632-
Err(e) => Err(e),
704+
Err(e) => Err(IoError::from_rtio_error(e)),
633705
}
634706
}
635707
}
636708

637709
impl Writer for File {
638-
fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.fd.write(buf) }
710+
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
711+
self.fd.write(buf).map_err(IoError::from_rtio_error)
712+
}
639713
}
640714

641715
impl Seek for File {
642716
fn tell(&self) -> IoResult<u64> {
643-
self.fd.tell()
717+
self.fd.tell().map_err(IoError::from_rtio_error)
644718
}
645719

646720
fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
721+
let style = match style {
722+
SeekSet => rtio::SeekSet,
723+
SeekCur => rtio::SeekCur,
724+
SeekEnd => rtio::SeekEnd,
725+
};
647726
match self.fd.seek(pos, style) {
648727
Ok(_) => {
649728
// successful seek resets EOF indicator
650729
self.last_nread = -1;
651730
Ok(())
652731
}
653-
Err(e) => Err(e),
732+
Err(e) => Err(IoError::from_rtio_error(e)),
654733
}
655734
}
656735
}

src/libstd/io/mod.rs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ use option::{Option, Some, None};
225225
use os;
226226
use owned::Box;
227227
use result::{Ok, Err, Result};
228+
use rt::rtio;
228229
use slice::{Vector, MutableVector, ImmutableVector};
229230
use str::{StrSlice, StrAllocating};
230231
use str;
@@ -323,6 +324,14 @@ impl IoError {
323324
libc::ERROR_BROKEN_PIPE => (EndOfFile, "the pipe has ended"),
324325
libc::ERROR_OPERATION_ABORTED =>
325326
(TimedOut, "operation timed out"),
327+
libc::WSAEINVAL => (InvalidInput, "invalid argument"),
328+
libc::ERROR_CALL_NOT_IMPLEMENTED =>
329+
(IoUnavailable, "function not implemented"),
330+
libc::ERROR_CALL_NOT_IMPLEMENTED =>
331+
(MismatchedFileTypeForOperation,
332+
"invalid handle provided to function"),
333+
libc::ERROR_NOTHING_TO_TERMINATE =>
334+
(InvalidInput, "no process to kill"),
326335

327336
// libuv maps this error code to EISDIR. we do too. if it is found
328337
// to be incorrect, we can add in some more machinery to only
@@ -351,9 +360,17 @@ impl IoError {
351360
libc::EADDRINUSE => (ConnectionRefused, "address in use"),
352361
libc::ENOENT => (FileNotFound, "no such file or directory"),
353362
libc::EISDIR => (InvalidInput, "illegal operation on a directory"),
354-
355-
// These two constants can have the same value on some systems, but
356-
// different values on others, so we can't use a match clause
363+
libc::ENOSYS => (IoUnavailable, "function not implemented"),
364+
libc::EINVAL => (InvalidInput, "invalid argument"),
365+
libc::ENOTTY =>
366+
(MismatchedFileTypeForOperation,
367+
"file descriptor is not a TTY"),
368+
libc::ETIMEDOUT => (TimedOut, "operation timed out"),
369+
libc::ECANCELED => (TimedOut, "operation aborted"),
370+
371+
// These two constants can have the same value on some systems,
372+
// but different values on others, so we can't use a match
373+
// clause
357374
x if x == libc::EAGAIN || x == libc::EWOULDBLOCK =>
358375
(ResourceUnavailable, "resource temporarily unavailable"),
359376

@@ -382,6 +399,17 @@ impl IoError {
382399
pub fn last_error() -> IoError {
383400
IoError::from_errno(os::errno() as uint, true)
384401
}
402+
403+
fn from_rtio_error(err: rtio::IoError) -> IoError {
404+
let rtio::IoError { code, extra, detail } = err;
405+
let mut ioerr = IoError::from_errno(code, false);
406+
ioerr.detail = detail;
407+
ioerr.kind = match ioerr.kind {
408+
TimedOut if extra > 0 => ShortWrite(extra),
409+
k => k,
410+
};
411+
return ioerr;
412+
}
385413
}
386414

387415
impl fmt::Show for IoError {

0 commit comments

Comments
 (0)