我需要使用我的erlang应用程序来读取和写入命名管道。
将命名管道作为文件打开将失败并显示eisdir
。
我编写了以下模块,但它很脆弱,在很多方面都感觉不对。一段时间后它也无法读取。有没有办法让它更优雅?
-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.
正如您可能已经注意到的那样,它正在模仿接受或返回的端口格式。 我希望它替换一个C代码,它将读取管道的另一端并从调试器启动。
答案 0 :(得分:2)
我认为eisdir
失败来自此代码,假设您在Unix上运行。
https://github.com/erlang/otp/blob/master/erts/emulator/drivers/unix/unix_efile.c
请参阅efile_openfile
和efile_may_openfile
。它们都进行检查,假设文件是!IS_REG(f)
,那么它是一个目录。这似乎有缺陷,但也许有充分的理由不打开非常规文件。 /dev/null
的kludge也是一个有趣的读物。
我之前也遇到过这个问题。也许是时候抓痒了。
答案 1 :(得分:2)
我刚遇到这个问题。如果其他人在将来找到这个帖子,Erlang不支持打开命名管道的原因与无法打开设备文件的原因相同。此链接总结了理由: