/rust/registry/src/index.crates.io-1949cf8c6b5b557f/same-file-1.0.6/src/unix.rs
Line | Count | Source |
1 | | use std::fs::{File, OpenOptions}; |
2 | | use std::hash::{Hash, Hasher}; |
3 | | use std::io; |
4 | | use std::os::unix::fs::MetadataExt; |
5 | | use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; |
6 | | use std::path::Path; |
7 | | |
8 | | #[derive(Debug)] |
9 | | pub struct Handle { |
10 | | file: Option<File>, |
11 | | // If is_std is true, then we don't drop the corresponding File since it |
12 | | // will close the handle. |
13 | | is_std: bool, |
14 | | dev: u64, |
15 | | ino: u64, |
16 | | } |
17 | | |
18 | | impl Drop for Handle { |
19 | 0 | fn drop(&mut self) { |
20 | 0 | if self.is_std { |
21 | 0 | // unwrap() will not panic. Since we were able to open an |
22 | 0 | // std stream successfully, then `file` is guaranteed to be Some() |
23 | 0 | self.file.take().unwrap().into_raw_fd(); |
24 | 0 | } |
25 | 0 | } |
26 | | } |
27 | | |
28 | | impl Eq for Handle {} |
29 | | |
30 | | impl PartialEq for Handle { |
31 | 0 | fn eq(&self, other: &Handle) -> bool { |
32 | 0 | (self.dev, self.ino) == (other.dev, other.ino) |
33 | 0 | } |
34 | | } |
35 | | |
36 | | impl AsRawFd for crate::Handle { |
37 | 0 | fn as_raw_fd(&self) -> RawFd { |
38 | | // unwrap() will not panic. Since we were able to open the |
39 | | // file successfully, then `file` is guaranteed to be Some() |
40 | 0 | self.0.file.as_ref().take().unwrap().as_raw_fd() |
41 | 0 | } |
42 | | } |
43 | | |
44 | | impl IntoRawFd for crate::Handle { |
45 | 0 | fn into_raw_fd(mut self) -> RawFd { |
46 | | // unwrap() will not panic. Since we were able to open the |
47 | | // file successfully, then `file` is guaranteed to be Some() |
48 | 0 | self.0.file.take().unwrap().into_raw_fd() |
49 | 0 | } |
50 | | } |
51 | | |
52 | | impl Hash for Handle { |
53 | 0 | fn hash<H: Hasher>(&self, state: &mut H) { |
54 | 0 | self.dev.hash(state); |
55 | 0 | self.ino.hash(state); |
56 | 0 | } |
57 | | } |
58 | | |
59 | | impl Handle { |
60 | 0 | pub fn from_path<P: AsRef<Path>>(p: P) -> io::Result<Handle> { |
61 | 0 | Handle::from_file(OpenOptions::new().read(true).open(p)?) |
62 | 0 | } Unexecuted instantiation: <same_file::unix::Handle>::from_path::<&std::path::PathBuf> Unexecuted instantiation: <same_file::unix::Handle>::from_path::<&&std::path::Path> Unexecuted instantiation: <same_file::unix::Handle>::from_path::<_> |
63 | | |
64 | 0 | pub fn from_file(file: File) -> io::Result<Handle> { |
65 | 0 | let md = file.metadata()?; |
66 | 0 | Ok(Handle { |
67 | 0 | file: Some(file), |
68 | 0 | is_std: false, |
69 | 0 | dev: md.dev(), |
70 | 0 | ino: md.ino(), |
71 | 0 | }) |
72 | 0 | } |
73 | | |
74 | 0 | pub fn from_std(file: File) -> io::Result<Handle> { |
75 | 0 | Handle::from_file(file).map(|mut h| { |
76 | 0 | h.is_std = true; |
77 | 0 | h |
78 | 0 | }) |
79 | 0 | } |
80 | | |
81 | 0 | pub fn stdin() -> io::Result<Handle> { |
82 | 0 | Handle::from_std(unsafe { File::from_raw_fd(0) }) |
83 | 0 | } |
84 | | |
85 | 0 | pub fn stdout() -> io::Result<Handle> { |
86 | 0 | Handle::from_std(unsafe { File::from_raw_fd(1) }) |
87 | 0 | } |
88 | | |
89 | 0 | pub fn stderr() -> io::Result<Handle> { |
90 | 0 | Handle::from_std(unsafe { File::from_raw_fd(2) }) |
91 | 0 | } |
92 | | |
93 | 0 | pub fn as_file(&self) -> &File { |
94 | | // unwrap() will not panic. Since we were able to open the |
95 | | // file successfully, then `file` is guaranteed to be Some() |
96 | 0 | self.file.as_ref().take().unwrap() |
97 | 0 | } |
98 | | |
99 | 0 | pub fn as_file_mut(&mut self) -> &mut File { |
100 | | // unwrap() will not panic. Since we were able to open the |
101 | | // file successfully, then `file` is guaranteed to be Some() |
102 | 0 | self.file.as_mut().take().unwrap() |
103 | 0 | } |
104 | | |
105 | 0 | pub fn dev(&self) -> u64 { |
106 | 0 | self.dev |
107 | 0 | } |
108 | | |
109 | 0 | pub fn ino(&self) -> u64 { |
110 | 0 | self.ino |
111 | 0 | } |
112 | | } |