diff options
Diffstat (limited to 'src/rebar_prv_shell.erl')
-rw-r--r-- | src/rebar_prv_shell.erl | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/src/rebar_prv_shell.erl b/src/rebar_prv_shell.erl index c644930..824293f 100644 --- a/src/rebar_prv_shell.erl +++ b/src/rebar_prv_shell.erl @@ -27,6 +27,7 @@ -module(rebar_prv_shell). -author("Kresten Krab Thorup <krab@trifork.com>"). +-author("Fred Hebert <mononcqc@ferd.ca>"). -behaviour(provider). @@ -111,16 +112,44 @@ info() -> "Start a shell with project and deps preloaded similar to~n'erl -pa ebin -pa deps/*/ebin'.~n". setup_shell() -> - %% scan all processes for any with references to the old user and save them to - %% update later + 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). + +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), + whereis(user). + +setup_old_shell() -> + %% scan all processes for any with references to the old user and save them to + %% update later + NewUser = rebar_user:start(), % hikack IO stuff with fake user NewUser = whereis(user), + NewUser. + +rewrite_leaders(OldUser, NewUser) -> %% set any process that had a reference to the old user's group leader to the %% new user process. Catch the race condition when the Pid exited after the %% liveness check. @@ -154,6 +183,7 @@ setup_shell() -> hope_for_best end. + setup_paths(State) -> %% Add deps to path code:add_pathsa(rebar_state:code_paths(State, all_deps)), |