@@ -349,6 +349,8 @@ pub struct FilePermissions {
349349pub struct FileTimes {
350350 accessed : Option < SystemTime > ,
351351 modified : Option < SystemTime > ,
352+ #[ cfg( any( target_os = "macos" , target_os = "ios" , target_os = "watchos" ) ) ]
353+ created : Option < SystemTime > ,
352354}
353355
354356#[ derive( Copy , Clone , Eq , Debug ) ]
@@ -591,6 +593,11 @@ impl FileTimes {
591593 pub fn set_modified ( & mut self , t : SystemTime ) {
592594 self . modified = Some ( t) ;
593595 }
596+
597+ #[ cfg( any( target_os = "macos" , target_os = "ios" , target_os = "watchos" ) ) ]
598+ pub fn set_created ( & mut self , t : SystemTime ) {
599+ self . created = Some ( t) ;
600+ }
594601}
595602
596603impl FileType {
@@ -1215,26 +1222,41 @@ impl File {
12151222 io:: ErrorKind :: Unsupported ,
12161223 "setting file times not supported" ,
12171224 ) )
1218- } else if #[ cfg( any( target_os = "android" , target_os = "macos" ) ) ] {
1225+ } else if #[ cfg( any( target_os = "macos" , target_os = "ios" , target_os = "watchos" ) ) ] {
1226+ let mut buf = [ mem:: MaybeUninit :: <libc:: timespec>:: uninit( ) ; 3 ] ;
1227+ let mut num_times = 0 ;
1228+ let mut attrlist: libc:: attrlist = unsafe { mem:: zeroed( ) } ;
1229+ attrlist. bitmapcount = libc:: ATTR_BIT_MAP_COUNT ;
1230+ if times. created. is_some( ) {
1231+ buf[ num_times] . write( to_timespec( times. created) ?) ;
1232+ num_times += 1 ;
1233+ attrlist. commonattr |= libc:: ATTR_CMN_CRTIME ;
1234+ }
1235+ if times. modified. is_some( ) {
1236+ buf[ num_times] . write( to_timespec( times. modified) ?) ;
1237+ num_times += 1 ;
1238+ attrlist. commonattr |= libc:: ATTR_CMN_MODTIME ;
1239+ }
1240+ if times. accessed. is_some( ) {
1241+ buf[ num_times] . write( to_timespec( times. accessed) ?) ;
1242+ num_times += 1 ;
1243+ attrlist. commonattr |= libc:: ATTR_CMN_ACCTIME ;
1244+ }
1245+ cvt( unsafe { libc:: fsetattrlist(
1246+ self . as_raw_fd( ) ,
1247+ ( & attrlist as * const libc:: attrlist) . cast:: <libc:: c_void>( ) . cast_mut( ) ,
1248+ buf. as_ptr( ) . cast:: <libc:: c_void>( ) . cast_mut( ) ,
1249+ num_times * mem:: size_of:: <libc:: timespec>( ) ,
1250+ 0
1251+ ) } ) ?;
1252+ Ok ( ( ) )
1253+ } else if #[ cfg( target_os = "android" ) ] {
12191254 let times = [ to_timespec( times. accessed) ?, to_timespec( times. modified) ?] ;
1220- // futimens requires macOS 10.13, and Android API level 19
1255+ // futimens requires Android API level 19
12211256 cvt( unsafe {
12221257 weak!( fn futimens( c_int, * const libc:: timespec) -> c_int) ;
12231258 match futimens. get( ) {
12241259 Some ( futimens) => futimens( self . as_raw_fd( ) , times. as_ptr( ) ) ,
1225- #[ cfg( target_os = "macos" ) ]
1226- None => {
1227- fn ts_to_tv( ts: & libc:: timespec) -> libc:: timeval {
1228- libc:: timeval {
1229- tv_sec: ts. tv_sec,
1230- tv_usec: ( ts. tv_nsec / 1000 ) as _
1231- }
1232- }
1233- let timevals = [ ts_to_tv( & times[ 0 ] ) , ts_to_tv( & times[ 1 ] ) ] ;
1234- libc:: futimes( self . as_raw_fd( ) , timevals. as_ptr( ) )
1235- }
1236- // futimes requires even newer Android.
1237- #[ cfg( target_os = "android" ) ]
12381260 None => return Err ( io:: const_io_error!(
12391261 io:: ErrorKind :: Unsupported ,
12401262 "setting file times requires Android API level >= 19" ,
0 commit comments