diff --git a/src/header/sys_time/mod.rs b/src/header/sys_time/mod.rs index edb2fc92d2..de7d34b6ff 100644 --- a/src/header/sys_time/mod.rs +++ b/src/header/sys_time/mod.rs @@ -5,6 +5,7 @@ use crate::{ header::time::timespec, platform::{types::*, Pal, PalSignal, Sys}, }; +use core::ptr::null; pub const ITIMER_REAL: c_int = 0; pub const ITIMER_VIRTUAL: c_int = 1; @@ -57,15 +58,23 @@ pub extern "C" fn gettimeofday(tp: *mut timeval, tzp: *mut timezone) -> c_int { #[no_mangle] pub unsafe extern "C" fn utimes(path: *const c_char, times: *const timeval) -> c_int { let path = CStr::from_ptr(path); - let times_spec = [ - timespec { - tv_sec: (*times.offset(0)).tv_sec, - tv_nsec: ((*times.offset(0)).tv_usec as c_long) * 1000, - }, - timespec { - tv_sec: (*times.offset(1)).tv_sec, - tv_nsec: ((*times.offset(1)).tv_usec as c_long) * 1000, - }, - ]; - Sys::utimens(path, times_spec.as_ptr()) + // Nullptr is valid here, it means "use current time" + let times_spec = if times.is_null() { + null() + } else { + { + [ + timespec { + tv_sec: (*times.offset(0)).tv_sec, + tv_nsec: ((*times.offset(0)).tv_usec as c_long) * 1000, + }, + timespec { + tv_sec: (*times.offset(1)).tv_sec, + tv_nsec: ((*times.offset(1)).tv_usec as c_long) * 1000, + }, + ] + } + .as_ptr() + }; + Sys::utimens(path, times_spec) } diff --git a/src/platform/redox/libredox.rs b/src/platform/redox/libredox.rs index df67379f3f..09686e588c 100644 --- a/src/platform/redox/libredox.rs +++ b/src/platform/redox/libredox.rs @@ -3,7 +3,7 @@ use core::{slice, str}; use syscall::{Error, Result, WaitFlags, EMFILE}; use crate::{ - header::{signal::sigaction, time::timespec}, + header::{signal::sigaction, sys_stat::UTIME_NOW, time::timespec}, platform::types::*, }; @@ -77,10 +77,24 @@ pub unsafe fn fstatvfs( Ok(()) } pub unsafe fn futimens(fd: usize, times: *const timespec) -> syscall::Result<()> { - let times = times - .cast::<[timespec; 2]>() - .read() - .map(|ts| syscall::TimeSpec::from(&ts)); + let times = if times.is_null() { + // null means set to current time using special UTIME_NOW value (tv_sec is ignored in that case) + [ + syscall::TimeSpec { + tv_sec: 0, + tv_nsec: UTIME_NOW as c_int, + }, + syscall::TimeSpec { + tv_sec: 0, + tv_nsec: UTIME_NOW as c_int, + }, + ] + } else { + times + .cast::<[timespec; 2]>() + .read() + .map(|ts| syscall::TimeSpec::from(&ts)) + }; syscall::futimens(fd as usize, ×)?; Ok(()) }