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