@@ -1948,7 +1948,7 @@ fn open_from(from: &Path) -> io::Result<(crate::fs::File, crate::fs::Metadata)>
19481948#[ cfg( target_os = "espidf" ) ]
19491949fn open_to_and_set_permissions (
19501950 to : & Path ,
1951- _reader_metadata : crate :: fs:: Metadata ,
1951+ _reader_metadata : & crate :: fs:: Metadata ,
19521952) -> io:: Result < ( crate :: fs:: File , crate :: fs:: Metadata ) > {
19531953 use crate :: fs:: OpenOptions ;
19541954 let writer = OpenOptions :: new ( ) . open ( to) ?;
@@ -1959,7 +1959,7 @@ fn open_to_and_set_permissions(
19591959#[ cfg( not( target_os = "espidf" ) ) ]
19601960fn open_to_and_set_permissions (
19611961 to : & Path ,
1962- reader_metadata : crate :: fs:: Metadata ,
1962+ reader_metadata : & crate :: fs:: Metadata ,
19631963) -> io:: Result < ( crate :: fs:: File , crate :: fs:: Metadata ) > {
19641964 use crate :: fs:: OpenOptions ;
19651965 use crate :: os:: unix:: fs:: { OpenOptionsExt , PermissionsExt } ;
@@ -1984,30 +1984,63 @@ fn open_to_and_set_permissions(
19841984 Ok ( ( writer, writer_metadata) )
19851985}
19861986
1987- #[ cfg( not( any( target_os = "linux" , target_os = "android" , target_vendor = "apple" ) ) ) ]
1988- pub fn copy ( from : & Path , to : & Path ) -> io:: Result < u64 > {
1989- let ( mut reader, reader_metadata) = open_from ( from) ?;
1990- let ( mut writer, _) = open_to_and_set_permissions ( to, reader_metadata) ?;
1987+ mod cfm {
1988+ use crate :: fs:: { File , Metadata } ;
1989+ use crate :: io:: { BorrowedCursor , IoSlice , IoSliceMut , Read , Result , Write } ;
19911990
1992- io :: copy ( & mut reader , & mut writer )
1993- }
1991+ # [ allow ( dead_code ) ]
1992+ pub struct CachedFileMetadata ( pub File , pub Metadata ) ;
19941993
1994+ impl Read for CachedFileMetadata {
1995+ fn read ( & mut self , buf : & mut [ u8 ] ) -> Result < usize > {
1996+ self . 0 . read ( buf)
1997+ }
1998+ fn read_vectored ( & mut self , bufs : & mut [ IoSliceMut < ' _ > ] ) -> Result < usize > {
1999+ self . 0 . read_vectored ( bufs)
2000+ }
2001+ fn read_buf ( & mut self , cursor : BorrowedCursor < ' _ > ) -> Result < ( ) > {
2002+ self . 0 . read_buf ( cursor)
2003+ }
2004+ #[ inline]
2005+ fn is_read_vectored ( & self ) -> bool {
2006+ self . 0 . is_read_vectored ( )
2007+ }
2008+ fn read_to_end ( & mut self , buf : & mut Vec < u8 > ) -> Result < usize > {
2009+ self . 0 . read_to_end ( buf)
2010+ }
2011+ fn read_to_string ( & mut self , buf : & mut String ) -> Result < usize > {
2012+ self . 0 . read_to_string ( buf)
2013+ }
2014+ }
2015+ impl Write for CachedFileMetadata {
2016+ fn write ( & mut self , buf : & [ u8 ] ) -> Result < usize > {
2017+ self . 0 . write ( buf)
2018+ }
2019+ fn write_vectored ( & mut self , bufs : & [ IoSlice < ' _ > ] ) -> Result < usize > {
2020+ self . 0 . write_vectored ( bufs)
2021+ }
2022+ #[ inline]
2023+ fn is_write_vectored ( & self ) -> bool {
2024+ self . 0 . is_write_vectored ( )
2025+ }
2026+ #[ inline]
2027+ fn flush ( & mut self ) -> Result < ( ) > {
2028+ self . 0 . flush ( )
2029+ }
2030+ }
2031+ }
19952032#[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
2033+ pub ( crate ) use cfm:: CachedFileMetadata ;
2034+
2035+ #[ cfg( not( target_vendor = "apple" ) ) ]
19962036pub fn copy ( from : & Path , to : & Path ) -> io:: Result < u64 > {
1997- let ( mut reader, reader_metadata) = open_from ( from) ?;
1998- let max_len = u64:: MAX ;
1999- let ( mut writer, _) = open_to_and_set_permissions ( to, reader_metadata) ?;
2000-
2001- use super :: kernel_copy:: { CopyResult , copy_regular_files} ;
2002-
2003- match copy_regular_files ( reader. as_raw_fd ( ) , writer. as_raw_fd ( ) , max_len) {
2004- CopyResult :: Ended ( bytes) => Ok ( bytes) ,
2005- CopyResult :: Error ( e, _) => Err ( e) ,
2006- CopyResult :: Fallback ( written) => match io:: copy:: generic_copy ( & mut reader, & mut writer) {
2007- Ok ( bytes) => Ok ( bytes + written) ,
2008- Err ( e) => Err ( e) ,
2009- } ,
2010- }
2037+ let ( reader, reader_metadata) = open_from ( from) ?;
2038+ let ( writer, writer_metadata) = open_to_and_set_permissions ( to, & reader_metadata) ?;
2039+
2040+ io:: copy (
2041+ & mut cfm:: CachedFileMetadata ( reader, reader_metadata) ,
2042+ & mut cfm:: CachedFileMetadata ( writer, writer_metadata) ,
2043+ )
20112044}
20122045
20132046#[ cfg( target_vendor = "apple" ) ]
@@ -2044,7 +2077,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
20442077 }
20452078
20462079 // Fall back to using `fcopyfile` if `fclonefileat` does not succeed.
2047- let ( writer, writer_metadata) = open_to_and_set_permissions ( to, reader_metadata) ?;
2080+ let ( writer, writer_metadata) = open_to_and_set_permissions ( to, & reader_metadata) ?;
20482081
20492082 // We ensure that `FreeOnDrop` never contains a null pointer so it is
20502083 // always safe to call `copyfile_state_free`
0 commit comments