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