I need my erlang application to read and write through a named pipe.
Opening the named pipe as a file will fail with eisdir
.
I wrote the following module, but it is fragile and feels wrong in many ways. Also it fails on reading after a while. Is there a way to make it more ... elegant ?
-module(port_forwarder).
-export([start/2, forwarder/2]).
-include("logger.hrl").
start(From, To)->
spawn(fun() -> forwarder(From, To) end).
forwarder(FromFile, ToFile) ->
To = open_port({spawn,"/bin/cat > " ++ ToFifo},
[binary, out, eof,{packet, 4}]),
From = open_port({spawn,"/bin/cat " ++ FromFifo},
[binary, in, eof, {packet, 4}]),
forwarder(From, To, nil).
forwarder(From, To, Pid) ->
receive
{Manager, {command, 开发者_如何学运维Bin}} ->
?ERROR("Sending : ~p", [Bin]),
To ! {self(), {command, Bin}},
forwarder(From, To, Manager);
{From ,{data,Data}} ->
Pid ! {self(), {data, Data}},
forwarder(From, To, Pid);
E ->
?ERROR("Quitting, first message not understood : ~p", [E])
end.
As you may have noticed, it's mimicking the port format in what it accepts or returns. I want it to replace a C code that will be reading the other ends of the pipes and being launched from the debugger.
I think that eisdir
failure comes from this code, assuming you are running on Unix.
https://github.com/erlang/otp/blob/master/erts/emulator/drivers/unix/unix_efile.c
See efile_openfile
and efile_may_openfile
. They both do checks that assume if a file is !IS_REG(f)
then it is a directory. That seems flawed, but maybe there are good reasons to not open non-regular files. The kludge for /dev/null
is also an interesting read.
I've been previously hit by this problem as well. Maybe it is time to scratch an itch.
I just ran into this issue. In case others find this thread in the future, the reason why Erlang does not support opening named pipes is the same as why device files cannot be opened. This link summarizes the rationale:
http://www.erlang.org/faq/problems.html#id56464
精彩评论