From c5b60bcda55abd19a9d1546fb02b95fcfb08385f Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Fri, 9 Jun 2023 08:13:34 +0200 Subject: [PATCH 1/7] Revert "Merge pull request #6881 from sile/fix-escript-binary-stdin-bug" This reverts commit 4e668b984ef53a6942d857aea82ebccce375e61a, reversing changes made to cfc86388f0536bb660728f1bc4784b90251e9a11. --- lib/kernel/src/group.erl | 4 +--- lib/stdlib/src/io_lib.erl | 24 ++++++++++++++++-------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/lib/kernel/src/group.erl b/lib/kernel/src/group.erl index ca7251d7ecca..b104a710d03d 100644 --- a/lib/kernel/src/group.erl +++ b/lib/kernel/src/group.erl @@ -537,10 +537,8 @@ get_chars_apply(Pbs, M, F, Xa, Drv, Shell, Buf, State0, LineCont, Encoding) -> get_chars_n_loop(Pbs, M, F, Xa, Drv, Shell, Buf0, State, Encoding) -> try M:F(State, cast(Buf0, get(read_mode), Encoding), Encoding, Xa) of - {stop,Result,eof} -> - {ok,Result,eof}; {stop,Result,Rest} -> - {ok,Result,append(Rest, [], Encoding)}; + {ok, Result, Rest}; State1 -> case get_chars_echo_off(Pbs, Drv, Shell) of interrupted -> diff --git a/lib/stdlib/src/io_lib.erl b/lib/stdlib/src/io_lib.erl index 5f45165968f2..7268fccc77bc 100644 --- a/lib/stdlib/src/io_lib.erl +++ b/lib/stdlib/src/io_lib.erl @@ -809,19 +809,23 @@ collect_chars(Tag, Data, N) -> %% Now we are aware of encoding... collect_chars(start, Data, unicode, N) when is_binary(Data), is_integer(N) -> {Size,Npos} = count_and_find_utf8(Data,N), - if Size >= N -> + if Size > N -> {B1,B2} = split_binary(Data, Npos), {stop,B1,B2}; Size < N -> - {binary,[Data],N-Size} + {binary,[Data],N-Size}; + true -> + {stop,Data,eof} end; collect_chars(start, Data, latin1, N) when is_binary(Data), is_integer(N) -> Size = byte_size(Data), - if Size >= N -> + if Size > N -> {B1,B2} = split_binary(Data, N), {stop,B1,B2}; Size < N -> - {binary,[Data],N-Size} + {binary,[Data],N-Size}; + true -> + {stop,Data,eof} end; collect_chars(start,Data,_,N) when is_list(Data), is_integer(N) -> collect_chars_list([], N, Data); @@ -831,19 +835,23 @@ collect_chars({binary,Stack,_N}, eof, _,_) -> {stop,binrev(Stack),eof}; collect_chars({binary,Stack,N}, Data,unicode, _) when is_integer(N) -> {Size,Npos} = count_and_find_utf8(Data,N), - if Size >= N -> + if Size > N -> {B1,B2} = split_binary(Data, Npos), {stop,binrev(Stack, [B1]),B2}; Size < N -> - {binary,[Data|Stack],N-Size} + {binary,[Data|Stack],N-Size}; + true -> + {stop,binrev(Stack, [Data]),eof} end; collect_chars({binary,Stack,N}, Data,latin1, _) when is_integer(N) -> Size = byte_size(Data), - if Size >= N -> + if Size > N -> {B1,B2} = split_binary(Data, N), {stop,binrev(Stack, [B1]),B2}; Size < N -> - {binary,[Data|Stack],N-Size} + {binary,[Data|Stack],N-Size}; + true -> + {stop,binrev(Stack, [Data]),eof} end; collect_chars({list,Stack,N}, Data, _,_) when is_integer(N) -> collect_chars_list(Stack, N, Data); From c4a03418d2955ab00add62386132fe2bc88a28a6 Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Fri, 9 Jun 2023 14:17:01 +0200 Subject: [PATCH 2/7] stdlib: Fix eof handling in io_lib:collect_chars Various eof scenarios when group is using io_lib:collect_chars was not handled correctly and thus when "oldshell" was changed to be handled by group it broke some existing usages. fixes #7368 fixes #6881 fixes #7286 --- lib/stdlib/src/io_lib.erl | 12 ++- lib/stdlib/test/io_proto_SUITE.erl | 115 ++++++++++++++++++++++++++++- 2 files changed, 120 insertions(+), 7 deletions(-) diff --git a/lib/stdlib/src/io_lib.erl b/lib/stdlib/src/io_lib.erl index 7268fccc77bc..87010361c050 100644 --- a/lib/stdlib/src/io_lib.erl +++ b/lib/stdlib/src/io_lib.erl @@ -815,7 +815,7 @@ collect_chars(start, Data, unicode, N) when is_binary(Data), is_integer(N) -> Size < N -> {binary,[Data],N-Size}; true -> - {stop,Data,eof} + {stop,Data,<<>>} end; collect_chars(start, Data, latin1, N) when is_binary(Data), is_integer(N) -> Size = byte_size(Data), @@ -825,12 +825,14 @@ collect_chars(start, Data, latin1, N) when is_binary(Data), is_integer(N) -> Size < N -> {binary,[Data],N-Size}; true -> - {stop,Data,eof} + {stop,Data,<<>>} end; collect_chars(start,Data,_,N) when is_list(Data), is_integer(N) -> collect_chars_list([], N, Data); collect_chars(start, eof, _,_) -> {stop,eof,eof}; +collect_chars({binary,[<<>>],_N}, eof, _,_) -> + {stop,eof,eof}; collect_chars({binary,Stack,_N}, eof, _,_) -> {stop,binrev(Stack),eof}; collect_chars({binary,Stack,N}, Data,unicode, _) when is_integer(N) -> @@ -841,7 +843,7 @@ collect_chars({binary,Stack,N}, Data,unicode, _) when is_integer(N) -> Size < N -> {binary,[Data|Stack],N-Size}; true -> - {stop,binrev(Stack, [Data]),eof} + {stop,binrev(Stack, [Data]),<<>>} end; collect_chars({binary,Stack,N}, Data,latin1, _) when is_integer(N) -> Size = byte_size(Data), @@ -851,7 +853,7 @@ collect_chars({binary,Stack,N}, Data,latin1, _) when is_integer(N) -> Size < N -> {binary,[Data|Stack],N-Size}; true -> - {stop,binrev(Stack, [Data]),eof} + {stop,binrev(Stack, [Data]),<<>>} end; collect_chars({list,Stack,N}, Data, _,_) when is_integer(N) -> collect_chars_list(Stack, N, Data); @@ -879,6 +881,8 @@ collect_chars1(N, [], Stack) -> collect_chars_list(Stack, 0, Data) -> {stop,lists:reverse(Stack, []),Data}; +collect_chars_list([], _N, eof) -> + {stop,eof,eof}; collect_chars_list(Stack, _N, eof) -> {stop,lists:reverse(Stack, []),eof}; collect_chars_list(Stack, N, []) -> diff --git a/lib/stdlib/test/io_proto_SUITE.erl b/lib/stdlib/test/io_proto_SUITE.erl index 368fdbdf0135..13457fe61caa 100644 --- a/lib/stdlib/test/io_proto_SUITE.erl +++ b/lib/stdlib/test/io_proto_SUITE.erl @@ -25,7 +25,10 @@ -export([setopts_getopts/1,unicode_options/1,unicode_options_gen/1, binary_options/1, read_modes_gl/1, read_modes_ogl/1, broken_unicode/1,eof_on_pipe/1, - unicode_prompt/1, shell_slogan/1, raw_stdout/1, raw_stdout_isatty/1]). + unicode_prompt/1, shell_slogan/1, raw_stdout/1, raw_stdout_isatty/1, + file_read_stdin_binary_mode/1, file_read_stdin_list_mode/1, + io_get_chars_stdin_binary_mode/1, io_get_chars_stdin_list_mode/1 + ]). -export([io_server_proxy/1,start_io_server_proxy/0, proxy_getall/1, @@ -35,7 +38,7 @@ -export([uprompt/1, slogan/0, session_slogan/0]). --export([write_raw_to_stdout/0]). +-export([write_raw_to_stdout/0, read_raw_from_stdin/1]). %%-define(debug, true). @@ -53,7 +56,13 @@ all() -> [setopts_getopts, unicode_options, unicode_options_gen, binary_options, read_modes_gl, read_modes_ogl, broken_unicode, eof_on_pipe, unicode_prompt, - shell_slogan, raw_stdout, raw_stdout_isatty]. + shell_slogan, raw_stdout, raw_stdout_isatty, + file_read_stdin_binary_mode, + file_read_stdin_list_mode, + io_get_chars_stdin_binary_mode, + io_get_chars_stdin_list_mode + + ]. groups() -> []. @@ -269,6 +278,106 @@ setopts_getopts(Config) when is_list(Config) -> ],[],"",["-oldshell"]), ok. +%% Test that reading from stdin using file:read works when io is in binary mode +file_read_stdin_binary_mode(_Config) -> + {ok, P, ErlPort} = start_stdin_node(fun() -> file:read(standard_io, 3) end, [binary]), + + erlang:port_command(ErlPort, "abc"), + {ok, "got: <<\"abc\">>\n"} = gen_tcp:recv(P, 0), + erlang:port_command(ErlPort, "def"), + {ok, "got: <<\"def\">>\n"} = gen_tcp:recv(P, 0), + ErlPort ! {self(), close}, + {ok, "got: eof"} = gen_tcp:recv(P, 0), + + ok. + +%% Test that reading from stdin using file:read works when io is in binary mode +file_read_stdin_list_mode(_Config) -> + {ok, P, ErlPort} = start_stdin_node(fun() -> file:read(standard_io, 3) end, [list]), + + erlang:port_command(ErlPort, "abc"), + {ok, "got: \"abc\"\n"} = gen_tcp:recv(P, 0), + erlang:port_command(ErlPort, "def"), + {ok, "got: \"def\"\n"} = gen_tcp:recv(P, 0), + ErlPort ! {self(), close}, + {ok, "got: eof"} = gen_tcp:recv(P, 0), + + ok. + +%% Test that reading from stdin using file:read works when io is in binary mode +io_get_chars_stdin_binary_mode(_Config) -> + {ok, P, ErlPort} = start_stdin_node( + fun() -> + case io:get_chars(standard_io, "", 1) of + eof -> eof; + Chars -> {ok, Chars} + end + end, [binary]), + + erlang:port_command(ErlPort, "x\n"), + {ok, "got: <<\"x\">>\n"} = gen_tcp:recv(P, 0), + {ok, "got: <<\"\\n\">>\n"} = gen_tcp:recv(P, 0), + ErlPort ! {self(), close}, + {ok, "got: eof"} = gen_tcp:recv(P, 0), + + ok. + +%% Test that reading from stdin using file:read works when io is in binary mode +io_get_chars_stdin_list_mode(_Config) -> + {ok, P, ErlPort} = start_stdin_node( + fun() -> case io:get_chars(standard_io, "", 1) of + eof -> eof; + Chars -> {ok, Chars} + end + end, [list]), + + erlang:port_command(ErlPort, "x\n"), + {ok, "got: \"x\"\n"} = gen_tcp:recv(P, 0), + {ok, "got: \"\\n\"\n"} = gen_tcp:recv(P, 0), + ErlPort ! {self(), close}, + {ok, "got: eof"} = gen_tcp:recv(P, 0), + + ok. + +start_stdin_node(ReadFun, IoOptions) -> + {ok, L} = gen_tcp:listen(0,[{active, false},{packet,4}]), + {ok, Port} = inet:port(L), + Cmd = lists:append( + [ct:get_progname(), + " -noshell", + " -pa ", filename:dirname(code:which(?MODULE)), + " -s ", atom_to_list(?MODULE), " read_raw_from_stdin ", integer_to_list(Port)]), + ct:log("~p~n", [Cmd]), + ErlPort = open_port({spawn, Cmd}, [stream, eof]), + {ok, P} = gen_tcp:accept(L), + gen_tcp:send(P, term_to_binary(IoOptions)), + gen_tcp:send(P, term_to_binary(ReadFun)), + {ok, P, ErlPort}. + +read_raw_from_stdin([Port]) -> + try + dbg:tracer(file, "/home/eluklar/git/otp/trace.txt"), + dbg:p(whereis(user),[c,m]), + dbg:tpl(io_lib, x), + {ok, P} = gen_tcp:connect(localhost, list_to_integer(atom_to_list(Port)), + [binary, {packet, 4}, {active, false}]), + {ok, OptionsBin} = gen_tcp:recv(P, 0), + io:setopts(standard_io, binary_to_term(OptionsBin)), + {ok, ReadFunBin} = gen_tcp:recv(P, 0), + read_raw_from_stdin(binary_to_term(ReadFunBin), P) + catch E:R:ST -> + io:format(standard_error, "~p ~p",[Port,{E,R,ST}]) + end. +read_raw_from_stdin(ReadFun, P) -> + case ReadFun() of + eof -> + gen_tcp:send(P, "got: eof"), + init:stop(); + {ok, Char} -> + gen_tcp:send(P, unicode:characters_to_binary( + io_lib:format("got: ~p\n",[Char]))), + read_raw_from_stdin(ReadFun, P) + end. get_lc_ctype() -> case {os:type(),os:version()} of From 538bac474e3e9e97e84361ebcf476b91296cd870 Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Wed, 14 Jun 2023 14:28:17 +0200 Subject: [PATCH 3/7] kernel: group:edit_line with echo needs to handle binaries fixes #6881 --- lib/kernel/src/group.erl | 9 ++++++--- lib/stdlib/test/io_proto_SUITE.erl | 31 ++++++++++++++++++++++++------ 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/lib/kernel/src/group.erl b/lib/kernel/src/group.erl index b104a710d03d..110bd58756e0 100644 --- a/lib/kernel/src/group.erl +++ b/lib/kernel/src/group.erl @@ -497,9 +497,12 @@ get_chars_loop(Pbs, M, F, Xa, Drv, Shell, Buf0, State, LineCont0, Encoding) -> true -> get_line(Buf0, Pbs, LineCont0, Drv, Shell, Encoding); false -> - %% get_line_echo_off only deals with lists - %% and does not need encoding... - get_line_echo_off(Buf0, Pbs, Drv, Shell) + %% get_line_echo_off only deals with lists, + %% so convert to list before calling it. + get_line_echo_off( + if Buf0 =:= eof -> eof; + true -> unicode:characters_to_list(Buf0, Encoding) + end, Pbs, Drv, Shell) end, case Result of {done,LineCont1,Buf} -> diff --git a/lib/stdlib/test/io_proto_SUITE.erl b/lib/stdlib/test/io_proto_SUITE.erl index 13457fe61caa..5874b812400c 100644 --- a/lib/stdlib/test/io_proto_SUITE.erl +++ b/lib/stdlib/test/io_proto_SUITE.erl @@ -27,7 +27,8 @@ read_modes_ogl/1, broken_unicode/1,eof_on_pipe/1, unicode_prompt/1, shell_slogan/1, raw_stdout/1, raw_stdout_isatty/1, file_read_stdin_binary_mode/1, file_read_stdin_list_mode/1, - io_get_chars_stdin_binary_mode/1, io_get_chars_stdin_list_mode/1 + io_get_chars_stdin_binary_mode/1, io_get_chars_stdin_list_mode/1, + io_get_chars_file_read_stdin_binary_mode/1 ]). @@ -60,8 +61,8 @@ all() -> file_read_stdin_binary_mode, file_read_stdin_list_mode, io_get_chars_stdin_binary_mode, - io_get_chars_stdin_list_mode - + io_get_chars_stdin_list_mode, + io_get_chars_file_read_stdin_binary_mode ]. groups() -> @@ -339,6 +340,27 @@ io_get_chars_stdin_list_mode(_Config) -> ok. +%% Test that mixing io:get_chars and file:read works when stdin is in binary mode. +io_get_chars_file_read_stdin_binary_mode(_Config) -> + {ok, P, ErlPort} = start_stdin_node( + fun() -> case file:read(standard_io, 1) of + eof -> eof; + {ok, Chars} -> + case io:get_line(standard_io, "") of + eof -> Chars; + Line -> + {ok, [Chars, Line]} + end + end + end, [binary]), + + erlang:port_command(ErlPort, "1\n"), + {ok, "got: [<<\"1\">>,<<\"\\n\">>]\n"} = gen_tcp:recv(P, 0), + ErlPort ! {self(), close}, + {ok, "got: eof"} = gen_tcp:recv(P, 0), + + ok. + start_stdin_node(ReadFun, IoOptions) -> {ok, L} = gen_tcp:listen(0,[{active, false},{packet,4}]), {ok, Port} = inet:port(L), @@ -356,9 +378,6 @@ start_stdin_node(ReadFun, IoOptions) -> read_raw_from_stdin([Port]) -> try - dbg:tracer(file, "/home/eluklar/git/otp/trace.txt"), - dbg:p(whereis(user),[c,m]), - dbg:tpl(io_lib, x), {ok, P} = gen_tcp:connect(localhost, list_to_integer(atom_to_list(Port)), [binary, {packet, 4}, {active, false}]), {ok, OptionsBin} = gen_tcp:recv(P, 0), From bf1916dbbecb74c8315c83ffabf412ee36aef6d4 Mon Sep 17 00:00:00 2001 From: frazze-jobb Date: Wed, 7 Jun 2023 14:09:31 +0200 Subject: [PATCH 4/7] kernel: Support sending byte stream on standard in As group now acts as the proxy when running "oldshell" or "noshell" it needs to be able to read and write raw binaries. Latin1 encoding allows all possible bytes, so by fixing latin1 we allow any bytes to be passed into and out of Erlang unmodified. fixes #7230 --- lib/kernel/doc/src/kernel_app.xml | 20 ++++++++- lib/kernel/src/group.erl | 72 ++++++++++++++++-------------- lib/kernel/src/prim_tty.erl | 23 +++++++--- lib/kernel/src/user_drv.erl | 5 +-- lib/stdlib/test/io_proto_SUITE.erl | 47 +++++++++++++++++-- 5 files changed, 120 insertions(+), 47 deletions(-) diff --git a/lib/kernel/doc/src/kernel_app.xml b/lib/kernel/doc/src/kernel_app.xml index 17edb810020a..2f023f3daeaf 100644 --- a/lib/kernel/doc/src/kernel_app.xml +++ b/lib/kernel/doc/src/kernel_app.xml @@ -614,7 +614,25 @@ MaxT = NetTickTime + NetTickTime / NetTickIntensity

