From bb6221c51d3652cff2aeadd56d39a967b5e9534c Mon Sep 17 00:00:00 2001 From: Elliot Saba Date: Sat, 19 Feb 2022 09:47:41 -0800 Subject: [PATCH] Ensure that `open(::Function, ::Cmd)` waits for termination (#44078) On Windows, we observed occasional issues where an error within the function callback to the `open(::Function, ::Cmd)` method would cause problems due to assuming that the opened process had finished by the time the `open()` call was finished. In most cases this was true, however on Windows, it was found that we need to explicitly `wait()` upon the process object to ensure that all file handles held by the subprocess were properly closed by the time `open()` is finished. Co-authored-by: Dilum Aluthge (cherry picked from commit 623ceb7834de47538eddeadfa84a8bf2d9741248) --- base/process.jl | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/base/process.jl b/base/process.jl index 16e66b0bd9884..6aac514191681 100644 --- a/base/process.jl +++ b/base/process.jl @@ -402,16 +402,25 @@ process failed, or if the process attempts to print anything to stdout. """ function open(f::Function, cmds::AbstractCmd, args...; kwargs...) P = open(cmds, args...; kwargs...) + function waitkill(P::Process) + close(P) + # 0.1 seconds after we hope it dies (from closing stdio), + # we kill the process with SIGTERM (15) + local t = Timer(0.1) do t + process_running(P) && kill(P) + end + wait(P) + close(t) + end ret = try f(P) catch - kill(P) - close(P) + waitkill(P) rethrow() end close(P.in) if !eof(P.out) - close(P.out) + waitkill(P) throw(_UVError("open(do)", UV_EPIPE)) end success(P) || pipeline_error(P)