From 032a22fd8df47e683a486b4dfc6507b38a1020d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Tue, 11 Jun 2024 22:17:25 +0200 Subject: [PATCH] Fix `Process.run` with closed IO --- spec/std/process_spec.cr | 8 ++++++++ src/crystal/system/unix/process.cr | 5 +++++ src/process.cr | 8 ++++++++ 3 files changed, 21 insertions(+) diff --git a/spec/std/process_spec.cr b/spec/std/process_spec.cr index d656e9353589..f067d2f5c775 100644 --- a/spec/std/process_spec.cr +++ b/spec/std/process_spec.cr @@ -181,6 +181,14 @@ pending_interpreted describe: Process do $?.exit_code.should eq(0) end + it "forwards closed io" do + closed_io = IO::Memory.new + closed_io.close + Process.run(*stdin_to_stdout_command, input: closed_io) + Process.run(*stdin_to_stdout_command, output: closed_io) + Process.run(*stdin_to_stdout_command, error: closed_io) + end + it "sets working directory with string" do parent = File.dirname(Dir.current) command = {% if flag?(:win32) %} diff --git a/src/crystal/system/unix/process.cr b/src/crystal/system/unix/process.cr index 4fd2b658cd59..c9dd1925169a 100644 --- a/src/crystal/system/unix/process.cr +++ b/src/crystal/system/unix/process.cr @@ -292,6 +292,11 @@ struct Crystal::System::Process end private def self.reopen_io(src_io : IO::FileDescriptor, dst_io : IO::FileDescriptor) + if src_io.closed? + dst_io.close + return + end + src_io = to_real_fd(src_io) dst_io.reopen(src_io) diff --git a/src/process.cr b/src/process.cr index a1b827d73754..045615c814a7 100644 --- a/src/process.cr +++ b/src/process.cr @@ -294,6 +294,14 @@ class Process when IO::FileDescriptor stdio when IO + if stdio.closed? + if dst_io == STDIN + return File.open(File::NULL, "r").tap(&.close) + else + return File.open(File::NULL, "w").tap(&.close) + end + end + if dst_io == STDIN fork_io, process_io = IO.pipe(read_blocking: true)