Skip to content

Commit

Permalink
kernel: Fix loading of prim_tty nif in embedded mode
Browse files Browse the repository at this point in the history
When running in embedded mode the on_load function is called
by the init process after the user processes are started. So
we add a way for user to call the on_load function earlier
in the boot sequence so that the shell can be started when
it should.

We cannot move the on_load calls for all modules to an earlier
place in the kernel boot sequence as the code in on_load may
depend on kernel services being started.
  • Loading branch information
garazdawi committed Aug 30, 2022
1 parent a286329 commit cf981d3
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 5 deletions.
Binary file modified erts/preloaded/ebin/init.beam
Binary file not shown.
20 changes: 15 additions & 5 deletions erts/preloaded/src/init.erl
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
get_argument/1,script_id/0,script_name/0]).

%% for the on_load functionality; not for general use
-export([run_on_load_handlers/0]).
-export([run_on_load_handlers/0, run_on_load_handlers/1]).

%% internal exports
-export([fetch_loaded/0,ensure_loaded/1,make_permanent/2,
Expand Down Expand Up @@ -1463,8 +1463,11 @@ archive_extension() ->
%%%

run_on_load_handlers() ->
run_on_load_handlers(all).

run_on_load_handlers(Mods) when is_list(Mods); Mods =:= all ->
Ref = monitor(process, ?ON_LOAD_HANDLER),
catch ?ON_LOAD_HANDLER ! run_on_load,
catch ?ON_LOAD_HANDLER ! {run_on_load, self(), Ref, Mods},
receive
{'DOWN',Ref,process,_,noproc} ->
%% There is no on_load handler process,
Expand All @@ -1477,7 +1480,9 @@ run_on_load_handlers() ->
{'DOWN',Ref,process,_,Res} ->
%% Failure to run an on_load handler.
%% This is fatal during start-up.
exit(Res)
exit(Res);
{reply, Ref, on_load_done} ->
ok
end.

start_on_load_handler_process() ->
Expand All @@ -1493,9 +1498,14 @@ on_load_loop(Mods, Debug0) ->
on_load_loop(Mods, Debug);
{loaded,Mod} ->
on_load_loop([Mod|Mods], Debug0);
run_on_load ->
{run_on_load, _, _, all} ->
run_on_load_handlers(Mods, Debug0),
exit(on_load_done)
exit(on_load_done);
{run_on_load, From, Ref, ModsToRun} ->
[run_on_load_handlers([Mod], Debug0)
|| Mod <- ModsToRun, lists:member(Mod, Mods)],
From ! {reply, Ref, on_load_done},
on_load_loop(Mods -- ModsToRun, Debug0)
end.

run_on_load_handlers([M|Ms], Debug) ->
Expand Down
3 changes: 3 additions & 0 deletions lib/kernel/src/user_drv.erl
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ callback_mode() -> state_functions.
-spec init(arguments()) -> gen_statem:init_result(init).
init(Args) ->
process_flag(trap_exit, true),
%% When running in embedded mode we need to call prim_tty:on_load manually here
%% as the automatic call happens after user is started.
ok = init:run_on_load_handlers([prim_tty]),
IsTTY = prim_tty:isatty(stdin) =:= true andalso prim_tty:isatty(stdout) =:= true,
StartShell = maps:get(initial_shell, Args, undefined) =/= noshell,
try
Expand Down

0 comments on commit cf981d3

Please sign in to comment.