anchor.diff:  ioctl(_, _) ->
      undefined.
   
  +
  +%%%------------------------------------------------------------------
  +%%%
  +%%% IDLE
  +%%%
  +%%%------------------------------------------------------------------
  +
  +'IDLE'({send, Data}, #fsm{exec=Exec, args=Args}=S) ->
  +   case (catch erlang:open_port({spawn_executable, Exec}, [{args, Args} | ?PORT_OPTS])) of
  +      {'EXIT', {Reason, _}} ->
  +         {reply,
  +            {error, Reason},
  +            'IDLE',
  +            S
  +         };
  +      Port ->
  +         lager:debug("pipe ~p to ~p ~p", [Port, Exec, Args]),
  +         port_command(Port, Data),
  +         {next_state,
  +            'PIPE',
  +            S#fsm{
  +               port = Port
  +            }
  +         }
  +   end.
  +
  +
  +%%%------------------------------------------------------------------
  +%%%
  +%%% PIPE
  +%%%
  +%%%------------------------------------------------------------------
  +
   %%
   %%
   'PIPE'({_Port, {data, Data}}, #fsm{port=Port}=S) ->
  
positive.code: 
  'PIPE'({_Port, {exit_status, 0}}, #fsm{port=Port}=S) ->
     lager:info("pipe terminated ~p", [Port]),
     {stop, normal, S};
  
  'PIPE'({_Port, {exit_status, Reason}},  #fsm{port=Port}=S) ->
     lager:error("pipe error ~p, peer ~p", [Reason, Port]),
     {stop, {error, Reason}, S};
  
  'PIPE'({send, Data}, #fsm{port=Port}=S) ->
     lager:debug("pipe send ~p~n~p~n", [Port, Data]),
  
negative.code: -include("knet.hrl").
  
  -export([init/1, free/2, ioctl/2]).
  -export(['IDLE'/2, 'PIPE'/2]).
  
  %%
  %%
  -record(fsm, {
  	exec,   %% executable
     args,   %% arguments
     port    %% communication port
  }).
  -define(PORT_OPTS, [binary, stream, exit_status]).
  
  %%
  %%
  init([Exec, Args]) ->
  	{ok, 
  	   'IDLE', 
  	   #fsm{
  	      exec = Exec,
  	      args = Args 
  	   }
  	}.
  
  