@@ -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