I’m rather new to Elixir. To cut my teeth, I’d like to write into a UNIX named pipe (created via mkfifo command).
When I try to open it to read or write, I got this:
ook@pity:~/work/light$ mkfifo -m a=rw a_named_pipe
ook@pity:~/work/light$ ls -l a_named_pipe
prw-rw-rw- 1 ook ook 0 juil. 19 17:56 a_named_pipe
ook@pity:~/work/light$ iex
Erlang/OTP 18 [erts-7.1] [source] [async-threads:10] [kernel-poll:false]
Interactive Elixir (1.3.0) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> {:ok, file} = File.open "a_named_pipe", [:write]
** (MatchError) no match of right hand side value: {:error, :eisdir}
Does that mean Elixir don’t know how to talk with a named pipe? I didn’t find any dedicated section for named pipe, and “pipe” is not really easy to search around Elixir
I vaguely recall digging into this at one point and if I recall correctly the underlying Erlang libraries basically restrict File.open to only “standard” unix files. The error gets reported
as :eisdir, when it is actually :eisnotanordinary file. I ran into this problem in attempting to
open /dev/random.
My understanding for this reasoning is that opening anything other than a standard file potentially exposes the BEAM scheduler to delays that would break the VM.
Note that underneath File.open there might be some caveats as we are warned about this in the Erlang’s documentation for the file module:
Warning
While this function can be used to open any file, we recommend against using it for NFS-mounted files, FIFOs, devices, or similar since they can cause IO threads to hang forever.
If your application needs to interact with these kinds of files we recommend breaking out those parts to a port program instead.
So my recommendation is to do careful testing when reading from pipes, especially to pay attention to avoid blocking on the pipe from the Erlang side, or at least to avoid blocking from more the 1 ms that is the maximum recommended time for NIFs to block (I suppose Erlang is doing this using some internal NIF).