@@ -802,8 +802,8 @@ pub(crate) fn utimensat(
802802 flags : AtFlags ,
803803) -> io:: Result < ( ) > {
804804 // Old 32-bit version: libc has `utimensat` but it is not y2038 safe by
805- // default. But there may be a `__utimensat16 ` we can use.
806- #[ cfg( fix_y2038) ]
805+ // default. But there may be a `__utimensat64 ` we can use.
806+ #[ cfg( all ( fix_y2038, not ( apple ) ) ) ]
807807 {
808808 #[ cfg( target_env = "gnu" ) ]
809809 if let Some ( libc_utimensat) = __utimensat64. get ( ) {
@@ -874,6 +874,10 @@ pub(crate) fn utimensat(
874874 ) ) ;
875875 }
876876
877+ // Convert `times`. We only need this in the child, but do it before
878+ // calling `fork` because it might fail.
879+ let ( attrbuf_size, times, attrs) = times_to_attrlist ( times) ?;
880+
877881 // `setattrlistat` was introduced in 10.13 along with `utimensat`, so
878882 // if we don't have `utimensat`, we don't have `setattrlistat` either.
879883 // Emulate it using `fork`, and `fchdir` and [`setattrlist`].
@@ -896,8 +900,6 @@ pub(crate) fn utimensat(
896900 flags_arg |= FSOPT_NOFOLLOW ;
897901 }
898902
899- let ( attrbuf_size, times, attrs) = times_to_attrlist ( times) ;
900-
901903 if setattrlist (
902904 c_str ( path) ,
903905 & attrs,
@@ -954,7 +956,7 @@ pub(crate) fn utimensat(
954956 }
955957}
956958
957- #[ cfg( fix_y2038) ]
959+ #[ cfg( all ( fix_y2038, not ( apple ) ) ) ]
958960fn utimensat_old (
959961 dirfd : BorrowedFd < ' _ > ,
960962 path : & CStr ,
@@ -1505,7 +1507,7 @@ fn libc_statvfs_to_statvfs(from: c::statvfs) -> StatVfs {
15051507pub ( crate ) fn futimens ( fd : BorrowedFd < ' _ > , times : & Timestamps ) -> io:: Result < ( ) > {
15061508 // Old 32-bit version: libc has `futimens` but it is not y2038 safe by
15071509 // default. But there may be a `__futimens64` we can use.
1508- #[ cfg( fix_y2038) ]
1510+ #[ cfg( all ( fix_y2038, not ( apple ) ) ) ]
15091511 {
15101512 #[ cfg( target_env = "gnu" ) ]
15111513 if let Some ( libc_futimens) = __futimens64. get ( ) {
@@ -1556,7 +1558,7 @@ pub(crate) fn futimens(fd: BorrowedFd<'_>, times: &Timestamps) -> io::Result<()>
15561558 }
15571559
15581560 // Otherwise use `fsetattrlist`.
1559- let ( attrbuf_size, times, attrs) = times_to_attrlist ( times) ;
1561+ let ( attrbuf_size, times, attrs) = times_to_attrlist ( times) ? ;
15601562
15611563 ret ( fsetattrlist (
15621564 borrowed_fd ( fd) ,
@@ -1568,7 +1570,7 @@ pub(crate) fn futimens(fd: BorrowedFd<'_>, times: &Timestamps) -> io::Result<()>
15681570 }
15691571}
15701572
1571- #[ cfg( fix_y2038) ]
1573+ #[ cfg( all ( fix_y2038, not ( apple ) ) ) ]
15721574fn futimens_old ( fd : BorrowedFd < ' _ > , times : & Timestamps ) -> io:: Result < ( ) > {
15731575 let old_times = [
15741576 c:: timespec {
@@ -2125,7 +2127,7 @@ pub(crate) fn fcntl_global_nocache(fd: BorrowedFd<'_>, value: bool) -> io::Resul
21252127/// Convert `times` from a `futimens`/`utimensat` argument into `setattrlist`
21262128/// arguments.
21272129#[ cfg( apple) ]
2128- fn times_to_attrlist ( times : & Timestamps ) -> ( c:: size_t , [ c:: timespec ; 2 ] , Attrlist ) {
2130+ fn times_to_attrlist ( times : & Timestamps ) -> io :: Result < ( c:: size_t , [ c:: timespec ; 2 ] , Attrlist ) > {
21292131 // ABI details.
21302132 const ATTR_CMN_MODTIME : u32 = 0x0000_0400 ;
21312133 const ATTR_CMN_ACCTIME : u32 = 0x0000_1000 ;
@@ -2134,7 +2136,8 @@ fn times_to_attrlist(times: &Timestamps) -> (c::size_t, [c::timespec; 2], Attrli
21342136 let mut times = times. clone ( ) ;
21352137
21362138 // If we have any `UTIME_NOW` elements, replace them with the current time.
2137- if times. last_access . tv_nsec == c:: UTIME_NOW || times. last_modification . tv_nsec == c:: UTIME_NOW
2139+ if times. last_access . tv_nsec == c:: UTIME_NOW . into ( )
2140+ || times. last_modification . tv_nsec == c:: UTIME_NOW . into ( )
21382141 {
21392142 let now = {
21402143 let mut tv = c:: timeval {
@@ -2150,11 +2153,17 @@ fn times_to_attrlist(times: &Timestamps) -> (c::size_t, [c::timespec; 2], Attrli
21502153 tv_nsec : ( tv. tv_usec * 1000 ) as _ ,
21512154 }
21522155 } ;
2153- if times. last_access . tv_nsec == c:: UTIME_NOW {
2154- times. last_access = now;
2156+ if times. last_access . tv_nsec == c:: UTIME_NOW . into ( ) {
2157+ times. last_access = crate :: timespec:: Timespec {
2158+ tv_sec : now. tv_sec . into ( ) ,
2159+ tv_nsec : now. tv_nsec as _ ,
2160+ } ;
21552161 }
2156- if times. last_modification . tv_nsec == c:: UTIME_NOW {
2157- times. last_modification = now;
2162+ if times. last_modification . tv_nsec == c:: UTIME_NOW . into ( ) {
2163+ times. last_modification = crate :: timespec:: Timespec {
2164+ tv_sec : now. tv_sec . into ( ) ,
2165+ tv_nsec : now. tv_nsec as _ ,
2166+ } ;
21582167 }
21592168 }
21602169
@@ -2176,19 +2185,33 @@ fn times_to_attrlist(times: &Timestamps) -> (c::size_t, [c::timespec; 2], Attrli
21762185 tv_nsec : 0 ,
21772186 } ; 2 ] ;
21782187 let mut times_index = 0 ;
2179- if times. last_modification . tv_nsec != c:: UTIME_OMIT {
2188+ if times. last_modification . tv_nsec != c:: UTIME_OMIT . into ( ) {
21802189 attrs. commonattr |= ATTR_CMN_MODTIME ;
2181- return_times[ times_index] = times. last_modification ;
2190+ return_times[ times_index] = c:: timespec {
2191+ tv_sec : times
2192+ . last_modification
2193+ . tv_sec
2194+ . try_into ( )
2195+ . map_err ( |_| io:: Errno :: OVERFLOW ) ?,
2196+ tv_nsec : times. last_modification . tv_nsec as _ ,
2197+ } ;
21822198 times_index += 1 ;
21832199 times_size += size_of :: < c:: timespec > ( ) ;
21842200 }
2185- if times. last_access . tv_nsec != c:: UTIME_OMIT {
2201+ if times. last_access . tv_nsec != c:: UTIME_OMIT . into ( ) {
21862202 attrs. commonattr |= ATTR_CMN_ACCTIME ;
2187- return_times[ times_index] = times. last_access ;
2203+ return_times[ times_index] = c:: timespec {
2204+ tv_sec : times
2205+ . last_access
2206+ . tv_sec
2207+ . try_into ( )
2208+ . map_err ( |_| io:: Errno :: OVERFLOW ) ?,
2209+ tv_nsec : times. last_access . tv_nsec as _ ,
2210+ } ;
21882211 times_size += size_of :: < c:: timespec > ( ) ;
21892212 }
21902213
2191- ( times_size, return_times, attrs)
2214+ Ok ( ( times_size, return_times, attrs) )
21922215}
21932216
21942217/// Support type for `Attrlist`.
0 commit comments