ei_rpc vs. erl_rpc

Kent Boortz kent@REDACTED
Wed Dec 11 19:12:13 CET 2002


Peter Strand <d98peter@REDACTED> writes:
> On Fri, Dec 06, 2002 at 06:14:05PM +0100, Peter Strand wrote:
> > I'm playing around a bit with erl_interface and have some
> > trouble with the ei_rpc function, it failes with -1 and
> > erl_errno == EIO when used as follows:
> > 	ei_x_new(&x); ei_x_new(&x2);
> > 	ei_x_format(&x, "[]");
> > 	ei_rpc(&ec, fd, "net_adm", "localhost", x.buff, x.index, &x2);
> > Am I doing anything wrong here?
> 
> Yes I was, the ei_rpc functions shouldn't have a version encoded
> in the argument.
> 
> The documentation seems a bit weak in this area, the example for
> ei_rpc both encodes and decodes the version byte, and it doesn't mention 
> that ei_rpc does more decoding than ei_rpc_from, which can be a bit
> surprising, at least it was for me before I looked at the source ;)

Thank you for pointing out the errors in the ei_rpc*() documentation,
I have updated it. I'm reorganizing, updating and correcting the
erl_interface/ei source at the moment and try to catch documentation
mistakes at the same time. Haven't tried the old or the updated
example but the old one I'm quite sure didn't work at all and not only
because the version header was added,

kent

    <func>
      <name><ret>int</ret> ei_rpc(ei_cnode *ec, int fd, char *mod,
        char *fun, const char *argbuf, int argbuflen, ei_x_buff *x)</name>
      <name><ret>int</ret> ei_rpc_to(ei_cnode *ec, int fd, char *mod,
        char *fun, const char *argbuf, int argbuflen)</name>
      <name><ret>int</ret> ei_rpc_from(ei_cnode *ec, int fd,
        int timeout, erlang_msg *msg, ei_x_buff *x)</name>
      <fsummary>Remote Procedure Call from C to Erlang</fsummary>
      <desc>
        <p>
          These functions support calling Erlang functions on remote nodes.
          <c>ei_rpc_to()</c> sends an rpc request to a remote node and
          <c>ei_rpc_from()</c> receives the results of such a call.
          <c>ei_rpc()</c> combines the functionality of these two functions
          by sending an rpc request and waiting for the results. See also
          <c>rpc:call/4</c>.
        <p>
          <c>ec</c> is the C-node structure previously initiated by a
          call to <c>ei_connect_init()</c> or
          <c>ei_connect_xinit()</c>
        <p>
          <c>fd</c> is an open descriptor to an Erlang connection.
        <p>
          <c>timeout</c> is the maximum time (in ms) to wait for
          results. Specify <c>ERL_NO_TIMEOUT</c> to wait forever.
          <c>ei_rpc()</c> will wait infinitely for the answer,
          i.e. the call will never time out.
        <p>
          <c>mod</c> is the name of the module containing the function
          to be run on the remote node.
        <p>
          <c>fun</c> is the name of the function to run.
        <p>
          <c>argbuf</c> is a pointer to a buffer with an encoded
          Erlang list, without a version magic number, containing the
          arguments to be passed to the function.
        <p>
          <c>argbuflen</c> is the length of the buffer containing the
          encoded Erlang list.
        <p>
          <c>msg</c> structure of type <c>erlang_msg</c> and contains
          information on the message received. See <c>ei_receive_msg()</c>
          for a description of the <c>erlang_msg</c> format.
        <p>
          <c>x</c> points to the dynamic buffer that receives the
          result. For <c>ei_rpc_from()</c> this will return a 2-tuple
          <c>{rex,Reply}</c>, for <c>ei_rpc()</c> this will be the
          result without the tuple.
        <p>
          <c>ei_rpc()</c> returns the number of bytes in the result
          on success and -1 on failure. <c>ei_rpc_from()</c> returns
          number of bytes or one of <c>ERL_TICK</c>, <c>ERL_TIMEOUT</c>
          and <c>ERL_ERROR</c> otherwise. When failing,
          all three functions set <c>erl_errno</c> to one of:
        <taglist>
          <tag><c>EIO</c></tag>
          <item>I/O error.</item>
          <tag><c>ETIMEDOUT</c></tag>
          <item>Timeout expired.</item>
          <tag><c>EAGAIN</c></tag>
          <item>Temporary error: Try again.</item>
        </taglist>
        <p>
          Example, check to see if an erlang process is alive:
          <code>
int index = 0, is_alive;
ei_x_buff args, result;

ei_x_new(&result);
ei_x_new(&args);
ei_x_encode_list_header(&args, 1);
ei_x_encode_pid(&args, &check_pid);
ei_x_encode_empty_list(&args);

if (ei_rpc(&ec, fd, "erlang", "is_process_alive",
           args.buff, args.index, &result) < 0)
    error();

if (ei_decode_version(result.buff, &index) < 0
    || ei_decode_bool(result.buff, &index, &is_alive) < 0)
    error();
        </code>
      </desc>
    </func>



More information about the erlang-questions mailing list