@@ -28,6 +28,8 @@ use nix::sys::stat::{Mode, SFlag, dev_t, mknod as nix_mknod, mode_t};
2828use thiserror:: Error ;
2929
3030use platform:: copy_on_write;
31+ #[ cfg( target_os = "wasi" ) ]
32+ use platform:: { SourceTimestamps , set_timestamps} ;
3133use uucore:: backup_control:: backup_would_destroy_source;
3234use uucore:: display:: Quotable ;
3335use uucore:: error:: { UError , UResult , UUsageError , set_exit_code, strip_errno} ;
@@ -2653,6 +2655,17 @@ fn copy_file(
26532655 } ) ?
26542656 } ;
26552657
2658+ #[ cfg( target_os = "wasi" ) ]
2659+ let source_timestamps = if !source_is_symlink
2660+ && source_metadata. file_type ( ) . is_file ( )
2661+ && options. copy_mode != CopyMode :: SymLink
2662+ && matches ! ( options. attributes. timestamps, Preserve :: Yes { .. } )
2663+ {
2664+ Some ( SourceTimestamps :: from_metadata ( & source_metadata) ?)
2665+ } else {
2666+ None
2667+ } ;
2668+
26562669 let dest_metadata = dest. symlink_metadata ( ) . ok ( ) ;
26572670
26582671 let dest_permissions = calculate_dest_permissions (
@@ -2704,9 +2717,11 @@ fn copy_file(
27042717 . ok ( )
27052718 . filter ( |p| p. exists ( ) )
27062719 . unwrap_or_else ( || source. to_path_buf ( ) ) ;
2707- copy_attributes (
2720+ copy_attributes_after_copy (
27082721 & src_for_attrs,
27092722 dest,
2723+ #[ cfg( target_os = "wasi" ) ]
2724+ source_timestamps,
27102725 & options. attributes ,
27112726 false ,
27122727 options. set_selinux_context ,
@@ -2718,9 +2733,11 @@ fn copy_file(
27182733 // copy function (see `copy_stream` under platform/linux.rs).
27192734 Ok ( ( ) )
27202735 } else {
2721- copy_attributes (
2736+ copy_attributes_after_copy (
27222737 source,
27232738 dest,
2739+ #[ cfg( target_os = "wasi" ) ]
2740+ source_timestamps,
27242741 & options. attributes ,
27252742 false ,
27262743 options. set_selinux_context ,
@@ -2753,6 +2770,40 @@ fn copy_file(
27532770 Ok ( ( ) )
27542771}
27552772
2773+ fn copy_attributes_after_copy (
2774+ source : & Path ,
2775+ dest : & Path ,
2776+ #[ cfg( target_os = "wasi" ) ] source_timestamps : Option < SourceTimestamps > ,
2777+ attributes : & Attributes ,
2778+ dest_is_freshly_created_dir : bool ,
2779+ skip_selinux_xattr : bool ,
2780+ ) -> CopyResult < ( ) > {
2781+ #[ cfg( target_os = "wasi" ) ]
2782+ if let Some ( source_timestamps) = source_timestamps {
2783+ let timestamps = attributes. timestamps ;
2784+ let mut remaining_attributes = * attributes;
2785+ remaining_attributes. timestamps = Preserve :: No { explicit : false } ;
2786+ copy_attributes (
2787+ source,
2788+ dest,
2789+ & remaining_attributes,
2790+ dest_is_freshly_created_dir,
2791+ skip_selinux_xattr,
2792+ ) ?;
2793+ return handle_preserve ( timestamps, || {
2794+ set_timestamps ( source_timestamps, dest) . map_err ( CpError :: from)
2795+ } ) ;
2796+ }
2797+
2798+ copy_attributes (
2799+ source,
2800+ dest,
2801+ attributes,
2802+ dest_is_freshly_created_dir,
2803+ skip_selinux_xattr,
2804+ )
2805+ }
2806+
27562807fn is_stream ( metadata : & Metadata ) -> bool {
27572808 #[ cfg( unix) ]
27582809 {
0 commit comments