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