diff --git a/lib/pythonx/application.ex b/lib/pythonx/application.ex index a4b8053..1be6aa8 100644 --- a/lib/pythonx/application.ex +++ b/lib/pythonx/application.ex @@ -5,6 +5,8 @@ defmodule Pythonx.Application do @impl true def start(_type, _args) do + enable_sigchld() + children = [ Pythonx.Janitor ] @@ -26,4 +28,16 @@ defmodule Pythonx.Application do else defp maybe_uv_init(), do: :noop end + + defp enable_sigchld() do + # Some APIs in Python, such as subprocess.run, wait for a child + # OS process to finish. On Unix, this relies on `waitpid` C API, + # which does not work properly if SIGCHLD is ignored, resulting + # in infinite waiting. ERTS ignores the signal by default, so we + # explicitly restore the default handler. + case :os.type() do + {:win32, _osname} -> :ok + {:unix, _osname} -> :os.set_signal(:sigchld, :default) + end + end end