xref: /drstd/src/std/os/linux/fs.rs (revision b38c79420b3f9b2af3cf74b30d9faaadb20eb8b0)
1 //! Linux-specific extensions to primitives in the [`std::fs`] module.
2 //!
3 //! [`std::fs`]: crate::std::fs
4 
5 use crate::std::fs::Metadata;
6 use crate::std::sys_common::AsInner;
7 use dlibc;
8 
9 #[allow(deprecated)]
10 use crate::std::os::linux::raw;
11 
12 /// OS-specific extensions to [`fs::Metadata`].
13 ///
14 /// [`fs::Metadata`]: crate::std::fs::Metadata
15 pub trait MetadataExt {
16     /// Gain a reference to the underlying `stat` structure which contains
17     /// the raw information returned by the OS.
18     ///
19     /// The contents of the returned [`stat`] are **not** consistent across
20     /// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the
21     /// cross-Unix abstractions contained within the raw stat.
22     ///
23     /// [`stat`]: struct@crate::std::os::linux::raw::stat
24     ///
25     /// # Examples
26     ///
27     /// ```no_run
28     /// use std::fs;
29     /// use std::io;
30     /// use std::os::linux::fs::MetadataExt;
31     ///
32     /// fn main() -> io::Result<()> {
33     ///     let meta = fs::metadata("some_file")?;
34     ///     let stat = meta.as_raw_stat();
35     ///     Ok(())
36     /// }
37     /// ```
38     #[deprecated(
39         since = "1.8.0",
40         note = "other methods of this trait are now preferred"
41     )]
42     #[allow(deprecated)]
43     fn as_raw_stat(&self) -> &raw::stat;
44 
45     /// Returns the device ID on which this file resides.
46     ///
47     /// # Examples
48     ///
49     /// ```no_run
50     /// use std::fs;
51     /// use std::io;
52     /// use std::os::linux::fs::MetadataExt;
53     ///
54     /// fn main() -> io::Result<()> {
55     ///     let meta = fs::metadata("some_file")?;
56     ///     println!("{}", meta.st_dev());
57     ///     Ok(())
58     /// }
59     /// ```
60     fn st_dev(&self) -> u64;
61     /// Returns the inode number.
62     ///
63     /// # Examples
64     ///
65     /// ```no_run
66     /// use std::fs;
67     /// use std::io;
68     /// use std::os::linux::fs::MetadataExt;
69     ///
70     /// fn main() -> io::Result<()> {
71     ///     let meta = fs::metadata("some_file")?;
72     ///     println!("{}", meta.st_ino());
73     ///     Ok(())
74     /// }
75     /// ```
76     fn st_ino(&self) -> u64;
77     /// Returns the file type and mode.
78     ///
79     /// # Examples
80     ///
81     /// ```no_run
82     /// use std::fs;
83     /// use std::io;
84     /// use std::os::linux::fs::MetadataExt;
85     ///
86     /// fn main() -> io::Result<()> {
87     ///     let meta = fs::metadata("some_file")?;
88     ///     println!("{}", meta.st_mode());
89     ///     Ok(())
90     /// }
91     /// ```
92     fn st_mode(&self) -> u32;
93     /// Returns the number of hard links to file.
94     ///
95     /// # Examples
96     ///
97     /// ```no_run
98     /// use std::fs;
99     /// use std::io;
100     /// use std::os::linux::fs::MetadataExt;
101     ///
102     /// fn main() -> io::Result<()> {
103     ///     let meta = fs::metadata("some_file")?;
104     ///     println!("{}", meta.st_nlink());
105     ///     Ok(())
106     /// }
107     /// ```
108     fn st_nlink(&self) -> u64;
109     /// Returns the user ID of the file owner.
110     ///
111     /// # Examples
112     ///
113     /// ```no_run
114     /// use std::fs;
115     /// use std::io;
116     /// use std::os::linux::fs::MetadataExt;
117     ///
118     /// fn main() -> io::Result<()> {
119     ///     let meta = fs::metadata("some_file")?;
120     ///     println!("{}", meta.st_uid());
121     ///     Ok(())
122     /// }
123     /// ```
124     fn st_uid(&self) -> u32;
125     /// Returns the group ID of the file owner.
126     ///
127     /// # Examples
128     ///
129     /// ```no_run
130     /// use std::fs;
131     /// use std::io;
132     /// use std::os::linux::fs::MetadataExt;
133     ///
134     /// fn main() -> io::Result<()> {
135     ///     let meta = fs::metadata("some_file")?;
136     ///     println!("{}", meta.st_gid());
137     ///     Ok(())
138     /// }
139     /// ```
140     fn st_gid(&self) -> u32;
141     /// Returns the device ID that this file represents. Only relevant for special file.
142     ///
143     /// # Examples
144     ///
145     /// ```no_run
146     /// use std::fs;
147     /// use std::io;
148     /// use std::os::linux::fs::MetadataExt;
149     ///
150     /// fn main() -> io::Result<()> {
151     ///     let meta = fs::metadata("some_file")?;
152     ///     println!("{}", meta.st_rdev());
153     ///     Ok(())
154     /// }
155     /// ```
156     fn st_rdev(&self) -> u64;
157     /// Returns the size of the file (if it is a regular file or a symbolic link) in bytes.
158     ///
159     /// The size of a symbolic link is the length of the pathname it contains,
160     /// without a terminating null byte.
161     ///
162     /// # Examples
163     ///
164     /// ```no_run
165     /// use std::fs;
166     /// use std::io;
167     /// use std::os::linux::fs::MetadataExt;
168     ///
169     /// fn main() -> io::Result<()> {
170     ///     let meta = fs::metadata("some_file")?;
171     ///     println!("{}", meta.st_size());
172     ///     Ok(())
173     /// }
174     /// ```
175     fn st_size(&self) -> u64;
176     /// Returns the last access time of the file, in seconds since Unix Epoch.
177     ///
178     /// # Examples
179     ///
180     /// ```no_run
181     /// use std::fs;
182     /// use std::io;
183     /// use std::os::linux::fs::MetadataExt;
184     ///
185     /// fn main() -> io::Result<()> {
186     ///     let meta = fs::metadata("some_file")?;
187     ///     println!("{}", meta.st_atime());
188     ///     Ok(())
189     /// }
190     /// ```
191     fn st_atime(&self) -> i64;
192     /// Returns the last access time of the file, in nanoseconds since [`st_atime`].
193     ///
194     /// [`st_atime`]: Self::st_atime
195     ///
196     /// # Examples
197     ///
198     /// ```no_run
199     /// use std::fs;
200     /// use std::io;
201     /// use std::os::linux::fs::MetadataExt;
202     ///
203     /// fn main() -> io::Result<()> {
204     ///     let meta = fs::metadata("some_file")?;
205     ///     println!("{}", meta.st_atime_nsec());
206     ///     Ok(())
207     /// }
208     /// ```
209     fn st_atime_nsec(&self) -> i64;
210     /// Returns the last modification time of the file, in seconds since Unix Epoch.
211     ///
212     /// # Examples
213     ///
214     /// ```no_run
215     /// use std::fs;
216     /// use std::io;
217     /// use std::os::linux::fs::MetadataExt;
218     ///
219     /// fn main() -> io::Result<()> {
220     ///     let meta = fs::metadata("some_file")?;
221     ///     println!("{}", meta.st_mtime());
222     ///     Ok(())
223     /// }
224     /// ```
225     fn st_mtime(&self) -> i64;
226     /// Returns the last modification time of the file, in nanoseconds since [`st_mtime`].
227     ///
228     /// [`st_mtime`]: Self::st_mtime
229     ///
230     /// # Examples
231     ///
232     /// ```no_run
233     /// use std::fs;
234     /// use std::io;
235     /// use std::os::linux::fs::MetadataExt;
236     ///
237     /// fn main() -> io::Result<()> {
238     ///     let meta = fs::metadata("some_file")?;
239     ///     println!("{}", meta.st_mtime_nsec());
240     ///     Ok(())
241     /// }
242     /// ```
243     fn st_mtime_nsec(&self) -> i64;
244     /// Returns the last status change time of the file, in seconds since Unix Epoch.
245     ///
246     /// # Examples
247     ///
248     /// ```no_run
249     /// use std::fs;
250     /// use std::io;
251     /// use std::os::linux::fs::MetadataExt;
252     ///
253     /// fn main() -> io::Result<()> {
254     ///     let meta = fs::metadata("some_file")?;
255     ///     println!("{}", meta.st_ctime());
256     ///     Ok(())
257     /// }
258     /// ```
259     fn st_ctime(&self) -> i64;
260     /// Returns the last status change time of the file, in nanoseconds since [`st_ctime`].
261     ///
262     /// [`st_ctime`]: Self::st_ctime
263     ///
264     /// # Examples
265     ///
266     /// ```no_run
267     /// use std::fs;
268     /// use std::io;
269     /// use std::os::linux::fs::MetadataExt;
270     ///
271     /// fn main() -> io::Result<()> {
272     ///     let meta = fs::metadata("some_file")?;
273     ///     println!("{}", meta.st_ctime_nsec());
274     ///     Ok(())
275     /// }
276     /// ```
277     fn st_ctime_nsec(&self) -> i64;
278     /// Returns the "preferred" block size for efficient filesystem I/O.
279     ///
280     /// # Examples
281     ///
282     /// ```no_run
283     /// use std::fs;
284     /// use std::io;
285     /// use std::os::linux::fs::MetadataExt;
286     ///
287     /// fn main() -> io::Result<()> {
288     ///     let meta = fs::metadata("some_file")?;
289     ///     println!("{}", meta.st_blksize());
290     ///     Ok(())
291     /// }
292     /// ```
293     fn st_blksize(&self) -> u64;
294     /// Returns the number of blocks allocated to the file, 512-byte units.
295     ///
296     /// # Examples
297     ///
298     /// ```no_run
299     /// use std::fs;
300     /// use std::io;
301     /// use std::os::linux::fs::MetadataExt;
302     ///
303     /// fn main() -> io::Result<()> {
304     ///     let meta = fs::metadata("some_file")?;
305     ///     println!("{}", meta.st_blocks());
306     ///     Ok(())
307     /// }
308     /// ```
309     fn st_blocks(&self) -> u64;
310 }
311 
312 impl MetadataExt for Metadata {
313     #[allow(deprecated)]
314     fn as_raw_stat(&self) -> &raw::stat {
315         unsafe { &*(self.as_inner().as_inner() as *const dlibc::stat64 as *const raw::stat) }
316     }
317     fn st_dev(&self) -> u64 {
318         self.as_inner().as_inner().st_dev as u64
319     }
320     fn st_ino(&self) -> u64 {
321         self.as_inner().as_inner().st_ino as u64
322     }
323     fn st_mode(&self) -> u32 {
324         self.as_inner().as_inner().st_mode as u32
325     }
326     fn st_nlink(&self) -> u64 {
327         self.as_inner().as_inner().st_nlink as u64
328     }
329     fn st_uid(&self) -> u32 {
330         self.as_inner().as_inner().st_uid as u32
331     }
332     fn st_gid(&self) -> u32 {
333         self.as_inner().as_inner().st_gid as u32
334     }
335     fn st_rdev(&self) -> u64 {
336         self.as_inner().as_inner().st_rdev as u64
337     }
338     fn st_size(&self) -> u64 {
339         self.as_inner().as_inner().st_size as u64
340     }
341     fn st_atime(&self) -> i64 {
342         let file_attr = self.as_inner();
343         #[cfg(all(target_env = "gnu", target_pointer_width = "32"))]
344         if let Some(atime) = file_attr.stx_atime() {
345             return atime.tv_sec;
346         }
347         file_attr.as_inner().st_atime as i64
348     }
349     fn st_atime_nsec(&self) -> i64 {
350         self.as_inner().as_inner().st_atime_nsec as i64
351     }
352     fn st_mtime(&self) -> i64 {
353         let file_attr = self.as_inner();
354         #[cfg(all(target_env = "gnu", target_pointer_width = "32"))]
355         if let Some(mtime) = file_attr.stx_mtime() {
356             return mtime.tv_sec;
357         }
358         file_attr.as_inner().st_mtime as i64
359     }
360     fn st_mtime_nsec(&self) -> i64 {
361         self.as_inner().as_inner().st_mtime_nsec as i64
362     }
363     fn st_ctime(&self) -> i64 {
364         let file_attr = self.as_inner();
365         #[cfg(all(target_env = "gnu", target_pointer_width = "32"))]
366         if let Some(ctime) = file_attr.stx_ctime() {
367             return ctime.tv_sec;
368         }
369         file_attr.as_inner().st_ctime as i64
370     }
371     fn st_ctime_nsec(&self) -> i64 {
372         self.as_inner().as_inner().st_ctime_nsec as i64
373     }
374     fn st_blksize(&self) -> u64 {
375         self.as_inner().as_inner().st_blksize as u64
376     }
377     fn st_blocks(&self) -> u64 {
378         self.as_inner().as_inner().st_blocks as u64
379     }
380 }
381