]> git.lizzy.rs Git - rust.git/blob - src/libstd/io/mod.rs
libstd: Document the following modules:
[rust.git] / src / libstd / io / mod.rs
1 // Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 // FIXME: cover these topics:
12 //        path, reader, writer, stream, raii (close not needed),
13 //        stdio, print!, println!, file access, process spawning,
14 //        error handling
15
16
17 /*! I/O, including files, networking, timers, and processes
18
19 `std::io` provides Rust's basic I/O types,
20 for reading and writing to files, TCP, UDP,
21 and other types of sockets and pipes,
22 manipulating the file system, spawning processes and signal handling.
23
24 # Examples
25
26 Some examples of obvious things you might want to do
27
28 * Read lines from stdin
29
30     ```rust
31     use std::io;
32
33     for line in io::stdin().lines() {
34         print!("{}", line.unwrap());
35     }
36     ```
37
38 * Read a complete file
39
40     ```rust
41     use std::io::File;
42
43     let contents = File::open(&Path::new("message.txt")).read_to_end();
44     ```
45
46 * Write a line to a file
47
48     ```rust
49     # #[allow(unused_must_use)];
50     use std::io::File;
51
52     let mut file = File::create(&Path::new("message.txt"));
53     file.write(bytes!("hello, file!\n"));
54     # drop(file);
55     # ::std::io::fs::unlink(&Path::new("message.txt"));
56     ```
57
58 * Iterate over the lines of a file
59
60     ```rust,no_run
61     use std::io::BufferedReader;
62     use std::io::File;
63
64     let path = Path::new("message.txt");
65     let mut file = BufferedReader::new(File::open(&path));
66     for line in file.lines() {
67         print!("{}", line.unwrap());
68     }
69     ```
70
71 * Pull the lines of a file into a vector of strings
72
73     ```rust,no_run
74     use std::io::BufferedReader;
75     use std::io::File;
76
77     let path = Path::new("message.txt");
78     let mut file = BufferedReader::new(File::open(&path));
79     let lines: ~[~str] = file.lines().map(|x| x.unwrap()).collect();
80     ```
81
82 * Make a simple TCP client connection and request
83
84     ```rust,should_fail
85     # #[allow(unused_must_use)];
86     use std::io::net::ip::SocketAddr;
87     use std::io::net::tcp::TcpStream;
88
89     let addr = from_str::<SocketAddr>("127.0.0.1:8080").unwrap();
90     let mut socket = TcpStream::connect(addr).unwrap();
91     socket.write(bytes!("GET / HTTP/1.0\n\n"));
92     let response = socket.read_to_end();
93     ```
94
95 * Make a simple TCP server
96
97     ```rust
98     # fn main() { }
99     # fn foo() {
100     # #[allow(unused_must_use, dead_code)];
101     use std::io::net::tcp::TcpListener;
102     use std::io::net::ip::{Ipv4Addr, SocketAddr};
103     use std::io::{Acceptor, Listener};
104
105     let addr = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 80 };
106     let listener = TcpListener::bind(addr);
107
108     // bind the listener to the specified address
109     let mut acceptor = listener.listen();
110
111     // accept connections and process them
112     # fn handle_client<T>(_: T) {}
113     for stream in acceptor.incoming() {
114         spawn(proc() {
115             handle_client(stream);
116         });
117     }
118
119     // close the socket server
120     drop(acceptor);
121     # }
122     ```
123
124
125 # Error Handling
126
127 I/O is an area where nearly every operation can result in unexpected
128 errors. Errors should be painfully visible when they happen, and handling them
129 should be easy to work with. It should be convenient to handle specific I/O
130 errors, and it should also be convenient to not deal with I/O errors.
131
132 Rust's I/O employs a combination of techniques to reduce boilerplate
133 while still providing feedback about errors. The basic strategy:
134
135 * All I/O operations return `IoResult<T>` which is equivalent to
136   `Result<T, IoError>`. The `Result` type is defined in the `std::result`
137   module.
138 * If the `Result` type goes unused, then the compiler will by default emit a
139   warning about the unused result. This is because `Result` has the
140   `#[must_use]` attribute.
141 * Common traits are implemented for `IoResult`, e.g.
142   `impl<R: Reader> Reader for IoResult<R>`, so that error values do not have
143   to be 'unwrapped' before use.
144
145 These features combine in the API to allow for expressions like
146 `File::create(&Path::new("diary.txt")).write(bytes!("Met a girl.\n"))`
147 without having to worry about whether "diary.txt" exists or whether
148 the write succeeds. As written, if either `new` or `write_line`
149 encounters an error then the result of the entire expression will
150 be an error.
151
152 If you wanted to handle the error though you might write:
153
154 ```rust
155 # #[allow(unused_must_use)];
156 use std::io::File;
157
158 match File::create(&Path::new("diary.txt")).write(bytes!("Met a girl.\n")) {
159     Ok(()) => (), // succeeded
160     Err(e) => println!("failed to write to my diary: {}", e),
161 }
162
163 # ::std::io::fs::unlink(&Path::new("diary.txt"));
164 ```
165
166 So what actually happens if `create` encounters an error?
167 It's important to know that what `new` returns is not a `File`
168 but an `IoResult<File>`.  If the file does not open, then `new` will simply
169 return `Err(..)`. Because there is an implementation of `Writer` (the trait
170 required ultimately required for types to implement `write_line`) there is no
171 need to inspect or unwrap the `IoResult<File>` and we simply call `write_line`
172 on it. If `new` returned an `Err(..)` then the followup call to `write_line`
173 will also return an error.
174
175 ## `try!`
176
177 Explicit pattern matching on `IoResult`s can get quite verbose, especially
178 when performing many I/O operations. Some examples (like those above) are
179 alleviated with extra methods implemented on `IoResult`, but others have more
180 complex interdependencies among each I/O operation.
181
182 The `try!` macro from `std::macros` is provided as a method of early-return
183 inside `Result`-returning functions. It expands to an early-return on `Err`
184 and otherwise unwraps the contained `Ok` value.
185
186 If you wanted to read several `u32`s from a file and return their product:
187
188 ```rust
189 use std::io::{File, IoResult};
190
191 fn file_product(p: &Path) -> IoResult<u32> {
192     let mut f = File::open(p);
193     let x1 = try!(f.read_le_u32());
194     let x2 = try!(f.read_le_u32());
195
196     Ok(x1 * x2)
197 }
198
199 match file_product(&Path::new("numbers.bin")) {
200     Ok(x) => println!("{}", x),
201     Err(e) => println!("Failed to read numbers!")
202 }
203 ```
204
205 With `try!` in `file_product`, each `read_le_u32` need not be directly
206 concerned with error handling; instead its caller is responsible for
207 responding to errors that may occur while attempting to read the numbers.
208
209 */
210
211 #[deny(unused_must_use)];
212
213 use cast;
214 use char::Char;
215 use container::Container;
216 use fmt;
217 use int;
218 use iter::Iterator;
219 use option::{Option, Some, None};
220 use path::Path;
221 use result::{Ok, Err, Result};
222 use str::{StrSlice, OwnedStr};
223 use str;
224 use uint;
225 use unstable::finally::try_finally;
226 use slice::{OwnedVector, MutableVector, ImmutableVector, OwnedCloneableVector};
227 use slice;
228
229 // Reexports
230 pub use self::stdio::stdin;
231 pub use self::stdio::stdout;
232 pub use self::stdio::stderr;
233 pub use self::stdio::print;
234 pub use self::stdio::println;
235
236 pub use self::fs::File;
237 pub use self::timer::Timer;
238 pub use self::net::ip::IpAddr;
239 pub use self::net::tcp::TcpListener;
240 pub use self::net::tcp::TcpStream;
241 pub use self::net::udp::UdpStream;
242 pub use self::pipe::PipeStream;
243 pub use self::process::{Process, ProcessConfig};
244 pub use self::tempfile::TempDir;
245
246 pub use self::mem::{MemReader, BufReader, MemWriter, BufWriter};
247 pub use self::buffered::{BufferedReader, BufferedWriter, BufferedStream,
248                          LineBufferedWriter};
249 pub use self::comm_adapters::{ChanReader, ChanWriter};
250
251 // this comes first to get the iotest! macro
252 pub mod test;
253
254 mod buffered;
255 mod comm_adapters;
256 mod mem;
257 mod result;
258 mod tempfile;
259 pub mod extensions;
260 pub mod fs;
261 pub mod net;
262 pub mod pipe;
263 pub mod process;
264 pub mod signal;
265 pub mod stdio;
266 pub mod timer;
267 pub mod util;
268
269 /// The default buffer size for various I/O operations
270 // libuv recommends 64k buffers to maximize throughput
271 // https://groups.google.com/forum/#!topic/libuv/oQO1HJAIDdA
272 static DEFAULT_BUF_SIZE: uint = 1024 * 64;
273
274 /// A convenient typedef of the return value of any I/O action.
275 pub type IoResult<T> = Result<T, IoError>;
276
277 /// The type passed to I/O condition handlers to indicate error
278 ///
279 /// # FIXME
280 ///
281 /// Is something like this sufficient? It's kind of archaic
282 #[deriving(Eq, Clone)]
283 pub struct IoError {
284     /// An enumeration which can be matched against for determining the flavor
285     /// of error.
286     kind: IoErrorKind,
287     /// A human-readable description about the error
288     desc: &'static str,
289     /// Detailed information about this error, not always available
290     detail: Option<~str>
291 }
292
293 impl fmt::Show for IoError {
294     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
295         try!(fmt.buf.write_str(self.desc));
296         match self.detail {
297             Some(ref s) => write!(fmt.buf, " ({})", *s),
298             None => Ok(())
299         }
300     }
301 }
302
303 /// A list specifying general categories of I/O error.
304 #[deriving(Eq, Clone, Show)]
305 #[allow(missing_doc)]
306 pub enum IoErrorKind {
307     /// Any I/O error not part of this list.
308     OtherIoError,
309     /// The operation could not complete because end of file was reached.
310     EndOfFile,
311     /// The file was not found.
312     FileNotFound,
313     /// The file permissions disallowed access to this file.
314     PermissionDenied,
315     /// A network connection failed for some reason not specified in this list.
316     ConnectionFailed,
317     /// The network operation failed because the network connection was cloesd.
318     Closed,
319     /// The connection was refused by the remote server.
320     ConnectionRefused,
321     /// The connection was reset by the remote server.
322     ConnectionReset,
323     /// The connection was aborted (terminated) by the remote server.
324     ConnectionAborted,
325     /// The network operation failed because it was not connected yet.
326     NotConnected,
327     /// The operation failed because a pipe was closed.
328     BrokenPipe,
329     /// A file already existed with that name.
330     PathAlreadyExists,
331     /// No file exists at that location.
332     PathDoesntExist,
333     /// The path did not specify the type of file that this operation required. For example,
334     /// attempting to copy a directory with the `fs::copy()` operation will fail with this error.
335     MismatchedFileTypeForOperation,
336     /// The operation temporarily failed (for example, because a signal was received), and retrying
337     /// may succeed.
338     ResourceUnavailable,
339     /// No I/O functionality is available for this task.
340     IoUnavailable,
341     /// A parameter was incorrect in a way that caused an I/O error not part of this list.
342     InvalidInput,
343 }
344
345 /// A trait for objects which are byte-oriented streams. Readers are defined by
346 /// one method, `read`. This function will block until data is available,
347 /// filling in the provided buffer with any data read.
348 ///
349 /// Readers are intended to be composable with one another. Many objects
350 /// throughout the I/O and related libraries take and provide types which
351 /// implement the `Reader` trait.
352 pub trait Reader {
353
354     // Only method which need to get implemented for this trait
355
356     /// Read bytes, up to the length of `buf` and place them in `buf`.
357     /// Returns the number of bytes read. The number of bytes read my
358     /// be less than the number requested, even 0. Returns `Err` on EOF.
359     ///
360     /// # Error
361     ///
362     /// If an error occurs during this I/O operation, then it is returned as
363     /// `Err(IoError)`. Note that end-of-file is considered an error, and can be
364     /// inspected for in the error's `kind` field. Also note that reading 0
365     /// bytes is not considered an error in all circumstances
366     fn read(&mut self, buf: &mut [u8]) -> IoResult<uint>;
367
368     // Convenient helper methods based on the above methods
369
370     /// Reads a single byte. Returns `Err` on EOF.
371     fn read_byte(&mut self) -> IoResult<u8> {
372         let mut buf = [0];
373         loop {
374             match self.read(buf) {
375                 Ok(0) => {}
376                 Ok(1) => return Ok(buf[0]),
377                 Ok(_) => unreachable!(),
378                 Err(e) => return Err(e)
379             }
380         }
381     }
382
383     /// Fills the provided slice with bytes from this reader
384     ///
385     /// This will continue to call `read` until the slice has been completely
386     /// filled with bytes.
387     ///
388     /// # Error
389     ///
390     /// If an error occurs at any point, that error is returned, and no further
391     /// bytes are read.
392     fn fill(&mut self, buf: &mut [u8]) -> IoResult<()> {
393         let mut read = 0;
394         while read < buf.len() {
395             read += try!(self.read(buf.mut_slice_from(read)));
396         }
397         Ok(())
398     }
399
400     /// Reads exactly `len` bytes and appends them to a vector.
401     ///
402     /// May push fewer than the requested number of bytes on error
403     /// or EOF. If `Ok(())` is returned, then all of the requested bytes were
404     /// pushed on to the vector, otherwise the amount `len` bytes couldn't be
405     /// read (an error was encountered), and the error is returned.
406     fn push_exact(&mut self, buf: &mut ~[u8], len: uint) -> IoResult<()> {
407         struct State<'a> {
408             buf: &'a mut ~[u8],
409             total_read: uint
410         }
411
412         let start_len = buf.len();
413         let mut s = State { buf: buf, total_read: 0 };
414
415         s.buf.reserve_additional(len);
416         unsafe { s.buf.set_len(start_len + len); }
417
418         try_finally(
419             &mut s, (),
420             |s, _| {
421                 while s.total_read < len {
422                     let len = s.buf.len();
423                     let slice = s.buf.mut_slice(start_len + s.total_read, len);
424                     match self.read(slice) {
425                         Ok(nread) => {
426                             s.total_read += nread;
427                         }
428                         Err(e) => return Err(e)
429                     }
430                 }
431                 Ok(())
432             },
433             |s| unsafe { s.buf.set_len(start_len + s.total_read) })
434     }
435
436     /// Reads exactly `len` bytes and gives you back a new vector of length
437     /// `len`
438     ///
439     /// # Error
440     ///
441     /// Fails with the same conditions as `read`. Additionally returns error
442     /// on EOF. Note that if an error is returned, then some number of bytes may
443     /// have already been consumed from the underlying reader, and they are lost
444     /// (not returned as part of the error). If this is unacceptable, then it is
445     /// recommended to use the `push_exact` or `read` methods.
446     fn read_exact(&mut self, len: uint) -> IoResult<~[u8]> {
447         let mut buf = slice::with_capacity(len);
448         match self.push_exact(&mut buf, len) {
449             Ok(()) => Ok(buf),
450             Err(e) => Err(e),
451         }
452     }
453
454     /// Reads all remaining bytes from the stream.
455     ///
456     /// # Error
457     ///
458     /// Returns any non-EOF error immediately. Previously read bytes are
459     /// discarded when an error is returned.
460     ///
461     /// When EOF is encountered, all bytes read up to that point are returned.
462     fn read_to_end(&mut self) -> IoResult<~[u8]> {
463         let mut buf = slice::with_capacity(DEFAULT_BUF_SIZE);
464         loop {
465             match self.push_exact(&mut buf, DEFAULT_BUF_SIZE) {
466                 Ok(()) => {}
467                 Err(ref e) if e.kind == EndOfFile => break,
468                 Err(e) => return Err(e)
469             }
470         }
471         return Ok(buf);
472     }
473
474     /// Reads all of the remaining bytes of this stream, interpreting them as a
475     /// UTF-8 encoded stream. The corresponding string is returned.
476     ///
477     /// # Error
478     ///
479     /// This function returns all of the same errors as `read_to_end` with an
480     /// additional error if the reader's contents are not a valid sequence of
481     /// UTF-8 bytes.
482     fn read_to_str(&mut self) -> IoResult<~str> {
483         self.read_to_end().and_then(|s| {
484             match str::from_utf8_owned(s) {
485                 Some(s) => Ok(s),
486                 None => Err(standard_error(InvalidInput)),
487             }
488         })
489     }
490
491     /// Create an iterator that reads a single byte on
492     /// each iteration, until EOF.
493     ///
494     /// # Error
495     ///
496     /// Any error other than `EndOfFile` that is produced by the underlying Reader
497     /// is returned by the iterator and should be handled by the caller.
498     fn bytes<'r>(&'r mut self) -> extensions::Bytes<'r, Self> {
499         extensions::Bytes::new(self)
500     }
501
502     // Byte conversion helpers
503
504     /// Reads `n` little-endian unsigned integer bytes.
505     ///
506     /// `n` must be between 1 and 8, inclusive.
507     fn read_le_uint_n(&mut self, nbytes: uint) -> IoResult<u64> {
508         assert!(nbytes > 0 && nbytes <= 8);
509
510         let mut val = 0u64;
511         let mut pos = 0;
512         let mut i = nbytes;
513         while i > 0 {
514             val += (try!(self.read_u8()) as u64) << pos;
515             pos += 8;
516             i -= 1;
517         }
518         Ok(val)
519     }
520
521     /// Reads `n` little-endian signed integer bytes.
522     ///
523     /// `n` must be between 1 and 8, inclusive.
524     fn read_le_int_n(&mut self, nbytes: uint) -> IoResult<i64> {
525         self.read_le_uint_n(nbytes).map(|i| extend_sign(i, nbytes))
526     }
527
528     /// Reads `n` big-endian unsigned integer bytes.
529     ///
530     /// `n` must be between 1 and 8, inclusive.
531     fn read_be_uint_n(&mut self, nbytes: uint) -> IoResult<u64> {
532         assert!(nbytes > 0 && nbytes <= 8);
533
534         let mut val = 0u64;
535         let mut i = nbytes;
536         while i > 0 {
537             i -= 1;
538             val += (try!(self.read_u8()) as u64) << i * 8;
539         }
540         Ok(val)
541     }
542
543     /// Reads `n` big-endian signed integer bytes.
544     ///
545     /// `n` must be between 1 and 8, inclusive.
546     fn read_be_int_n(&mut self, nbytes: uint) -> IoResult<i64> {
547         self.read_be_uint_n(nbytes).map(|i| extend_sign(i, nbytes))
548     }
549
550     /// Reads a little-endian unsigned integer.
551     ///
552     /// The number of bytes returned is system-dependant.
553     fn read_le_uint(&mut self) -> IoResult<uint> {
554         self.read_le_uint_n(uint::BYTES).map(|i| i as uint)
555     }
556
557     /// Reads a little-endian integer.
558     ///
559     /// The number of bytes returned is system-dependant.
560     fn read_le_int(&mut self) -> IoResult<int> {
561         self.read_le_int_n(int::BYTES).map(|i| i as int)
562     }
563
564     /// Reads a big-endian unsigned integer.
565     ///
566     /// The number of bytes returned is system-dependant.
567     fn read_be_uint(&mut self) -> IoResult<uint> {
568         self.read_be_uint_n(uint::BYTES).map(|i| i as uint)
569     }
570
571     /// Reads a big-endian integer.
572     ///
573     /// The number of bytes returned is system-dependant.
574     fn read_be_int(&mut self) -> IoResult<int> {
575         self.read_be_int_n(int::BYTES).map(|i| i as int)
576     }
577
578     /// Reads a big-endian `u64`.
579     ///
580     /// `u64`s are 8 bytes long.
581     fn read_be_u64(&mut self) -> IoResult<u64> {
582         self.read_be_uint_n(8)
583     }
584
585     /// Reads a big-endian `u32`.
586     ///
587     /// `u32`s are 4 bytes long.
588     fn read_be_u32(&mut self) -> IoResult<u32> {
589         self.read_be_uint_n(4).map(|i| i as u32)
590     }
591
592     /// Reads a big-endian `u16`.
593     ///
594     /// `u16`s are 2 bytes long.
595     fn read_be_u16(&mut self) -> IoResult<u16> {
596         self.read_be_uint_n(2).map(|i| i as u16)
597     }
598
599     /// Reads a big-endian `i64`.
600     ///
601     /// `i64`s are 8 bytes long.
602     fn read_be_i64(&mut self) -> IoResult<i64> {
603         self.read_be_int_n(8)
604     }
605
606     /// Reads a big-endian `i32`.
607     ///
608     /// `i32`s are 4 bytes long.
609     fn read_be_i32(&mut self) -> IoResult<i32> {
610         self.read_be_int_n(4).map(|i| i as i32)
611     }
612
613     /// Reads a big-endian `i16`.
614     ///
615     /// `i16`s are 2 bytes long.
616     fn read_be_i16(&mut self) -> IoResult<i16> {
617         self.read_be_int_n(2).map(|i| i as i16)
618     }
619
620     /// Reads a big-endian `f64`.
621     ///
622     /// `f64`s are 8 byte, IEEE754 double-precision floating point numbers.
623     fn read_be_f64(&mut self) -> IoResult<f64> {
624         self.read_be_u64().map(|i| unsafe {
625             cast::transmute::<u64, f64>(i)
626         })
627     }
628
629     /// Reads a big-endian `f32`.
630     ///
631     /// `f32`s are 4 byte, IEEE754 single-precision floating point numbers.
632     fn read_be_f32(&mut self) -> IoResult<f32> {
633         self.read_be_u32().map(|i| unsafe {
634             cast::transmute::<u32, f32>(i)
635         })
636     }
637
638     /// Reads a little-endian `u64`.
639     ///
640     /// `u64`s are 8 bytes long.
641     fn read_le_u64(&mut self) -> IoResult<u64> {
642         self.read_le_uint_n(8)
643     }
644
645     /// Reads a little-endian `u32`.
646     ///
647     /// `u32`s are 4 bytes long.
648     fn read_le_u32(&mut self) -> IoResult<u32> {
649         self.read_le_uint_n(4).map(|i| i as u32)
650     }
651
652     /// Reads a little-endian `u16`.
653     ///
654     /// `u16`s are 2 bytes long.
655     fn read_le_u16(&mut self) -> IoResult<u16> {
656         self.read_le_uint_n(2).map(|i| i as u16)
657     }
658
659     /// Reads a little-endian `i64`.
660     ///
661     /// `i64`s are 8 bytes long.
662     fn read_le_i64(&mut self) -> IoResult<i64> {
663         self.read_le_int_n(8)
664     }
665
666     /// Reads a little-endian `i32`.
667     ///
668     /// `i32`s are 4 bytes long.
669     fn read_le_i32(&mut self) -> IoResult<i32> {
670         self.read_le_int_n(4).map(|i| i as i32)
671     }
672
673     /// Reads a little-endian `i16`.
674     ///
675     /// `i16`s are 2 bytes long.
676     fn read_le_i16(&mut self) -> IoResult<i16> {
677         self.read_le_int_n(2).map(|i| i as i16)
678     }
679
680     /// Reads a little-endian `f64`.
681     ///
682     /// `f64`s are 8 byte, IEEE754 double-precision floating point numbers.
683     fn read_le_f64(&mut self) -> IoResult<f64> {
684         self.read_le_u64().map(|i| unsafe {
685             cast::transmute::<u64, f64>(i)
686         })
687     }
688
689     /// Reads a little-endian `f32`.
690     ///
691     /// `f32`s are 4 byte, IEEE754 single-precision floating point numbers.
692     fn read_le_f32(&mut self) -> IoResult<f32> {
693         self.read_le_u32().map(|i| unsafe {
694             cast::transmute::<u32, f32>(i)
695         })
696     }
697
698     /// Read a u8.
699     ///
700     /// `u8`s are 1 byte.
701     fn read_u8(&mut self) -> IoResult<u8> {
702         self.read_byte()
703     }
704
705     /// Read an i8.
706     ///
707     /// `i8`s are 1 byte.
708     fn read_i8(&mut self) -> IoResult<i8> {
709         self.read_byte().map(|i| i as i8)
710     }
711
712     /// Creates a wrapper around a mutable reference to the reader.
713     ///
714     /// This is useful to allow applying adaptors while still
715     /// retaining ownership of the original value.
716     fn by_ref<'a>(&'a mut self) -> RefReader<'a, Self> {
717         RefReader { inner: self }
718     }
719 }
720
721 impl Reader for ~Reader {
722     fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.read(buf) }
723 }
724
725 impl<'a> Reader for &'a mut Reader {
726     fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.read(buf) }
727 }
728
729 /// A `RefReader` is a struct implementing `Reader` which contains a reference
730 /// to another reader. This is often useful when composing streams.
731 ///
732 /// # Example
733 ///
734 /// ```
735 /// # fn main() {}
736 /// # fn process_input<R: Reader>(r: R) {}
737 /// # fn foo() {
738 /// use std::io;
739 /// use std::io::util::LimitReader;
740 ///
741 /// let mut stream = io::stdin();
742 ///
743 /// // Only allow the function to process at most one kilobyte of input
744 /// {
745 ///     let stream = LimitReader::new(stream.by_ref(), 1024);
746 ///     process_input(stream);
747 /// }
748 ///
749 /// // 'stream' is still available for use here
750 ///
751 /// # }
752 /// ```
753 pub struct RefReader<'a, R> {
754     /// The underlying reader which this is referencing
755     inner: &'a mut R
756 }
757
758 impl<'a, R: Reader> Reader for RefReader<'a, R> {
759     fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.inner.read(buf) }
760 }
761
762 fn extend_sign(val: u64, nbytes: uint) -> i64 {
763     let shift = (8 - nbytes) * 8;
764     (val << shift) as i64 >> shift
765 }
766
767 /// A trait for objects which are byte-oriented streams. Writers are defined by
768 /// one method, `write`. This function will block until the provided buffer of
769 /// bytes has been entirely written, and it will return any failurs which occur.
770 ///
771 /// Another commonly overriden method is the `flush` method for writers such as
772 /// buffered writers.
773 ///
774 /// Writers are intended to be composable with one another. Many objects
775 /// throughout the I/O and related libraries take and provide types which
776 /// implement the `Writer` trait.
777 pub trait Writer {
778     /// Write the entirety of a given buffer
779     ///
780     /// # Errors
781     ///
782     /// If an error happens during the I/O operation, the error is returned as
783     /// `Err`. Note that it is considered an error if the entire buffer could
784     /// not be written, and if an error is returned then it is unknown how much
785     /// data (if any) was actually written.
786     fn write(&mut self, buf: &[u8]) -> IoResult<()>;
787
788     /// Flush this output stream, ensuring that all intermediately buffered
789     /// contents reach their destination.
790     ///
791     /// This is by default a no-op and implementers of the `Writer` trait should
792     /// decide whether their stream needs to be buffered or not.
793     fn flush(&mut self) -> IoResult<()> { Ok(()) }
794
795     /// Write a rust string into this sink.
796     ///
797     /// The bytes written will be the UTF-8 encoded version of the input string.
798     /// If other encodings are desired, it is recommended to compose this stream
799     /// with another performing the conversion, or to use `write` with a
800     /// converted byte-array instead.
801     fn write_str(&mut self, s: &str) -> IoResult<()> {
802         self.write(s.as_bytes())
803     }
804
805     /// Writes a string into this sink, and then writes a literal newline (`\n`)
806     /// byte afterwards. Note that the writing of the newline is *not* atomic in
807     /// the sense that the call to `write` is invoked twice (once with the
808     /// string and once with a newline character).
809     ///
810     /// If other encodings or line ending flavors are desired, it is recommended
811     /// that the `write` method is used specifically instead.
812     fn write_line(&mut self, s: &str) -> IoResult<()> {
813         self.write_str(s).and_then(|()| self.write(['\n' as u8]))
814     }
815
816     /// Write a single char, encoded as UTF-8.
817     fn write_char(&mut self, c: char) -> IoResult<()> {
818         let mut buf = [0u8, ..4];
819         let n = c.encode_utf8(buf.as_mut_slice());
820         self.write(buf.slice_to(n))
821     }
822
823     /// Write the result of passing n through `int::to_str_bytes`.
824     fn write_int(&mut self, n: int) -> IoResult<()> {
825         write!(self, "{:d}", n)
826     }
827
828     /// Write the result of passing n through `uint::to_str_bytes`.
829     fn write_uint(&mut self, n: uint) -> IoResult<()> {
830         write!(self, "{:u}", n)
831     }
832
833     /// Write a little-endian uint (number of bytes depends on system).
834     fn write_le_uint(&mut self, n: uint) -> IoResult<()> {
835         extensions::u64_to_le_bytes(n as u64, uint::BYTES, |v| self.write(v))
836     }
837
838     /// Write a little-endian int (number of bytes depends on system).
839     fn write_le_int(&mut self, n: int) -> IoResult<()> {
840         extensions::u64_to_le_bytes(n as u64, int::BYTES, |v| self.write(v))
841     }
842
843     /// Write a big-endian uint (number of bytes depends on system).
844     fn write_be_uint(&mut self, n: uint) -> IoResult<()> {
845         extensions::u64_to_be_bytes(n as u64, uint::BYTES, |v| self.write(v))
846     }
847
848     /// Write a big-endian int (number of bytes depends on system).
849     fn write_be_int(&mut self, n: int) -> IoResult<()> {
850         extensions::u64_to_be_bytes(n as u64, int::BYTES, |v| self.write(v))
851     }
852
853     /// Write a big-endian u64 (8 bytes).
854     fn write_be_u64(&mut self, n: u64) -> IoResult<()> {
855         extensions::u64_to_be_bytes(n, 8u, |v| self.write(v))
856     }
857
858     /// Write a big-endian u32 (4 bytes).
859     fn write_be_u32(&mut self, n: u32) -> IoResult<()> {
860         extensions::u64_to_be_bytes(n as u64, 4u, |v| self.write(v))
861     }
862
863     /// Write a big-endian u16 (2 bytes).
864     fn write_be_u16(&mut self, n: u16) -> IoResult<()> {
865         extensions::u64_to_be_bytes(n as u64, 2u, |v| self.write(v))
866     }
867
868     /// Write a big-endian i64 (8 bytes).
869     fn write_be_i64(&mut self, n: i64) -> IoResult<()> {
870         extensions::u64_to_be_bytes(n as u64, 8u, |v| self.write(v))
871     }
872
873     /// Write a big-endian i32 (4 bytes).
874     fn write_be_i32(&mut self, n: i32) -> IoResult<()> {
875         extensions::u64_to_be_bytes(n as u64, 4u, |v| self.write(v))
876     }
877
878     /// Write a big-endian i16 (2 bytes).
879     fn write_be_i16(&mut self, n: i16) -> IoResult<()> {
880         extensions::u64_to_be_bytes(n as u64, 2u, |v| self.write(v))
881     }
882
883     /// Write a big-endian IEEE754 double-precision floating-point (8 bytes).
884     fn write_be_f64(&mut self, f: f64) -> IoResult<()> {
885         unsafe {
886             self.write_be_u64(cast::transmute(f))
887         }
888     }
889
890     /// Write a big-endian IEEE754 single-precision floating-point (4 bytes).
891     fn write_be_f32(&mut self, f: f32) -> IoResult<()> {
892         unsafe {
893             self.write_be_u32(cast::transmute(f))
894         }
895     }
896
897     /// Write a little-endian u64 (8 bytes).
898     fn write_le_u64(&mut self, n: u64) -> IoResult<()> {
899         extensions::u64_to_le_bytes(n, 8u, |v| self.write(v))
900     }
901
902     /// Write a little-endian u32 (4 bytes).
903     fn write_le_u32(&mut self, n: u32) -> IoResult<()> {
904         extensions::u64_to_le_bytes(n as u64, 4u, |v| self.write(v))
905     }
906
907     /// Write a little-endian u16 (2 bytes).
908     fn write_le_u16(&mut self, n: u16) -> IoResult<()> {
909         extensions::u64_to_le_bytes(n as u64, 2u, |v| self.write(v))
910     }
911
912     /// Write a little-endian i64 (8 bytes).
913     fn write_le_i64(&mut self, n: i64) -> IoResult<()> {
914         extensions::u64_to_le_bytes(n as u64, 8u, |v| self.write(v))
915     }
916
917     /// Write a little-endian i32 (4 bytes).
918     fn write_le_i32(&mut self, n: i32) -> IoResult<()> {
919         extensions::u64_to_le_bytes(n as u64, 4u, |v| self.write(v))
920     }
921
922     /// Write a little-endian i16 (2 bytes).
923     fn write_le_i16(&mut self, n: i16) -> IoResult<()> {
924         extensions::u64_to_le_bytes(n as u64, 2u, |v| self.write(v))
925     }
926
927     /// Write a little-endian IEEE754 double-precision floating-point
928     /// (8 bytes).
929     fn write_le_f64(&mut self, f: f64) -> IoResult<()> {
930         unsafe {
931             self.write_le_u64(cast::transmute(f))
932         }
933     }
934
935     /// Write a little-endian IEEE754 single-precision floating-point
936     /// (4 bytes).
937     fn write_le_f32(&mut self, f: f32) -> IoResult<()> {
938         unsafe {
939             self.write_le_u32(cast::transmute(f))
940         }
941     }
942
943     /// Write a u8 (1 byte).
944     fn write_u8(&mut self, n: u8) -> IoResult<()> {
945         self.write([n])
946     }
947
948     /// Write a i8 (1 byte).
949     fn write_i8(&mut self, n: i8) -> IoResult<()> {
950         self.write([n as u8])
951     }
952
953     /// Creates a wrapper around a mutable reference to the writer.
954     ///
955     /// This is useful to allow applying wrappers while still
956     /// retaining ownership of the original value.
957     fn by_ref<'a>(&'a mut self) -> RefWriter<'a, Self> {
958         RefWriter { inner: self }
959     }
960 }
961
962 impl Writer for ~Writer {
963     fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.write(buf) }
964     fn flush(&mut self) -> IoResult<()> { self.flush() }
965 }
966
967 impl<'a> Writer for &'a mut Writer {
968     fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.write(buf) }
969     fn flush(&mut self) -> IoResult<()> { self.flush() }
970 }
971
972 /// A `RefWriter` is a struct implementing `Writer` which contains a reference
973 /// to another writer. This is often useful when composing streams.
974 ///
975 /// # Example
976 ///
977 /// ```
978 /// # fn main() {}
979 /// # fn process_input<R: Reader>(r: R) {}
980 /// # fn foo () {
981 /// use std::io::util::TeeReader;
982 /// use std::io::{stdin, MemWriter};
983 ///
984 /// let mut output = MemWriter::new();
985 ///
986 /// {
987 ///     // Don't give ownership of 'output' to the 'tee'. Instead we keep a
988 ///     // handle to it in the outer scope
989 ///     let mut tee = TeeReader::new(stdin(), output.by_ref());
990 ///     process_input(tee);
991 /// }
992 ///
993 /// println!("input processed: {}", output.unwrap());
994 /// # }
995 /// ```
996 pub struct RefWriter<'a, W> {
997     /// The underlying writer which this is referencing
998     inner: &'a mut W
999 }
1000
1001 impl<'a, W: Writer> Writer for RefWriter<'a, W> {
1002     fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.inner.write(buf) }
1003     fn flush(&mut self) -> IoResult<()> { self.inner.flush() }
1004 }
1005
1006
1007 /// A Stream is a readable and a writable object. Data written is typically
1008 /// received by the object which reads receive data from.
1009 pub trait Stream: Reader + Writer { }
1010
1011 impl<T: Reader + Writer> Stream for T {}
1012
1013 /// An iterator that reads a line on each iteration,
1014 /// until `.read_line()` encounters `EndOfFile`.
1015 ///
1016 /// # Notes about the Iteration Protocol
1017 ///
1018 /// The `Lines` may yield `None` and thus terminate
1019 /// an iteration, but continue to yield elements if iteration
1020 /// is attempted again.
1021 ///
1022 /// # Error
1023 ///
1024 /// Any error other than `EndOfFile` that is produced by the underlying Reader
1025 /// is returned by the iterator and should be handled by the caller.
1026 pub struct Lines<'r, T> {
1027     priv buffer: &'r mut T,
1028 }
1029
1030 impl<'r, T: Buffer> Iterator<IoResult<~str>> for Lines<'r, T> {
1031     fn next(&mut self) -> Option<IoResult<~str>> {
1032         match self.buffer.read_line() {
1033             Ok(x) => Some(Ok(x)),
1034             Err(IoError { kind: EndOfFile, ..}) => None,
1035             Err(y) => Some(Err(y))
1036         }
1037     }
1038 }
1039
1040 /// An iterator that reads a utf8-encoded character on each iteration,
1041 /// until `.read_char()` encounters `EndOfFile`.
1042 ///
1043 /// # Notes about the Iteration Protocol
1044 ///
1045 /// The `Chars` may yield `None` and thus terminate
1046 /// an iteration, but continue to yield elements if iteration
1047 /// is attempted again.
1048 ///
1049 /// # Error
1050 ///
1051 /// Any error other than `EndOfFile` that is produced by the underlying Reader
1052 /// is returned by the iterator and should be handled by the caller.
1053 pub struct Chars<'r, T> {
1054     priv buffer: &'r mut T
1055 }
1056
1057 impl<'r, T: Buffer> Iterator<IoResult<char>> for Chars<'r, T> {
1058     fn next(&mut self) -> Option<IoResult<char>> {
1059         match self.buffer.read_char() {
1060             Ok(x) => Some(Ok(x)),
1061             Err(IoError { kind: EndOfFile, ..}) => None,
1062             Err(y) => Some(Err(y))
1063         }
1064     }
1065 }
1066
1067 /// A Buffer is a type of reader which has some form of internal buffering to
1068 /// allow certain kinds of reading operations to be more optimized than others.
1069 /// This type extends the `Reader` trait with a few methods that are not
1070 /// possible to reasonably implement with purely a read interface.
1071 pub trait Buffer: Reader {
1072     /// Fills the internal buffer of this object, returning the buffer contents.
1073     /// Note that none of the contents will be "read" in the sense that later
1074     /// calling `read` may return the same contents.
1075     ///
1076     /// The `consume` function must be called with the number of bytes that are
1077     /// consumed from this buffer returned to ensure that the bytes are never
1078     /// returned twice.
1079     ///
1080     /// # Error
1081     ///
1082     /// This function will return an I/O error if the underlying reader was
1083     /// read, but returned an error. Note that it is not an error to return a
1084     /// 0-length buffer.
1085     fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]>;
1086
1087     /// Tells this buffer that `amt` bytes have been consumed from the buffer,
1088     /// so they should no longer be returned in calls to `fill` or `read`.
1089     fn consume(&mut self, amt: uint);
1090
1091     /// Reads the next line of input, interpreted as a sequence of UTF-8
1092     /// encoded unicode codepoints. If a newline is encountered, then the
1093     /// newline is contained in the returned string.
1094     ///
1095     /// # Example
1096     ///
1097     /// ```rust
1098     /// use std::io;
1099     ///
1100     /// let mut reader = io::stdin();
1101     /// let input = reader.read_line().ok().unwrap_or(~"nothing");
1102     /// ```
1103     ///
1104     /// # Error
1105     ///
1106     /// This function has the same error semantics as `read_until`:
1107     ///
1108     /// * All non-EOF errors will be returned immediately
1109     /// * If an error is returned previously consumed bytes are lost
1110     /// * EOF is only returned if no bytes have been read
1111     /// * Reach EOF may mean that the delimiter is not present in the return
1112     ///   value
1113     ///
1114     /// Additionally, this function can fail if the line of input read is not a
1115     /// valid UTF-8 sequence of bytes.
1116     fn read_line(&mut self) -> IoResult<~str> {
1117         self.read_until('\n' as u8).and_then(|line|
1118             match str::from_utf8_owned(line) {
1119                 Some(s) => Ok(s),
1120                 None => Err(standard_error(InvalidInput)),
1121             }
1122         )
1123     }
1124
1125     /// Create an iterator that reads a line on each iteration until EOF.
1126     ///
1127     /// # Error
1128     ///
1129     /// Any error other than `EndOfFile` that is produced by the underlying Reader
1130     /// is returned by the iterator and should be handled by the caller.
1131     fn lines<'r>(&'r mut self) -> Lines<'r, Self> {
1132         Lines { buffer: self }
1133     }
1134
1135     /// Reads a sequence of bytes leading up to a specified delimiter. Once the
1136     /// specified byte is encountered, reading ceases and the bytes up to and
1137     /// including the delimiter are returned.
1138     ///
1139     /// # Error
1140     ///
1141     /// If any I/O error is encountered other than EOF, the error is immediately
1142     /// returned. Note that this may discard bytes which have already been read,
1143     /// and those bytes will *not* be returned. It is recommended to use other
1144     /// methods if this case is worrying.
1145     ///
1146     /// If EOF is encountered, then this function will return EOF if 0 bytes
1147     /// have been read, otherwise the pending byte buffer is returned. This
1148     /// is the reason that the byte buffer returned may not always contain the
1149     /// delimiter.
1150     fn read_until(&mut self, byte: u8) -> IoResult<~[u8]> {
1151         let mut res = ~[];
1152
1153         let mut used;
1154         loop {
1155             {
1156                 let available = match self.fill_buf() {
1157                     Ok(n) => n,
1158                     Err(ref e) if res.len() > 0 && e.kind == EndOfFile => {
1159                         used = 0;
1160                         break
1161                     }
1162                     Err(e) => return Err(e)
1163                 };
1164                 match available.iter().position(|&b| b == byte) {
1165                     Some(i) => {
1166                         res.push_all(available.slice_to(i + 1));
1167                         used = i + 1;
1168                         break
1169                     }
1170                     None => {
1171                         res.push_all(available);
1172                         used = available.len();
1173                     }
1174                 }
1175             }
1176             self.consume(used);
1177         }
1178         self.consume(used);
1179         Ok(res)
1180     }
1181
1182     /// Reads the next utf8-encoded character from the underlying stream.
1183     ///
1184     /// # Error
1185     ///
1186     /// If an I/O error occurs, or EOF, then this function will return `Err`.
1187     /// This function will also return error if the stream does not contain a
1188     /// valid utf-8 encoded codepoint as the next few bytes in the stream.
1189     fn read_char(&mut self) -> IoResult<char> {
1190         let first_byte = try!(self.read_byte());
1191         let width = str::utf8_char_width(first_byte);
1192         if width == 1 { return Ok(first_byte as char) }
1193         if width == 0 { return Err(standard_error(InvalidInput)) } // not utf8
1194         let mut buf = [first_byte, 0, 0, 0];
1195         {
1196             let mut start = 1;
1197             while start < width {
1198                 match try!(self.read(buf.mut_slice(start, width))) {
1199                     n if n == width - start => break,
1200                     n if n < width - start => { start += n; }
1201                     _ => return Err(standard_error(InvalidInput)),
1202                 }
1203             }
1204         }
1205         match str::from_utf8(buf.slice_to(width)) {
1206             Some(s) => Ok(s.char_at(0)),
1207             None => Err(standard_error(InvalidInput))
1208         }
1209     }
1210
1211     /// Create an iterator that reads a utf8-encoded character on each iteration
1212     /// until EOF.
1213     ///
1214     /// # Error
1215     ///
1216     /// Any error other than `EndOfFile` that is produced by the underlying Reader
1217     /// is returned by the iterator and should be handled by the caller.
1218     fn chars<'r>(&'r mut self) -> Chars<'r, Self> {
1219         Chars { buffer: self }
1220     }
1221 }
1222
1223 /// When seeking, the resulting cursor is offset from a base by the offset given
1224 /// to the `seek` function. The base used is specified by this enumeration.
1225 pub enum SeekStyle {
1226     /// Seek from the beginning of the stream
1227     SeekSet,
1228     /// Seek from the end of the stream
1229     SeekEnd,
1230     /// Seek from the current position
1231     SeekCur,
1232 }
1233
1234 /// An object implementing `Seek` internally has some form of cursor which can
1235 /// be moved within a stream of bytes. The stream typically has a fixed size,
1236 /// allowing seeking relative to either end.
1237 pub trait Seek {
1238     /// Return position of file cursor in the stream
1239     fn tell(&self) -> IoResult<u64>;
1240
1241     /// Seek to an offset in a stream
1242     ///
1243     /// A successful seek clears the EOF indicator. Seeking beyond EOF is
1244     /// allowed, but seeking before position 0 is not allowed.
1245     ///
1246     /// # Errors
1247     ///
1248     /// * Seeking to a negative offset is considered an error
1249     /// * Seeking past the end of the stream does not modify the underlying
1250     ///   stream, but the next write may cause the previous data to be filled in
1251     ///   with a bit pattern.
1252     fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()>;
1253 }
1254
1255 /// A listener is a value that can consume itself to start listening for
1256 /// connections.
1257 ///
1258 /// Doing so produces some sort of Acceptor.
1259 pub trait Listener<T, A: Acceptor<T>> {
1260     /// Spin up the listener and start queuing incoming connections
1261     ///
1262     /// # Error
1263     ///
1264     /// Returns `Err` if this listener could not be bound to listen for
1265     /// connections. In all cases, this listener is consumed.
1266     fn listen(self) -> IoResult<A>;
1267 }
1268
1269 /// An acceptor is a value that presents incoming connections
1270 pub trait Acceptor<T> {
1271     /// Wait for and accept an incoming connection
1272     ///
1273     /// # Error
1274     ///
1275     /// Returns `Err` if an I/O error is encountered.
1276     fn accept(&mut self) -> IoResult<T>;
1277
1278     /// Create an iterator over incoming connection attempts.
1279     ///
1280     /// Note that I/O errors will be yielded by the iterator itself.
1281     fn incoming<'r>(&'r mut self) -> IncomingConnections<'r, Self> {
1282         IncomingConnections { inc: self }
1283     }
1284 }
1285
1286 /// An infinite iterator over incoming connection attempts.
1287 /// Calling `next` will block the task until a connection is attempted.
1288 ///
1289 /// Since connection attempts can continue forever, this iterator always returns
1290 /// `Some`. The `Some` contains the `IoResult` representing whether the
1291 /// connection attempt was successful.  A successful connection will be wrapped
1292 /// in `Ok`. A failed connection is represented as an `Err`.
1293 pub struct IncomingConnections<'a, A> {
1294     priv inc: &'a mut A,
1295 }
1296
1297 impl<'a, T, A: Acceptor<T>> Iterator<IoResult<T>> for IncomingConnections<'a, A> {
1298     fn next(&mut self) -> Option<IoResult<T>> {
1299         Some(self.inc.accept())
1300     }
1301 }
1302
1303 /// Creates a standard error for a commonly used flavor of error. The `detail`
1304 /// field of the returned error will always be `None`.
1305 ///
1306 /// # Example
1307 ///
1308 /// ```
1309 /// use std::io;
1310 ///
1311 /// let eof = io::standard_error(io::EndOfFile);
1312 /// let einval = io::standard_error(io::InvalidInput);
1313 /// ```
1314 pub fn standard_error(kind: IoErrorKind) -> IoError {
1315     let desc = match kind {
1316         EndOfFile => "end of file",
1317         IoUnavailable => "I/O is unavailable",
1318         InvalidInput => "invalid input",
1319         _ => fail!()
1320     };
1321     IoError {
1322         kind: kind,
1323         desc: desc,
1324         detail: None,
1325     }
1326 }
1327
1328 /// A mode specifies how a file should be opened or created. These modes are
1329 /// passed to `File::open_mode` and are used to control where the file is
1330 /// positioned when it is initially opened.
1331 pub enum FileMode {
1332     /// Opens a file positioned at the beginning.
1333     Open,
1334     /// Opens a file positioned at EOF.
1335     Append,
1336     /// Opens a file, truncating it if it already exists.
1337     Truncate,
1338 }
1339
1340 /// Access permissions with which the file should be opened. `File`s
1341 /// opened with `Read` will return an error if written to.
1342 pub enum FileAccess {
1343     /// Read-only access, requests to write will result in an error
1344     Read,
1345     /// Write-only access, requests to read will result in an error
1346     Write,
1347     /// Read-write access, no requests are denied by default
1348     ReadWrite,
1349 }
1350
1351 /// Different kinds of files which can be identified by a call to stat
1352 #[deriving(Eq, Show, Hash)]
1353 pub enum FileType {
1354     /// This is a normal file, corresponding to `S_IFREG`
1355     TypeFile,
1356
1357     /// This file is a directory, corresponding to `S_IFDIR`
1358     TypeDirectory,
1359
1360     /// This file is a named pipe, corresponding to `S_IFIFO`
1361     TypeNamedPipe,
1362
1363     /// This file is a block device, corresponding to `S_IFBLK`
1364     TypeBlockSpecial,
1365
1366     /// This file is a symbolic link to another file, corresponding to `S_IFLNK`
1367     TypeSymlink,
1368
1369     /// The type of this file is not recognized as one of the other categories
1370     TypeUnknown,
1371 }
1372
1373 /// A structure used to describe metadata information about a file. This
1374 /// structure is created through the `stat` method on a `Path`.
1375 ///
1376 /// # Example
1377 ///
1378 /// ```
1379 /// # fn main() {}
1380 /// # fn foo() {
1381 /// let info = match Path::new("foo.txt").stat() {
1382 ///     Ok(stat) => stat,
1383 ///     Err(e) => fail!("couldn't read foo.txt: {}", e),
1384 /// };
1385 ///
1386 /// println!("path: {}", info.path.display());
1387 /// println!("byte size: {}", info.size);
1388 /// # }
1389 /// ```
1390 #[deriving(Hash)]
1391 pub struct FileStat {
1392     /// The path that this stat structure is describing
1393     path: Path,
1394     /// The size of the file, in bytes
1395     size: u64,
1396     /// The kind of file this path points to (directory, file, pipe, etc.)
1397     kind: FileType,
1398     /// The file permissions currently on the file
1399     perm: FilePermission,
1400
1401     // FIXME(#10301): These time fields are pretty useless without an actual
1402     //                time representation, what are the milliseconds relative
1403     //                to?
1404
1405     /// The time that the file was created at, in platform-dependent
1406     /// milliseconds
1407     created: u64,
1408     /// The time that this file was last modified, in platform-dependent
1409     /// milliseconds
1410     modified: u64,
1411     /// The time that this file was last accessed, in platform-dependent
1412     /// milliseconds
1413     accessed: u64,
1414
1415     /// Information returned by stat() which is not guaranteed to be
1416     /// platform-independent. This information may be useful on some platforms,
1417     /// but it may have different meanings or no meaning at all on other
1418     /// platforms.
1419     ///
1420     /// Usage of this field is discouraged, but if access is desired then the
1421     /// fields are located here.
1422     #[unstable]
1423     unstable: UnstableFileStat,
1424 }
1425
1426 /// This structure represents all of the possible information which can be
1427 /// returned from a `stat` syscall which is not contained in the `FileStat`
1428 /// structure. This information is not necessarily platform independent, and may
1429 /// have different meanings or no meaning at all on some platforms.
1430 #[unstable]
1431 #[allow(missing_doc)]
1432 #[deriving(Hash)]
1433 pub struct UnstableFileStat {
1434     /// The ID of the device containing the file.
1435     device: u64,
1436     /// The file serial number.
1437     inode: u64,
1438     /// The device ID.
1439     rdev: u64,
1440     /// The number of hard links to this file.
1441     nlink: u64,
1442     /// The user ID of the file.
1443     uid: u64,
1444     /// The group ID of the file.
1445     gid: u64,
1446     /// The optimal block size for I/O.
1447     blksize: u64,
1448     /// The blocks allocated for this file.
1449     blocks: u64,
1450     /// User-defined flags for the file.
1451     flags: u64,
1452     /// The file generation number.
1453     gen: u64,
1454 }
1455
1456 /// A set of permissions for a file or directory is represented by a set of
1457 /// flags which are or'd together.
1458 pub type FilePermission = u32;
1459
1460 // Each permission bit
1461 pub static UserRead: FilePermission     = 0x100;
1462 pub static UserWrite: FilePermission    = 0x080;
1463 pub static UserExecute: FilePermission  = 0x040;
1464 pub static GroupRead: FilePermission    = 0x020;
1465 pub static GroupWrite: FilePermission   = 0x010;
1466 pub static GroupExecute: FilePermission = 0x008;
1467 pub static OtherRead: FilePermission    = 0x004;
1468 pub static OtherWrite: FilePermission   = 0x002;
1469 pub static OtherExecute: FilePermission = 0x001;
1470
1471 // Common combinations of these bits
1472 pub static UserRWX: FilePermission  = UserRead | UserWrite | UserExecute;
1473 pub static GroupRWX: FilePermission = GroupRead | GroupWrite | GroupExecute;
1474 pub static OtherRWX: FilePermission = OtherRead | OtherWrite | OtherExecute;
1475
1476 /// A set of permissions for user owned files, this is equivalent to 0644 on
1477 /// unix-like systems.
1478 pub static UserFile: FilePermission = UserRead | UserWrite | GroupRead | OtherRead;
1479 /// A set of permissions for user owned directories, this is equivalent to 0755
1480 /// on unix-like systems.
1481 pub static UserDir: FilePermission = UserRWX | GroupRead | GroupExecute |
1482                                      OtherRead | OtherExecute;
1483 /// A set of permissions for user owned executables, this is equivalent to 0755
1484 /// on unix-like systems.
1485 pub static UserExec: FilePermission = UserDir;
1486
1487 /// A mask for all possible permission bits
1488 pub static AllPermissions: FilePermission = 0x1ff;