@@ -52,19 +52,22 @@ fs::unlink(&path);
5252use c_str:: ToCStr ;
5353use clone:: Clone ;
5454use container:: Container ;
55+ use io;
5556use iter:: Iterator ;
5657use 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;
6259use option:: { Some , None , Option } ;
6360use owned:: Box ;
64- use result:: { Ok , Err } ;
65- use path;
6661use path:: { Path , GenericPath } ;
62+ use path;
63+ use result:: { Ok , Err } ;
64+ use rt:: rtio:: { RtioFileStream , IoFactory , LocalIo } ;
65+ use rt:: rtio;
6766use 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 } ;
6871use 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.
245261pub 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.
270288pub 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`
284303pub 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.
306362pub 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.
384442pub 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.
389449pub 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.
396458pub 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.
402466pub 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<()> {
412478pub 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.
435501pub 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.
455523pub 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
618688pub 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
622694impl 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
637709impl 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
641715impl 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}
0 commit comments