@@ -100,19 +100,24 @@ pub fn splice_unbounded(source: &impl AsFd, dest: &mut impl AsFd) -> rustix::io:
100100 Ok ( ( ) )
101101}
102102
103- /// force-splice source to dest even both of them are not pipe
104- /// return true if we need read/write fallback
103+ /// force-splice source to dest even both of them are not pipe via broker pipe
104+ /// returns Ok(Ok(())) if splice succeeds
105+ /// returns Ok(Err()) if splice failed, but you can fallback to read/write
106+ /// returns std::io::Result if splice from broker failed and read/write fallback from broker failed
105107///
108+ /// Thus, ?.is_err() returns serious error at early stage and checks that you can fallback
106109/// This should not be used if one of them are pipe to save resources
107110#[ inline]
108111#[ cfg( any( target_os = "linux" , target_os = "android" ) ) ]
109- pub fn splice_unbounded_broker ( source : & impl AsFd , dest : & mut impl AsFd ) -> std:: io:: Result < bool > {
112+ pub fn splice_unbounded_broker (
113+ source : & impl AsFd ,
114+ dest : & mut impl AsFd ,
115+ ) -> std:: io:: Result < Result < ( ) , ( ) > > {
110116 static PIPE_CACHE : OnceLock < Option < ( PipeReader , PipeWriter ) > > = OnceLock :: new ( ) ;
111- let Some ( ( pipe_rd, pipe_wr) ) = PIPE_CACHE
112- . get_or_init ( || pipe :: < false > ( MAX_ROOTLESS_PIPE_SIZE ) . ok ( ) )
113- . as_ref ( )
117+ let Some ( ( pipe_rd, pipe_wr) ) =
118+ PIPE_CACHE . get_or_init ( || pipe :: < false > ( MAX_ROOTLESS_PIPE_SIZE ) . ok ( ) )
114119 else {
115- return Ok ( true ) ;
120+ return Ok ( Err ( ( ) ) ) ;
116121 } ;
117122 // improve throughput
118123 // no need to increase pipe size of input fd since
@@ -122,7 +127,7 @@ pub fn splice_unbounded_broker(source: &impl AsFd, dest: &mut impl AsFd) -> std:
122127
123128 loop {
124129 match splice ( & source, & pipe_wr, MAX_ROOTLESS_PIPE_SIZE ) {
125- Ok ( 0 ) => return Ok ( false ) ,
130+ Ok ( 0 ) => return Ok ( Ok ( ( ) ) ) ,
126131 Ok ( n) => {
127132 if splice_exact ( & pipe_rd, dest, n) . is_err ( ) {
128133 // If the first splice manages to copy to the intermediate
@@ -135,10 +140,10 @@ pub fn splice_unbounded_broker(source: &impl AsFd, dest: &mut impl AsFd) -> std:
135140 let mut drain = Vec :: with_capacity ( n) ;
136141 pipe_rd. take ( n as u64 ) . read_to_end ( & mut drain) ?;
137142 RawWriter ( & dest) . write_all ( & drain) ?;
138- return Ok ( true ) ;
143+ return Ok ( Err ( ( ) ) ) ;
139144 }
140145 }
141- Err ( _) => return Ok ( true ) ,
146+ Err ( _) => return Ok ( Err ( ( ) ) ) ,
142147 }
143148 }
144149}
@@ -153,7 +158,7 @@ pub fn splice_unbounded_auto(source: &impl AsFd, dest: &mut impl AsFd) -> std::i
153158 // use splice to check that input or output is pipe which is efficient
154159 let fallback = match splice ( & source, dest, MAX_ROOTLESS_PIPE_SIZE ) {
155160 Ok ( _) => splice_unbounded ( source, dest) . is_err ( ) ,
156- _ => splice_unbounded_broker ( source, dest) ?,
161+ _ => splice_unbounded_broker ( source, dest) ?. is_err ( ) ,
157162 } ;
158163 Ok ( fallback)
159164}
0 commit comments