@@ -348,6 +348,8 @@ pub struct FilePermissions {
348348pub struct FileTimes {
349349 accessed : Option < SystemTime > ,
350350 modified : Option < SystemTime > ,
351+ #[ cfg( any( target_os = "macos" , target_os = "ios" , target_os = "watchos" ) ) ]
352+ created : Option < SystemTime > ,
351353}
352354
353355#[ derive( Copy , Clone , Eq , Debug ) ]
@@ -579,6 +581,11 @@ impl FileTimes {
579581 pub fn set_modified ( & mut self , t : SystemTime ) {
580582 self . modified = Some ( t) ;
581583 }
584+
585+ #[ cfg( any( target_os = "macos" , target_os = "ios" , target_os = "watchos" ) ) ]
586+ pub fn set_created ( & mut self , t : SystemTime ) {
587+ self . created = Some ( t) ;
588+ }
582589}
583590
584591impl FileType {
@@ -1192,8 +1199,6 @@ impl File {
11921199 None => Ok ( libc:: timespec { tv_sec : 0 , tv_nsec : libc:: UTIME_OMIT as _ } ) ,
11931200 }
11941201 } ;
1195- #[ cfg( not( any( target_os = "redox" , target_os = "espidf" , target_os = "horizon" ) ) ) ]
1196- let times = [ to_timespec ( times. accessed ) ?, to_timespec ( times. modified ) ?] ;
11971202 cfg_if:: cfg_if! {
11981203 if #[ cfg( any( target_os = "redox" , target_os = "espidf" , target_os = "horizon" ) ) ] {
11991204 // Redox doesn't appear to support `UTIME_OMIT`.
@@ -1204,25 +1209,41 @@ impl File {
12041209 io:: ErrorKind :: Unsupported ,
12051210 "setting file times not supported" ,
12061211 ) )
1207- } else if #[ cfg( any( target_os = "android" , target_os = "macos" ) ) ] {
1208- // futimens requires macOS 10.13, and Android API level 19
1212+ } else if #[ cfg( any( target_os = "macos" , target_os = "ios" , target_os = "watchos" ) ) ] {
1213+ let mut buf = [ mem:: MaybeUninit :: <libc:: timespec>:: uninit( ) ; 3 ] ;
1214+ let mut num_times = 0 ;
1215+ let mut attrlist: libc:: attrlist = unsafe { mem:: zeroed( ) } ;
1216+ attrlist. bitmapcount = libc:: ATTR_BIT_MAP_COUNT ;
1217+ if times. created. is_some( ) {
1218+ buf[ num_times] . write( to_timespec( times. created) ?) ;
1219+ num_times += 1 ;
1220+ attrlist. commonattr |= libc:: ATTR_CMN_CRTIME ;
1221+ }
1222+ if times. modified. is_some( ) {
1223+ buf[ num_times] . write( to_timespec( times. modified) ?) ;
1224+ num_times += 1 ;
1225+ attrlist. commonattr |= libc:: ATTR_CMN_MODTIME ;
1226+ }
1227+ if times. accessed. is_some( ) {
1228+ buf[ num_times] . write( to_timespec( times. accessed) ?) ;
1229+ num_times += 1 ;
1230+ attrlist. commonattr |= libc:: ATTR_CMN_ACCTIME ;
1231+ }
1232+ cvt( unsafe { libc:: fsetattrlist(
1233+ self . as_raw_fd( ) ,
1234+ ( & attrlist as * const libc:: attrlist) . cast:: <libc:: c_void>( ) . cast_mut( ) ,
1235+ buf. as_ptr( ) . cast:: <libc:: c_void>( ) . cast_mut( ) ,
1236+ num_times * mem:: size_of:: <libc:: timespec>( ) ,
1237+ 0
1238+ ) } ) ?;
1239+ Ok ( ( ) )
1240+ } else if #[ cfg( target_os = "android" ) ] {
1241+ let times = [ to_timespec( times. accessed) ?, to_timespec( times. modified) ?] ;
1242+ // futimens requires Android API level 19
12091243 cvt( unsafe {
12101244 weak!( fn futimens( c_int, * const libc:: timespec) -> c_int) ;
12111245 match futimens. get( ) {
12121246 Some ( futimens) => futimens( self . as_raw_fd( ) , times. as_ptr( ) ) ,
1213- #[ cfg( target_os = "macos" ) ]
1214- None => {
1215- fn ts_to_tv( ts: & libc:: timespec) -> libc:: timeval {
1216- libc:: timeval {
1217- tv_sec: ts. tv_sec,
1218- tv_usec: ( ts. tv_nsec / 1000 ) as _
1219- }
1220- }
1221- let timevals = [ ts_to_tv( & times[ 0 ] ) , ts_to_tv( & times[ 1 ] ) ] ;
1222- libc:: futimes( self . as_raw_fd( ) , timevals. as_ptr( ) )
1223- }
1224- // futimes requires even newer Android.
1225- #[ cfg( target_os = "android" ) ]
12261247 None => return Err ( io:: const_io_error!(
12271248 io:: ErrorKind :: Unsupported ,
12281249 "setting file times requires Android API level >= 19" ,
@@ -1231,6 +1252,7 @@ impl File {
12311252 } ) ?;
12321253 Ok ( ( ) )
12331254 } else {
1255+ let times = [ to_timespec( times. accessed) ?, to_timespec( times. modified) ?] ;
12341256 cvt( unsafe { libc:: futimens( self . as_raw_fd( ) , times. as_ptr( ) ) } ) ?;
12351257 Ok ( ( ) )
12361258 }
0 commit comments