@@ -162,6 +162,46 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res
162
162
}
163
163
}
164
164
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
+
165
205
fn random_number ( ) -> usize {
166
206
static N : AtomicUsize = AtomicUsize :: new ( 0 ) ;
167
207
loop {
@@ -189,6 +229,9 @@ impl AnonPipe {
189
229
pub fn into_handle ( self ) -> Handle {
190
230
self . inner
191
231
}
232
+ fn duplicate ( & self ) -> io:: Result < Self > {
233
+ self . inner . duplicate ( 0 , false , c:: DUPLICATE_SAME_ACCESS ) . map ( |inner| AnonPipe { inner } )
234
+ }
192
235
193
236
pub fn read ( & self , buf : & mut [ u8 ] ) -> io:: Result < usize > {
194
237
let result = unsafe {
0 commit comments