From 95819102613b47fe873a81ce9f50defe949ad9f9 Mon Sep 17 00:00:00 2001 From: Adam Wight Date: Mon, 17 Feb 2025 08:44:27 +0100 Subject: [PATCH] Minor doc update: "orphan" processes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch makes two small changes to the documentation: First, "zombie" processes are in a terminated state and will appear in "ps" output in "Z" state. The problem described in our documentation seems to actually be about the "orphan" condition, in which a process continues running after its parent terminates. Most unix systems will reparent the process with PID 1 but this can vary, but there is no convention that the process should stop unless it has been wired using eg. "prctl" to detect a terminated parent. The distinction between zombie and orphan is important because it means the child is still active. Second, our suggestion that the child process should detect stdin closure is a good workaround but is not generally true for applications that aren't doing their work on stdio. I've tried to clean up the text around the example shell script to clarify that developers are free to use this technique to detect parent termination, but it's not the rule for polite unix applications. Hijacking stdin also comes with some drawbacks as is already mentioned. I'm not suggesting a different workaround at the moment—there is a linux-specific technique of using "prctl" which is demonstrated in https://groups.google.com/g/elixir-lang-core/c/yiepKrcEniU , however this isn't portable. See #7495 and #9171 --- lib/elixir/lib/port.ex | 14 +++++++------- lib/elixir/lib/system.ex | 2 +- lib/mix/lib/mix/tasks/cmd.ex | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/elixir/lib/port.ex b/lib/elixir/lib/port.ex index 4a84615b1c1..424790c765b 100644 --- a/lib/elixir/lib/port.ex +++ b/lib/elixir/lib/port.ex @@ -142,22 +142,22 @@ defmodule Port do reimplementing core part of the Runtime System, such as the `:user` and `:shell` processes. - ## Zombie operating system processes + ## Orphan operating system processes A port can be closed via the `close/1` function or by sending a `{pid, :close}` message. However, if the VM crashes, a long-running program started by the port will have its stdin and stdout channels closed but **it won't be automatically terminated**. - While most Unix command line tools will exit once its communication channels - are closed, not all command line applications will do so. You can easily check + While some Unix command line tools will exit once its parent process + terminates, not all command line applications will do so. You can easily check this by starting the port and then shutting down the VM and inspecting your operating system to see if the port process is still running. - While we encourage graceful termination by detecting if stdin/stdout has been - closed, we do not always have control over how third-party software terminates. - In those cases, you can wrap the application in a script that checks for stdin. - Here is such script that has been verified to work on bash shells: + We do not always have control over how third-party software terminates. + If necessary, one workaround is to wrap the child application in a script that + checks whether stdin has been closed. Here is such a script that has been + verified to work on bash shells: #!/usr/bin/env bash diff --git a/lib/elixir/lib/system.ex b/lib/elixir/lib/system.ex index b5cd2c7af89..d2881e5b0b5 100644 --- a/lib/elixir/lib/system.ex +++ b/lib/elixir/lib/system.ex @@ -997,7 +997,7 @@ defmodule System do ports guarantee stdin/stdout devices will be closed but it does not automatically terminate the program. The documentation for the `Port` module describes this problem and possible solutions under - the "Zombie processes" section. + the "Orphan operating system processes" section. > #### Windows argument splitting and untrusted arguments {: .warning} > diff --git a/lib/mix/lib/mix/tasks/cmd.ex b/lib/mix/lib/mix/tasks/cmd.ex index 8868e64e08a..5749c1b3e7a 100644 --- a/lib/mix/lib/mix/tasks/cmd.ex +++ b/lib/mix/lib/mix/tasks/cmd.ex @@ -39,7 +39,7 @@ defmodule Mix.Tasks.Cmd do * `--cd` *(since v1.10.4)* - the directory to run the command in - ## Zombie operating system processes + ## Orphan operating system processes Beware that the Erlang VM does not terminate child processes when it shuts down. Therefore, if you use `mix cmd` to start @@ -48,7 +48,7 @@ defmodule Mix.Tasks.Cmd do A solution is to make sure the child processes listen to the standard input and terminate when standard input is closed. - We discuss this topic at length in the "Zombie operating system processes" + We discuss this topic at length in the "Orphan operating system processes" of the `Port` module documentation. """