@@ -291,33 +291,20 @@ class Process
291
291
292
292
private def stdio_to_fd (stdio : Stdio , for dst_io : IO ::FileDescriptor ) : IO ::FileDescriptor
293
293
case stdio
294
- when IO ::FileDescriptor
295
- stdio
296
- when IO
297
- if stdio.closed?
298
- if dst_io == STDIN
299
- return File .open(File ::NULL , " r" ).tap(& .close)
300
- else
301
- return File .open(File ::NULL , " w" ).tap(& .close)
294
+ in IO ::FileDescriptor
295
+ # on Windows, only async pipes can be passed to child processes, async
296
+ # regular files will report an error and those require a separate pipe
297
+ # (https://github.com/crystal-lang/crystal/pull/13362#issuecomment-1519082712)
298
+ {% if flag?(:win32 ) % }
299
+ unless stdio.blocking || stdio.info.type.pipe?
300
+ return io_to_fd(stdio, for: dst_io)
302
301
end
303
- end
304
-
305
- if dst_io == STDIN
306
- fork_io, process_io = IO .pipe(read_blocking: true )
307
-
308
- @wait_count += 1
309
- ensure_channel
310
- spawn { copy_io(stdio, process_io, channel, close_dst: true ) }
311
- else
312
- process_io, fork_io = IO .pipe(write_blocking: true )
302
+ {% end % }
313
303
314
- @wait_count += 1
315
- ensure_channel
316
- spawn { copy_io(process_io, stdio, channel, close_src: true ) }
317
- end
318
-
319
- fork_io
320
- when Redirect ::Pipe
304
+ stdio
305
+ in IO
306
+ io_to_fd(stdio, for: dst_io)
307
+ in Redirect ::Pipe
321
308
case dst_io
322
309
when STDIN
323
310
fork_io, @input = IO .pipe(read_blocking: true )
@@ -330,17 +317,41 @@ class Process
330
317
end
331
318
332
319
fork_io
333
- when Redirect ::Inherit
320
+ in Redirect ::Inherit
334
321
dst_io
335
- when Redirect ::Close
322
+ in Redirect ::Close
336
323
if dst_io == STDIN
337
324
File .open(File ::NULL , " r" )
338
325
else
339
326
File .open(File ::NULL , " w" )
340
327
end
328
+ end
329
+ end
330
+
331
+ private def io_to_fd (stdio : Stdio , for dst_io : IO ::FileDescriptor ) : IO ::FileDescriptor
332
+ if stdio.closed?
333
+ if dst_io == STDIN
334
+ return File .open(File ::NULL , " r" ).tap(& .close)
335
+ else
336
+ return File .open(File ::NULL , " w" ).tap(& .close)
337
+ end
338
+ end
339
+
340
+ if dst_io == STDIN
341
+ fork_io, process_io = IO .pipe(read_blocking: true )
342
+
343
+ @wait_count += 1
344
+ ensure_channel
345
+ spawn { copy_io(stdio, process_io, channel, close_dst: true ) }
341
346
else
342
- raise " BUG: Impossible type in stdio #{ stdio.class } "
347
+ process_io, fork_io = IO .pipe(write_blocking: true )
348
+
349
+ @wait_count += 1
350
+ ensure_channel
351
+ spawn { copy_io(process_io, stdio, channel, close_src: true ) }
343
352
end
353
+
354
+ fork_io
344
355
end
345
356
346
357
# :nodoc:
0 commit comments