Skip to content

Commit

Permalink
Properly handle set_file_{,handle_}times_now in unix/utimes.rs
Browse files Browse the repository at this point in the history
This is a POSIX-feature according to
https://pubs.opengroup.org/onlinepubs/9699919799/

By changing mod.rs, I verified that this works on Linux 4.9 and Linux 6.6.
  • Loading branch information
BenWiederhake committed Mar 25, 2024
1 parent dc341ef commit f3e0ec6
Showing 1 changed file with 31 additions and 8 deletions.
39 changes: 31 additions & 8 deletions src/unix/utimes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::fs;
use std::io;
use std::os::unix::prelude::*;
use std::path::Path;
use std::ptr;

#[allow(dead_code)]
pub fn set_file_times(p: &Path, atime: FileTime, mtime: FileTime) -> io::Result<()> {
Expand All @@ -12,13 +13,19 @@ pub fn set_file_times(p: &Path, atime: FileTime, mtime: FileTime) -> io::Result<

#[allow(dead_code)]
pub fn set_file_times_now(p: &Path, follow_symlink: bool) -> io::Result<()> {
let time = FileTime::now();
// TODO: Do the same trick as on Linux?
if follow_symlink {
set_file_times(p, time, time)
let p = CString::new(p.as_os_str().as_bytes())?;
let rc = unsafe {
if !follow_symlink {
libc::lutimes(p.as_ptr(), ptr::null::<libc::timeval>())
} else {
libc::utimes(p.as_ptr(), ptr::null::<libc::timeval>())
}
};
return if rc == 0 {
Ok(())
} else {
set_symlink_file_times(p, time, time)
}
Err(io::Error::last_os_error())
};
}

#[allow(dead_code)]
Expand Down Expand Up @@ -71,10 +78,26 @@ pub fn set_file_handle_times(
};
}

#[cfg(not(target_env = "uclibc"))]
#[allow(dead_code)]
pub fn set_file_handle_times_now(f: &fs::File) -> io::Result<()> {
let rc = unsafe { libc::futimes(f.as_raw_fd(), ptr::null::<libc::timeval>()) };
return if rc == 0 {
Ok(())
} else {
Err(io::Error::last_os_error())
};
}

#[cfg(target_env = "uclibc")]
#[allow(dead_code)]
pub fn set_file_handle_times_now(f: &fs::File) -> io::Result<()> {
let time = FileTime::now();
set_file_handle_times(f, Some(time), Some(time)) // TODO: Do the same trick as on Linux?
let rc = unsafe { libc::futimens(f.as_raw_fd(), ptr::null::<libc::timespec>()) };
return if rc == 0 {
Ok(())
} else {
Err(io::Error::last_os_error())
};
}

fn get_times(
Expand Down

0 comments on commit f3e0ec6

Please sign in to comment.