aboutsummaryrefslogtreecommitdiffstats
path: root/lib/erl_interface/doc/src/ei_connect.xml
diff options
context:
space:
mode:
Diffstat (limited to 'lib/erl_interface/doc/src/ei_connect.xml')
-rw-r--r--lib/erl_interface/doc/src/ei_connect.xml639
1 files changed, 639 insertions, 0 deletions
diff --git a/lib/erl_interface/doc/src/ei_connect.xml b/lib/erl_interface/doc/src/ei_connect.xml
new file mode 100644
index 0000000000..08e7b122c6
--- /dev/null
+++ b/lib/erl_interface/doc/src/ei_connect.xml
@@ -0,0 +1,639 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE cref SYSTEM "cref.dtd">
+
+<cref>
+ <header>
+ <copyright>
+ <year>2001</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>ei_connect</title>
+ <prepared>Jakob Cederlund</prepared>
+ <docno></docno>
+ <approved>?</approved>
+ <checked>?</checked>
+ <date>2001-09-01</date>
+ <rev>A</rev>
+ <file>ei_connect.sgml</file>
+ </header>
+ <lib>ei_connect</lib>
+ <libsummary>Communicate with distributed erlang</libsummary>
+ <description>
+ <p>This module enables C programs to communicate with erlang nodes,
+ using the erlang distribution over TCP/IP.</p>
+ <p>A C node appears to Erlang as a
+ <em>hidden node</em>.
+ That is, Erlang processes that know the name of the
+ C node are able to communicate with it in a normal manner, but
+ the node name will not appear in the listing provided by the
+ Erlang function <c><![CDATA[nodes/0]]></c>.</p>
+ <p>The environment variable <c><![CDATA[ERL_EPMD_PORT]]></c> can be used
+ to indicate which logical cluster a C node belongs to.</p>
+ </description>
+
+ <section>
+ <title>Timeout functions</title>
+ <p>Most functions appear in a version with the suffix
+ <c><![CDATA[_tmo]]></c> appended to the function name. Those function take
+ an additional argument, a timeout in <em>milliseconds</em>. The
+ semantics is this; for each communication primitive involved in
+ the operation, if the primitive does not complete within the time
+ specified, the function will return an error and
+ <c><![CDATA[erl_errno]]></c> will be set to <c><![CDATA[ETIMEDOUT]]></c>. With
+ communication primitive is ment an operation on the socket, like
+ <c><![CDATA[connect]]></c>, <c><![CDATA[accept]]></c>, <c><![CDATA[recv]]></c> or <c><![CDATA[send]]></c>.</p>
+ <p>Obviously the timeouts are for implementing fault tolerance,
+ not to keep hard realtime promises. The <c><![CDATA[_tmo]]></c> functions
+ are for detecting non-responsive peers and to avoid blocking on
+ socket operations. </p>
+ <p>A timeout value of <c><![CDATA[0]]></c> (zero), means that timeouts are
+ disabled. Calling a <c><![CDATA[_tmo]]></c>-function with the last argument as
+ <c><![CDATA[0]]></c> is therefore exactly the same thing as calling the
+ function without the <c><![CDATA[_tmo]]></c> suffix.</p>
+ <p>As with all other ei functions, you are <em>not</em> expected
+ to put the socket in non blocking mode yourself in the program. Every
+ use of non blocking mode is embedded inside the timeout
+ functions. The socket will always be back in blocking mode after
+ the operations are completed (regardless of the result). To
+ avoid problems, leave the socket options alone. Ei will handle
+ any socket options that need modification.</p>
+ <p>In all other senses, the <c><![CDATA[_tmo]]></c> functions inherit all
+ the return values and the semantics from the functions without
+ the <c><![CDATA[_tmo]]></c> suffix.</p>
+ </section>
+ <funcs>
+ <func>
+ <name><ret>int</ret><nametext>ei_connect_init(ei_cnode* ec, const char* this_node_name, const char *cookie, short creation)</nametext></name>
+ <name><ret>int</ret><nametext>ei_connect_xinit(ei_cnode* ec, const char *thishostname, const char *thisalivename, const char *thisnodename, Erl_IpAddr thisipaddr, const char *cookie, short creation)</nametext></name>
+ <fsummary>Initialize for a connection.</fsummary>
+ <desc>
+ <p>These function initializes the <c><![CDATA[ec]]></c> structure, to
+ identify the node name and cookie of the server. One of them
+ has to be called before other functions that works on the
+ type <c><![CDATA[ei_cnode]]></c> or a file descriptor associated with a
+ connection to another node are used.</p>
+ <p><c><![CDATA[ec]]></c> is a structure containing information about the
+ C-node. It is used in other <c><![CDATA[ei]]></c> functions for
+ connecting and receiving data.</p>
+ <p><c><![CDATA[this_node_name]]></c> is the registered name of the process
+ (the name before '@').</p>
+ <p><c><![CDATA[cookie]]></c> is the cookie for the node.</p>
+ <p><c><![CDATA[creation]]></c> identifies a specific instance of a C
+ node. It can help prevent the node from receiving messages
+ sent to an earlier process with the same registered name.</p>
+ <p><c><![CDATA[thishostname]]></c> is the name of the machine we're running
+ on. If long names are to be used, it should be fully
+ qualified (i.e. <c><![CDATA[durin.erix.ericsson.se]]></c> instead of
+ <c><![CDATA[durin]]></c>).</p>
+ <p><c><![CDATA[thisalivename]]></c> is the registered name of the process.</p>
+ <p><c><![CDATA[thisnodename]]></c> is the full name of the node,
+ i.e. <c><![CDATA[einode@durin]]></c>.</p>
+ <p><c><![CDATA[thispaddr]]></c> if the IP address of the host.</p>
+ <p>A C node acting as a server will be assigned a creation
+ number when it calls <c><![CDATA[ei_publish()]]></c>.</p>
+ <p>A connection is closed by simply closing the socket. Refer
+ to system documentation to close the socket gracefully (when
+ there are outgoing packets before close).</p>
+ <p>This function return a negative value indicating that an error
+ occurred.</p>
+ <p>Example 1:
+ </p>
+ <code type="none"><![CDATA[
+int n = 0;
+struct in_addr addr;
+ei_cnode ec;
+addr = inet_addr("150.236.14.75");
+if (ei_connect_xinit(&ec,
+ "chivas",
+ "madonna",
+ &addr;
+ "cookie...",
+ n++) < 0) {
+ fprintf(stderr,"ERROR when initializing: %d",erl_errno);
+ exit(-1);
+}
+ ]]></code>
+ <p>Example 2:
+ </p>
+ <code type="none"><![CDATA[
+if (ei_connect_init(&ec, "madonna", "cookie...", n++) < 0) {
+ fprintf("ERROR when initializing: %d",erl_errno);
+ exit(-1);
+}
+ ]]></code>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_connect(ei_cnode* ec, char *nodename)</nametext></name>
+ <name><ret>int</ret><nametext>ei_xconnect(ei_cnode* ec, Erl_IpAddr adr, char *alivename)</nametext></name>
+ <fsummary>Establishe a connection to an Erlang node</fsummary>
+ <desc>
+ <p>These functions set up a connection to an Erlang node.</p>
+ <p><c><![CDATA[ei_xconnect()]]></c> requires the IP address of the remote
+ host and the alive name of the remote node
+ to be specified. <c><![CDATA[ei_connect()]]></c> provides an alternative
+ interface, and determines the information from the node name
+ provided.</p>
+ <p><c><![CDATA[addr]]></c> is the 32-bit IP address of the remote host.</p>
+ <p><c><![CDATA[alive]]></c> is the alivename of the remote node.</p>
+ <p><c><![CDATA[node]]></c> is the name of the remote node.</p>
+ <p>These functions return an open file descriptor on success, or
+ a negative value indicating that an error occurred --- in
+ which case they will set <c><![CDATA[erl_errno]]></c> to one of:</p>
+ <taglist>
+ <tag><c><![CDATA[EHOSTUNREACH]]></c></tag>
+ <item>The remote host <c><![CDATA[node]]></c> is unreachable</item>
+ <tag><c><![CDATA[ENOMEM]]></c></tag>
+ <item>No more memory available.</item>
+ <tag><c><![CDATA[EIO]]></c></tag>
+ <item>I/O error.</item>
+ </taglist>
+ <p>Additionally, <c><![CDATA[errno]]></c> values from
+ <c><![CDATA[socket]]></c><em>(2)</em> and <c><![CDATA[connect]]></c><em>(2)</em>
+ system calls may be propagated into <c><![CDATA[erl_errno]]></c>.</p>
+ <p>Example:</p>
+ <code type="none"><![CDATA[
+#define NODE "[email protected]"
+#define ALIVE "madonna"
+#define IP_ADDR "150.236.14.75"
+
+/*** Variant 1 ***/
+int fd = ei_connect(&ec, NODE);
+
+/*** Variant 2 ***/
+struct in_addr addr;
+addr = inet_addr(IP_ADDR);
+fd = ei_xconnect(&ec, &addr, ALIVE);
+ ]]></code>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_connect_tmo(ei_cnode* ec, char *nodename, unsigned timeout_ms)</nametext></name>
+ <name><ret>int</ret><nametext>ei_xconnect_tmo(ei_cnode* ec, Erl_IpAddr adr, char *alivename, unsigned timeout_ms)</nametext></name>
+ <fsummary>Establish a connection to an Erlang node with optional timeout</fsummary>
+ <desc>
+ <p>ei_connect and ei_xconnect with an optional timeout argument,
+ see the description at the beginning of this document.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_receive(int fd, unsigned char* bufp, int bufsize)</nametext></name>
+ <fsummary>Receive a message</fsummary>
+ <desc>
+ <p>This function receives a message consisting of a sequence
+ of bytes in the Erlang external format.</p>
+ <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection. It
+ is obtained from a previous <c><![CDATA[ei_connect]]></c> or
+ <c><![CDATA[ei_accept]]></c>.</p>
+ <p><c><![CDATA[bufp]]></c> is a buffer large enough to hold the expected
+ message. </p>
+ <p><c><![CDATA[bufsize]]></c> indicates the size of <c><![CDATA[bufp]]></c>.</p>
+ <p>If a <em>tick</em> occurs, i.e., the Erlang node on the
+ other end of the connection has polled this node to see if it
+ is still alive, the function will return <c><![CDATA[ERL_TICK]]></c> and
+ no message will be placed in the buffer. Also,
+ <c><![CDATA[erl_errno]]></c> will be set to <c><![CDATA[EAGAIN]]></c>.</p>
+ <p>On success, the message is placed in the specified buffer
+ and the function returns the number of bytes actually read. On
+ failure, the function returns <c><![CDATA[ERL_ERROR]]></c> and will set
+ <c><![CDATA[erl_errno]]></c> to one of:</p>
+ <taglist>
+ <tag><c><![CDATA[EAGAIN]]></c></tag>
+ <item>Temporary error: Try again.</item>
+ <tag><c><![CDATA[EMSGSIZE]]></c></tag>
+ <item>Buffer too small.</item>
+ <tag><c><![CDATA[EIO]]></c></tag>
+ <item>I/O error.</item>
+ </taglist>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_receive_tmo(int fd, unsigned char* bufp, int bufsize, unsigned timeout_ms)</nametext></name>
+ <fsummary>Receive a message with optional timeout</fsummary>
+ <desc>
+ <p>ei_receive with an optional timeout argument,
+ see the description at the beginning of this document.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_receive_msg(int fd, erlang_msg* msg, ei_x_buff* x)</nametext></name>
+ <name><ret>int</ret><nametext>ei_xreceive_msg(int fd, erlang_msg* msg, ei_x_buff* x)</nametext></name>
+ <fsummary>Receive a message</fsummary>
+ <desc>
+ <p>These functions receives a message to the buffer in
+ <c><![CDATA[x]]></c>. <c><![CDATA[ei_xreceive_msg]]></c> allows the buffer in
+ <c><![CDATA[x]]></c> to grow, but <c><![CDATA[ei_receive_msg]]></c> fails if the
+ message is bigger than the preallocated buffer in <c><![CDATA[x]]></c>.</p>
+ <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.</p>
+ <p><c><![CDATA[msg]]></c> is a pointer to an <c><![CDATA[erlang_msg]]></c> structure
+ and contains information on the message received.</p>
+ <p><c><![CDATA[x]]></c> is buffer obtained from <c><![CDATA[ei_x_new]]></c>.</p>
+ <p>On success, the function returns <c><![CDATA[ERL_MSG]]></c> and the
+ <c><![CDATA[msg]]></c> struct will be initialized. <c><![CDATA[erlang_msg]]></c>
+ is defined as follows:</p>
+ <code type="none"><![CDATA[
+typedef struct {
+ long msgtype;
+ erlang_pid from;
+ erlang_pid to;
+ char toname[MAXATOMLEN+1];
+ char cookie[MAXATOMLEN+1];
+ erlang_trace token;
+} erlang_msg;
+ ]]></code>
+ <p><c><![CDATA[msgtype]]></c> identifies the type of message, and is one of
+ <c><![CDATA[ERL_SEND]]></c>, <c><![CDATA[ERL_REG_SEND]]></c>, <c><![CDATA[ERL_LINK]]></c>,
+ <c><![CDATA[ERL_UNLINK]]></c> and <c><![CDATA[ERL_EXIT]]></c>.</p>
+ <p>If <c><![CDATA[msgtype]]></c> is <c><![CDATA[ERL_SEND]]></c> this indicates that an
+ ordinary send operation has taken place, and <c><![CDATA[msg->to]]></c>
+ contains the Pid of the recipient (the C-node). If
+ <c><![CDATA[type]]></c> is <c><![CDATA[ERL_REG_SEND]]></c> then a registered send
+ operation took place, and <c><![CDATA[msg->from]]></c> contains the Pid
+ of the sender.</p>
+ <p>If <c><![CDATA[msgtype]]></c> is <c><![CDATA[ERL_LINK]]></c> or <c><![CDATA[ERL_UNLINK]]></c>, then
+ <c><![CDATA[msg->to]]></c> and <c><![CDATA[msg->from]]></c> contain the pids of the
+ sender and recipient of the link or unlink.</p>
+ <p>If <c><![CDATA[msgtype]]></c> is <c><![CDATA[ERL_EXIT]]></c>, then this indicates that
+ a link has been broken. In this case, <c><![CDATA[msg->to]]></c> and
+ <c><![CDATA[msg->from]]></c> contain the pids of the linked processes.</p>
+ <p>The return value is the same as for <c><![CDATA[ei_receive]]></c>, see
+ above.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_receive_msg_tmo(int fd, erlang_msg* msg, ei_x_buff* x, unsigned imeout_ms)</nametext></name>
+ <name><ret>int</ret><nametext>ei_xreceive_msg_tmo(int fd, erlang_msg* msg, ei_x_buff* x, unsigned timeout_ms)</nametext></name>
+ <fsummary>Receive a message with optional timeout</fsummary>
+ <desc>
+ <p>ei_receive_msg and ei_xreceive_msg with an optional timeout argument,
+ see the description at the beginning of this document.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_receive_encoded(int fd, char **mbufp, int *bufsz, erlang_msg *msg, int *msglen)</nametext></name>
+ <fsummary>Obsolete function for receiving a message</fsummary>
+ <desc>
+ <p>This function is retained for compatibility with code
+ generated by the interface compiler and with code following
+ examples in the same application.</p>
+ <p>In essence the function performs the same operation as
+ <c><![CDATA[ei_xreceive_msg]]></c>, but instead of using an ei_x_buff, the
+ function expects a pointer to a character pointer
+ (<c><![CDATA[mbufp]]></c>), where the character pointer should point to a
+ memory area allocated by <c><![CDATA[malloc]]></c>. The argument
+ <c><![CDATA[bufsz]]></c> should be a pointer to an integer containing the
+ exact size (in bytes) of the memory area. The function may
+ reallocate the memory area and will in such cases put the new
+ size in <c><![CDATA[*bufsz]]></c> and update <c><![CDATA[*mbufp]]></c>.</p>
+ <p>Furthermore the function returns either ERL_TICK or the
+ <c><![CDATA[msgtype]]></c> field of the <c><![CDATA[erlang_msg *msg]]></c>. The actual
+ length of the message is put in <c><![CDATA[*msglen]]></c>. On error it
+ will return a value <c><![CDATA[< 0]]></c>.</p>
+ <p>It is recommended to use ei_xreceive_msg instead when
+ possible, for the sake of readability. The function will
+ however be retained in the interface for compatibility and
+ will <em>not</em> be removed not be removed in future releases
+ without notice.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_receive_encoded_tmo(int fd, char **mbufp, int *bufsz, erlang_msg *msg, int *msglen, unsigned timeout_ms)</nametext></name>
+ <fsummary>Obsolete function for receiving a message with timeout</fsummary>
+ <desc>
+ <p>ei_receive_encoded with an optional timeout argument,
+ see the description at the beginning of this document.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_send(int fd, erlang_pid* to, char* buf, int len)</nametext></name>
+ <fsummary>Send a message</fsummary>
+ <desc>
+ <p>This function sends an Erlang term to a process.</p>
+ <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.</p>
+ <p><c><![CDATA[to]]></c> is the Pid of the intended recipient of the
+ message.</p>
+ <p><c><![CDATA[buf]]></c> is the buffer containing the term in binary
+ format.</p>
+ <p><c><![CDATA[len]]></c> is the length of the message in bytes.</p>
+ <p>The function returns 0 if successful, otherwise -1, in the
+ latter case it will set <c><![CDATA[erl_errno]]></c> to <c><![CDATA[EIO]]></c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_send_tmo(int fd, erlang_pid* to, char* buf, int len, unsigned timeout_ms)</nametext></name>
+ <fsummary>Send a message with optional timeout</fsummary>
+ <desc>
+ <p>ei_send with an optional timeout argument,
+ see the description at the beginning of this document.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_send_encoded(int fd, erlang_pid* to, char* buf, int len)</nametext></name>
+ <fsummary>Obsolete function to send a message</fsummary>
+ <desc>
+ <p>Works exactly as ei_send, the alternative name retained for
+ backward compatibility. The function will <em>not</em> be
+ removed without notice.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_send_encoded_tmo(int fd, erlang_pid* to, char* buf, int len, unsigned timeout_ms)</nametext></name>
+ <fsummary>Obsolete function to send a message with optional timeout</fsummary>
+ <desc>
+ <p>ei_send_encoded with an optional timeout argument,
+ see the description at the beginning of this document.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_reg_send(ei_cnode* ec, int fd, char* server_name, char* buf, int len)</nametext></name>
+ <fsummary>Send a message to a registered name</fsummary>
+ <desc>
+ <p>This function sends an Erlang term to a registered process.
+ </p>
+ <p>This function sends an Erlang term to a process.</p>
+ <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.</p>
+ <p><c><![CDATA[server_name]]></c> is the registered name of the intended
+ recipient.</p>
+ <p><c><![CDATA[buf]]></c> is the buffer containing the term in binary
+ format.</p>
+ <p><c><![CDATA[len]]></c> is the length of the message in bytes.</p>
+ <p>The function returns 0 if successful, otherwise -1, in the
+ latter case it will set <c><![CDATA[erl_errno]]></c> to <c><![CDATA[EIO]]></c>.</p>
+ <p>Example, send the atom "ok" to the process "worker":</p>
+ <code type="none"><![CDATA[
+ei_x_buff x;
+ei_x_new_with_version(&x);
+ei_x_encode_atom(&x, "ok");
+if (ei_reg_send(&ec, fd, x.buff, x.index) < 0)
+ handle_error();
+ ]]></code>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_reg_send_tmo(ei_cnode* ec, int fd, char* server_name, char* buf, int len, unsigned timeout_ms)</nametext></name>
+ <fsummary>Send a message to a registered name with optional timeout</fsummary>
+ <desc>
+ <p>ei_reg_send with an optional timeout argument,
+ see the description at the beginning of this document.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_send_reg_encoded(int fd, const erlang_pid *from, const char *to, const char *buf, int len)</nametext></name>
+ <fsummary>Obsolete function to send a message to a registered name</fsummary>
+ <desc>
+ <p>This function is retained for compatibility with code
+ generated by the interface compiler and with code following
+ examples in the same application.</p>
+ <p>The function works as <c><![CDATA[ei_reg_send]]></c> with one
+ exception. Instead of taking the <c><![CDATA[ei_cnode]]></c> as a first
+ argument, it takes a second argument, an <c><![CDATA[erlang_pid]]></c>
+ which should be the process identifier of the sending process
+ (in the erlang distribution protocol). </p>
+ <p>A suitable <c><![CDATA[erlang_pid]]></c> can be constructed from the
+ <c><![CDATA[ei_cnode]]></c> structure by the following example code:</p>
+ <code type="none"><![CDATA[
+ ei_cnode ec;
+ erlang_pid *self;
+ int fd; /* the connection fd */
+ ...
+ self = ei_self(&ec);
+ self->num = fd;
+ ]]></code>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_send_reg_encoded_tmo(int fd, const erlang_pid *from, const char *to, const char *buf, int len)</nametext></name>
+ <fsummary>Obsolete function to send a message to a registered name with timeout</fsummary>
+ <desc>
+ <p>ei_send_reg_encoded with an optional timeout argument,
+ see the description at the beginning of this document.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_rpc(ei_cnode *ec, int fd, char *mod, char *fun, const char *argbuf, int argbuflen, ei_x_buff *x)</nametext></name>
+ <name><ret>int</ret><nametext>ei_rpc_to(ei_cnode *ec, int fd, char *mod, char *fun, const char *argbuf, int argbuflen)</nametext></name>
+ <name><ret>int</ret><nametext>ei_rpc_from(ei_cnode *ec, int fd, int timeout, erlang_msg *msg, ei_x_buff *x)</nametext></name>
+ <fsummary>Remote Procedure Call from C to Erlang</fsummary>
+ <desc>
+ <p>These functions support calling Erlang functions on remote nodes.
+ <c><![CDATA[ei_rpc_to()]]></c> sends an rpc request to a remote node and
+ <c><![CDATA[ei_rpc_from()]]></c> receives the results of such a call.
+ <c><![CDATA[ei_rpc()]]></c> combines the functionality of these two functions
+ by sending an rpc request and waiting for the results. See also
+ <c><![CDATA[rpc:call/4]]></c>. </p>
+ <p><c><![CDATA[ec]]></c> is the C-node structure previously initiated by a
+ call to <c><![CDATA[ei_connect_init()]]></c> or
+ <c><![CDATA[ei_connect_xinit()]]></c></p>
+ <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.</p>
+ <p><c><![CDATA[timeout]]></c> is the maximum time (in ms) to wait for
+ results. Specify <c><![CDATA[ERL_NO_TIMEOUT]]></c> to wait forever.
+ <c><![CDATA[ei_rpc()]]></c> will wait infinitely for the answer,
+ i.e. the call will never time out.</p>
+ <p><c><![CDATA[mod]]></c> is the name of the module containing the function
+ to be run on the remote node.</p>
+ <p><c><![CDATA[fun]]></c> is the name of the function to run.</p>
+ <p><c><![CDATA[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>
+ <p><c><![CDATA[argbuflen]]></c> is the length of the buffer containing the
+ encoded Erlang list.</p>
+ <p><c><![CDATA[msg]]></c> structure of type <c><![CDATA[erlang_msg]]></c> and contains
+ information on the message received. See <c><![CDATA[ei_receive_msg()]]></c>
+ for a description of the <c><![CDATA[erlang_msg]]></c> format.</p>
+ <p><c><![CDATA[x]]></c> points to the dynamic buffer that receives the
+ result. For for <c><![CDATA[ei_rpc()]]></c> this will be the result
+ without the version magic number. For <c><![CDATA[ei_rpc_from()]]></c>
+ the result will return a version magic number and a 2-tuple
+ <c><![CDATA[{rex,Reply}]]></c>.</p>
+ <p><c><![CDATA[ei_rpc()]]></c> returns the number of bytes in the result
+ on success and -1 on failure. <c><![CDATA[ei_rpc_from()]]></c> returns
+ number of bytes or one of <c><![CDATA[ERL_TICK]]></c>, <c><![CDATA[ERL_TIMEOUT]]></c>
+ and <c><![CDATA[ERL_ERROR]]></c> otherwise. When failing,
+ all three functions set <c><![CDATA[erl_errno]]></c> to one of:</p>
+ <taglist>
+ <tag><c><![CDATA[EIO]]></c></tag>
+ <item>I/O error.</item>
+ <tag><c><![CDATA[ETIMEDOUT]]></c></tag>
+ <item>Timeout expired.</item>
+ <tag><c><![CDATA[EAGAIN]]></c></tag>
+ <item>Temporary error: Try again.</item>
+ </taglist>
+ <p>Example, check to see if an erlang process is alive:</p>
+ <code type="none"><![CDATA[
+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)
+ handle_error();
+
+if (ei_decode_version(result.buff, &index) < 0
+ || ei_decode_bool(result.buff, &index, &is_alive) < 0)
+ handle_error();
+ ]]></code>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_publish(ei_cnode *ec, int port)</nametext></name>
+ <fsummary>Publish a node name</fsummary>
+ <desc>
+ <p>These functions are used by a server process to register
+ with the local name server <em>epmd</em>, thereby allowing
+ other processes to send messages by using the registered name.
+ Before calling either of these functions, the process should
+ have called <c><![CDATA[bind()]]></c> and <c><![CDATA[listen()]]></c> on an open socket.</p>
+ <p><c><![CDATA[ec]]></c> is the C-node structure.</p>
+ <p><c><![CDATA[port]]></c> is the local name to register, and should be the
+ same as the port number that was previously bound to the socket.</p>
+ <p><c><![CDATA[addr]]></c> is the 32-bit IP address of the local host.</p>
+ <p>To unregister with epmd, simply close the returned
+ descriptor. See also <c><![CDATA[ei_unpublish()]]></c>.</p>
+ <p>On success, the functions return a descriptor connecting the
+ calling process to epmd. On failure, they return -1 and set
+ <c><![CDATA[erl_errno]]></c> to <c><![CDATA[EIO]]></c>.</p>
+ <p>Additionally, <c><![CDATA[errno]]></c> values from <c><![CDATA[socket]]></c><em>(2)</em>
+ and <c><![CDATA[connect]]></c><em>(2)</em> system calls may be propagated
+ into <c><![CDATA[erl_errno]]></c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_publish_tmo(ei_cnode *ec, int port, unsigned timeout_ms)</nametext></name>
+ <fsummary>Publish a node name with optional timeout</fsummary>
+ <desc>
+ <p>ei_publish with an optional timeout argument,
+ see the description at the beginning of this document.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_accept(ei_cnode *ec, int listensock, ErlConnect *conp)</nametext></name>
+ <fsummary>Accept a connection from another node</fsummary>
+ <desc>
+ <p>This function is used by a server process to accept a
+ connection from a client process.</p>
+ <p><c><![CDATA[ec]]></c> is the C-node structure.</p>
+ <p><c><![CDATA[listensock]]></c> is an open socket descriptor on which
+ <c><![CDATA[listen()]]></c> has previously been called.</p>
+ <p><c><![CDATA[conp]]></c> is a pointer to an <c><![CDATA[ErlConnect]]></c> struct,
+ described as follows:</p>
+ <code type="none"><![CDATA[
+typedef struct {
+ char ipadr[4];
+ char nodename[MAXNODELEN];
+} ErlConnect;
+ ]]></code>
+ <p>On success, <c><![CDATA[conp]]></c> is filled in with the address and
+ node name of the connecting client and a file descriptor is
+ returned. On failure, <c><![CDATA[ERL_ERROR]]></c> is returned and
+ <c><![CDATA[erl_errno]]></c> is set to <c><![CDATA[EIO]]></c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_accept_tmo(ei_cnode *ec, int listensock, ErlConnect *conp, unsigned timeout_ms)</nametext></name>
+ <fsummary>Accept a connection from another node with optional timeout</fsummary>
+ <desc>
+ <p>ei_accept with an optional timeout argument,
+ see the description at the beginning of this document.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_unpublish(ei_cnode *ec)</nametext></name>
+ <fsummary>Unpublish a node name</fsummary>
+ <desc>
+ <p>This function can be called by a process to unregister a
+ specified node from epmd on the localhost. This may be
+ useful, for example, when epmd has not detected the failure of a
+ node, and will not allow the name to be reused. If you use this
+ function to unregister your own process, be sure to also close
+ the descriptor that was returned by <c><![CDATA[ei_publish()]]></c>.</p>
+ <note>
+ <p>Careless use of this function may have unpredictable
+ results, if the registered node is in fact still running.</p>
+ </note>
+ <p><c><![CDATA[ec]]></c> is the node structure of the node to unregister.</p>
+ <p>If the node was successfully unregistered from epmd, the
+ function returns 0. Otherwise, it returns -1 and sets
+ <c><![CDATA[erl_errno]]></c> is to <c><![CDATA[EIO]]></c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_unpublish_tmo(ei_cnode *ec, unsigned timeout_ms)</nametext></name>
+ <fsummary>Unpublish a node name with optional timeout</fsummary>
+ <desc>
+ <p>ei_unpublish with an optional timeout argument,
+ see the description at the beginning of this document.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>const char *</ret><nametext>ei_thisnodename(ei_cnode *ec)</nametext></name>
+ <name><ret>const char *</ret><nametext>ei_thishostname(ei_cnode *ec)</nametext></name>
+ <name><ret>const char *</ret><nametext>ei_thisalivename(ei_cnode *ec)</nametext></name>
+ <fsummary>Retrieve some values</fsummary>
+ <desc>
+ <p>These functions can be used to retrieve information about
+ the C Node. These values are initially set with
+ <c><![CDATA[ei_connect_init()]]></c> or <c><![CDATA[ei_connect_xinit()]]></c>.</p>
+ <p>They simply fetches the appropriate field from the <c><![CDATA[ec]]></c>
+ structure. Read the field directly will probably be safe for
+ a long time, so these functions are not really needed.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>erlang_pid *</ret><nametext>ei_self(ei_cnode *ec)</nametext></name>
+ <fsummary>Retrieve the Pid of the C-node</fsummary>
+ <desc>
+ <p>This function retrieves the Pid of the C-node. Every C-node
+ has a (pseudo) pid used in <c><![CDATA[ei_send_reg]]></c>, <c><![CDATA[ei_rpc]]></c>
+ and others. This is contained in a field in the <c><![CDATA[ec]]></c>
+ structure. It will be safe for a long time to fetch this
+ field directly from the <c><![CDATA[ei_cnode]]></c> structure.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>struct hostent</ret><nametext>*ei_gethostbyname(const char *name)</nametext></name>
+ <name><ret>struct hostent</ret><nametext>*ei_gethostbyaddr(const char *addr, int len, int type)</nametext></name>
+ <name><ret>struct hostent</ret><nametext>*ei_gethostbyname_r(const char *name, struct hostent *hostp, char *buffer, int buflen, int *h_errnop)</nametext></name>
+ <name><ret>struct hostent</ret><nametext>*ei_gethostbyaddr_r(const char *addr, int length, int type, struct hostent *hostp, char *buffer, int buflen, int *h_errnop)</nametext></name>
+ <fsummary>Name lookup functions</fsummary>
+ <desc>
+ <p>These are convenience functions for some common name lookup functions.</p>
+ </desc>
+ </func>
+ </funcs>
+
+ <section>
+ <title>Debug Information</title>
+ <p>If a connection attempt fails, the following can be checked:</p>
+ <list type="bulleted">
+ <item><c><![CDATA[erl_errno]]></c></item>
+ <item>that the right cookie was used</item>
+ <item>that <em>epmd</em> is running</item>
+ <item>the remote Erlang node on the other side is running the
+ same version of Erlang as the <c><![CDATA[ei]]></c>
+ library.</item>
+ <item>the environment variable <c><![CDATA[ERL_EPMD_PORT]]></c>
+ is set correctly.</item>
+ </list>
+ </section>
+</cref>
+