@@ -1948,7 +1948,7 @@ fn open_from(from: &Path) -> io::Result<(crate::fs::File, crate::fs::Metadata)>
1948
1948
#[ cfg( target_os = "espidf" ) ]
1949
1949
fn open_to_and_set_permissions (
1950
1950
to : & Path ,
1951
- _reader_metadata : crate :: fs:: Metadata ,
1951
+ _reader_metadata : & crate :: fs:: Metadata ,
1952
1952
) -> io:: Result < ( crate :: fs:: File , crate :: fs:: Metadata ) > {
1953
1953
use crate :: fs:: OpenOptions ;
1954
1954
let writer = OpenOptions :: new ( ) . open ( to) ?;
@@ -1959,7 +1959,7 @@ fn open_to_and_set_permissions(
1959
1959
#[ cfg( not( target_os = "espidf" ) ) ]
1960
1960
fn open_to_and_set_permissions (
1961
1961
to : & Path ,
1962
- reader_metadata : crate :: fs:: Metadata ,
1962
+ reader_metadata : & crate :: fs:: Metadata ,
1963
1963
) -> io:: Result < ( crate :: fs:: File , crate :: fs:: Metadata ) > {
1964
1964
use crate :: fs:: OpenOptions ;
1965
1965
use crate :: os:: unix:: fs:: { OpenOptionsExt , PermissionsExt } ;
@@ -1984,30 +1984,63 @@ fn open_to_and_set_permissions(
1984
1984
Ok ( ( writer, writer_metadata) )
1985
1985
}
1986
1986
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 } ;
1991
1990
1992
- io :: copy ( & mut reader , & mut writer )
1993
- }
1991
+ # [ allow ( dead_code ) ]
1992
+ pub struct CachedFileMetadata ( pub File , pub Metadata ) ;
1994
1993
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
+ }
1995
2032
#[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
2033
+ pub ( crate ) use cfm:: CachedFileMetadata ;
2034
+
2035
+ #[ cfg( not( target_vendor = "apple" ) ) ]
1996
2036
pub 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
+ )
2011
2044
}
2012
2045
2013
2046
#[ cfg( target_vendor = "apple" ) ]
@@ -2044,7 +2077,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
2044
2077
}
2045
2078
2046
2079
// 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) ?;
2048
2081
2049
2082
// We ensure that `FreeOnDrop` never contains a null pointer so it is
2050
2083
// always safe to call `copyfile_state_free`
0 commit comments