Joe,<br><br>I don't know if this is still a problem, but I didn't know the answer, so I was intrigued. Having never used C ports before, I thought it would be useful to learn about them. <br><br>I looked at the C code for Erlang (io.c module) and it seems that this signal (badsig) is sent when bad port command is received. The port command was bad because you can't just send raw data to a port as in Port ! <<"Hello">>. It requires a specific format. You have to either send Port ! {self(), {command, <<"Hello">>}} or (which I like better) erlang:port_command(Port, <<"Hello">>).<br>
<br>In terms of how you can send and receive strings, this whole port thing turned out to be much more difficult to figure than I anticipated (but easier when you know how). One of the most annoying aspects is that under circumstances that are not clear to me, the C program that is spawned sometimes does not seem to be sent a signal for end of file when you close the port, so if it is reading stdin, it's just going to sit there until killed manually. Worse, if it gets stuck doing something and is NOT reading stdin then you are out of luck.<br>
<br>But what if the 'C' program is not under your control, say, it's part of Linux, and you need to make sure it's killed when you are done? Then I believe you need to write a wrapper around the 'C' program. I refer you to the following post for an interesting way to do this:<br>
<br><a href="http://www.erlang.org/pipermail/erlang-questions/2007-October/030377.html">http://www.erlang.org/pipermail/erlang-questions/2007-October/030377.html</a><br><br>As for how to send and receive strings, assuming there is a way to terminate the 'C' program, I eventually came up with the following "demo" code (which does rely on newlines, and I know there are other ways; this is one of them). Hope this helps.<br>
<br>Regards,<br>Edwin Fine<br><br>/* echo_svr.c: Simple C program to echo stdin to stdout */<br>#include <stdio.h><br><br>int main()<br>{<br>    char buf[4096];<br><br>    while (fgets(buf, sizeof(buf), stdin) != NULL)<br>
    {<br>        fputs(buf, stdout);<br>        fflush(stdout);<br>    }<br>    <br>    return 0;<br>}<br><br>echo_svr.erl:<br><br>-module(test_echo_svr).<br>-export([go/2]).<br><br>go(EchoSvrExecFilePath, Iters) when is_list(EchoSvrExecFilePath), is_integer(Iters), Iters >= 0  -><br>
    process_flag(trap_exit, true),<br>    Port = erlang:open_port({spawn, EchoSvrExecFilePath}, [binary]),<br>    test(Port, <<>>, Iters, 1).<br><br>test(Port, _Buf, 0, _N) -><br>    erlang:port_close(Port), ok;<br>
test(Port, Buf, Iters, N) -><br>    Out = list_to_binary([<<"Test message ">>, integer_to_list(N), $\n]),<br>    erlang:port_command(Port, Out),<br>    receive<br>        {Port, {data, In}} -><br>
            {Line, Rest} = parse(list_to_binary([Buf, In])),<br>            io:format("~p~n", [Line]),<br>            test(Port, Rest, Iters - 1, N + 1)<br>    after 3000 -><br>            io:format("Receive timeout, stopping.~n")<br>
    end.<br><br>parse(Msg) -> parse(Msg, []).<br><br>parse(<<>>, Acc) ->                  {lists:reverse(Acc), <<>>};<br>parse(<<$\n, Rest/binary>>, Acc)  -> {lists:reverse(Acc), Rest}; % EOL<br>
parse(<<Byte, Rest/binary>>, Acc) ->  parse(Rest, [Byte|Acc]).<br><br>113> test_echo_svr:go("/path/to/echo_svr", 3).<br>"Test message 1"<br>"Test message 2"<br>"Test message 3"<br>
ok<br><br><br><div class="gmail_quote">On Fri, Nov 21, 2008 at 6:37 PM, Joe Williams <span dir="ltr"><<a href="mailto:joe@joetify.com">joe@joetify.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Hello,<br>
<br>
I am having an issue when I attempt to send and receive messages to a C<br>
executable. I believe the task should be fairly trivial but I am getting<br>
hung up on sending messages to the port. Here's what I have so far:<br>
<br>
> Eshell V5.6.3  (abort with ^G)<br>
> 1> Cmd = "SOME_EXECUTABLE",<br>
> 1> Port = open_port({spawn, Cmd}, []).<br>
> #Port<0.93><br>
> 2> receive<br>
> 2> {Port, {data, Data}} -><br>
> 2> io:format("~p~n", [Data]);<br>
> 2> Error -><br>
> 2> io:format("~p~n", [Error])<br>
> 2> end.<br>
> "TEXT FROM THE EXECUTABLE"<br>
> ok<br>
> 3> Port ! <<"TEXT TO THE EXECUTABLE">>.<br>
> ** exception exit: badsig<br>
> 4> Port ! <<"TEXT TO THE EXECUTABLE">>.<br>
> <<"TEXT TO THE EXECUTABLE">><br>
> 5> receive<br>
> 5> {Port, {data, Data}} -><br>
> 5> io:format("~p~n", [Data]);<br>
> 5> Error -><br>
> 5> io:format("~p~n", [Error])<br>
> 5> end.<br>
<br>
After the last end my code just hangs and waits to receive a message<br>
rather than receiving the response from "TEXT TO THE EXECUTABLE". Since<br>
it received the first message properly I assume it would receive further<br>
responses in the same way. So I have two questions, the first is what<br>
does "exception exit: badsig" generally mean? The second how can I write<br>
this in such a way that I can send and receive strings until I have the<br>
program exit?<br>
<br>
Any guidance is appreciated.<br>
<br>
-Joe<br>
<font color="#888888"><br>
--<br>
Name: Joseph A. Williams<br>
Email: <a href="mailto:joe@joetify.com">joe@joetify.com</a><br>
<br>
_______________________________________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br>
<a href="http://www.erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://www.erlang.org/mailman/listinfo/erlang-questions</a><br>
<br>
</font></blockquote></div><br>