[erlang-questions] Escript using old i/o server still?
Alex Wilson
alex@REDACTED
Tue Apr 14 04:35:57 CEST 2015
On Mon, 2015-04-13 at 12:38 -0500, Tristan Sloughter wrote:
> Attempting to accept a password input from an escript led me to discover
> this issue from 2009 is still the case:
Changing this behaviour is actually fairly complicated, if you want to
do it without compromising the ability of escripts to accept input from
non-terminal sources (eg from a shell pipeline). So I'm not sure it's
going to happen any time soon...
If you're desperate you can use a really horrible workaround, something
like this:
-define(OP_PUTC,0).
getpw() ->
case io:setopts([binary, {echo, false}]) of
ok ->
PwLine = io:get_line(<<"Password:">>),
ok = io:setopts([binary, {echo, true}]),
io:format("\n"),
[Pw | _] = binary:split(PwLine, <<"\n">>),
Pw;
_ ->
Port = open_port({spawn, 'tty_sl -e'}, [binary, eof]),
port_command(Port, <<?OP_PUTC, "Password:">>),
receive
{Port, {data, PwLine}} ->
[Pw | _] = binary:split(PwLine, <<"\n">>),
port_command(Port, <<?OP_PUTC, $\n>>),
port_close(Port),
Pw
end
end.
This uses the tty_sl port driver that's only for internal use inside the
new I/O server, which is private API and could disappear at any time.
However, in practice it's been very stable since it was introduced,
so...
It should be safe for tty_sl to just temporarily hijack the terminal
like this as long as nothing else in your program causes the old I/O
server to talk to it at the same time. If there are any other processes
running that could cause io: functions to be called during this, things
could possibly get hairy.
I'd only recommend it from an escript main/1 or similar, before starting
any other processes, and probably after turning off the error_logger or
putting it in silent mode.
More information about the erlang-questions
mailing list