summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md4
-rw-r--r--src/sys/stat.rs24
-rw-r--r--test/test_stat.rs14
3 files changed, 36 insertions, 6 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 326f5e31..4de6ade2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,8 +16,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
([#916](https://github.com/nix-rust/nix/pull/916))
- Added `kmod` module that allows loading and unloading kernel modules on Linux.
([#930](https://github.com/nix-rust/nix/pull/930))
-- Added `futimens` and `utimesat` wrappers.
- ([#944](https://github.com/nix-rust/nix/pull/944))
+- Added `futimens` and `utimesat` wrappers ([#944](https://github.com/nix-rust/nix/pull/944))
+ and a `utimes` wrapper ([#946](https://github.com/nix-rust/nix/pull/946)).
### Changed
- Increased required Rust version to 1.22.1/
diff --git a/src/sys/stat.rs b/src/sys/stat.rs
index 6ac4444e..b810c167 100644
--- a/src/sys/stat.rs
+++ b/src/sys/stat.rs
@@ -8,7 +8,7 @@ use libc::{self, mode_t};
use std::mem;
use std::os::raw;
use std::os::unix::io::RawFd;
-use sys::time::TimeSpec;
+use sys::time::{TimeSpec, TimeVal};
libc_bitflags!(
pub struct SFlag: mode_t {
@@ -190,6 +190,25 @@ pub fn fchmodat<P: ?Sized + NixPath>(
Errno::result(res).map(|_| ())
}
+/// Change the access and modification times of a file.
+///
+/// `utimes(path, times)` is identical to
+/// `utimensat(None, path, times, UtimensatFlags::FollowSymlink)`. The former
+/// is a deprecated API so prefer using the latter if the platforms you care
+/// about support it.
+///
+/// # References
+///
+/// [utimes(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/utimes.html).
+pub fn utimes<P: ?Sized + NixPath>(path: &P, atime: &TimeVal, mtime: &TimeVal) -> Result<()> {
+ let times: [libc::timeval; 2] = [*atime.as_ref(), *mtime.as_ref()];
+ let res = path.with_nix_path(|cstr| unsafe {
+ libc::utimes(cstr.as_ptr(), &times[0])
+ })?;
+
+ Errno::result(res).map(|_| ())
+}
+
/// Change the access and modification times of the file specified by a file descriptor.
///
/// # References
@@ -220,7 +239,8 @@ pub enum UtimensatFlags {
/// then the mode of the symbolic link is changed.
///
/// `utimensat(None, path, times, UtimensatFlags::FollowSymlink)` is identical to
-/// `libc::utimes(path, times)`. That's why `utimes` is unimplemented in the `nix` crate.
+/// `utimes(path, times)`. The latter is a deprecated API so prefer using the
+/// former if the platforms you care about support it.
///
/// # References
///
diff --git a/test/test_stat.rs b/test/test_stat.rs
index 49cc49fd..e72dffd3 100644
--- a/test/test_stat.rs
+++ b/test/test_stat.rs
@@ -6,9 +6,9 @@ use std::time::{Duration, UNIX_EPOCH};
use libc::{S_IFMT, S_IFLNK};
use nix::fcntl;
-use nix::sys::stat::{self, fchmod, fchmodat, fstat, futimens, lstat, stat, utimensat};
+use nix::sys::stat::{self, fchmod, fchmodat, fstat, futimens, lstat, stat, utimes, utimensat};
use nix::sys::stat::{FileStat, Mode, FchmodatFlags, UtimensatFlags};
-use nix::sys::time::{TimeSpec, TimeValLike};
+use nix::sys::time::{TimeSpec, TimeVal, TimeValLike};
use nix::unistd::chdir;
use nix::Result;
use tempfile;
@@ -169,6 +169,16 @@ fn assert_times_eq(exp_atime_sec: u64, exp_mtime_sec: u64, attr: &fs::Metadata)
}
#[test]
+fn test_utimes() {
+ let tempdir = tempfile::tempdir().unwrap();
+ let fullpath = tempdir.path().join("file");
+ drop(File::create(&fullpath).unwrap());
+
+ utimes(&fullpath, &TimeVal::seconds(9990), &TimeVal::seconds(5550));
+ assert_times_eq(9990, 5550, &fs::metadata(&fullpath).unwrap());
+}
+
+#[test]
fn test_futimens() {
let tempdir = tempfile::tempdir().unwrap();
let fullpath = tempdir.path().join("file");