@@ -52,8 +52,8 @@ use crate::cmp::min;
5252use crate :: fs:: { File , Metadata } ;
5353use crate :: io:: copy:: generic_copy;
5454use crate :: io:: {
55- BufRead , BufReader , BufWriter , Error , Read , Result , StderrLock , StdinLock , StdoutLock , Take ,
56- Write ,
55+ BorrowedCursor , BufRead , BufReader , BufWriter , Error , IoSlice , IoSliceMut , Read , Result ,
56+ StderrLock , StdinLock , StdoutLock , Take , Write ,
5757} ;
5858use crate :: mem:: ManuallyDrop ;
5959use crate :: net:: TcpStream ;
@@ -192,7 +192,7 @@ impl<R: CopyRead, W: CopyWrite> SpecCopy for Copier<'_, '_, R, W> {
192192 let w_cfg = writer. properties ( ) ;
193193
194194 // before direct operations on file descriptors ensure that all source and sink buffers are empty
195- let mut flush = || -> crate :: io :: Result < u64 > {
195+ let mut flush = || -> Result < u64 > {
196196 let bytes = reader. drain_to ( writer, u64:: MAX ) ?;
197197 // BufWriter buffered bytes have already been accounted for in earlier write() calls
198198 writer. flush ( ) ?;
@@ -537,6 +537,58 @@ impl<T: ?Sized + CopyWrite> CopyWrite for BufWriter<T> {
537537 }
538538}
539539
540+ pub ( crate ) struct CachedFileMetadata ( pub File , pub Metadata ) ;
541+
542+ impl Read for CachedFileMetadata {
543+ fn read ( & mut self , buf : & mut [ u8 ] ) -> Result < usize > {
544+ self . 0 . read ( buf)
545+ }
546+ fn read_vectored ( & mut self , bufs : & mut [ IoSliceMut < ' _ > ] ) -> Result < usize > {
547+ self . 0 . read_vectored ( bufs)
548+ }
549+ fn read_buf ( & mut self , cursor : BorrowedCursor < ' _ > ) -> Result < ( ) > {
550+ self . 0 . read_buf ( cursor)
551+ }
552+ #[ inline]
553+ fn is_read_vectored ( & self ) -> bool {
554+ self . 0 . is_read_vectored ( )
555+ }
556+ fn read_to_end ( & mut self , buf : & mut Vec < u8 > ) -> Result < usize > {
557+ self . 0 . read_to_end ( buf)
558+ }
559+ fn read_to_string ( & mut self , buf : & mut String ) -> Result < usize > {
560+ self . 0 . read_to_string ( buf)
561+ }
562+ }
563+ impl Write for CachedFileMetadata {
564+ fn write ( & mut self , buf : & [ u8 ] ) -> Result < usize > {
565+ self . 0 . write ( buf)
566+ }
567+ fn write_vectored ( & mut self , bufs : & [ IoSlice < ' _ > ] ) -> Result < usize > {
568+ self . 0 . write_vectored ( bufs)
569+ }
570+ #[ inline]
571+ fn is_write_vectored ( & self ) -> bool {
572+ self . 0 . is_write_vectored ( )
573+ }
574+ #[ inline]
575+ fn flush ( & mut self ) -> Result < ( ) > {
576+ self . 0 . flush ( )
577+ }
578+ }
579+
580+ impl CopyRead for CachedFileMetadata {
581+ fn properties ( & self ) -> CopyParams {
582+ CopyParams ( FdMeta :: Metadata ( self . 1 . clone ( ) ) , Some ( self . 0 . as_raw_fd ( ) ) )
583+ }
584+ }
585+
586+ impl CopyWrite for CachedFileMetadata {
587+ fn properties ( & self ) -> CopyParams {
588+ CopyParams ( FdMeta :: Metadata ( self . 1 . clone ( ) ) , Some ( self . 0 . as_raw_fd ( ) ) )
589+ }
590+ }
591+
540592fn fd_to_meta < T : AsRawFd > ( fd : & T ) -> FdMeta {
541593 let fd = fd. as_raw_fd ( ) ;
542594 let file: ManuallyDrop < File > = ManuallyDrop :: new ( unsafe { File :: from_raw_fd ( fd) } ) ;
0 commit comments