@@ -349,6 +349,8 @@ pub struct FilePermissions {
349
349
pub struct FileTimes {
350
350
accessed : Option < SystemTime > ,
351
351
modified : Option < SystemTime > ,
352
+ #[ cfg( any( target_os = "macos" , target_os = "ios" , target_os = "watchos" ) ) ]
353
+ created : Option < SystemTime > ,
352
354
}
353
355
354
356
#[ derive( Copy , Clone , Eq , Debug ) ]
@@ -591,6 +593,11 @@ impl FileTimes {
591
593
pub fn set_modified ( & mut self , t : SystemTime ) {
592
594
self . modified = Some ( t) ;
593
595
}
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
+ }
594
601
}
595
602
596
603
impl FileType {
@@ -1215,26 +1222,41 @@ impl File {
1215
1222
io:: ErrorKind :: Unsupported ,
1216
1223
"setting file times not supported" ,
1217
1224
) )
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" ) ] {
1219
1254
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
1221
1256
cvt( unsafe {
1222
1257
weak!( fn futimens( c_int, * const libc:: timespec) -> c_int) ;
1223
1258
match futimens. get( ) {
1224
1259
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" ) ]
1238
1260
None => return Err ( io:: const_io_error!(
1239
1261
io:: ErrorKind :: Unsupported ,
1240
1262
"setting file times requires Android API level >= 19" ,
0 commit comments