]>
Commit | Line | Data |
---|---|---|
7cac9316 XL |
1 | use std::fs::{File, OpenOptions}; |
2 | use std::io; | |
3 | use std::os::unix::fs::MetadataExt; | |
4 | use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; | |
5 | use std::path::Path; | |
6 | ||
7 | #[derive(Debug)] | |
8 | pub struct Handle { | |
9 | file: Option<File>, | |
10 | // If is_std is true, then we don't drop the corresponding File since it | |
11 | // will close the handle. | |
12 | is_std: bool, | |
13 | dev: u64, | |
14 | ino: u64, | |
15 | } | |
16 | ||
17 | impl Drop for Handle { | |
18 | fn drop(&mut self) { | |
19 | if self.is_std { | |
20 | self.file.take().unwrap().into_raw_fd(); | |
21 | } | |
22 | } | |
23 | } | |
24 | ||
25 | impl Eq for Handle {} | |
26 | ||
27 | impl PartialEq for Handle { | |
28 | fn eq(&self, other: &Handle) -> bool { | |
29 | (self.dev, self.ino) == (other.dev, other.ino) | |
30 | } | |
31 | } | |
32 | ||
33 | impl AsRawFd for ::Handle { | |
34 | fn as_raw_fd(&self) -> RawFd { | |
35 | self.0.file.as_ref().take().unwrap().as_raw_fd() | |
36 | } | |
37 | } | |
38 | ||
39 | impl IntoRawFd for ::Handle { | |
40 | fn into_raw_fd(mut self) -> RawFd { | |
41 | self.0.file.take().unwrap().into_raw_fd() | |
42 | } | |
43 | } | |
44 | ||
45 | impl Handle { | |
46 | pub fn from_path<P: AsRef<Path>>(p: P) -> io::Result<Handle> { | |
47 | Handle::from_file(try!(OpenOptions::new().read(true).open(p))) | |
48 | } | |
49 | ||
50 | pub fn from_file(file: File) -> io::Result<Handle> { | |
51 | let md = try!(file.metadata()); | |
52 | Ok(Handle { | |
53 | file: Some(file), | |
54 | is_std: false, | |
55 | dev: md.dev(), | |
56 | ino: md.ino(), | |
57 | }) | |
58 | } | |
59 | ||
60 | pub fn from_std(file: File) -> io::Result<Handle> { | |
61 | Handle::from_file(file).map(|mut h| { | |
62 | h.is_std = true; | |
63 | h | |
64 | }) | |
65 | } | |
66 | ||
67 | pub fn stdin() -> io::Result<Handle> { | |
68 | Handle::from_std(unsafe { File::from_raw_fd(0) }) | |
69 | } | |
70 | ||
71 | pub fn stdout() -> io::Result<Handle> { | |
72 | Handle::from_std(unsafe { File::from_raw_fd(1) }) | |
73 | } | |
74 | ||
75 | pub fn stderr() -> io::Result<Handle> { | |
76 | Handle::from_std(unsafe { File::from_raw_fd(2) }) | |
77 | } | |
78 | ||
79 | pub fn as_file(&self) -> &File { | |
80 | self.file.as_ref().take().unwrap() | |
81 | } | |
82 | ||
83 | pub fn as_file_mut(&mut self) -> &mut File { | |
84 | self.file.as_mut().take().unwrap() | |
85 | } | |
86 | ||
87 | pub fn dev(&self) -> u64 { | |
88 | self.dev | |
89 | } | |
90 | ||
91 | pub fn ino(&self) -> u64 { | |
92 | self.ino | |
93 | } | |
94 | } |