How to stop Erlang VM from polling stdin?

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?

I think you should try the Erlang flags -detached and/or -noshell / -noinput.

Take a look at Erlang erl

So:

elixir —erl “-noinput -detached “

Or something close

2 Likes

Thanks. -noinput does the trick.

1 Like