From 32fe7efe508cc54b35f26f11b43e40c134715d37 Mon Sep 17 00:00:00 2001 From: Elliot Saba <staticfloat@gmail.com> Date: Tue, 8 Feb 2022 10:41:35 -0800 Subject: [PATCH] Ensure that `open(::Function, ::Cmd)` waits for termination 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. --- base/process.jl | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/base/process.jl b/base/process.jl index da73d10332b5d..0ab68e8181a9a 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)