summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/rebar_shell.erl30
1 files changed, 26 insertions, 4 deletions
diff --git a/src/rebar_shell.erl b/src/rebar_shell.erl
index 348e540..0220a79 100644
--- a/src/rebar_shell.erl
+++ b/src/rebar_shell.erl
@@ -41,10 +41,20 @@
shell(_Config, _AppFile) ->
true = code:add_pathz(rebar_utils:ebin_dir()),
+ %% scan all processes for any with references to the old user and save them to
+ %% update later
+ NeedsUpdate = [Pid || Pid <- erlang:processes(),
+ proplists:get_value(group_leader, erlang:process_info(Pid)) == whereis(user)
+ ],
%% terminate the current user
ok = supervisor:terminate_child(kernel_sup, user),
%% start a new shell (this also starts a new user under the correct group)
- user_drv:start(),
+ _ = user_drv:start(),
+ %% wait until user_drv and user have been registered (max 3 seconds)
+ ok = wait_until_user_started(3000),
+ %% set any process that had a reference to the old user's group leader to the
+ %% new user process
+ _ = [erlang:group_leader(whereis(user), Pid) || Pid <- NeedsUpdate],
%% enable error_logger's tty output
ok = error_logger:swap_handler(tty),
%% disable the simple error_logger (which may have been added multiple
@@ -56,9 +66,10 @@ shell(_Config, _AppFile) ->
info(help, shell) ->
?CONSOLE(
- "Start a shell with project and deps preloaded similar to~n"
- "'erl -pa ebin -pa deps/*/ebin'.~n",
- []).
+ "Start a shell with project and deps preloaded similar to~n"
+ "'erl -pa ebin -pa deps/*/ebin'.~n",
+ []
+ ).
remove_error_handler(0) ->
?WARN("Unable to remove simple error_logger handler~n", []);
@@ -66,4 +77,15 @@ remove_error_handler(N) ->
case gen_event:delete_handler(error_logger, error_logger, []) of
{error, module_not_found} -> ok;
{error_logger, _} -> remove_error_handler(N-1)
+ end.
+
+%% Timeout is a period to wait before giving up
+wait_until_user_started(0) ->
+ ?ABORT("Timeout exceeded waiting for `user` to register itself~n", []),
+ erlang:error(timeout);
+wait_until_user_started(Timeout) ->
+ case whereis(user) of
+ %% if user is not yet registered wait a tenth of a second and try again
+ undefined -> timer:sleep(100), wait_until_user_started(Timeout - 100);
+ _ -> ok
end. \ No newline at end of file