@@ -348,6 +348,8 @@ pub struct FilePermissions {
348
348
pub struct FileTimes {
349
349
accessed : Option < SystemTime > ,
350
350
modified : Option < SystemTime > ,
351
+ #[ cfg( any( target_os = "macos" , target_os = "ios" , target_os = "watchos" ) ) ]
352
+ created : Option < SystemTime > ,
351
353
}
352
354
353
355
#[ derive( Copy , Clone , Eq , Debug ) ]
@@ -579,6 +581,11 @@ impl FileTimes {
579
581
pub fn set_modified ( & mut self , t : SystemTime ) {
580
582
self . modified = Some ( t) ;
581
583
}
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
+ }
582
589
}
583
590
584
591
impl FileType {
@@ -1192,8 +1199,6 @@ impl File {
1192
1199
None => Ok ( libc:: timespec { tv_sec : 0 , tv_nsec : libc:: UTIME_OMIT as _ } ) ,
1193
1200
}
1194
1201
} ;
1195
- #[ cfg( not( any( target_os = "redox" , target_os = "espidf" , target_os = "horizon" ) ) ) ]
1196
- let times = [ to_timespec ( times. accessed ) ?, to_timespec ( times. modified ) ?] ;
1197
1202
cfg_if:: cfg_if! {
1198
1203
if #[ cfg( any( target_os = "redox" , target_os = "espidf" , target_os = "horizon" ) ) ] {
1199
1204
// Redox doesn't appear to support `UTIME_OMIT`.
@@ -1204,25 +1209,41 @@ impl File {
1204
1209
io:: ErrorKind :: Unsupported ,
1205
1210
"setting file times not supported" ,
1206
1211
) )
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
1209
1243
cvt( unsafe {
1210
1244
weak!( fn futimens( c_int, * const libc:: timespec) -> c_int) ;
1211
1245
match futimens. get( ) {
1212
1246
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" ) ]
1226
1247
None => return Err ( io:: const_io_error!(
1227
1248
io:: ErrorKind :: Unsupported ,
1228
1249
"setting file times requires Android API level >= 19" ,
@@ -1231,6 +1252,7 @@ impl File {
1231
1252
} ) ?;
1232
1253
Ok ( ( ) )
1233
1254
} else {
1255
+ let times = [ to_timespec( times. accessed) ?, to_timespec( times. modified) ?] ;
1234
1256
cvt( unsafe { libc:: futimens( self . as_raw_fd( ) , times. as_ptr( ) ) } ) ?;
1235
1257
Ok ( ( ) )
1236
1258
}
0 commit comments