I’m developing a terminal UI application. The structure of the application is like so:
- Core logic is handled by Elixir
- Interacting with the terminal (draw, reading events,…) is handled via a NIF
The NIF reads from stdin and translates into keyboard events. The problem is the Erlang VM seems to also reads from stdin, stealing the input from the NIF. Here’s the dtruss output (dtrace wrapper) when running a simple Elixir script with mix run
(just enable terminal raw mode and sleep):
select(0x16, 0x1496041B8, 0x0, 0x149604238, 0x16D76ABB8) = 1 0
libsystem_kernel.dylib`__select+0x8
beam.smp`erts_schedule+0x39bc
0x143885be0
0x1439047d8
read(0x0, "b\0", 0x10000) = 1 0
libsystem_kernel.dylib`read+0x8
beam.smp`erts_port_task_execute+0x980
beam.smp`erts_schedule+0x3030
0x143885be0
0x1439047d8
My theory is that there a separated thread in the VM keep polling on a list of file descriptors (stdin included). The bytes is buffer somewhere and can be retrieved later on, for example IO.read(:stdio, 5)
.
Is this correct? If so, how can tell the VM to NOT read from the stdin?