summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosé Valim <jose.valim@plataformatec.com.br>2019-06-14 22:14:08 +0200
committerJosé Valim <jose.valim@plataformatec.com.br>2019-06-14 22:14:20 +0200
commitfedcff15977930db980faca51580f1a3a94e9439 (patch)
tree676dc6ae86175628e21f17b461cf827471c20f5d
parent4b758913263036e4d8556a7601f07e68412d012f (diff)
downloadelixir-fedcff15977930db980faca51580f1a3a94e9439.tar.gz
Exit IEx session if the group leader exits, closes #9138
-rw-r--r--lib/iex/lib/iex/server.ex26
1 files changed, 22 insertions, 4 deletions
diff --git a/lib/iex/lib/iex/server.ex b/lib/iex/lib/iex/server.ex
index e05971af6..12d5ccf9e 100644
--- a/lib/iex/lib/iex/server.ex
+++ b/lib/iex/lib/iex/server.ex
@@ -38,6 +38,7 @@ defmodule IEx.Server do
defp run_without_registration(opts) do
Process.flag(:trap_exit, true)
+ Process.link(Process.group_leader())
IO.puts(
"Interactive Elixir (#{System.version()}) - press Ctrl+C to exit (type h() ENTER for help)"
@@ -124,16 +125,18 @@ defmodule IEx.Server do
send(evaluator, {:eval, self(), code, state})
wait_eval(state, evaluator, evaluator_ref)
- {:input, ^input, {:error, :interrupted}} ->
- io_error("** (EXIT) interrupted")
- loop(%{state | cache: ''}, evaluator, evaluator_ref)
-
{:input, ^input, :eof} ->
case state.on_eof do
:halt -> System.halt(0)
:stop_evaluator -> stop_evaluator(evaluator, evaluator_ref)
end
+ # Triggered by pressing "i" as the job control switch
+ {:input, ^input, {:error, :interrupted}} ->
+ io_error("** (EXIT) interrupted")
+ loop(%{state | cache: ''}, evaluator, evaluator_ref)
+
+ # Triggered when IO dies while waiting for input
{:input, ^input, {:error, :terminated}} ->
stop_evaluator(evaluator, evaluator_ref)
@@ -212,6 +215,21 @@ defmodule IEx.Server do
loop(%{state | cache: ''}, evaluator, Process.monitor(evaluator))
end
+ defp handle_take_over(
+ {:EXIT, pid, reason},
+ state,
+ _evaluator,
+ _evaluator_ref,
+ _input,
+ callback
+ ) do
+ if pid == Process.group_leader() do
+ exit(reason)
+ else
+ callback.(state)
+ end
+ end
+
defp handle_take_over({:respawn, evaluator}, _state, evaluator, evaluator_ref, input, _callback) do
rerun([], evaluator, evaluator_ref, input)
end