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