@@ -52,8 +52,8 @@ use crate::cmp::min;
52
52
use crate :: fs:: { File , Metadata } ;
53
53
use crate :: io:: copy:: generic_copy;
54
54
use 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 ,
57
57
} ;
58
58
use crate :: mem:: ManuallyDrop ;
59
59
use crate :: net:: TcpStream ;
@@ -192,7 +192,7 @@ impl<R: CopyRead, W: CopyWrite> SpecCopy for Copier<'_, '_, R, W> {
192
192
let w_cfg = writer. properties ( ) ;
193
193
194
194
// 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 > {
196
196
let bytes = reader. drain_to ( writer, u64:: MAX ) ?;
197
197
// BufWriter buffered bytes have already been accounted for in earlier write() calls
198
198
writer. flush ( ) ?;
@@ -537,6 +537,58 @@ impl<T: ?Sized + CopyWrite> CopyWrite for BufWriter<T> {
537
537
}
538
538
}
539
539
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
+
540
592
fn fd_to_meta < T : AsRawFd > ( fd : & T ) -> FdMeta {
541
593
let fd = fd. as_raw_fd ( ) ;
542
594
let file: ManuallyDrop < File > = ManuallyDrop :: new ( unsafe { File :: from_raw_fd ( fd) } ) ;
0 commit comments