views:

235

answers:

1

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.

+1  A: 

I think that eisdir failure comes from this code, assuming you are running on unix.

http://github.com/erlang/otp/blob/dev/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.

Christian
Thanks for the pointer. I might scratch.
cstar