@@ -2226,3 +2226,124 @@ fn test_open_options_invalid_combinations() {
2226
2226
assert_eq ! ( err. kind( ) , ErrorKind :: InvalidInput ) ;
2227
2227
assert_eq ! ( err. to_string( ) , "must specify at least one of read, write, or append access" ) ;
2228
2228
}
2229
+
2230
+ #[ test]
2231
+ fn test_fs_set_times ( ) {
2232
+ #[ cfg( target_vendor = "apple" ) ]
2233
+ use crate :: os:: darwin:: fs:: FileTimesExt ;
2234
+ #[ cfg( windows) ]
2235
+ use crate :: os:: windows:: fs:: FileTimesExt ;
2236
+
2237
+ let tmp = tmpdir ( ) ;
2238
+ let path = tmp. join ( "foo" ) ;
2239
+ File :: create ( & path) . unwrap ( ) ;
2240
+
2241
+ let mut times = FileTimes :: new ( ) ;
2242
+ let accessed = SystemTime :: UNIX_EPOCH + Duration :: from_secs ( 12345 ) ;
2243
+ let modified = SystemTime :: UNIX_EPOCH + Duration :: from_secs ( 54321 ) ;
2244
+ times = times. set_accessed ( accessed) . set_modified ( modified) ;
2245
+
2246
+ #[ cfg( any( windows, target_vendor = "apple" ) ) ]
2247
+ let created = SystemTime :: UNIX_EPOCH + Duration :: from_secs ( 32123 ) ;
2248
+ #[ cfg( any( windows, target_vendor = "apple" ) ) ]
2249
+ {
2250
+ times = times. set_created ( created) ;
2251
+ }
2252
+
2253
+ match fs:: set_times ( & path, times) {
2254
+ // Allow unsupported errors on platforms which don't support setting times.
2255
+ #[ cfg( not( any(
2256
+ windows,
2257
+ all(
2258
+ unix,
2259
+ not( any(
2260
+ target_os = "android" ,
2261
+ target_os = "redox" ,
2262
+ target_os = "espidf" ,
2263
+ target_os = "horizon"
2264
+ ) )
2265
+ )
2266
+ ) ) ) ]
2267
+ Err ( e) if e. kind ( ) == ErrorKind :: Unsupported => return ,
2268
+ Err ( e) => panic ! ( "error setting file times: {e:?}" ) ,
2269
+ Ok ( _) => { }
2270
+ }
2271
+
2272
+ let metadata = fs:: metadata ( & path) . unwrap ( ) ;
2273
+ assert_eq ! ( metadata. accessed( ) . unwrap( ) , accessed) ;
2274
+ assert_eq ! ( metadata. modified( ) . unwrap( ) , modified) ;
2275
+ #[ cfg( any( windows, target_vendor = "apple" ) ) ]
2276
+ {
2277
+ assert_eq ! ( metadata. created( ) . unwrap( ) , created) ;
2278
+ }
2279
+ }
2280
+
2281
+ #[ test]
2282
+ fn test_fs_set_times_nofollow ( ) {
2283
+ #[ cfg( target_vendor = "apple" ) ]
2284
+ use crate :: os:: darwin:: fs:: FileTimesExt ;
2285
+ #[ cfg( windows) ]
2286
+ use crate :: os:: windows:: fs:: FileTimesExt ;
2287
+
2288
+ let tmp = tmpdir ( ) ;
2289
+
2290
+ // Create a target file and a symlink to it
2291
+ let target = tmp. join ( "target" ) ;
2292
+ File :: create ( & target) . unwrap ( ) ;
2293
+
2294
+ #[ cfg( unix) ]
2295
+ let link = tmp. join ( "link" ) ;
2296
+ #[ cfg( unix) ]
2297
+ crate :: os:: unix:: fs:: symlink ( & target, & link) . unwrap ( ) ;
2298
+
2299
+ #[ cfg( windows) ]
2300
+ let link = tmp. join ( "link.txt" ) ;
2301
+ #[ cfg( windows) ]
2302
+ crate :: os:: windows:: fs:: symlink_file ( & target, & link) . unwrap ( ) ;
2303
+
2304
+ let mut times = FileTimes :: new ( ) ;
2305
+ let accessed = SystemTime :: UNIX_EPOCH + Duration :: from_secs ( 11111 ) ;
2306
+ let modified = SystemTime :: UNIX_EPOCH + Duration :: from_secs ( 22222 ) ;
2307
+ times = times. set_accessed ( accessed) . set_modified ( modified) ;
2308
+
2309
+ #[ cfg( any( windows, target_vendor = "apple" ) ) ]
2310
+ let created = SystemTime :: UNIX_EPOCH + Duration :: from_secs ( 33333 ) ;
2311
+ #[ cfg( any( windows, target_vendor = "apple" ) ) ]
2312
+ {
2313
+ times = times. set_created ( created) ;
2314
+ }
2315
+
2316
+ // Set times on the symlink itself (not following it)
2317
+ match fs:: set_times_nofollow ( & link, times) {
2318
+ // Allow unsupported errors on platforms which don't support setting times.
2319
+ #[ cfg( not( any(
2320
+ windows,
2321
+ all(
2322
+ unix,
2323
+ not( any(
2324
+ target_os = "android" ,
2325
+ target_os = "redox" ,
2326
+ target_os = "espidf" ,
2327
+ target_os = "horizon"
2328
+ ) )
2329
+ )
2330
+ ) ) ) ]
2331
+ Err ( e) if e. kind ( ) == ErrorKind :: Unsupported => return ,
2332
+ Err ( e) => panic ! ( "error setting symlink times: {e:?}" ) ,
2333
+ Ok ( _) => { }
2334
+ }
2335
+
2336
+ // Read symlink metadata (without following)
2337
+ let metadata = fs:: symlink_metadata ( & link) . unwrap ( ) ;
2338
+ assert_eq ! ( metadata. accessed( ) . unwrap( ) , accessed) ;
2339
+ assert_eq ! ( metadata. modified( ) . unwrap( ) , modified) ;
2340
+ #[ cfg( any( windows, target_vendor = "apple" ) ) ]
2341
+ {
2342
+ assert_eq ! ( metadata. created( ) . unwrap( ) , created) ;
2343
+ }
2344
+
2345
+ // Verify that the target file's times were NOT changed
2346
+ let target_metadata = fs:: metadata ( & target) . unwrap ( ) ;
2347
+ assert_ne ! ( target_metadata. accessed( ) . unwrap( ) , accessed) ;
2348
+ assert_ne ! ( target_metadata. modified( ) . unwrap( ) , modified) ;
2349
+ }
0 commit comments