diff options
Diffstat (limited to 'lib/erl_interface/doc/src/ei_connect.xml')
-rw-r--r-- | lib/erl_interface/doc/src/ei_connect.xml | 639 |
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", + "[email protected]", + &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> + |