+ iex> :timer.sleep(500) # wait for the reader and writer to change pipe owner, otherwise `await_exit` will close the pipes before we change pipe owner
+ iex> Process.await_exit(p, :infinity) # let the reader and writer take indefinite time to finish
+ {:ok, 0}
+ iex> Task.await(writer)
+ :ok
+ iex> Task.await(reader)
+ {:ok, "Hello World"}
+ ```
+
"""
use GenServer
alias Exile.Process.Exec
alias Exile.Process.Nif
alias Exile.Process.Operations
alias Exile.Process.Pipe
alias Exile.Process.State
require Logger
defmodule Error do
defexception [:message]
end
@type pipe_name :: :stdin | :stdout | :stderr
@type t :: %__MODULE__{
monitor_ref: reference(),
exit_ref: reference(),
pid: pid | nil,
owner: pid
}
defstruct [:monitor_ref, :exit_ref, :pid, :owner]
@type exit_status :: non_neg_integer
@default_opts [env: [], enable_stderr: false]
@default_buffer_size 65_535
@os_signal_timeout 1000
@doc """
- Starts `Exile.Process`
+ Starts `Exile.Process` server.
Starts external program using `cmd_with_args` with options `opts`
- `cmd_with_args` must be a list containing command with arguments. example: `["cat", "file.txt"]`.
+ `cmd_with_args` must be a list containing command with arguments.
+ example: `["cat", "file.txt"]`.
### Options
+
* `cd` - the directory to run the command in
- * `env` - a list of tuples containing environment key-value. These can be accessed in the external program
- * `enable_stderr` - when set to true, Exile connects stderr pipe for the consumption. Defaults to false. Note that when set to true stderr must be consumed to avoid external program from blocking
+
+ * `env` - a list of tuples containing environment key-value.
+ These can be accessed in the external program
+
+ * `enable_stderr` - when set to true, Exile connects stderr
+ pipe for the consumption. Defaults to false. Note that when set
+ to true stderr must be consumed to avoid external program from blocking.
+
+ Caller of the process will be the owner owner of the Exile Process.
+ And default owner of all opened pipes.
+
+ Please check module documentation for more details
"""
@spec start_link(nonempty_list(String.t()),
cd: String.t(),
env: [{String.t(), String.t()}],
enable_stderr: boolean()
) :: {:ok, t} | {:error, any()}
def start_link(cmd_with_args, opts \\ []) do
opts = Keyword.merge(@default_opts, opts)
case Exec.normalize_exec_args(cmd_with_args, opts) do