summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFred Hebert <mononcqc@ferd.ca>2016-01-06 15:20:34 -0500
committerFred Hebert <mononcqc@ferd.ca>2016-01-06 15:20:34 -0500
commitf7047073358ceedfc1bc61d6df01f4d6710ad8b1 (patch)
tree0923f963e3356d83714299867f8461dd92786e8f
parent814d18a31fdd58bb796c068e7c927e35fd9322f6 (diff)
Correct TTY type detection
This reuses the trick used within OTP to pick within old and new shell. The 'user' structure is the same for all cases (escript, escript + dumb TERM, unstable install, unstable install + dumb TERM), so we take it down first. Then we boot the TTY driver, which fails if TERM=dumb, in which case we boot the retro-style usr. If it worked, we shut down the driver again, and boot a modern shell structure. This avoids all warnings and seems to work in all cases.
-rw-r--r--src/rebar_prv_shell.erl40
1 files changed, 23 insertions, 17 deletions
diff --git a/src/rebar_prv_shell.erl b/src/rebar_prv_shell.erl
index b2479f1..824293f 100644
--- a/src/rebar_prv_shell.erl
+++ b/src/rebar_prv_shell.erl
@@ -112,36 +112,42 @@ info() ->
"Start a shell with project and deps preloaded similar to~n'erl -pa ebin -pa deps/*/ebin'.~n".
setup_shell() ->
- case process_info(whereis(user), current_function) of
- {_,{user,_,_}} -> setup_old_shell();
- _ -> setup_new_shell()
- end.
+ OldUser = kill_old_user(),
+ %% Test for support here
+ NewUser = try erlang:open_port({spawn,'tty_sl -c -e'}, []) of
+ Port when is_port(Port) ->
+ true = port_close(Port),
+ setup_new_shell()
+ catch
+ error:_ ->
+ setup_old_shell()
+ end,
+ rewrite_leaders(OldUser, NewUser).
-setup_new_shell() ->
- %% scan all processes for any with references to the old user and save them to
- %% update later
+kill_old_user() ->
OldUser = whereis(user),
- %% terminate the current user
+ %% terminate the current user's port, in a way that makes it shut down,
+ %% but without taking down the supervision tree so that the escript doesn't
+ %% fully die
+ [P] = [P || P <- element(2,process_info(whereis(user), links)), is_port(P)],
+ user ! {'EXIT', P, normal}, % pretend the port died, then the port can die!
+ OldUser.
+
+setup_new_shell() ->
+ %% terminate the current user supervision structure
ok = supervisor:terminate_child(kernel_sup, user),
%% start a new shell (this also starts a new user under the correct group)
_ = user_drv:start(),
%% wait until user_drv and user have been registered (max 3 seconds)
ok = wait_until_user_started(3000),
- NewUser = whereis(user),
- rewrite_leaders(OldUser, NewUser).
+ whereis(user).
setup_old_shell() ->
%% scan all processes for any with references to the old user and save them to
%% update later
- OldUser = whereis(user),
- %% terminate the current user's port, in a way that makes it shut down,
- %% but without taking down the supervision tree so that the escript doesn't
- %% fully die
- [P] = [P || P <- element(2,process_info(whereis(user), links)), is_port(P)],
- user ! {'EXIT', P, normal}, % pretend the port died, then the port can die!
NewUser = rebar_user:start(), % hikack IO stuff with fake user
NewUser = whereis(user),
- rewrite_leaders(OldUser, NewUser).
+ NewUser.
rewrite_leaders(OldUser, NewUser) ->
%% set any process that had a reference to the old user's group leader to the