Coverage Report

Created: 2025-12-28 06:31

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}