4

我需要我的 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 代码。

4

2 回答 2

2

我认为eisdir失败来自这段代码,假设你在 Unix 上运行。

https://github.com/erlang/otp/blob/master/erts/emulator/drivers/unix/unix_efile.c

efile_openfileefile_may_openfile。他们都做检查假设如果一个文件是!IS_REG(f)那么它是一个目录。这似乎有缺陷,但也许有充分的理由不打开非常规文件。kludge for/dev/null也是一本有趣的读物。

我以前也遇到过这个问题。也许是时候抓痒了。

于 2010-04-15T07:57:16.523 回答
2

我刚遇到这个问题。万一以后别人发现这个线程,Erlang不支持打开命名管道的原因和设备文件打不开的原因是一样的。此链接总结了基本原理:

http://www.erlang.org/faq/problems.html#id56464

于 2013-11-08T16:54:24.727 回答