@@ -162,6 +162,46 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res
162162 }
163163}
164164
165+ /// Takes an asynchronous source pipe and returns a synchronous pipe suitable
166+ /// for sending to a child process.
167+ ///
168+ /// This is achieved by creating a new set of pipes and spawning a thread that
169+ /// relays messages between the source and the synchronous pipe.
170+ pub fn spawn_pipe_relay (
171+ source : & AnonPipe ,
172+ ours_readable : bool ,
173+ their_handle_inheritable : bool ,
174+ ) -> io:: Result < AnonPipe > {
175+ // We need this handle to live for the lifetime of the thread spawned below.
176+ let source = source. duplicate ( ) ?;
177+
178+ // create a new pair of anon pipes.
179+ let Pipes { theirs, ours } = anon_pipe ( ours_readable, their_handle_inheritable) ?;
180+
181+ // Spawn a thread that passes messages from one pipe to the other.
182+ // Any errors will simply cause the thread to exit.
183+ let ( reader, writer) = if ours_readable { ( ours, source) } else { ( source, ours) } ;
184+ crate :: thread:: spawn ( move || {
185+ let mut buf = [ 0_u8 ; 4096 ] ;
186+ ' reader: while let Ok ( len) = reader. read ( & mut buf) {
187+ if len == 0 {
188+ break ;
189+ }
190+ let mut start = 0 ;
191+ while let Ok ( written) = writer. write ( & buf[ start..len] ) {
192+ start += written;
193+ if start == len {
194+ continue ' reader;
195+ }
196+ }
197+ break ;
198+ }
199+ } ) ;
200+
201+ // Return the pipe that should be sent to the child process.
202+ Ok ( theirs)
203+ }
204+
165205fn random_number ( ) -> usize {
166206 static N : AtomicUsize = AtomicUsize :: new ( 0 ) ;
167207 loop {
@@ -189,6 +229,9 @@ impl AnonPipe {
189229 pub fn into_handle ( self ) -> Handle {
190230 self . inner
191231 }
232+ fn duplicate ( & self ) -> io:: Result < Self > {
233+ self . inner . duplicate ( 0 , false , c:: DUPLICATE_SAME_ACCESS ) . map ( |inner| AnonPipe { inner } )
234+ }
192235
193236 pub fn read ( & self , buf : & mut [ u8 ] ) -> io:: Result < usize > {
194237 let result = unsafe {
0 commit comments