diff --git a/Cargo.lock b/Cargo.lock index 47297a5f..c821c4f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,7 +21,7 @@ name = "atty" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -58,7 +58,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "iso8601 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "locale 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", "pad 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -88,7 +88,7 @@ dependencies = [ "git2 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "locale 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "natord 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -108,7 +108,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "libgit2-sys 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.9.47 (registry+https://github.com/rust-lang/crates.io-index)", @@ -162,7 +162,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.51" +version = "0.2.62" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -171,7 +171,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -182,7 +182,7 @@ version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -192,7 +192,7 @@ name = "locale" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -241,7 +241,7 @@ name = "num_cpus" version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -264,7 +264,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-src 111.3.0+1.1.1c (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -350,7 +350,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -367,7 +367,7 @@ name = "termion" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -421,7 +421,7 @@ name = "users" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -507,7 +507,7 @@ dependencies = [ "checksum iso8601 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "11dc464f8c6f17595d191447c9c6559298b2d023d6f846a4a23ac7ea3c46c477" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" -"checksum libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "bedcc7a809076656486ffe045abeeac163da1b558e963a31e29fbfbeba916917" +"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba" "checksum libgit2-sys 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "941a41e23f77323b8c9d2ee118aec9ee39dfc176078c18b4757d3bad049d9ff7" "checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe" "checksum locale 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5fdbe492a9c0238da900a1165c42fc5067161ce292678a6fe80921f30fe307fd" diff --git a/Cargo.toml b/Cargo.toml index e685aebc..6663a18a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,7 +32,7 @@ datetime = "0.4.7" env_logger = "0.6.1" glob = "0.3.0" lazy_static = "1.3.0" -libc = "0.2.51" +libc = "^0.2.57" locale = "0.2.2" log = "0.4.6" natord = "1.0.9" diff --git a/src/fs/file.rs b/src/fs/file.rs index 3a63aaeb..5d866739 100644 --- a/src/fs/file.rs +++ b/src/fs/file.rs @@ -3,6 +3,7 @@ use std::fs::{self, metadata}; use std::io::Error as IOError; use std::io::Result as IOResult; +use std::os::unix::ffi::OsStrExt; use std::os::unix::fs::{MetadataExt, PermissionsExt, FileTypeExt}; use std::path::{Path, PathBuf}; use std::time::{UNIX_EPOCH, Duration}; @@ -11,6 +12,9 @@ use fs::dir::Dir; use fs::fields as f; use options::Misfire; +extern crate libc; +use libc::{syscall, SYS_statx, statx, STATX_BTIME}; + /// A **File** is a wrapper around one of Rust's Path objects, along with /// associated data about the file. @@ -343,7 +347,16 @@ impl<'dir> File<'dir> { /// This file’s created timestamp. pub fn created_time(&self) -> Duration { - self.metadata.created().unwrap().duration_since(UNIX_EPOCH).unwrap() + if cfg!(target_os = "linux") { + let statx_data = statx_creation_time(&self.path).unwrap(); + if statx_data.stx_btime.tv_sec < 0 { + Duration::from_secs(0) + } else { + Duration::new(statx_data.stx_btime.tv_sec as u64, statx_data.stx_btime.tv_nsec) + } + } else { + self.metadata.created().unwrap().duration_since(UNIX_EPOCH).unwrap() + } } /// This file’s ‘type’. @@ -474,11 +487,19 @@ impl PlatformMetadata { // Call the functions that return a Result to see if it works PlatformMetadata::AccessedTime => metadata(temp_dir()).unwrap().accessed(), PlatformMetadata::ModifiedTime => metadata(temp_dir()).unwrap().modified(), - PlatformMetadata::CreatedTime => metadata(temp_dir()).unwrap().created(), + PlatformMetadata::CreatedTime if cfg!(target_os = "linux") => { + if statx_creation_time(&temp_dir()).is_some() { + return Ok(()); + } + return Err(Misfire::Unsupported( + "creation time is not available on this platform currently \ + (needs Linux >= 4.11)".to_string())); + }, + PlatformMetadata::CreatedTime => metadata(temp_dir()).unwrap().created(), // We use the Unix API so we know it’s not available elsewhere PlatformMetadata::ChangedTime => { if cfg!(target_family = "unix") { - return Ok(()) + return Ok(()); } else { return Err(Misfire::Unsupported( // for consistency, this error message similar to the one Rust @@ -494,6 +515,21 @@ impl PlatformMetadata { } } +fn statx_creation_time(path: &PathBuf) -> Option { + let mut statx_data: statx = unsafe { std::mem::MaybeUninit::uninit().assume_init() }; + let path_name = std::ffi::CString::new(path + .canonicalize() + .unwrap() + .as_os_str() + .as_bytes()).unwrap(); + let result = unsafe { syscall(SYS_statx, 0, path_name.as_ptr(), 0, STATX_BTIME, &mut statx_data) }; + if result == 0 { + Some(statx_data) + } else { + None + } +} + /// More readable aliases for the permission bits exposed by libc. #[allow(trivial_numeric_casts)] diff --git a/src/options/view.rs b/src/options/view.rs index 23e9a444..4e1d8849 100644 --- a/src/options/view.rs +++ b/src/options/view.rs @@ -544,8 +544,6 @@ mod test { // Created #[cfg(not(target_os = "linux"))] test!(cr: TimeTypes <- ["--created"]; Both => Ok(TimeTypes { modified: false, changed: false, accessed: false, created: true })); - #[cfg(target_os = "linux")] - test!(cr: TimeTypes <- ["--created"]; Both => err Misfire::Unsupported("creation time is not available on this platform currently".to_string())); #[cfg(not(target_os = "linux"))] test!(c: TimeTypes <- ["-U"]; Both => Ok(TimeTypes { modified: false, changed: false, accessed: false, created: true })); #[cfg(not(target_os = "linux"))]