- + standard_io_encoding = Encoding + +

Set whether bytes sent or received via standard_io should be interpreted as unicode or latin1. + By default input and output is interpreted as Unicode if it is supported on the host. With this flag + you may configure the encoding on startup.

+

This works similarly to io:setopts(standard_io, {encoding, Encoding}) + but is applied before any bytes on standard_io may have been read.

+

Encoding is one of:

+ + unicode +

Configure standard_io to use unicode mode.

+ latin1 +

Configure standard_io to use latin1 mode.

+ _ +

Anything other than unicode or latin1 will be ignored and the system will + configure the encoding by itself, typically unicode on modern systems.

+
+
+
diff --git a/lib/kernel/src/group.erl b/lib/kernel/src/group.erl index 110bd58756e0..89d402896c09 100644 --- a/lib/kernel/src/group.erl +++ b/lib/kernel/src/group.erl @@ -20,6 +20,11 @@ -module(group). %% A group leader process for user io. +%% This process receives input data from user_drv in this format +%% {Drv,{data,unicode:charlist()}} +%% It then keeps that data as unicode in its state and converts it +%% to latin1/unicode on a per request basis. If any data is left after +%% a request, that data is again kept as unicode. -export([start/2, start/3, whereis_shell/0, server/4]). @@ -108,6 +113,9 @@ start_shell1(Fun) -> exit(Error) % let the group process crash end. +-spec server_loop(UserDrv :: pid(), Shell:: pid(), + Buffer :: unicode:chardata()) -> + no_return(). server_loop(Drv, Shell, Buf0) -> receive {io_request,From,ReplyAs,Req} when is_pid(From) -> @@ -499,14 +507,12 @@ get_chars_loop(Pbs, M, F, Xa, Drv, Shell, Buf0, State, LineCont0, Encoding) -> false -> %% get_line_echo_off only deals with lists, %% so convert to list before calling it. - get_line_echo_off( - if Buf0 =:= eof -> eof; - true -> unicode:characters_to_list(Buf0, Encoding) - end, Pbs, Drv, Shell) + get_line_echo_off(cast(Buf0, list, Encoding), Pbs, Drv, Shell) end, case Result of {done,LineCont1,Buf} -> - get_chars_apply(Pbs, M, F, Xa, Drv, Shell, Buf, State, LineCont1, Encoding); + get_chars_apply(Pbs, M, F, Xa, Drv, Shell, append(Buf, [], Encoding), + State, LineCont1, Encoding); interrupted -> {error,{error,interrupted},[]}; @@ -541,7 +547,7 @@ get_chars_apply(Pbs, M, F, Xa, Drv, Shell, Buf, State0, LineCont, Encoding) -> get_chars_n_loop(Pbs, M, F, Xa, Drv, Shell, Buf0, State, Encoding) -> try M:F(State, cast(Buf0, get(read_mode), Encoding), Encoding, Xa) of {stop,Result,Rest} -> - {ok, Result, Rest}; + {ok, Result, append(Rest,[],Encoding)}; State1 -> case get_chars_echo_off(Pbs, Drv, Shell) of interrupted -> @@ -605,13 +611,12 @@ get_line1({undefined,{_A,Mode,Char},Cs,Cont,Rs}, Drv, Shell, Ls0, Encoding) send_drv_reqs(Drv, edlin:erase_line()), {more_chars,Ncont,Nrs} = edlin:start(edlin:prompt(Cont)), send_drv_reqs(Drv, Nrs), - get_line1(edlin:edit_line1(string:to_graphemes(lists:sublist(Lcs, - 1, - length(Lcs)-1)), - Ncont), - Drv, - Shell, - Ls, Encoding) + get_line1( + edlin:edit_line1( + string:to_graphemes( + lists:sublist(Lcs, 1, length(Lcs)-1)), + Ncont), + Drv, Shell, Ls, Encoding) end; get_line1({undefined,{_A,Mode,Char},Cs,Cont,Rs}, Drv, Shell, Ls0, Encoding) when Mode =:= none, Char =:= $\^N; @@ -801,7 +806,8 @@ more_data(What, Cont0, Drv, Shell, Ls, Encoding) -> send_drv_reqs(Drv, edlin:redraw_line(Cont0)), more_data(What, Cont0, Drv, Shell, Ls, Encoding); {Drv,{data,Cs}} -> - get_line1(edlin:edit_line(Cs, Cont0), Drv, Shell, Ls, Encoding); + get_line1(edlin:edit_line(cast(Cs, list), Cont0), + Drv, Shell, Ls, Encoding); {Drv,eof} -> get_line1(edlin:edit_line(eof, Cont0), Drv, Shell, Ls, Encoding); {io_request,From,ReplyAs,Req} when is_pid(From) -> @@ -832,7 +838,7 @@ get_line_echo_off(Chars, Pbs, Drv, Shell) -> get_line_echo_off1({Chars,[]}, Drv, Shell) -> receive {Drv,{data,Cs}} -> - get_line_echo_off1(edit_line(Cs, Chars), Drv, Shell); + get_line_echo_off1(edit_line(cast(Cs, list), Chars), Drv, Shell); {Drv,eof} -> get_line_echo_off1(edit_line(eof, Chars), Drv, Shell); {io_request,From,ReplyAs,Req} when is_pid(From) -> @@ -861,7 +867,7 @@ get_chars_echo_off(Pbs, Drv, Shell) -> get_chars_echo_off1(Drv, Shell) -> receive {Drv, {data, Cs}} -> - Cs; + cast(Cs, list); {Drv, eof} -> eof; {io_request,From,ReplyAs,Req} when is_pid(From) -> @@ -1009,7 +1015,7 @@ get_password_line(Chars, Drv, Shell) -> get_password1({Chars,[]}, Drv, Shell) -> receive {Drv,{data,Cs}} -> - get_password1(edit_password(Cs,Chars),Drv,Shell); + get_password1(edit_password(Cs,cast(Chars,list)),Drv,Shell); {io_request,From,ReplyAs,Req} when is_pid(From) -> io_request(Req, From, ReplyAs, Drv, Shell, []), %WRONG!!! %% I guess the reason the above line is wrong is that Buf is @@ -1049,20 +1055,18 @@ edit_password([Char|Cs],Chars) -> prompt_bytes(Prompt, Encoding) -> lists:flatten(io_lib:format_prompt(Prompt, Encoding)). -cast(L, binary,latin1) when is_list(L) -> - list_to_binary(L); -cast(L, list, latin1) when is_list(L) -> - binary_to_list(list_to_binary(L)); %% Exception if not bytes -cast(L, binary,unicode) when is_list(L) -> - unicode:characters_to_binary(L,utf8); -cast(Other, _, _) -> - Other. - -append(B, L, latin1) when is_binary(B) -> - binary_to_list(B)++L; -append(B, L, unicode) when is_binary(B) -> - unicode:characters_to_list(B,utf8)++L; -append(L1, L2, _) when is_list(L1) -> - L1++L2; -append(_Eof, L, _) -> - L. +cast(Buf, Type) -> + cast(Buf, Type, utf8). +cast(eof, _, _) -> + eof; +cast(L, binary, ToEnc) -> + unicode:characters_to_binary(L, utf8, ToEnc); +cast(L, list, _ToEnc) -> + unicode:characters_to_list(L, utf8). + +append(eof, [], _) -> + eof; +append(eof, L, _) -> + L; +append(B, L, FromEnc) -> + unicode:characters_to_list(B, FromEnc) ++ L. diff --git a/lib/kernel/src/prim_tty.erl b/lib/kernel/src/prim_tty.erl index a03e746cc99f..006bd8146c1c 100644 --- a/lib/kernel/src/prim_tty.erl +++ b/lib/kernel/src/prim_tty.erl @@ -218,7 +218,7 @@ init(UserOptions) when is_map(UserOptions) -> {ok, TTY} = tty_create(), %% Initialize the locale to see if we support utf-8 or not - UnicodeMode = + UnicodeSupported = case setlocale(TTY) of primitive -> lists:any( @@ -228,6 +228,11 @@ init(UserOptions) when is_map(UserOptions) -> UnicodeLocale when is_boolean(UnicodeLocale) -> UnicodeLocale end, + IOEncoding = application:get_env(kernel, standard_io_encoding, default), + UnicodeMode = if IOEncoding =:= latin1 -> false; + IOEncoding =:= unicode -> true; + true -> UnicodeSupported + end, {ok, ANSI_RE_MP} = re:compile(?ANSI_REGEXP, [unicode]), init_term(#state{ tty = TTY, unicode = UnicodeMode, options = Options, ansi_regexp = ANSI_RE_MP }). init_term(State = #state{ tty = TTY, options = Options }) -> @@ -252,7 +257,12 @@ init_term(State = #state{ tty = TTY, options = Options }) -> ReaderState = case {maps:get(input, Options), TTYState#state.reader} of {true, undefined} -> - {ok, Reader} = proc_lib:start_link(?MODULE, reader, [[State#state.tty, self()]]), + DefaultReaderEncoding = if State#state.unicode -> utf8; + not State#state.unicode -> latin1 + end, + {ok, Reader} = proc_lib:start_link( + ?MODULE, reader, + [[State#state.tty, DefaultReaderEncoding, self()]]), WriterState#state{ reader = Reader }; {true, _} -> WriterState; @@ -421,14 +431,15 @@ call(Pid, Msg) -> {error, Reason} end. -reader([TTY, Parent]) -> +reader([TTY, Encoding, Parent]) -> register(user_drv_reader, self()), ReaderRef = make_ref(), SignalRef = make_ref(), + ok = tty_select(TTY, SignalRef, ReaderRef), proc_lib:init_ack({ok, {self(), ReaderRef}}), FromEnc = case os:type() of - {unix, _} -> utf8; + {unix, _} -> Encoding; {win32, _} -> case isatty(stdin) of true -> @@ -436,7 +447,7 @@ reader([TTY, Parent]) -> _ -> %% When not reading from a console %% the data read is utf8 encoded - utf8 + Encoding end end, reader_loop(TTY, Parent, SignalRef, ReaderRef, FromEnc, <<>>). @@ -486,7 +497,7 @@ reader_loop(TTY, Parent, SignalRef, ReaderRef, FromEnc, Acc) -> Alias ! {Alias, true} end, receive - {Parent, set_unicode_state, true} -> ok + {Parent, set_unicode_state, _} -> ok end, Latin1Chars = unicode:characters_to_binary(Error, latin1, utf8), {<>, <<>>, latin1}; diff --git a/lib/kernel/src/user_drv.erl b/lib/kernel/src/user_drv.erl index 25ebcbdd681b..0bc27e76ee88 100644 --- a/lib/kernel/src/user_drv.erl +++ b/lib/kernel/src/user_drv.erl @@ -421,8 +421,7 @@ server({call, From}, {start_shell, _Args}, _State) -> keep_state_and_data; server(info, {ReadHandle,{data,UTF8Binary}}, State = #state{ read = ReadHandle }) when State#state.current_group =:= State#state.user -> - State#state.current_group ! - {self(), {data, unicode:characters_to_list(UTF8Binary, utf8)}}, + State#state.current_group ! {self(), {data,UTF8Binary}}, keep_state_and_data; server(info, {ReadHandle,{data,UTF8Binary}}, State = #state{ read = ReadHandle }) -> case contains_ctrl_g_or_ctrl_c(UTF8Binary) of @@ -435,7 +434,7 @@ server(info, {ReadHandle,{data,UTF8Binary}}, State = #state{ read = ReadHandle } keep_state_and_data; none -> State#state.current_group ! - {self(), {data, unicode:characters_to_list(UTF8Binary, utf8)}}, + {self(), {data, UTF8Binary}}, keep_state_and_data end; server(info, {ReadHandle,eof}, State = #state{ read = ReadHandle }) -> diff --git a/lib/stdlib/test/io_proto_SUITE.erl b/lib/stdlib/test/io_proto_SUITE.erl index 5874b812400c..2e6ba632e0c0 100644 --- a/lib/stdlib/test/io_proto_SUITE.erl +++ b/lib/stdlib/test/io_proto_SUITE.erl @@ -28,7 +28,8 @@ unicode_prompt/1, shell_slogan/1, raw_stdout/1, raw_stdout_isatty/1, file_read_stdin_binary_mode/1, file_read_stdin_list_mode/1, io_get_chars_stdin_binary_mode/1, io_get_chars_stdin_list_mode/1, - io_get_chars_file_read_stdin_binary_mode/1 + io_get_chars_file_read_stdin_binary_mode/1, + file_read_stdin_latin1_mode/1 ]). @@ -62,7 +63,8 @@ all() -> file_read_stdin_list_mode, io_get_chars_stdin_binary_mode, io_get_chars_stdin_list_mode, - io_get_chars_file_read_stdin_binary_mode + io_get_chars_file_read_stdin_binary_mode, + file_read_stdin_latin1_mode ]. groups() -> @@ -361,12 +363,47 @@ io_get_chars_file_read_stdin_binary_mode(_Config) -> ok. +%% Test that reading from stdin using file:read_line works when io is not utf8 +file_read_stdin_latin1_mode(_Config) -> + {ok, P, ErlPort} = start_stdin_node( + fun() -> file:read_line(standard_io) end, + [binary], + "-kernel standard_io_encoding latin1"), + + %% Invalid utf8 + erlang:port_command(ErlPort, <<192,128,10,192,128,10,192,128,10>>), + + {ok, "got: <<192,128,10>>\n"} = gen_tcp:recv(P, 0, 5000), + {ok, "got: <<192,128,10>>\n"} = gen_tcp:recv(P, 0, 5000), + {ok, "got: <<192,128,10>>\n"} = gen_tcp:recv(P, 0, 5000), + ErlPort ! {self(), close}, + {ok, "got: eof"} = gen_tcp:recv(P, 0, 5000), + + {ok, P2, ErlPort2} = start_stdin_node( + fun() -> file:read(standard_io, 5) end, + [binary], + "-kernel standard_io_encoding latin1"), + + %% Valid utf8 + erlang:port_command(ErlPort2, <<"duπaduπaduπa"/utf8>>), + + {ok, "got: <<100,117,207,128,97>>\n"} = gen_tcp:recv(P2, 0, 5000), + {ok, "got: <<100,117,207,128,97>>\n"} = gen_tcp:recv(P2, 0, 5000), + {ok, "got: <<100,117,207,128,97>>\n"} = gen_tcp:recv(P2, 0, 5000), + ErlPort2 ! {self(), close}, + {ok, "got: eof"} = gen_tcp:recv(P2, 0, 5000), + + ok. + start_stdin_node(ReadFun, IoOptions) -> + start_stdin_node(ReadFun, IoOptions, ""). +start_stdin_node(ReadFun, IoOptions, ExtraArgs) -> {ok, L} = gen_tcp:listen(0,[{active, false},{packet,4}]), {ok, Port} = inet:port(L), Cmd = lists:append( [ct:get_progname(), - " -noshell", + " -noshell ", + ExtraArgs, " -pa ", filename:dirname(code:which(?MODULE)), " -s ", atom_to_list(?MODULE), " read_raw_from_stdin ", integer_to_list(Port)]), ct:log("~p~n", [Cmd]), @@ -383,6 +420,10 @@ read_raw_from_stdin([Port]) -> {ok, OptionsBin} = gen_tcp:recv(P, 0), io:setopts(standard_io, binary_to_term(OptionsBin)), {ok, ReadFunBin} = gen_tcp:recv(P, 0), + spawn(fun() -> + gen_tcp:recv(P, 0), + init:stop("crash") + end), read_raw_from_stdin(binary_to_term(ReadFunBin), P) catch E:R:ST -> io:format(standard_error, "~p ~p",[Port,{E,R,ST}]) From 13355a65101f4d6a029b89bb19a82914bf854d41 Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Fri, 16 Jun 2023 10:46:46 +0200 Subject: [PATCH 5/7] kernel: Make group and prim_tty not get purged by cover --- lib/kernel/src/group.erl | 14 ++++++++------ lib/kernel/src/prim_tty.erl | 22 ++++++++++++---------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/lib/kernel/src/group.erl b/lib/kernel/src/group.erl index 89d402896c09..53beae6e4fe1 100644 --- a/lib/kernel/src/group.erl +++ b/lib/kernel/src/group.erl @@ -28,6 +28,8 @@ -export([start/2, start/3, whereis_shell/0, server/4]). +-export([server_loop/3]). + start(Drv, Shell) -> start(Drv, Shell, []). @@ -122,20 +124,20 @@ server_loop(Drv, Shell, Buf0) -> %% This io_request may cause a transition to a couple of %% selective receive loops elsewhere in this module. Buf = io_request(Req, From, ReplyAs, Drv, Shell, Buf0), - server_loop(Drv, Shell, Buf); + ?MODULE:server_loop(Drv, Shell, Buf); {reply,{From,ReplyAs},Reply} -> io_reply(From, ReplyAs, Reply), - server_loop(Drv, Shell, Buf0); + ?MODULE:server_loop(Drv, Shell, Buf0); {driver_id,ReplyTo} -> ReplyTo ! {self(),driver_id,Drv}, - server_loop(Drv, Shell, Buf0); + ?MODULE:server_loop(Drv, Shell, Buf0); {Drv, echo, Bool} -> put(echo, Bool), - server_loop(Drv, Shell, Buf0); + ?MODULE:server_loop(Drv, Shell, Buf0); {'EXIT',Drv,interrupt} -> %% Send interrupt to the shell. exit_shell(interrupt), - server_loop(Drv, Shell, Buf0); + ?MODULE:server_loop(Drv, Shell, Buf0); {'EXIT',Drv,R} -> exit(R); {'EXIT',Shell,R} -> @@ -147,7 +149,7 @@ server_loop(Drv, Shell, Buf0) -> (tuple_size(NotDrvTuple) =/= 2) orelse (element(1, NotDrvTuple) =/= Drv) -> %% Ignore this unknown message. - server_loop(Drv, Shell, Buf0) + ?MODULE:server_loop(Drv, Shell, Buf0) end. exit_shell(Reason) -> diff --git a/lib/kernel/src/prim_tty.erl b/lib/kernel/src/prim_tty.erl index 006bd8146c1c..1319b75e23f9 100644 --- a/lib/kernel/src/prim_tty.erl +++ b/lib/kernel/src/prim_tty.erl @@ -115,6 +115,8 @@ sizeof_wchar/0, tgetent_nif/1, tgetnum_nif/1, tgetflag_nif/1, tgetstr_nif/1, tgoto_nif/2, tgoto_nif/3, tty_read_signal/2]). +-export([reader_loop/6, writer_loop/2]). + %% Exported in order to remove "unused function" warning -export([sizeof_wchar/0, wcswidth/1, tgoto/2, tgoto/3]). @@ -459,20 +461,20 @@ reader_loop(TTY, Parent, SignalRef, ReaderRef, FromEnc, Acc) -> receive {EnableAlias, enable} -> EnableAlias ! {EnableAlias, ok}, - reader_loop(TTY, Parent, SignalRef, ReaderRef, FromEnc, Acc) + ?MODULE:reader_loop(TTY, Parent, SignalRef, ReaderRef, FromEnc, Acc) end; {select, TTY, SignalRef, ready_input} -> {ok, Signal} = tty_read_signal(TTY, SignalRef), Parent ! {ReaderRef,{signal,Signal}}, - reader_loop(TTY, Parent, SignalRef, ReaderRef, FromEnc, Acc); + ?MODULE:reader_loop(TTY, Parent, SignalRef, ReaderRef, FromEnc, Acc); {Alias, {set_unicode_state, _}} when FromEnc =:= {utf16, little} -> %% Ignore requests on windows Alias ! {Alias, true}, - reader_loop(TTY, Parent, SignalRef, ReaderRef, FromEnc, Acc); + ?MODULE:reader_loop(TTY, Parent, SignalRef, ReaderRef, FromEnc, Acc); {Alias, {set_unicode_state, Bool}} -> Alias ! {Alias, FromEnc =/= latin1}, NewFromEnc = if Bool -> utf8; not Bool -> latin1 end, - reader_loop(TTY, Parent, SignalRef, ReaderRef, NewFromEnc, Acc); + ?MODULE:reader_loop(TTY, Parent, SignalRef, ReaderRef, NewFromEnc, Acc); {_Alias, stop} -> ok; {select, TTY, ReaderRef, ready_input} -> @@ -482,7 +484,7 @@ reader_loop(TTY, Parent, SignalRef, ReaderRef, FromEnc, Acc) -> ok; {ok, <<>>} -> %% EAGAIN or EINTR - reader_loop(TTY, Parent, SignalRef, ReaderRef, FromEnc, Acc); + ?MODULE:reader_loop(TTY, Parent, SignalRef, ReaderRef, FromEnc, Acc); {ok, UtfXBytes} -> {Bytes, NewAcc, NewFromEnc} = @@ -507,7 +509,7 @@ reader_loop(TTY, Parent, SignalRef, ReaderRef, FromEnc, Acc) -> {B, <<>>, FromEnc} end, Parent ! {ReaderRef, {data, Bytes}}, - reader_loop(TTY, Parent, SignalRef, ReaderRef, NewFromEnc, NewAcc) + ?MODULE:reader_loop(TTY, Parent, SignalRef, ReaderRef, NewFromEnc, NewAcc) end end. @@ -529,18 +531,18 @@ write(#state{ writer = {WriterPid, _WriterRef}}, Chars, From) -> writer_loop(TTY, WriterRef) -> receive {write, []} -> - writer_loop(TTY, WriterRef); + ?MODULE:writer_loop(TTY, WriterRef); {write, Chars} -> _ = write_nif(TTY, Chars), - writer_loop(TTY, WriterRef); + ?MODULE:writer_loop(TTY, WriterRef); {write, From, []} -> From ! {WriterRef, ok}, - writer_loop(TTY, WriterRef); + ?MODULE:writer_loop(TTY, WriterRef); {write, From, Chars} -> case write_nif(TTY, Chars) of ok -> From ! {WriterRef, ok}, - writer_loop(TTY, WriterRef); + ?MODULE:writer_loop(TTY, WriterRef); {error, Reason} -> exit(self(), Reason) end From 9a50bd82b1b6f0645388744de0b95e6620ac62c8 Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Fri, 16 Jun 2023 10:47:34 +0200 Subject: [PATCH 6/7] tty: Add cover spec for tty --- lib/kernel/test/Makefile | 2 +- lib/kernel/test/tty.cover | 3 +++ lib/stdlib/test/Makefile | 2 +- lib/stdlib/test/tty.cover | 1 + 4 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 lib/kernel/test/tty.cover create mode 120000 lib/stdlib/test/tty.cover diff --git a/lib/kernel/test/Makefile b/lib/kernel/test/Makefile index 0d88e3555e25..1d1c17776d92 100644 --- a/lib/kernel/test/Makefile +++ b/lib/kernel/test/Makefile @@ -150,7 +150,7 @@ TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) INSTALL_PROGS= $(TARGET_FILES) EMAKEFILE=Emakefile -COVERFILE=kernel.cover logger.cover +COVERFILE=kernel.cover logger.cover tty.cover # ---------------------------------------------------- # Release directory specification diff --git a/lib/kernel/test/tty.cover b/lib/kernel/test/tty.cover new file mode 100644 index 000000000000..cf4d26ea8e1a --- /dev/null +++ b/lib/kernel/test/tty.cover @@ -0,0 +1,3 @@ +%% -*- erlang -*- +{incl_mods,[prim_tty, user_drv, group, shell, edlin, edlin_expand, io_lib]}. + diff --git a/lib/stdlib/test/Makefile b/lib/stdlib/test/Makefile index 259715700448..98a7a03caa63 100644 --- a/lib/stdlib/test/Makefile +++ b/lib/stdlib/test/Makefile @@ -133,7 +133,7 @@ ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS)) EBIN = . EMAKEFILE=Emakefile -COVERFILE=stdlib.cover +COVERFILE=stdlib.cover tty.cover # ---------------------------------------------------- # Targets diff --git a/lib/stdlib/test/tty.cover b/lib/stdlib/test/tty.cover new file mode 120000 index 000000000000..841833897bae --- /dev/null +++ b/lib/stdlib/test/tty.cover @@ -0,0 +1 @@ +../../../lib/kernel/test/tty.cover \ No newline at end of file From 2b1ce5dc22b3a07db72565036f0739aad034c9c9 Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Thu, 15 Jun 2023 15:22:47 +0200 Subject: [PATCH 7/7] Update primary bootstrap --- bootstrap/lib/kernel/ebin/group.beam | Bin 15436 -> 16756 bytes bootstrap/lib/kernel/ebin/prim_tty.beam | Bin 14492 -> 21672 bytes bootstrap/lib/kernel/ebin/user_drv.beam | Bin 16884 -> 17616 bytes bootstrap/lib/stdlib/ebin/io_lib.beam | Bin 14232 -> 14424 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/bootstrap/lib/kernel/ebin/group.beam b/bootstrap/lib/kernel/ebin/group.beam index 73c53767c409d06f7a09e36deb39af3a6e93366f..1ee8fa4aac04027152a4c293b4d0af31146598e9 100644 GIT binary patch literal 16756 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 literal 15436 zcmbtbd3+ni_1AjW_ITrgjaP~7B#?y_WIrGM z1{}apjzCgiIhup?NTDSqPpk_A~Tp>qZRYR>AGURKbJ^f zHCU|A<%ckQ7BTUpld3cwiu%ufx<_ z2AzdEpiivt&kUzEdaui;`%{UvL#Z?y2L41Uzg|yYmFv%@5(C3oEuCC7R9|{ukz6%xYA{(G9Lo0RH;xfMm>n3Zmb0~VK9|&z z{h7=J$t54AN{zJos-ZRY745UD`*XR>MvXX8Gn_5-52Ppf97|+|hI0DgP$HjRHw>;; z=hHN>WBJ)Vb%WVrI-eiT73)&@L2x%Qn8Nx7i#{%cm{BZlOsq@~txXp}W#vn4ad2&V zXt+3$Mh#~NlUQE@6cy7G3x~EeNJ#1Y+QDpp#vfFh9r6iTGnmQfAcOjf>6DbfaJD#@ zsR7NI!4-87Wg@w%KVPWH^cM%SvujJpjv4Dn6gFm)+Hi58B}fDNlK@vp6o(Qk05iX_ z8fzTNOTZEiPYz`=>0}8iBicwA>dVdYg<8kfO)t6rLSe&DKE+CWEYxC|L%Cw17W0PJ zW(!(=XhWeEL#c7XIKvA}*1>dENJDd=M7&%fp%jiSsZcr#9u8(#1`ES03dO%^JLS7_F;n_!ke2gnV9#rF#UPZnKaoifK%dtoRzNS-q>J@sU<6-Vkxu7oGU@Ef;wr_hmM)+c z+^32@M$YVpLb^YnT$NZi3<7=Fa7WZs z%tOX-UW02@7*%&3*V<3fv&;PuG_y8W@6ugrSd- zSDR16jtl7t`E)AZzd^D?BX3YA8BL7R=to*DK}wJlOAHMRNG&+1WwvbcMOYqXj*Gk8 zG`k_6UfVwiN1adf4?w9B*^Csv1Xl7A)!=D%4TF0lf4s3So8CZvAi0J@KynQm&iSuU zTDW)FR#)g>@5^&c9}1k%gKKhKg}NNPvm9F$4jW^`OI}^=Po<76v8D`O1NszPkK{8$ z>=*=DE8(yt1IKYo_KcYXEkt52x6I~JIm)l(y`gW36&s7`0x!wiZ>vQ#Di+gOIPyaA z7}Be8zjTamy3{}&HLxG}hX!K!xC^7635Y<$nRJ4JgS5Ab_v76o+4ii{U09bJaogdQ z1A$qOBjy??^!H>SpxlG!BE|5Gs)iFS#S&F^O{7DKcoyCxil_@j^=e~9d-$UEyr^nd zx{MuN9ntn^hh1fNn6}xWnrcT>wZ%=QXi&Y#vWTVhd7`S}CZXi&g%D9q*g;{2gc=jO zO!1`Zb=6vtnKuVJ10rTV-e|!X^oQhKlE8k4?cE zoQT32>$@V4H(FYJOfA5_x&Xwj2@}Ak0_vhTZxTV91RPTzZ;S*(F^^5Fjj)LdYg!x^ zYJ4_tj?*Mf9Ti~pab;4DKZum+6{IwaIG|h1U=3Xgo8qw(h#)XCn9#VV#P#_-T=eq5+Tg#{`?WhzcOh>DXds5nl9K*bEA0#J_k zm;)+iqB^}k5)n375CmL>S&jTuwUwXZi`!}Jv-pe%KT+@#6m~*ceqrvIx;vXYwy@1f z5Iz(j0@-wnV7mxKM-9tkr)Yh=y<|;6slJxNPAo$pg$Z-p)K6>WwmlEU0w@txC$*UY zyUjF6IXrf%7U9KThA<{U61&aDh^fyG z!59F3R`5{R&OETx!ZbCEN~np08K+D-bkwQM)E@R&1j0GpP}oekK>Y-ua?QNhMGEcK z2dq6Rj9@lY$_yy%G>@H*(NT<^#f?bGPC$>P>M?00(V)U2jr??ob+$SWB~q3`n9sKL z7=BF+0#PSP)0y4G!Q|7Y@W^iuOcwea-=Lx%ivi6UKodI@%^4ES9H5!g$mash89;MJ zC7LsA{fsa_qY}*-O?-~R=1$>r2u-KuqiONj89*}^Y-r_%uzag0?yCA+>1f$p;F;IR z7XZ(E;F&*$2dtfsQTR1AY5#IL^PBiQg)NxE=T$Cep~qT)rv=Mdbm($g#26Z=pRn~7{8lbUH1Wj>TQY?&u3S!=$L0Zz+o!O09*Ok9noCiM1Z3Kx-4@;L zdrWY5zShOhkv{gUMq%+YBRsCKcv(^qj~3<~rar?r1)+sT$?_NY2I4cXS|L z8+TYd9pRS=zPyVs?c?Vv>|9`ohIu}!FEB(G90DSO=x$THlDnggk!W`kcnhRv!tNIO z0<1kL%yywKG;22TPbh3D=3}^laTdl!MlfBS-_7%l7|nb2Mf^O4oi{%z8y52mb-|Y@ zY*~HZ7H~B#Ml{hL6w#0{V~cwD`C>%I@d8$~#P{FlFYcMcyHumg0PlsqM2EkFmlwgF z(JpYZ4FUW{BNEuHHd=bCCUvI^@!$fXx53=nYb^$ixL|R74!`)QK;lOLa^aCF?5?1& z!>6#DDC|*%zStzHEa9;;32i0G8e+m|1oU@1(&i~c*kXCDE`#YWC& zLRCtxI1- z(@L{06>3zf!I`!ws3KW7NEsei*kzSqr4sb%9XzFX@+81suCU9;6d?gcxI$r9)OT$X z?V5;|az3!)N)jF5d+Z#a8&?uHRvaX~AmWP9;xd?@djxJI=J38keWU_3NrzxAJybM4 zDBmv6I|8V_!zt{SvL`2QMi}WKccYJ~Xf!DqGdEc|j-wGe{IrAZt!RNr#fR*b&j@X>*TM`sN|Di2-njQI11 zO6bqw>-6(^PGLDBx!tU>_zs1w6P=>8lzf@=cxP8TxL)wsg>aW$aF@jvevP_B?S{)V zEq*O|^{XO$SYgA+agt$vZEw=hXCT+1dQzWJFZw7K^}U!Ki}CfUh(#Cj4GLQ?@==9t zXfv($QhM4AHgr?SK)xknHtiFTdtsjdo(qLtRe_@QFu)sqz*j45qXc|4h^PeIb9BJh z#CQQw;aac*tG&)+7h$y*L=<*?nBSo0OKJBFJRl+zwe<^3+hZ38shzeX3_F%y%(&1} z*o{08vFZXgg+d!HYx(%7n>=<2Ms;J&yR|+5cX=6<;19kq8Cj2E?0ZGRF zAmcueai7BOqwRQkXR`{BTNm;N6m~zz8gCz@c7;7as3xnDQhhn01h+#%Uk>=Iffn!| zg0L^;5ANcg!aVcVN3484r7GEjV)pH1QFn-U2xr zq^o0-&$7T@;2%&Y8gnB7!w6W0@mN4@L~=!n{sH;B-D5+TemUn&px{&Wu*iI6Q!ge8t-yMUFH>r}%YMwue0lO9Us6Sx0(P!)qVL-DSFvc8p zcMy%sRnY_5a!@oR_8)|zAm@9GbW?Uhdq|Z!V=J!kJJYudrVvIN(x%UO}Fwry=s^5mQBj| zeAjIHjM)?BA651FqH~M?{!!7n!>>K&u_9phZBp3d6e|mwNCriBNVLa9G%gBI#9_^H zuakTs4Szz4{^Ps&#}xK45lo6uw}`cicvPHN5IS-TZG`g6>MeX z6F{jcU(QhFPs{Z@y^BAku%{3mMR!!BOfk|fl91`u@XFs=$UmvDr>PGe=%$WqG~sfE zeX^B51HK~`B6YTsB3KybhfkBxwu+Qmy@P)?r?6+j{8ME)^jh%+@Y|~*6-LMwrXM|C<-BwjEU~JXzvlxl(36J-ApT(Y%bcyKPR@@Vgxi@4@J0v z_P41hxY15VQ|v~rMdq6m3j5sRZ9?7F%Aeh~pm&?apQY%yKf*t+u+O(`qh0c|s-9}w zW^8WTW^D`eFKpA(W45_jPdDrUonHv^FZLD1O!k@F2I?wdedt&(2hS)X8!jT}lOvd2w6krm1e;T56J3$gzl zA^Aa_p_%{VvCWXq05t1MN6;+azf3k)rT90*h%FW6=CV*A4H${M9$h>+wQxuIJzU^*20>rm{K{A>Dr z{#Av2RhmA*`r4SveSKV2)uc3CXm4r7J+$I4L1VwMI)yHfZja_lTps-|T>hrVZUci> zMHKd}Fn~;+8>{8fw>btsRL@(!IIP{ZA=lc-F zo451tf=7ekkp>=-7J2LrgsKrzsW@qO9BSsVI}!P(NGW3*3V*MXph@$v@6p=*^F^d; z&%+YF>#_IYw3Qw3*j=Du4QP12l^^go+6Nl@BK&uP|F(;NPhsDy+!d9!$XmnwrS5zy zeEf>B?y zN_=~viT^-hKWwJo7sLD~kLr2+?yFm(upiZL!a6NYI;)YGXpf6%kFZn1ESA@LpQMPy zcRwgOzD%WiE(Fz%Re>M_CoVq@>KUQKtgSv7S05lI&@l_ne`$a29fi0b1AVARs>g$6 zE);z((802SW95g&x$yTA7kVTYiXiG?BF|%wTw5Jr(}U`D)dsVA)xL?gm`FL2(BQhd zaB6S@sS?hD3;{w;Bo>i&k^Pmp^pi0EDHLHQ|JlA*6!z0F|Apk!FZR{7DePzeH=jN* z#;5Iv@u_p1Pd`6|Pdg6b)6S#t>F48o+I18@Jvz>(e;mfA-9Dc_`2Xh9FJMOC6MpyA zHNZ?L`8cwbd`NPH^!vkQiVxB6j}XPAQTo*?ok~MQoqI8Uk4zZ!YhY?01wZWV{GW%Z z|6@M%F$H^E%Jp#Ve+h>oa1Q#l{1yE={z{&|tgx5=E8QQHkfF;`kw1>NN=1I+C<1z= zelJWZf~-|^$3zlYSdSPBSNRB z2u=T%IoEG?@n0$ISEU5SW6xmN$wEim?A&j{&SrS*Q`f=>r>h}{|GGES*B{0sX6V

jvm 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 b&~@GJ9)|zRL-TS+aLqZ&;ll-3k>h^=OGl!d diff --git a/bootstrap/lib/kernel/ebin/user_drv.beam b/bootstrap/lib/kernel/ebin/user_drv.beam index 6ddb0fd0ba16313ec8c47fe84e995facb9133e5c..cd65cfc9af79c7a046e9b068160090c211bc5985 100644 GIT binary patch delta 7683 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 Wvf`$P25kK8mC7%_q}7Jh?EeAwJBB|1 delta 6983 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 E55J$1H2?qr delta 4076 zcmZu!3wRXO6`t9a=S)oQg`MO$gBZ56Eow%V7P{&!|6SlKU=xpU^;bIyOx zf6l#gX#U;T(J@n|l_^R^=RVq!lV3bZQ4}4Q{Bya`#QxSbM(G4CWd!l9}Cg|22lMb$8`J@_`shfDM7?={PGXe$=lC`ET=(eEA zCZ9AE%-3P3N9M^wYj_UJ?Vc&<586WWX^BB>MpI;dYNj4G=kJN?LEaGI2H`UeLAU#s z3|KNU)n@;`J5HyS3c541#2k=51CAu2JPBtko+Le77FBJ{WqHKO?M{({+R_mg>*WE> z1<;1V&N;$}L}iPi+X z_??wteGI+HMNmy*$^TlLoYr5^eekRuo}KNm0VzXQrDvA(OwdO%wN|8RKqV`*YOS~> z=ziY~L(eljH%K-}g)TEKhxJcca3ief-s(p)+pOMcGr{^>Iyb#^E+z(y776+oj4p@K zbGQ{pxmZ0oi>Wp&bjcT7wPOw|Cfd?+HV_f=f^85?8lu_*E7%}ICOKgAFjSf) zf<6IH)9`f2L)sWl$O9zFyI7n=JGI&lT^r2<9eVNs(ojDlm88XNSd?#LrLQxl+N_HW zCDDhyY10B7TeS{X2M3 zFqzXND(XO6$jz2TJ4PVQ{5%35T_fJghNt2kJVj_pheCAj))9-;jipf{xlp=;kf1B* zPvD4|mZ*$mE33#lG^j&KRx%evFd7_IW?&U=@N`gKSZ{)xU>>}bz47VOdFdut8F*0d zmvvGaECaxL2{4&0gP)#Un3i4DFN0xz3gZuwWEV^LFm=tS8S+6NIQB0!&$ zsb^ab>CLA`w(3YXm2Fuyl zSOps!bl8~8XT^QeFJo-JqFc3+L_P=d@lvy= zwN18fPc}i&mnLBH`GURz@auHdo_L~=UIh||>av_WQ_w3lAIHLptOUDJL<1n}_&v z?EiH^Lh`WewXFcgFJ-JxWw=#Q61~xYe`nIn% zsOMR`B7_$iYjr*7vYA<}n2AsiL;NpU0d>$kU$rlVj>`l+gaC9R0GB7&6;kaL4r@9U za8o6l;T4Ub?_|zp{nOt<5RnLA>l6eMzzjj(Z4a3MDmM$*YgFy;3Hn>u+KA}S)Iv0h zLsq<)U73pWlu?grz_KeHc2&wc8SJYB{aw!x#s1bLXM5XE=Fs4Nz7GYdNK>BSoAHpx zY;V%OrVF^9OLi3t<$`x!~-c?rMf zbi!j6_8|B-Po{-L;t=qJq=z&Od)GQxuT_Jkf_{L6B_Nvv^|FTM3i>Cwbtj@XPo(Le z{pOBXS#rnrTa;x;g6Xb2mYPB0!M{$>zhK=az@Lu@UoYr~c)Sab3mmr4L#M4r1T3!I zN+!FsT(uWgvX(6M7kNxLIYH2mFABRS>p;*Wei1B|MWEr-CM$5UpdWv$3fAf- z99$siC%)J#0-!h9GWgT7g|$j*-l*EGL)cP}^h-#VDcH>898BV@L$#MoU4i$Qx?Z)H zN^>xFgP?x}Fabr&608mV(i68ito=I}KJ{_7SF+_kMF*#hty!xp9JUh2(L8=?e z`y?=MH2tSf*0mt(I!RXVo5PZ%mAj0E9%%{suVC6`w+Q<0{}0D%*jejfC1@)1Y$EjQ zpj1-yW^>m9EsPHY5}Xxbox)atV)*QcXTP&qb|GP_D47Z@-Y66-xnEK3+j%}g*;cA{ z#+O0O9h?|aY*HK^?-X_bbGKvFCa&!u2En&r!=eR^%KnX|hXd2^z~lY$`w*Xpx8vV^ za)7_vaK8mt0ONYxSK7W}Dv1P}*j+qm} zPhC(l`uwds%RX8cZLOYkWX9*OOzciqhdN4?L%n)G&r2U4IsL1ni#E=^XLs4$i+8@6 zTyszJ6OVuV&Sl5aORpZ-yz|-I1FzPua+Am2NGvXRq3r#NNypMRuiJ1p-*^0s-Irc} zeCC|5wjHEJ+Mus{&fbuy**bjTVev`fu(yxy>t4`K@DIRXxgD?R2S%Fs4vT&X^p4Ussd2#2=_qslPdG8y! Scf7QDdvmk0|GMEv)c*o=fnpQ@