aboutsummaryrefslogtreecommitdiffstats
path: root/lib/erl_interface/doc/src
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
committerErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
commit84adefa331c4159d432d22840663c38f155cd4c1 (patch)
treebff9a9c66adda4df2106dfd0e5c053ab182a12bd /lib/erl_interface/doc/src
downloadotp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz
otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2
otp-84adefa331c4159d432d22840663c38f155cd4c1.zip
The R13B03 release.OTP_R13B03
Diffstat (limited to 'lib/erl_interface/doc/src')
-rw-r--r--lib/erl_interface/doc/src/Makefile129
-rw-r--r--lib/erl_interface/doc/src/book.xml49
-rw-r--r--lib/erl_interface/doc/src/ei.xml728
-rw-r--r--lib/erl_interface/doc/src/ei_connect.xml639
-rw-r--r--lib/erl_interface/doc/src/ei_users_guide.xml612
-rw-r--r--lib/erl_interface/doc/src/erl_call.xml240
-rw-r--r--lib/erl_interface/doc/src/erl_connect.xml566
-rw-r--r--lib/erl_interface/doc/src/erl_error.xml136
-rw-r--r--lib/erl_interface/doc/src/erl_eterm.xml675
-rw-r--r--lib/erl_interface/doc/src/erl_format.xml141
-rw-r--r--lib/erl_interface/doc/src/erl_global.xml141
-rw-r--r--lib/erl_interface/doc/src/erl_interface.xml625
-rw-r--r--lib/erl_interface/doc/src/erl_malloc.xml200
-rw-r--r--lib/erl_interface/doc/src/erl_marshal.xml272
-rw-r--r--lib/erl_interface/doc/src/fascicules.xml24
-rw-r--r--lib/erl_interface/doc/src/make.dep24
-rw-r--r--lib/erl_interface/doc/src/note.gifbin0 -> 1539 bytes
-rw-r--r--lib/erl_interface/doc/src/notes.xml535
-rw-r--r--lib/erl_interface/doc/src/notes_history.xml367
-rw-r--r--lib/erl_interface/doc/src/part.xml33
-rw-r--r--lib/erl_interface/doc/src/part_erl_interface.xml33
-rw-r--r--lib/erl_interface/doc/src/part_notes.xml38
-rw-r--r--lib/erl_interface/doc/src/part_notes_history.xml36
-rw-r--r--lib/erl_interface/doc/src/ref_man.xml55
-rw-r--r--lib/erl_interface/doc/src/ref_man_ei.xml47
-rw-r--r--lib/erl_interface/doc/src/ref_man_erl_interface.xml52
-rw-r--r--lib/erl_interface/doc/src/registry.xml611
-rw-r--r--lib/erl_interface/doc/src/warning.gifbin0 -> 1498 bytes
28 files changed, 7008 insertions, 0 deletions
diff --git a/lib/erl_interface/doc/src/Makefile b/lib/erl_interface/doc/src/Makefile
new file mode 100644
index 0000000000..e05b647cb2
--- /dev/null
+++ b/lib/erl_interface/doc/src/Makefile
@@ -0,0 +1,129 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1998-2009. All Rights Reserved.
+#
+# 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.
+#
+# %CopyrightEnd%
+#
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include ../../vsn.mk
+VSN=$(EI_VSN)
+APPLICATION=erl_interface
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+
+XML_REF1_FILES = erl_call.xml
+XML_REF3_FILES = erl_connect.xml \
+ erl_error.xml \
+ erl_eterm.xml \
+ erl_format.xml \
+ erl_malloc.xml \
+ erl_marshal.xml \
+ erl_global.xml \
+ ei.xml \
+ ei_connect.xml \
+ registry.xml
+
+BOOK_FILES = book.xml
+XML_APPLICATION_FILES = ref_man.xml
+#ref_man_ei.xml ref_man_erl_interface.xml
+XML_PART_FILES = \
+ part.xml \
+ part_notes.xml \
+ part_notes_history.xml
+XML_CHAPTER_FILES = ei_users_guide.xml notes.xml notes_history.xml
+
+XML_FILES = $(XML_REF1_FILES) $(XML_REF3_FILES) $(BOOK_FILES) \
+ $(XML_APPLICATION_FILES) $(XML_PART_FILES) $(XML_CHAPTER_FILES)
+# ----------------------------------------------------
+
+HTML_FILES = $(XML_APPLICATION_FILES:%.xml=$(HTMLDIR)/%.html) \
+ $(XML_PART_FILES:%.xml=$(HTMLDIR)/%.html)
+
+INFO_FILE = ../../info
+
+GIF_FILES =
+
+MAN1_FILES = $(XML_REF1_FILES:%.xml=$(MAN1DIR)/%.1)
+MAN3_FILES = $(XML_REF3_FILES:%.xml=$(MAN3DIR)/%.3)
+
+HTML_REF_MAN_FILE = $(HTMLDIR)/index.html
+
+TOP_PDF_FILE = $(PDFDIR)/$(APPLICATION)-$(VSN).pdf
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+XML_FLAGS +=
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+$(HTMLDIR)/%.gif: %.gif
+ $(INSTALL_DATA) $< $@
+
+docs: pdf html man
+
+$(TOP_PDF_FILE): $(XML_FILES)
+
+pdf: $(TOP_PDF_FILE)
+
+html: gifs $(HTML_REF_MAN_FILE)
+
+man: $(MAN1_FILES) $(MAN3_FILES)
+
+gifs: $(GIF_FILES:%=$(HTMLDIR)/%)
+
+debug opt:
+
+clean clean_docs clean_tex:
+ rm -rf $(HTMLDIR)/*
+ rm -f $(MAN1DIR)/*
+ rm -f $(MAN3DIR)/*
+ rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo)
+ rm -f errs core *~
+
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_docs_spec: docs
+ $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf
+ $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf
+ $(INSTALL_DIR) $(RELSYSDIR)/doc/html
+ $(INSTALL_DATA) $(HTMLDIR)/* \
+ $(RELSYSDIR)/doc/html
+ $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR)
+ $(INSTALL_DIR) $(RELEASE_PATH)/man/man1
+ $(INSTALL_DATA) $(MAN1_FILES) $(RELEASE_PATH)/man/man1
+ $(INSTALL_DIR) $(RELEASE_PATH)/man/man3
+ $(INSTALL_DATA) $(MAN3_FILES) $(RELEASE_PATH)/man/man3
+
+
+release_spec:
+
diff --git a/lib/erl_interface/doc/src/book.xml b/lib/erl_interface/doc/src/book.xml
new file mode 100644
index 0000000000..e911b6aa2b
--- /dev/null
+++ b/lib/erl_interface/doc/src/book.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE book SYSTEM "book.dtd">
+
+<book xmlns:xi="http://www.w3.org/2001/XInclude">
+ <header titlestyle="normal">
+ <copyright>
+ <year>1998</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>Erlang Interface</title>
+ <prepared>Gordon Beaton</prepared>
+ <docno></docno>
+ <date>1998-11-30</date>
+ <rev>1.2</rev>
+ <file>book.sgml</file>
+ </header>
+ <insidecover>
+ </insidecover>
+ <pagetext>Erlang Interface</pagetext>
+ <preamble>
+ <contents level="2"></contents>
+ </preamble>
+ <parts lift="no">
+ <xi:include href="part.xml"/>
+ </parts>
+ <applications>
+ <xi:include href="ref_man.xml"/>
+ </applications>
+ <releasenotes>
+ <xi:include href="notes.xml"/>
+ </releasenotes>
+ <listofterms></listofterms>
+ <index></index>
+</book>
+
diff --git a/lib/erl_interface/doc/src/ei.xml b/lib/erl_interface/doc/src/ei.xml
new file mode 100644
index 0000000000..2f65a8c375
--- /dev/null
+++ b/lib/erl_interface/doc/src/ei.xml
@@ -0,0 +1,728 @@
+<?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</title>
+ <prepared>Jakob Cederlund</prepared>
+ <responsible>Kent Boortz</responsible>
+ <docno>1</docno>
+ <approved>Kenneth Lundin</approved>
+ <checked></checked>
+ <date>2000-11-27</date>
+ <rev>PA1</rev>
+ <file>ei.sgml</file>
+ </header>
+ <lib>ei</lib>
+ <libsummary>routines for handling the erlang binary term format</libsummary>
+ <description>
+ <p>The library <c><![CDATA[ei]]></c> contains macros and functions to encode
+ and decode the erlang binary term format.</p>
+ <p>With <c><![CDATA[ei]]></c>, you can convert atoms, lists, numbers and
+ binaries to and from the binary format. This is useful when
+ writing port programs and drivers. <c><![CDATA[ei]]></c> uses a given
+ buffer, and no dynamic memory (with the exception of
+ <c><![CDATA[ei_decode_fun()]]></c>), and is often quite fast.</p>
+ <p>It also handles C-nodes, C-programs that talks erlang
+ distribution with erlang nodes (or other C-nodes) using the
+ erlang distribution format. The difference between <c><![CDATA[ei]]></c> and
+ <c><![CDATA[erl_interface]]></c> is that <c><![CDATA[ei]]></c> uses the binary format
+ directly when sending and receiving terms. It is also thread
+ safe, and using threads, one process can handle multiple
+ C-nodes. The <c><![CDATA[erl_interface]]></c> library is built on top of
+ <c><![CDATA[ei]]></c>, but of legacy reasons, it doesn't allow for multiple
+ C-nodes. In general, <c><![CDATA[ei]]></c> is the preferred way of doing
+ C-nodes.</p>
+ <p>The decode and encode functions use a buffer an index into the
+ buffer, which points at the point where to encode and
+ decode. The index is updated to point right after the term
+ encoded/decoded. No checking is done whether the term fits in
+ the buffer or not. If encoding goes outside the buffer, the
+ program may crash.</p>
+ <p>All functions takes two parameter, <c><![CDATA[buf]]></c> is a pointer to
+ the buffer where the binary data is / will be, <c><![CDATA[index]]></c> is a
+ pointer to an index into the buffer. This parameter will be
+ incremented with the size of the term decoded / encoded. The
+ data is thus at <c><![CDATA[buf[*index]]]></c> when an <c><![CDATA[ei]]></c> function is
+ called.</p>
+ <p>The encode functions all assumes that the <c><![CDATA[buf]]></c> and
+ <c><![CDATA[index]]></c> parameters points to a buffer big enough for the
+ data. To get the size of an encoded term, without encoding it,
+ pass <c><![CDATA[NULL]]></c> instead of a buffer pointer. The <c><![CDATA[index]]></c>
+ parameter will be incremented, but nothing will be encoded. This
+ is the way in <c><![CDATA[ei]]></c> to "preflight" term encoding.</p>
+ <p>There are also encode-functions that uses a dynamic buffer. It
+ is often more convenient to use these to encode data. All encode
+ functions comes in two versions: those starting with <c><![CDATA[ei_x]]></c>,
+ uses a dynamic buffer.</p>
+ <p>All functions return <c><![CDATA[0]]></c> if successful, and <c><![CDATA[-1]]></c> if
+ not. (For instance, if a term is not of the expected type, or
+ the data to decode is not a valid erlang term.)</p>
+ <p>Some of the decode-functions needs a preallocated buffer. This
+ buffer must be allocated big enough, and for non compound types
+ the <c><![CDATA[ei_get_type()]]></c>
+ function returns the size required (note that for strings an
+ extra byte is needed for the 0 string terminator).</p>
+ </description>
+ <funcs>
+ <func>
+ <name><ret>void</ret><nametext>ei_set_compat_rel(release_number)</nametext></name>
+ <fsummary>Set the ei library in compatibility mode</fsummary>
+ <type>
+ <v>unsigned release_number;</v>
+ </type>
+ <desc>
+ <marker id="ei_set_compat_rel"></marker>
+ <p>By default, the <c><![CDATA[ei]]></c> library is only guaranteed
+ to be compatible with other Erlang/OTP components from the same
+ release as the <c><![CDATA[ei]]></c> library itself. For example, <c><![CDATA[ei]]></c> from
+ the OTP R10 release is not compatible with an Erlang emulator
+ from the OTP R9 release by default.</p>
+ <p>A call to <c><![CDATA[ei_set_compat_rel(release_number)]]></c> sets the
+ <c><![CDATA[ei]]></c> library in compatibility mode of release
+ <c><![CDATA[release_number]]></c>. Valid range of <c><![CDATA[release_number]]></c>
+ is [7, current release]. This makes it possible to
+ communicate with Erlang/OTP components from earlier releases.</p>
+ <note>
+ <p>If this function is called, it may only be called once
+ and must be called before any other functions in the <c><![CDATA[ei]]></c>
+ library is called.</p>
+ </note>
+ <warning>
+ <p>You may run into trouble if this feature is used
+ carelessly. Always make sure that all communicating
+ components are either from the same Erlang/OTP release, or
+ from release X and release Y where all components
+ from release Y are in compatibility mode of release X.</p>
+ </warning>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_encode_version(char *buf, int *index)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_version(ei_x_buff* x)</nametext></name>
+ <fsummary>Encode version</fsummary>
+ <desc>
+ <p>Encodes a version magic number for the binary format. Must
+ be the first token in a binary term.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_encode_long(char *buf, int *index, long p)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_long(ei_x_buff* x, long p)</nametext></name>
+ <fsummary>Encode integer</fsummary>
+ <desc>
+ <p>Encodes a long integer in the binary format.
+ Note that if the code is 64 bits the function ei_encode_long() is
+ exactly the same as ei_encode_longlong().</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_encode_ulong(char *buf, int *index, unsigned long p)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_ulong(ei_x_buff* x, unsigned long p)</nametext></name>
+ <fsummary>Encode unsigned integer</fsummary>
+ <desc>
+ <p>Encodes an unsigned long integer in the binary format.
+ Note that if the code is 64 bits the function ei_encode_ulong() is
+ exactly the same as ei_encode_ulonglong().</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_encode_longlong(char *buf, int *index, long long p)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_longlong(ei_x_buff* x, long long p)</nametext></name>
+ <fsummary>Encode integer</fsummary>
+ <desc>
+ <p>Encodes a GCC <c><![CDATA[long long]]></c> or Visual C++ <c><![CDATA[__int64]]></c> (64 bit)
+ integer in the binary format. Note that this function is missing
+ in the VxWorks port.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_encode_ulonglong(char *buf, int *index, unsigned long long p)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_ulonglong(ei_x_buff* x, unsigned long long p)</nametext></name>
+ <fsummary>Encode unsigned integer</fsummary>
+ <desc>
+ <p>Encodes a GCC <c><![CDATA[unsigned long long]]></c> or Visual C++ <c><![CDATA[unsigned __int64]]></c> (64 bit) integer in the binary format. Note that
+ this function is missing in the VxWorks port.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_encode_bignum(char *buf, int *index, mpz_t obj)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_bignum(ei_x_buff *x, mpz_t obj)</nametext></name>
+ <fsummary>Encode an arbitrary precision integer</fsummary>
+ <desc>
+ <p>Encodes a GMP <c><![CDATA[mpz_t]]></c> integer to binary format.
+ To use this function the ei library needs to be configured and compiled
+ to use the GMP library. </p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_encode_double(char *buf, int *index, double p)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_double(ei_x_buff* x, double p)</nametext></name>
+ <fsummary>Encode a double float</fsummary>
+ <desc>
+ <p>Encodes a double-precision (64 bit) floating point number in
+ the binary format.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_encode_boolean(char *buf, int *index, int p)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_boolean(ei_x_buff* x, int p)</nametext></name>
+ <fsummary>Encode a boolean</fsummary>
+ <desc>
+ <p>Encodes a boolean value, as the atom <c><![CDATA[true]]></c> if p is not
+ zero or <c><![CDATA[false]]></c> if p is zero.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_encode_char(char *buf, int *index, char p)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_char(ei_x_buff* x, char p)</nametext></name>
+ <fsummary>Encode an 8-bit integer between 0-255</fsummary>
+ <desc>
+ <p>Encodes a char (8-bit) as an integer between 0-255 in the binary format.
+ Note that for historical reasons the integer argument is of
+ type <c><![CDATA[char]]></c>. Your C code should consider the
+ given argument to be of type <c><![CDATA[unsigned char]]></c> even if
+ the C compilers and system may define <c><![CDATA[char]]></c> to be
+ signed.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_encode_string(char *buf, int *index, const char *p)</nametext></name>
+ <name><ret>int</ret><nametext>ei_encode_string_len(char *buf, int *index, const char *p, int len)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_string(ei_x_buff* x, const char *p)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_string_len(ei_x_buff* x, const char* s, int len)</nametext></name>
+ <fsummary>Encode a string</fsummary>
+ <desc>
+ <p>Encodes a string in the binary format. (A string in erlang
+ is a list, but is encoded as a character array in the binary
+ format.) The string should be zero-terminated, except for
+ the <c><![CDATA[ei_x_encode_string_len()]]></c> function.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_encode_atom(char *buf, int *index, const char *p)</nametext></name>
+ <name><ret>int</ret><nametext>ei_encode_atom_len(char *buf, int *index, const char *p, int len)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_atom(ei_x_buff* x, const char *p)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_atom_len(ei_x_buff* x, const char *p, int len)</nametext></name>
+ <fsummary>Encode an atom</fsummary>
+ <desc>
+ <p>Encodes an atom in the binary format. The <c><![CDATA[p]]></c> parameter
+ is the name of the atom. Only upto <c><![CDATA[MAXATOMLEN]]></c> bytes
+ are encoded. The name should be zero-terminated, except for
+ the <c><![CDATA[ei_x_encode_atom_len()]]></c> function.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_encode_binary(char *buf, int *index, const void *p, long len)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_binary(ei_x_buff* x, const void *p, long len)</nametext></name>
+ <fsummary>Encode a binary</fsummary>
+ <desc>
+ <p>Encodes a binary in the binary format. The data is at
+ <c><![CDATA[p]]></c>, of <c><![CDATA[len]]></c> bytes length.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_encode_pid(char *buf, int *index, const erlang_pid *p)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_pid(ei_x_buff* x, const erlang_pid *p)</nametext></name>
+ <fsummary>Encode a pid</fsummary>
+ <desc>
+ <p>Encodes an erlang process identifier, pid, in the binary
+ format. The <c><![CDATA[p]]></c> parameter points to an
+ <c><![CDATA[erlang_pid]]></c> structure (which should have been obtained
+ earlier with <c><![CDATA[ei_decode_pid()]]></c>).</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_encode_fun(char *buf, int *index, const erlang_fun *p)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_fun(ei_x_buff* x, const erlang_fun* fun)</nametext></name>
+ <fsummary>Encode a fun</fsummary>
+ <desc>
+ <p>Encodes a fun in the binary format. The <c><![CDATA[p]]></c> parameter
+ points to an <c><![CDATA[erlang_fun]]></c> structure. The
+ <c><![CDATA[erlang_fun]]></c> is not freed automatically, the
+ <c><![CDATA[free_fun]]></c> should be called if the fun is not needed
+ after encoding.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_encode_port(char *buf, int *index, const erlang_port *p)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_port(ei_x_buff* x, const erlang_port *p)</nametext></name>
+ <fsummary>Encodes a port</fsummary>
+ <desc>
+ <p>Encodes an erlang port in the binary format. The <c><![CDATA[p]]></c>
+ parameter points to a <c><![CDATA[erlang_port]]></c> structure (which
+ should have been obtained earlier with
+ <c><![CDATA[ei_decode_port()]]></c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_encode_ref(char *buf, int *index, const erlang_ref *p)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_ref(ei_x_buff* x, const erlang_ref *p)</nametext></name>
+ <fsummary>Encodes a ref</fsummary>
+ <desc>
+ <p>Encodes an erlang reference in the binary format. The
+ <c><![CDATA[p]]></c> parameter points to a <c><![CDATA[erlang_ref]]></c> structure
+ (which should have been obtained earlier with
+ <c><![CDATA[ei_decode_ref()]]></c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_encode_term(char *buf, int *index, void *t)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_term(ei_x_buff* x, void *t)</nametext></name>
+ <fsummary>Encode an <c><![CDATA[erl_interface]]></c>term</fsummary>
+ <desc>
+ <p>This function encodes an <c><![CDATA[ETERM]]></c>, as obtained from
+ <c><![CDATA[erl_interface]]></c>. The <c><![CDATA[t]]></c> parameter is actually an
+ <c><![CDATA[ETERM]]></c> pointer. This function doesn't free the
+ <c><![CDATA[ETERM]]></c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_encode_trace(char *buf, int *index, const erlang_trace *p)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_trace(ei_x_buff* x, const erlang_trace *p)</nametext></name>
+ <fsummary>Encode a trace token</fsummary>
+ <desc>
+ <p>This function encodes an erlang trace token in the binary
+ format. The <c><![CDATA[p]]></c> parameter points to a
+ <c><![CDATA[erlang_trace]]></c> structure (which should have been
+ obtained earlier with <c><![CDATA[ei_decode_trace()]]></c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_encode_tuple_header(char *buf, int *index, int arity)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_tuple_header(ei_x_buff* x, int arity)</nametext></name>
+ <fsummary>Encode a tuple</fsummary>
+ <desc>
+ <p>This function encodes a tuple header, with a specified
+ arity. The next <c><![CDATA[arity]]></c> terms encoded will be the
+ elements of the tuple. Tuples and lists are encoded
+ recursively, so that a tuple may contain another tuple or
+ list.</p>
+ <p>E.g. to encode the tuple <c><![CDATA[{a, {b, {}}}]]></c>:</p>
+ <pre>
+ei_encode_tuple_header(buf, &amp;i, 2);
+ei_encode_atom(buf, &amp;i, "a");
+ei_encode_tuple_header(buf, &amp;i, 2);
+ei_encode_atom(buf, &amp;i, "b");
+ei_encode_tuple_header(buf, &amp;i, 0);
+ </pre>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_encode_list_header(char *buf, int *index, int arity)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_list_header(ei_x_buff* x, int arity)</nametext></name>
+ <fsummary>Encode a list</fsummary>
+ <desc>
+ <p>This function encodes a list header, with a specified
+ arity. The next <c><![CDATA[arity+1]]></c> terms are the elements
+ (actually it's <c><![CDATA[arity]]></c> cons cells) and the tail of the
+ list. Lists and tuples are encoded recursively, so that a
+ list may contain another list or tuple.</p>
+ <p>E.g. to encode the list <c><![CDATA[[c, d, [e | f]]]]></c>:</p>
+ <pre>
+ei_encode_list_header(buf, &amp;i, 3);
+ei_encode_atom(buf, &amp;i, "c");
+ei_encode_atom(buf, &amp;i, "d");
+ei_encode_list_header(buf, &amp;i, 1);
+ei_encode_atom(buf, &amp;i, "e");
+ei_encode_atom(buf, &amp;i, "f");
+ei_encode_empty_list(buf, &amp;i);
+ </pre>
+ <note>
+ <p>It may seem that there is no way to create a list without
+ knowing the number of elements in advance. But indeed
+ there is a way. Note that the list <c><![CDATA[[a, b, c]]]></c> can be
+ written as <c><![CDATA[[a | [b | [c]]]]]></c>. Using this, a list can
+ be written as conses.</p>
+ </note>
+ <p>To encode a list, without knowing the arity in advance:</p>
+ <pre>
+while (something()) {
+ ei_x_encode_list_header(&amp;x, 1);
+ ei_x_encode_ulong(&amp;x, i); /* just an example */
+}
+ei_x_encode_empty_list(&amp;x);
+ </pre>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_encode_empty_list(char* buf, int* index)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_encode_empty_list(ei_x_buff* x)</nametext></name>
+ <fsummary>Encode an empty list (<c><![CDATA[nil]]></c>)</fsummary>
+ <desc>
+ <p>This function encodes an empty list. It's often used at the
+ tail of a list.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_get_type(const char *buf, const int *index, int *type, int *size)</nametext></name>
+ <fsummary>Fetch the type and size of an encoded term</fsummary>
+ <desc>
+ <p>This function returns the type in <c><![CDATA[type]]></c> and size in
+ <c><![CDATA[size]]></c> of the encoded term.
+ For strings and atoms, size
+ is the number of characters <em>not</em> including the
+ terminating 0. For binaries, <c><![CDATA[size]]></c> is the number of
+ bytes. For lists and tuples, <c><![CDATA[size]]></c> is the arity of the
+ object. For other types, <c><![CDATA[size]]></c> is 0. In all cases,
+ <c><![CDATA[index]]></c> is left unchanged.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_version(const char *buf, int *index, int *version)</nametext></name>
+ <fsummary>Encode an empty list (<c><![CDATA[nil]]></c>)</fsummary>
+ <desc>
+ <p>This function decodes the version magic number for the
+ erlang binary term format. It must be the first token in a
+ binary term.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_long(const char *buf, int *index, long *p)</nametext></name>
+ <fsummary>Decode integer</fsummary>
+ <desc>
+ <p>This function decodes a long integer from the binary format.
+ Note that if the code is 64 bits the function ei_decode_long() is
+ exactly the same as ei_decode_longlong().</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_ulong(const char *buf, int *index, unsigned long *p)</nametext></name>
+ <fsummary>Decode unsigned integer</fsummary>
+ <desc>
+ <p>This function decodes an unsigned long integer from
+ the binary format.
+ Note that if the code is 64 bits the function ei_decode_ulong() is
+ exactly the same as ei_decode_ulonglong().</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_longlong(const char *buf, int *index, long long *p)</nametext></name>
+ <fsummary>Decode integer</fsummary>
+ <desc>
+ <p>This function decodes a GCC <c><![CDATA[long long]]></c> or Visual C++ <c><![CDATA[__int64]]></c>
+ (64 bit) integer from the binary format. Note that this
+ function is missing in the VxWorks port.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_ulonglong(const char *buf, int *index, unsigned long long *p)</nametext></name>
+ <fsummary>Decode unsigned integer</fsummary>
+ <desc>
+ <p>This function decodes a GCC <c><![CDATA[unsigned long long]]></c> or Visual C++
+ <c><![CDATA[unsigned __int64]]></c> (64 bit) integer from the binary format.
+ Note that this function is missing in the VxWorks port.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_bignum(const char *buf, int *index, mpz_t obj)</nametext></name>
+ <fsummary>Decode a GMP arbitrary precision integer</fsummary>
+ <desc>
+ <p>This function decodes an integer in the binary format to a GMP <c><![CDATA[mpz_t]]></c> integer.
+ To use this function the ei library needs to be configured and compiled
+ to use the GMP library. </p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_double(const char *buf, int *index, double *p)</nametext></name>
+ <fsummary>Decode a double</fsummary>
+ <desc>
+ <p>This function decodes an double-precision (64 bit) floating
+ point number from the binary format.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_boolean(const char *buf, int *index, int *p)</nametext></name>
+ <fsummary>Decode a boolean</fsummary>
+ <desc>
+ <p>This function decodes a boolean value from the binary
+ format. A boolean is actually an atom, <c><![CDATA[true]]></c> decodes 1
+ and <c><![CDATA[false]]></c> decodes 0.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_char(const char *buf, int *index, char *p)</nametext></name>
+ <fsummary>Decode an 8-bit integer between 0-255</fsummary>
+ <desc>
+ <p>This function decodes a char (8-bit) integer between 0-255
+ from the binary format.
+ Note that for historical reasons the returned integer is of
+ type <c><![CDATA[char]]></c>. Your C code should consider the
+ returned value to be of type <c><![CDATA[unsigned char]]></c> even if
+ the C compilers and system may define <c><![CDATA[char]]></c> to be
+ signed.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_string(const char *buf, int *index, char *p)</nametext></name>
+ <fsummary>Decode a string</fsummary>
+ <desc>
+ <p>This function decodes a string from the binary format. A
+ string in erlang is a list of integers between 0 and
+ 255. Note that since the string is just a list, sometimes
+ lists are encoded as strings by <c><![CDATA[term_to_binary/1]]></c>,
+ even if it was not intended.</p>
+ <p>The string is copied to <c><![CDATA[p]]></c>, and enough space must be
+ allocated. The returned string is null terminated so you
+ need to add an extra byte to the memory requirement.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_atom(const char *buf, int *index, char *p)</nametext></name>
+ <fsummary>Decode an atom</fsummary>
+ <desc>
+ <p>This function decodes an atom from the binary format. The
+ name of the atom is placed at <c><![CDATA[p]]></c>. There can be at most
+ <c><![CDATA[MAXATOMLEN]]></c> bytes placed in the buffer.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_binary(const char *buf, int *index, void *p, long *len)</nametext></name>
+ <fsummary>Decode a binary</fsummary>
+ <desc>
+ <p>This function decodes a binary from the binary format. The
+ <c><![CDATA[len]]></c> parameter is set to the actual size of the
+ binary. Note that <c><![CDATA[ei_decode_binary()]]></c> assumes that there
+ are enough room for the binary. The size required can be
+ fetched by <c><![CDATA[ei_get_type()]]></c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_fun(const char *buf, int *index, erlang_fun *p)</nametext></name>
+ <name><ret>void</ret><nametext>free_fun(erlang_fun* f)</nametext></name>
+ <fsummary>Decode a fun</fsummary>
+ <desc>
+ <p>This function decodes a fun from the binary format. The
+ <c><![CDATA[p]]></c> parameter should be NULL or point to an
+ <c><![CDATA[erlang_fun]]></c> structure. This is the only decode
+ function that allocates memory; when the <c><![CDATA[erlang_fun]]></c>
+ is no longer needed, it should be freed with
+ <c><![CDATA[free_fun]]></c>. (This has to do with the arbitrary size of
+ the environment for a fun.)</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_pid(const char *buf, int *index, erlang_pid *p)</nametext></name>
+ <fsummary>Decode a <c><![CDATA[pid]]></c></fsummary>
+ <desc>
+ <p>Decodes a pid, process identifier, from the binary format.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_port(const char *buf, int *index, erlang_port *p)</nametext></name>
+ <fsummary>Decode a port</fsummary>
+ <desc>
+ <p>This function decodes a port identifier from the binary
+ format.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_ref(const char *buf, int *index, erlang_ref *p)</nametext></name>
+ <fsummary>Decode a reference</fsummary>
+ <desc>
+ <p>This function decodes a reference from the binary format.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_trace(const char *buf, int *index, erlang_trace *p)</nametext></name>
+ <fsummary>Decode a trace token</fsummary>
+ <desc>
+ <p>Decodes an erlang trace token from the binary format.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_tuple_header(const char *buf, int *index, int *arity)</nametext></name>
+ <fsummary>Decode a tuple</fsummary>
+ <desc>
+ <p>This function decodes a tuple header, the number of elements
+ is returned in <c><![CDATA[arity]]></c>. The tuple elements follows in order in
+ the buffer.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_list_header(const char *buf, int *index, int *arity)</nametext></name>
+ <fsummary>Decode a list</fsummary>
+ <desc>
+ <p>This function decodes a list header from the binary
+ format. The number of elements is returned in
+ <c><![CDATA[arity]]></c>. The <c><![CDATA[arity+1]]></c> elements follows (the last
+ one is the tail of the list, normally an empty list.) If
+ <c><![CDATA[arity]]></c> is <c><![CDATA[0]]></c>, it's an empty list.</p>
+ <p>Note that lists are encoded as strings, if they consist
+ entirely of integers in the range 0..255. This function will
+ not decode such strings, use <c><![CDATA[ei_decode_string()]]></c>
+ instead.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_ei_term(const char* buf, int* index, ei_term* term)</nametext></name>
+ <fsummary>Decode a term, without prior knowledge of type</fsummary>
+ <desc>
+ <p>This function decodes any term, or at least tries to. If the
+ term pointed at by <c><![CDATA[*index]]></c> in <c><![CDATA[buf]]></c> fits in the
+ <c><![CDATA[term]]></c> union, it is decoded, and the appropriate field
+ in <c><![CDATA[term->value]]></c> is set, and <c><![CDATA[*index]]></c> is
+ incremented by the term size.</p>
+ <p>The function returns 0 on successful encoding, -1 on error,
+ and 1 if the term seems alright, but does not fit in the
+ <c><![CDATA[term]]></c> structure. If it returns 0, the <c><![CDATA[index]]></c>
+ will be incremented, and the <c><![CDATA[term]]></c> contains the
+ decoded term.</p>
+ <p>The <c><![CDATA[term]]></c> structure will contain the arity for a tuple
+ or list, size for a binary, string or atom. It will contains
+ a term if it's any of the following: integer, float, atom,
+ pid, port or ref.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_decode_term(const char *buf, int *index, void *t)</nametext></name>
+ <fsummary>Decode a <c><![CDATA[ETERM]]></c></fsummary>
+ <desc>
+ <p>This function decodes a term from the binary format. The
+ term is return in <c><![CDATA[t]]></c> as a <c><![CDATA[ETERM*]]></c>, so <c><![CDATA[t]]></c>
+ is actually an <c><![CDATA[ETERM**]]></c> (see
+ <c><![CDATA[erl_interface(3)]]></c>. The term should later be
+ deallocated.</p>
+ <p>Note that this function is located in the erl_interface
+ library.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_print_term(FILE* fp, const char* buf, int* index)</nametext></name>
+ <name><ret>int</ret><nametext>ei_s_print_term(char** s, const char* buf, int* index)</nametext></name>
+ <fsummary>Print a term in clear text</fsummary>
+ <desc>
+ <p>This function prints a term, in clear text, to the file
+ given by <c><![CDATA[fp]]></c>, or the buffer pointed to by <c><![CDATA[s]]></c>. It
+ tries to resemble the term printing in the erlang shell.</p>
+ <p>In <c><![CDATA[ei_s_print_term()]]></c>, the parameter <c><![CDATA[s]]></c> should
+ point to a dynamically (malloc) allocated string of
+ <c><![CDATA[BUFSIZ]]></c> bytes or a NULL pointer. The string may be
+ reallocated (and <c><![CDATA[*s]]></c> may be updated) by this function
+ if the result is more than <c><![CDATA[BUFSIZ]]></c> characters. The
+ string returned is zero-terminated.</p>
+ <p>The return value is the number of characters written to the
+ file or string, or -1 if <c><![CDATA[buf[index]]]></c> doesn't contain a
+ valid term. Unfortunately, I/O errors on <c><![CDATA[fp]]></c> is not
+ checked.</p>
+ <p>The argument <c><![CDATA[index]]></c> is updated, i.e. this function can
+ be viewed as en decode function that decodes a term into a
+ human readable format.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_x_format(ei_x_buff* x, const char* fmt, ...)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_format_wo_ver(ei_x_buff* x, const char *fmt, ... )</nametext></name>
+ <fsummary>Format a term from a format string and parameters.</fsummary>
+ <desc>
+ <p>Format a term, given as a string, to a buffer. This
+ functions works like a sprintf for erlang terms. The
+ <c><![CDATA[fmt]]></c> contains a format string, with arguments like
+ <c><![CDATA[~d]]></c>, to insert terms from variables. The following
+ formats are supported (with the C types given):</p>
+ <p></p>
+ <pre>
+~a - an atom, char*
+~s - a string, char*
+~i - an integer, int
+~l - a long integer, long int
+~u - a unsigned long integer, unsigned long int
+~f - a float, float
+~d - a double float, double float
+ </pre>
+ <p>For instance, to encode a tuple with some stuff:</p>
+ <pre>
+ei_x_format("{~a,~i,~d}", "numbers", 12, 3.14159)
+encodes the tuple {numbers,12,3.14159}
+ </pre>
+ <p>The <c><![CDATA[ei_x_format_wo_ver()]]></c> formats into a buffer, without
+ the initial version byte.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_x_new(ei_x_buff* x)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_new_with_version(ei_x_buff* x)</nametext></name>
+ <fsummary>Allocate a new buffer</fsummary>
+ <desc>
+ <p>This function allocates a new <c><![CDATA[ei_x_buff]]></c> buffer. The
+ fields of the structure pointed to by <c><![CDATA[x]]></c> parameter is
+ filled in, and a default buffer is allocated. The
+ <c><![CDATA[ei_x_new_with_version()]]></c> also puts an initial version
+ byte, that is used in the binary format. (So that
+ <c><![CDATA[ei_x_encode_version()]]></c> won't be needed.)</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_x_free(ei_x_buff* x)</nametext></name>
+ <fsummary>Frees a buffer</fsummary>
+ <desc>
+ <p>This function frees an <c><![CDATA[ei_x_buff]]></c> buffer. The memory
+ used by the buffer is returned to the OS.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_x_append(ei_x_buff* x, const ei_x_buff* x2)</nametext></name>
+ <name><ret>int</ret><nametext>ei_x_append_buf(ei_x_buff* x, const char* buf, int len)</nametext></name>
+ <fsummary>Appends a buffer at the end</fsummary>
+ <desc>
+ <p>These functions appends data at the end of the buffer <c><![CDATA[x]]></c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_skip_term(const char* buf, int* index)</nametext></name>
+ <fsummary>skip a term</fsummary>
+ <desc>
+ <p>This function skips a term in the given buffer, it
+ recursively skips elements of lists and tuples, so that a
+ full term is skipped. This is a way to get the size of an
+ erlang term.</p>
+ <p><c><![CDATA[buf]]></c> is the buffer.</p>
+ <p><c><![CDATA[index]]></c> is updated to point right after the term in the
+ buffer.</p>
+ <note>
+ <p>This can be useful when you want to hold arbitrary
+ terms: just skip them and copy the binary term data to some
+ buffer.</p>
+ </note>
+ <p>The function returns <c><![CDATA[0]]></c> on success and <c><![CDATA[-1]]></c> on
+ failure.</p>
+ </desc>
+ </func>
+ </funcs>
+
+ <section>
+ <title>Debug Information</title>
+ <p>Some tips on what to check when the emulator doesn't seem to
+ receive the terms that you send.</p>
+ <list type="bulleted">
+ <item>be careful with the version header, use
+ <c><![CDATA[ei_x_new_with_version()]]></c> when appropriate</item>
+ <item>turn on distribution tracing on the erlang node</item>
+ <item>check the result codes from ei_decode_-calls</item>
+ </list>
+ </section>
+
+ <section>
+ <title>See Also</title>
+ <p>erl_interface(3)</p>
+ </section>
+</cref>
+
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>
+
diff --git a/lib/erl_interface/doc/src/ei_users_guide.xml b/lib/erl_interface/doc/src/ei_users_guide.xml
new file mode 100644
index 0000000000..5d18e356cb
--- /dev/null
+++ b/lib/erl_interface/doc/src/ei_users_guide.xml
@@ -0,0 +1,612 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2002</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>The El Library User's Guide</title>
+ <prepared>Kent Boortz</prepared>
+ <responsible>Kent Boortz</responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date></date>
+ <rev></rev>
+ <file>ei_users_guide.xml</file>
+ </header>
+ <p>The Erl_Interface library contains functions. which help you
+ integrate programs written in C and Erlang. The functions in
+ Erl_Interface support the following:</p>
+ <list type="bulleted">
+ <item>manipulation of data represented as Erlang data types</item>
+ <item>conversion of data between C and Erlang formats</item>
+ <item>encoding and decoding of Erlang data types for transmission or storage</item>
+ <item>communication between C nodes and Erlang processes</item>
+ <item>backup and restore of C node state to and from Mnesia</item>
+ </list>
+ <p>In the following sections, these topics are described:</p>
+ <list type="bulleted">
+ <item>compiling your code for use with Erl_Interface</item>
+ <item>initializing Erl_Interface</item>
+ <item>encoding, decoding, and sending Erlang terms</item>
+ <item>building terms and patterns</item>
+ <item>pattern matching</item>
+ <item>connecting to a distributed Erlang node</item>
+ <item>using EPMD</item>
+ <item>sending and receiving Erlang messages</item>
+ <item>remote procedure calls</item>
+ <item>global names</item>
+ <item>the registry</item>
+ </list>
+
+ <section>
+ <title>Compiling and Linking Your Code</title>
+ <p>In order to use any of the Erl_Interface functions, include the
+ following lines in your code:</p>
+ <code type="none"><![CDATA[
+#include "erl_interface.h"
+#include "ei.h" ]]></code>
+ <p>Determine where the top directory of your OTP installation is. You
+ can find this out by starting Erlang and entering the following
+ command at the Eshell prompt:</p>
+ <code type="none"><![CDATA[
+Eshell V4.7.4 (abort with ^G)
+1> code:root_dir().
+/usr/local/otp ]]></code>
+ <p>To compile your code, make sure that your C compiler knows where
+ to find <c><![CDATA[erl_interface.h]]></c> by specifying an appropriate <c><![CDATA[-I]]></c>
+ argument on the command line, or by adding it to the <c><![CDATA[CFLAGS]]></c>
+ definition in your <c><![CDATA[Makefile]]></c>. The correct value for this path is
+ <c><![CDATA[$OTPROOT/lib/erl_interface]]></c><em>Vsn</em><c><![CDATA[/include]]></c>, where <c><![CDATA[$OTPROOT]]></c> is the path
+ reported by <c><![CDATA[code:root_dir/0]]></c> in the above example, and <em>Vsn</em> is
+ the version of the Erl_interface application, for example
+ <c><![CDATA[erl_interface-3.2.3]]></c></p>
+ <code type="none"><![CDATA[
+$ cc -c -I/usr/local/otp/lib/erl_interface-3.2.3/include myprog.c ]]></code>
+ <p>When linking, you will need to specify the path to
+ <c><![CDATA[liberl_interface.a]]></c> and <c><![CDATA[libei.a]]></c> with
+ <c><![CDATA[-L$OTPROOT/lib/erl_interface-3.2.3/lib]]></c>, and you will need to specify the
+ name of the libraries with <c><![CDATA[-lerl_interface -lei]]></c>. You can do
+ this on the command line or by adding the flags to the <c><![CDATA[LDFLAGS]]></c>
+ definition in your <c><![CDATA[Makefile]]></c>.</p>
+ <code type="none"><![CDATA[
+$ ld -L/usr/local/otp/lib/erl_interface-3.2.3/
+ lib myprog.o -lerl_interface -lei -o myprog ]]></code>
+ <p>Also, on some systems it may be necessary to link with some
+ additional libraries (e.g. <c><![CDATA[libnsl.a]]></c> and <c><![CDATA[libsocket.a]]></c> on
+ Solaris, or <c><![CDATA[wsock32.lib]]></c> on Windows) in order to use the
+ communication facilities of Erl_Interface.</p>
+ <p>If you are using Erl_Interface functions in a threaded
+ application based on POSIX threads or Solaris threads, then
+ Erl_Interface needs access to some of the synchronization
+ facilities in your threads package, and you will need to specify
+ additional compiler flags in order to indicate which of the packages
+ you are using. Define <c><![CDATA[_REENTRANT]]></c> and either <c><![CDATA[STHREADS]]></c> or
+ <c><![CDATA[PTHREADS]]></c>. The default is to use POSIX threads if
+ <c><![CDATA[_REENTRANT]]></c> is specified.</p>
+ </section>
+
+ <section>
+ <title>Initializing the erl_interface Library</title>
+ <p>Before calling any of the other Erl_Interface functions, you
+ must call <c><![CDATA[erl_init()]]></c> exactly once to initialize the library.
+ <c><![CDATA[erl_init()]]></c> takes two arguments, however the arguments are no
+ longer used by Erl_Interface, and should therefore be specified
+ as <c><![CDATA[erl_init(NULL,0)]]></c>.</p>
+ </section>
+
+ <section>
+ <title>Encoding, Decoding and Sending Erlang Terms</title>
+ <p>Data sent between distributed Erlang nodes is encoded in the
+ Erlang external format. Consequently, you have to encode and decode
+ Erlang terms into byte streams if you want to use the distribution
+ protocol to communicate between a C program and Erlang. </p>
+ <p>The Erl_Interface library supports this activity. It has a
+ number of C functions which create and manipulate Erlang data
+ structures. The library also contains an encode and a decode function.
+ The example below shows how to create and encode an Erlang tuple
+ <c><![CDATA[{tobbe,3928}]]></c>:</p>
+ <code type="none"><![CDATA[
+
+ETERM *arr[2], *tuple;
+char buf[BUFSIZ];
+int i;
+
+arr[0] = erl_mk_atom("tobbe");
+arr[1] = erl_mk_integer(3928);
+tuple = erl_mk_tuple(arr, 2);
+i = erl_encode(tuple, buf); ]]></code>
+ <p>Alternatively, you can use <c><![CDATA[erl_send()]]></c> and
+ <c><![CDATA[erl_receive_msg]]></c>, which handle the encoding and decoding of
+ messages transparently.</p>
+ <p>Refer to the Reference Manual for a complete description of the
+ following modules:</p>
+ <list type="bulleted">
+ <item>the <c><![CDATA[erl_eterm]]></c> module for creating Erlang terms</item>
+ <item>the <c><![CDATA[erl_marshal]]></c> module for encoding and decoding routines.</item>
+ </list>
+ </section>
+
+ <section>
+ <title>Building Terms and Patterns</title>
+ <p>The previous example can be simplified by using
+ <c><![CDATA[erl_format()]]></c> to create an Erlang term.</p>
+ <code type="none"><![CDATA[
+
+ETERM *ep;
+ep = erl_format("{~a,~i}", "tobbe", 3928); ]]></code>
+ <p>Refer to the Reference Manual, the <c><![CDATA[erl_format]]></c> module, for a
+ full description of the different format directives. The following
+ example is more complex:</p>
+ <code type="none"><![CDATA[
+
+ETERM *ep;
+ep = erl_format("[{name,~a},{age,~i},{data,~w}]",
+ "madonna",
+ 21,
+ erl_format("[{adr,~s,~i}]", "E-street", 42));
+erl_free_compound(ep); ]]></code>
+ <p>As in previous examples, it is your responsibility to free the
+ memory allocated for Erlang terms. In this example,
+ <c><![CDATA[erl_free_compound()]]></c> ensures that the complete term pointed to
+ by <c><![CDATA[ep]]></c> is released. This is necessary, because the pointer from
+ the second call to <c><![CDATA[erl_format()]]></c> is lost. </p>
+ <p>The following
+ example shows a slightly different solution:</p>
+ <code type="none"><![CDATA[
+
+ETERM *ep,*ep2;
+ep2 = erl_format("[{adr,~s,~i}]","E-street",42);
+ep = erl_format("[{name,~a},{age,~i},{data,~w}]",
+ "madonna", 21, ep2);
+erl_free_term(ep);
+erl_free_term(ep2); ]]></code>
+ <p>In this case, you free the two terms independently. The order in
+ which you free the terms <c><![CDATA[ep]]></c> and <c><![CDATA[ep2]]></c> is not important,
+ because the Erl_Interface library uses reference counting to
+ determine when it is safe to actually remove objects. </p>
+ <p>If you are not sure whether you have freed the terms properly, you
+ can use the following function to see the status of the fixed term
+ allocator:</p>
+ <code type="none"><![CDATA[
+long allocated, freed;
+
+erl_eterm_statistics(&allocated,&freed);
+printf("currently allocated blocks: %ld\n",allocated);
+printf("length of freelist: %ld\n",freed);
+
+/* really free the freelist */
+erl_eterm_release();
+ ]]></code>
+ <p>Refer to the Reference Manual, the <c><![CDATA[erl_malloc]]></c> module for more
+ information.</p>
+ </section>
+
+ <section>
+ <title>Pattern Matching</title>
+ <p>An Erlang pattern is a term that may contain unbound variables or
+ <c><![CDATA["do not care"]]></c> symbols. Such a pattern can be matched against a
+ term and, if the match is successful, any unbound variables in the
+ pattern will be bound as a side effect. The content of a bound
+ variable can then be retrieved.</p>
+ <code type="none"><![CDATA[
+
+ETERM *pattern;
+pattern = erl_format("{madonna,Age,_}"); ]]></code>
+ <p><c><![CDATA[erl_match()]]></c> is used to perform pattern matching. It takes a
+ pattern and a term and tries to match them. As a side effect any unbound
+ variables in the pattern will be bound. In the following example, we
+ create a pattern with a variable <em>Age</em> which appears at two
+ positions in the tuple. The pattern match is performed as follows:</p>
+ <list type="ordered">
+ <item><c><![CDATA[erl_match()]]></c> will bind the contents of
+ <em>Age</em> to <em>21</em> the first time it reaches the variable</item>
+ <item>the second occurrence of <em>Age</em> will cause a test for
+ equality between the terms since <em>Age</em> is already bound to
+ <em>21</em>. Since <em>Age</em> is bound to 21, the equality test will
+ succeed and the match continues until the end of the pattern.</item>
+ <item>if the end of the pattern is reached, the match succeeds and you
+ can retrieve the contents of the variable</item>
+ </list>
+ <code type="none"><![CDATA[
+ETERM *pattern,*term;
+pattern = erl_format("{madonna,Age,Age}");
+term = erl_format("{madonna,21,21}");
+if (erl_match(pattern, term)) {
+ fprintf(stderr, "Yes, they matched: Age = ");
+ ep = erl_var_content(pattern, "Age");
+ erl_print_term(stderr, ep);
+ fprintf(stderr,"\n");
+ erl_free_term(ep);
+}
+erl_free_term(pattern);
+erl_free_term(term); ]]></code>
+ <p>Refer to the Reference Manual, the <c><![CDATA[erl_match()]]></c> function for
+ more information.</p>
+ </section>
+
+ <section>
+ <title>Connecting to a Distributed Erlang Node</title>
+ <p>In order to connect to a distributed Erlang node you need to first
+ initialize the connection routine with <c><![CDATA[erl_connect_init()]]></c>,
+ which stores information such as the host name, node name, and IP
+ address for later use:</p>
+ <code type="none"><![CDATA[
+int identification_number = 99;
+int creation=1;
+char *cookie="a secret cookie string"; /* An example */
+erl_connect_init(identification_number, cookie, creation); ]]></code>
+ <p>Refer to the Reference Manual, the <c><![CDATA[erl_connect]]></c> module for more information.</p>
+ <p>After initialization, you set up the connection to the Erlang node.
+ Use <c><![CDATA[erl_connect()]]></c> to specify the Erlang node you want to
+ connect to. The following example sets up the connection and should
+ result in a valid socket file descriptor:</p>
+ <code type="none"><![CDATA[
+int sockfd;
+char *nodename="[email protected]"; /* An example */
+if ((sockfd = erl_connect(nodename)) < 0)
+ erl_err_quit("ERROR: erl_connect failed"); ]]></code>
+ <p><c><![CDATA[erl_err_quit()]]></c> prints the specified string and terminates
+ the program. Refer to the Reference Manual, the <c><![CDATA[erl_error()]]></c>
+ function for more information.</p>
+ </section>
+
+ <section>
+ <title>Using EPMD</title>
+ <p><c><![CDATA[Epmd]]></c> is the Erlang Port Mapper Daemon. Distributed Erlang nodes
+ register with <c><![CDATA[epmd]]></c> on the localhost to indicate to other nodes that
+ they exist and can accept connections. <c><![CDATA[Epmd]]></c> maintains a register of
+ node and port number information, and when a node wishes to connect to
+ another node, it first contacts <c><![CDATA[epmd]]></c> in order to find out the correct
+ port number to connect to.</p>
+ <p>When you use <c><![CDATA[erl_connect()]]></c> to connect to an Erlang node, a
+ connection is first made to <c><![CDATA[epmd]]></c> and, if the node is known, a
+ connection is then made to the Erlang node.</p>
+ <p>C nodes can also register themselves with <c><![CDATA[epmd]]></c> if they want other
+ nodes in the system to be able to find and connect to them.</p>
+ <p>Before registering with <c><![CDATA[epmd]]></c>, you need to first create a listen socket
+ and bind it to a port. Then:</p>
+ <code type="none"><![CDATA[
+int pub;
+
+pub = erl_publish(port); ]]></code>
+ <p><c><![CDATA[pub]]></c> is a file descriptor now connected to <c><![CDATA[epmd]]></c>. <c><![CDATA[Epmd]]></c>
+ monitors the other end of the connection, and if it detects that the
+ connection has been closed, the node will be unregistered. So, if you
+ explicitly close the descriptor or if your node fails, it will be
+ unregistered from <c><![CDATA[epmd]]></c>.</p>
+ <p>Be aware that on some systems (such as VxWorks), a failed node will
+ not be detected by this mechanism since the operating system does not
+ automatically close descriptors that were left open when the node
+ failed. If a node has failed in this way, <c><![CDATA[epmd]]></c> will prevent you from
+ registering a new node with the old name, since it thinks that the old
+ name is still in use. In this case, you must unregister the name
+ explicitly:</p>
+ <code type="none"><![CDATA[
+erl_unpublish(node); ]]></code>
+ <p>This will cause <c><![CDATA[epmd]]></c> to close the connection from the far end. Note
+ that if the name was in fact still in use by a node, the results of
+ this operation are unpredictable. Also, doing this does not cause the
+ local end of the connection to close, so resources may be consumed.</p>
+ </section>
+
+ <section>
+ <title>Sending and Receiving Erlang Messages</title>
+ <p>Use one of the following two functions to send messages:</p>
+ <list type="bulleted">
+ <item><c><![CDATA[erl_send()]]></c></item>
+ <item><c><![CDATA[erl_reg_send()]]></c></item>
+ </list>
+ <p>As in Erlang, it is possible to send messages to a
+ <em>Pid</em> or to a registered name. It is easier to send a
+ message to a registered name because it avoids the problem of finding
+ a suitable <em>Pid</em>.</p>
+ <p>Use one of the following two functions to receive messages:</p>
+ <list type="bulleted">
+ <item><c><![CDATA[erl_receive()]]></c></item>
+ <item><c><![CDATA[erl_receive_msg()]]></c></item>
+ </list>
+ <p><c><![CDATA[erl_receive()]]></c> receives the message into a buffer, while
+ <c><![CDATA[erl_receive_msg()]]></c> decodes the message into an Erlang term. </p>
+
+ <section>
+ <title>Example of Sending Messages</title>
+ <p>In the following example, <c><![CDATA[{Pid, hello_world}]]></c> is
+ sent to a registered process <c><![CDATA[my_server]]></c>. The message is encoded
+ by <c><![CDATA[erl_send()]]></c>:</p>
+ <code type="none"><![CDATA[
+extern const char *erl_thisnodename(void);
+extern short erl_thiscreation(void);
+#define SELF(fd) erl_mk_pid(erl_thisnodename(),fd,0,erl_thiscreation())
+ETERM *arr[2], *emsg;
+int sockfd, creation=1;
+
+arr[0] = SELF(sockfd);
+arr[1] = erl_mk_atom("Hello world");
+emsg = erl_mk_tuple(arr, 2);
+
+erl_reg_send(sockfd, "my_server", emsg);
+erl_free_term(emsg); ]]></code>
+ <p>The first element of the tuple that is sent is your own
+ <em>Pid</em>. This enables <c><![CDATA[my_server]]></c> to reply. Refer to the
+ Reference Manual, the <c><![CDATA[erl_connect]]></c> module for more information
+ about send primitives.</p>
+ </section>
+
+ <section>
+ <title>Example of Receiving Messages</title>
+ <p>In this example <c><![CDATA[{Pid, Something}]]></c> is received. The
+ received Pid is then used to return <c><![CDATA[{goodbye,Pid}]]></c></p>
+ <code type="none"><![CDATA[
+ETERM *arr[2], *answer;
+int sockfd,rc;
+char buf[BUFSIZE];
+ErlMessage emsg;
+
+if ((rc = erl_receive_msg(sockfd , buf, BUFSIZE, &emsg)) == ERL_MSG) {
+ arr[0] = erl_mk_atom("goodbye");
+ arr[1] = erl_element(1, emsg.msg);
+ answer = erl_mk_tuple(arr, 2);
+ erl_send(sockfd, arr[1], answer);
+ erl_free_term(answer);
+ erl_free_term(emsg.msg);
+ erl_free_term(emsg.to);
+} ]]></code>
+ <p>In order to provide robustness, a distributed Erlang node
+ occasionally polls all its connected neighbours in an attempt to
+ detect failed nodes or communication links. A node which receives such
+ a message is expected to respond immediately with an <c><![CDATA[ERL_TICK]]></c> message.
+ This is done automatically by <c><![CDATA[erl_receive()]]></c>, however when this
+ has occurred <c><![CDATA[erl_receive]]></c> returns <c><![CDATA[ERL_TICK]]></c> to the caller
+ without storing a message into the <c><![CDATA[ErlMessage]]></c> structure.</p>
+ <p>When a message has been received, it is the caller's responsibility
+ to free the received message <c><![CDATA[emsg.msg]]></c> as well as <c><![CDATA[emsg.to]]></c>
+ or <c><![CDATA[emsg.from]]></c>, depending on the type of message received.</p>
+ <p>Refer to the Reference Manual for additional information about the
+ following modules:</p>
+ <list type="bulleted">
+ <item><c><![CDATA[erl_connect]]></c></item>
+ <item><c><![CDATA[erl_eterm]]></c>.</item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Remote Procedure Calls</title>
+ <p>An Erlang node acting as a client to another Erlang node
+ typically sends a request and waits for a reply. Such a request is
+ included in a function call at a remote node and is called a remote
+ procedure call. The following example shows how the
+ Erl_Interface library supports remote procedure calls:</p>
+ <code type="none"><![CDATA[
+
+char modname[]=THE_MODNAME;
+ETERM *reply,*ep;
+ep = erl_format("[~a,[]]", modname);
+if (!(reply = erl_rpc(fd, "c", "c", ep)))
+ erl_err_msg("<ERROR> when compiling file: %s.erl !\n", modname);
+erl_free_term(ep);
+ep = erl_format("{ok,_}");
+if (!erl_match(ep, reply))
+ erl_err_msg("<ERROR> compiler errors !\n");
+erl_free_term(ep);
+erl_free_term(reply); ]]></code>
+ <p><c><![CDATA[c:c/1]]></c> is called to compile the specified module on the
+ remote node. <c><![CDATA[erl_match()]]></c> checks that the compilation was
+ successful by testing for the expected <c><![CDATA[ok]]></c>.</p>
+ <p>Refer to the Reference Manual, the <c><![CDATA[erl_connect]]></c> module for
+ more information about <c><![CDATA[erl_rpc()]]></c>, and its companions
+ <c><![CDATA[erl_rpc_to()]]></c> and <c><![CDATA[erl_rpc_from()]]></c>.</p>
+ </section>
+
+ <section>
+ <title>Using Global Names</title>
+ <p>A C node has access to names registered through the Erlang Global
+ module. Names can be looked up, allowing the C node to send messages
+ to named Erlang services. C nodes can also register global names,
+ allowing them to provide named services to Erlang processes or other C
+ nodes. </p>
+ <p>Erl_Interface does not provide a native implementation of the global
+ service. Instead it uses the global services provided by a "nearby"
+ Erlang node. In order to use the services described in this section,
+ it is necessary to first open a connection to an Erlang node.</p>
+ <p>To see what names there are:</p>
+ <code type="none"><![CDATA[
+char **names;
+int count;
+int i;
+
+names = erl_global_names(fd,&count);
+
+if (names)
+ for (i=0; i<count; i++)
+ printf("%s\n",names[i]);
+
+free(names); ]]></code>
+ <p><c><![CDATA[erl_global_names()]]></c> allocates and returns a buffer containing
+ all the names known to global. <c><![CDATA[count]]></c> will be initialized to
+ indicate how many names are in the array. The array of strings in
+ names is terminated by a NULL pointer, so it is not necessary to use
+ <c><![CDATA[count]]></c> to determine when the last name is reached.</p>
+ <p>It is the caller's responsibility to free the array.
+ <c><![CDATA[erl_global_names()]]></c> allocates the array and all of the strings
+ using a single call to <c><![CDATA[malloc()]]></c>, so <c><![CDATA[free(names)]]></c> is all
+ that is necessary.</p>
+ <p>To look up one of the names:</p>
+ <code type="none"><![CDATA[
+ETERM *pid;
+char node[256];
+
+pid = erl_global_whereis(fd,"schedule",node); ]]></code>
+ <p>If <c><![CDATA["schedule"]]></c> is known to global, an Erlang pid is returned
+ that can be used to send messages to the schedule service.
+ Additionally, <c><![CDATA[node]]></c> will be initialized to contain the name of
+ the node where the service is registered, so that you can make a
+ connection to it by simply passing the variable to <c><![CDATA[erl_connect()]]></c>.</p>
+ <p>Before registering a name, you should already have registered your
+ port number with <c><![CDATA[epmd]]></c>. This is not strictly necessary, but if you
+ neglect to do so, then other nodes wishing to communicate with your
+ service will be unable to find or connect to your process.</p>
+ <p>Create a pid that Erlang processes can use to communicate with your
+ service:</p>
+ <code type="none"><![CDATA[
+ETERM *pid;
+
+pid = erl_mk_pid(thisnode,14,0,0);
+erl_global_register(fd,servicename,pid); ]]></code>
+ <p>After registering the name, you should use <c><![CDATA[erl_accept()]]></c> to wait for
+ incoming connections.</p>
+ <p>Do not forget to free <c><![CDATA[pid]]></c> later with <c><![CDATA[erl_free_term()]]></c>!</p>
+ <p>To unregister a name:</p>
+ <code type="none"><![CDATA[
+erl_global_unregister(fd,servicename); ]]></code>
+ </section>
+
+ <section>
+ <title>The Registry</title>
+ <p>This section describes the use of the registry, a simple mechanism
+ for storing key-value pairs in a C-node, as well as backing them up or
+ restoring them from a Mnesia table on an Erlang node. More detailed
+ information about the individual API functions can be found in the
+ Reference Manual.</p>
+ <p>Keys are strings, i.e. 0-terminated arrays of characters, and values
+ are arbitrary objects. Although integers and floating point numbers
+ are treated specially by the registry, you can store strings or binary
+ objects of any type as pointers.</p>
+ <p>To start, you need to open a registry:</p>
+ <code type="none"><![CDATA[
+ei_reg *reg;
+
+reg = ei_reg_open(45); ]]></code>
+ <p>The number 45 in the example indicates the approximate number of
+ objects that you expect to store in the registry. Internally the
+ registry uses hash tables with collision chaining, so there is no
+ absolute upper limit on the number of objects that the registry can
+ contain, but if performance or memory usage are important, then you
+ should choose a number accordingly. The registry can be resized later.</p>
+ <p>You can open as many registries as you like (if memory permits).</p>
+ <p>Objects are stored and retrieved through set and get functions. In
+ the following examples you see how to store integers, floats, strings
+ and arbitrary binary objects:</p>
+ <code type="none"><![CDATA[
+struct bonk *b = malloc(sizeof(*b));
+char *name = malloc(7);
+
+ei_reg_setival(reg,"age",29);
+ei_reg_setfval(reg,"height",1.85);
+
+strcpy(name,"Martin");
+ei_reg_setsval(reg,"name",name);
+
+b->l = 42;
+b->m = 12;
+ei_reg_setpval(reg,"jox",b,sizeof(*b)); ]]></code>
+ <p>If you attempt to store an object in the registry and there is an
+ existing object with the same key, the new value will replace the old
+ one. This is done regardless of whether the new object and the old one
+ have the same type, so you can, for example, replace a string with an
+ integer. If the existing value is a string or binary, it will be freed
+ before the new value is assigned.</p>
+ <p>Stored values are retrieved from the registry as follows:</p>
+ <code type="none"><![CDATA[
+long i;
+double f;
+char *s;
+struct bonk *b;
+int size;
+
+i = ei_reg_getival(reg,"age");
+f = ei_reg_getfval(reg,"height");
+s = ei_reg_getsval(reg,"name");
+b = ei_reg_getpval(reg,"jox",&size); ]]></code>
+ <p>In all of the above examples, the object must exist and it must be of
+ the right type for the specified operation. If you do not know the
+ type of a given object, you can ask:</p>
+ <code type="none"><![CDATA[
+struct ei_reg_stat buf;
+
+ei_reg_stat(reg,"name",&buf); ]]></code>
+ <p>Buf will be initialized to contain object attributes.</p>
+ <p>Objects can be removed from the registry:</p>
+ <code type="none"><![CDATA[
+ei_reg_delete(reg,"name"); ]]></code>
+ <p>When you are finished with a registry, close it to remove all the
+ objects and free the memory back to the system:</p>
+ <code type="none"><![CDATA[
+ei_reg_close(reg); ]]></code>
+
+ <section>
+ <title>Backing Up the Registry to Mnesia</title>
+ <p>The contents of a registry can be backed up to Mnesia on a "nearby"
+ Erlang node. You need to provide an open connection to the Erlang node
+ (see <c><![CDATA[erl_connect()]]></c>). Also, Mnesia 3.0 or later must be running
+ on the Erlang node before the backup is initiated:</p>
+ <code type="none"><![CDATA[
+ei_reg_dump(fd, reg, "mtab", dumpflags); ]]></code>
+ <p>The example above will backup the contents of the registry to the
+ specified Mnesia table <c><![CDATA["mtab"]]></c>. Once a registry has been backed
+ up to Mnesia in this manner, additional backups will only affect
+ objects that have been modified since the most recent backup, i.e.
+ objects that have been created, changed or deleted. The backup
+ operation is done as a single atomic transaction, so that the entire
+ backup will be performed or none of it will.</p>
+ <p>In the same manner, a registry can be restored from a Mnesia table:</p>
+ <code type="none"><![CDATA[
+ei_reg_restore(fd, reg, "mtab"); ]]></code>
+ <p>This will read the entire contents of <c><![CDATA["mtab"]]></c> into the specified
+ registry. After the restore, all of the objects in the registry will
+ be marked as unmodified, so a subsequent backup will only affect
+ objects that you have modified since the restore.</p>
+ <p>Note that if you restore to a non-empty registry, objects in the
+ table will overwrite objects in the registry with the same keys. Also,
+ the <em>entire</em> contents of the registry is marked as unmodified
+ after the restore, including any modified objects that were not
+ overwritten by the restore operation. This may not be your intention.</p>
+ </section>
+
+ <section>
+ <title>Storing Strings and Binaries</title>
+ <p>When string or binary objects are stored in the registry it is
+ important that a number of simple guidelines are followed. </p>
+ <p>Most importantly, the object must have been created with a single call
+ to <c><![CDATA[malloc()]]></c> (or similar), so that it can later be removed by a
+ single call to <c><![CDATA[free()]]></c>. Objects will be freed by the registry
+ when it is closed, or when you assign a new value to an object that
+ previously contained a string or binary.</p>
+ <p>You should also be aware that if you store binary objects that are
+ context-dependent (e.g. containing pointers or open file descriptors),
+ they will lose their meaning if they are backed up to a Mnesia table
+ and subsequently restored in a different context.</p>
+ <p>When you retrieve a stored string or binary value from the registry,
+ the registry maintains a pointer to the object and you are passed a
+ copy of that pointer. You should never free an object retrieved in
+ this manner because when the registry later attempts to free it, a
+ runtime error will occur that will likely cause the C-node to crash.</p>
+ <p>You are free to modify the contents of an object retrieved this way.
+ However when you do so, the registry will not be aware of the changes
+ you make, possibly causing it to be missed the next time you make a
+ Mnesia backup of the registry contents. This can be avoided if you
+ mark the object as dirty after any such changes with
+ <c><![CDATA[ei_reg_markdirty()]]></c>, or pass appropriate flags to
+ <c><![CDATA[ei_reg_dump()]]></c>.</p>
+ </section>
+ </section>
+</chapter>
+
diff --git a/lib/erl_interface/doc/src/erl_call.xml b/lib/erl_interface/doc/src/erl_call.xml
new file mode 100644
index 0000000000..2d88e7616a
--- /dev/null
+++ b/lib/erl_interface/doc/src/erl_call.xml
@@ -0,0 +1,240 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE comref SYSTEM "comref.dtd">
+
+<comref>
+ <header>
+ <copyright>
+ <year>1996</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>erl_call</title>
+ <prepared>Torbj&ouml;rn T&ouml;rnkvist</prepared>
+ <responsible>Torbj&ouml;rn T&ouml;rnkvist</responsible>
+ <docno></docno>
+ <approved>Bjarne D&auml;cker</approved>
+ <checked>Torbj&ouml;rn T&ouml;rnkvist</checked>
+ <date>97-05-16</date>
+ <rev>B</rev>
+ <file>erl_call.sgml</file>
+ </header>
+ <com>erl_call</com>
+ <comsummary>Call/Start a Distributed Erlang Node</comsummary>
+ <description>
+ <p><c><![CDATA[erl_call]]></c> makes it possible to start and/or communicate with
+ a distributed Erlang node. It is built upon the <c><![CDATA[erl_interface]]></c>
+ library as an example application. Its purpose is to use an Unix shell script to interact with a distributed Erlang node. It performs all
+ communication with the Erlang <em>rex server</em>, using the standard Erlang RPC facility. It does not require any special
+ software to be run at the Erlang target node.</p>
+ <p>The main use is to either start a distributed Erlang node
+ or to make an ordinary function call. However, it is also
+ possible to pipe an Erlang module to <c><![CDATA[erl_call]]></c> and have it
+ compiled, or to pipe a sequence of Erlang expressions to be evaluated
+ (similar to the Erlang shell).</p>
+ <p>Options, which cause <c><![CDATA[stdin]]></c> to be read, can be used with
+ advantage
+ as scripts from within (Unix) shell scripts. Another
+ nice use of <c><![CDATA[erl_call]]></c> could be from (http) CGI-bin scripts.</p>
+ </description>
+ <funcs>
+ <func>
+ <name>erl_call &lt;options></name>
+ <fsummary>Start/Call Erlang</fsummary>
+ <desc>
+ <p>Each option flag is described below with its name, type and
+ meaning. </p>
+ <taglist>
+ <tag>-a [Mod [Fun [Args]]]]</tag>
+ <item>
+ <p>(<em>optional</em>): Applies the specified function
+ and returns the result. <c><![CDATA[Mod]]></c> must be specified, however
+ <em>[]</em> is assumed for unspecified <c><![CDATA[Fun]]></c> and <c><![CDATA[Args]]></c>. <c><![CDATA[Args]]></c> should
+ be in the same format as for <c><![CDATA[erlang:apply/3]]></c>. Note
+ that this flag takes exactly one argument, so quoting
+ may be necessary in order to group <c><![CDATA[Mod]]></c>, <c><![CDATA[Fun]]></c>
+ and <c><![CDATA[Args]]></c>, in a manner dependent on the behavior
+ of your command shell.</p>
+ <p></p>
+ </item>
+ <tag>-c Cookie</tag>
+ <item>
+ <p>(<em>optional</em>): Use this option to specify a certain cookie. If no cookie is specified, the <c><![CDATA[~/.erlang.cookie]]></c> file is read and its content are used as cookie. The Erlang node we want to communicate with must have the same cookie.</p>
+ </item>
+ <tag>-d</tag>
+ <item>
+ <p>(<em>optional</em>): Debug mode. This causes all IO to be output
+ to the file <c><![CDATA[~/.erl_call.out.Nodename]]></c>, where <c><![CDATA[Nodename]]></c>
+ is the node name of the Erlang node in question.</p>
+ <p></p>
+ </item>
+ <tag>-e</tag>
+ <item>
+ <p>(<em>optional</em>): Reads a sequence of Erlang expressions, separated
+ by '<em>,</em>' and ended with a '<em>.</em>', from <c><![CDATA[stdin]]></c> until
+ EOF (Control-D). Evaluates the expressions and returns the result from
+ the last expression. Returns <c><![CDATA[{ok,Result}]]></c> if successful.</p>
+ <p></p>
+ </item>
+ <tag>-h HiddenName</tag>
+ <item>
+ <p>(<em>optional</em>): Specifies the name of the hidden node
+ that <c><![CDATA[erl_call]]></c> represents.</p>
+ <p></p>
+ </item>
+ <tag>-m</tag>
+ <item>
+ <p>(<em>optional</em>): Reads an Erlang module from <c><![CDATA[stdin]]></c> and
+ compiles it.</p>
+ <p></p>
+ </item>
+ <tag>-n Node</tag>
+ <item>
+ <p>(one of <c><![CDATA[-n, -name, -sname]]></c> is required):
+ Has the same meaning as <c><![CDATA[-name]]></c> and can still be used for
+ backwards compatibility reasons.</p>
+ <p></p>
+ </item>
+ <tag>-name Node</tag>
+ <item>
+ <p>(one of <c><![CDATA[-n, -name, -sname]]></c> is required): <c><![CDATA[Node]]></c> is the name of the node to be
+ started or communicated with. It is assumed that
+ <c><![CDATA[Node]]></c> is started with <c><![CDATA[erl -name]]></c>, which means that fully
+ qualified long node names are used.
+ If the <c><![CDATA[-s]]></c> option is given, an Erlang node will (if necessary)
+ be started with <c><![CDATA[erl -name]]></c>.</p>
+ <p></p>
+ </item>
+ <tag>-q</tag>
+ <item>
+ <p>(<em>optional</em>): Halts the Erlang node specified
+ with the -n switch. This switch overrides the -s switch.</p>
+ <p></p>
+ </item>
+ <tag>-r</tag>
+ <item>
+ <p>(<em>optional</em>): Generates a random name of the hidden node
+ that <c><![CDATA[erl_call]]></c> represents.</p>
+ <p></p>
+ </item>
+ <tag>-s</tag>
+ <item>
+ <p>(<em>optional</em>): Starts a distributed Erlang node if necessary.
+ This means that in a sequence of calls, where the '<c><![CDATA[-s]]></c>'
+ and '<c><![CDATA[-n Node]]></c>' are constant, only the first call will start
+ the Erlang node. This makes the rest of the communication
+ very fast. This flag is currently only available on the Unix platform.</p>
+ <p></p>
+ </item>
+ <tag>-sname Node</tag>
+ <item>
+ <p>(one of <c><![CDATA[-n, -name, -sname]]></c> is required): <c><![CDATA[Node]]></c> is the name of the node to
+ be started or communicated with. It is assumed that <c><![CDATA[Node]]></c> is started with <c><![CDATA[erl -sname]]></c> which means that short node names are used.
+ If <c><![CDATA[-s]]></c> option is given, an Erlang node will be started (if necessary) with <c><![CDATA[erl -sname]]></c>.</p>
+ <p></p>
+ </item>
+ <tag>-v</tag>
+ <item>
+ <p>(<em>optional</em>): Prints a lot of <c><![CDATA[verbose]]></c> information.
+ This is only useful for the developer and maintainer of <c><![CDATA[erl_call]]></c>.</p>
+ <p></p>
+ </item>
+ <tag>-x ErlScript</tag>
+ <item>
+ <p>(<em>optional</em>): Specifies another name of the Erlang start-up script
+ to be used. If not specified, the standard <c><![CDATA[erl]]></c> start-up script
+ is used.</p>
+ </item>
+ </taglist>
+ </desc>
+ </func>
+ </funcs>
+
+ <section>
+ <title>Examples</title>
+ <p>Starts an Erlang node and calls <c><![CDATA[erlang:time/0]]></c>.</p>
+ <code type="none"><![CDATA[
+erl_call -s -a 'erlang time' -n madonna
+{18,27,34}
+ ]]></code>
+ <p>Terminates an Erlang node by calling <c><![CDATA[erlang:halt/0]]></c>.</p>
+ <code type="none"><![CDATA[
+erl_call -s -a 'erlang halt' -n madonna
+ ]]></code>
+ <p>An apply with several arguments.</p>
+ <code type="none"><![CDATA[
+erl_call -s -a 'lists map [{math,sqrt},[1,4,9,16,25]]' -n madonna
+ ]]></code>
+ <p>Evaluates a couple of expressions. <b>The input ends with EOF (Control-D)</b>.</p>
+ <code type="none"><![CDATA[
+erl_call -s -e -n madonna
+statistics(runtime),
+X=1,
+Y=2,
+{_,T}=statistics(runtime),
+{X+Y,T}.
+^D
+{ok,{3,0}}
+ ]]></code>
+ <p>Compiles a module and runs it. <b>Again, the input ends with EOF (Control-D)</b>. (In the example shown, the output has been formatted afterwards).</p>
+ <code type="none"><![CDATA[
+erl_call -s -m -a lolita -n madonna
+-module(lolita).
+-compile(export_all).
+start() ->
+ P = processes(),
+ F = fun(X) -> {X,process_info(X,registered_name)} end,
+ lists:map(F,[],P).
+^D
+ {registered_name,init}},
+ {registered_name,erl_prim_loader}},
+ {registered_name,error_logger}},
+ {registered_name,application_controller}},
+ {registered_name,kernel}},
+ []},
+ {registered_name,kernel_sup}},
+ {registered_name,net_sup}},
+ {registered_name,net_kernel}},
+ []},
+ {registered_name,global_name_server}},
+ {registered_name,auth}},
+ {registered_name,rex}},
+ []},
+ {registered_name,file_server}},
+ {registered_name,code_server}},
+ {registered_name,user}},
+ []}]
+ ]]></code>
+ </section>
+</comref>
+
diff --git a/lib/erl_interface/doc/src/erl_connect.xml b/lib/erl_interface/doc/src/erl_connect.xml
new file mode 100644
index 0000000000..b2235925b2
--- /dev/null
+++ b/lib/erl_interface/doc/src/erl_connect.xml
@@ -0,0 +1,566 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE cref SYSTEM "cref.dtd">
+
+<cref>
+ <header>
+ <copyright>
+ <year>1996</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>erl_connect</title>
+ <prepared>Torbj&ouml;rn T&ouml;rnkvist</prepared>
+ <responsible>Torbj&ouml;rn T&ouml;rnkvist</responsible>
+ <docno></docno>
+ <approved>Bjarne D&auml;cker</approved>
+ <checked>Torbj&ouml;rn T&ouml;rnkvist</checked>
+ <date>980703</date>
+ <rev>A</rev>
+ <file>erl_connect.sgml</file>
+ </header>
+ <lib>erl_connect</lib>
+ <libsummary>Communicate with Distributed Erlang</libsummary>
+ <description>
+ <p>This module provides support for communication between distributed
+ Erlang nodes and C nodes, in a manner that is transparent to Erlang
+ processes.</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>
+ </description>
+ <funcs>
+ <func>
+ <name><ret>int</ret><nametext>erl_connect_init(number, cookie, creation)</nametext></name>
+ <name><ret>int</ret><nametext>erl_connect_xinit(host, alive, node, addr, cookie, creation)</nametext></name>
+ <fsummary>Initialize communication</fsummary>
+ <type>
+ <v>int number;</v>
+ <v>char *cookie;</v>
+ <v>short creation;</v>
+ <v>char *host,*alive,*node;</v>
+ <v>struct in_addr *addr;</v>
+ </type>
+ <desc>
+ <p>These functions initialize the <c><![CDATA[erl_connect]]></c>
+ module. In particular, they are used to identify the name of the
+ C-node from which they are called. One of these functions must
+ be called before any of the other functions in the erl_connect
+ module are used.</p>
+ <p><c><![CDATA[erl_connect_xinit()]]></c> stores for later use information about
+ the node's host name <c><![CDATA[host]]></c>, alive name <c><![CDATA[alive]]></c>, node
+ name <c><![CDATA[node]]></c>, IP address <c><![CDATA[addr]]></c>, cookie <c><![CDATA[cookie]]></c>,
+ and creation number <c><![CDATA[creation]]></c>. <c><![CDATA[erl_connect_init()]]></c>
+ provides an alternative interface which does not require as much
+ information from the caller. Instead, <c><![CDATA[erl_connect_init()]]></c>
+ uses <c><![CDATA[gethostbyname()]]></c> to obtain default values.
+ </p>
+ <p>If you use <c><![CDATA[erl_connect_init()]]></c> your node will have a
+ short name, i.e., it will not be fully qualified. If you need to
+ use fully qualified (a.k.a. long) names, use
+ <c><![CDATA[erl_connect_xinit()]]></c> instead.
+ </p>
+ <p><c><![CDATA[host]]></c> is the name of the host on which the node is running.</p>
+ <p><c><![CDATA[alive]]></c> is the alivename of the node.</p>
+ <p><c><![CDATA[node]]></c> is the name of the node. The nodename should
+ be of the form <em>alivename@hostname</em>.</p>
+ <p><c><![CDATA[addr]]></c> is the 32-bit IP address of <c><![CDATA[host]]></c>.</p>
+ <p><c><![CDATA[cookie]]></c> is the authorization string required for access
+ to the remote node. If NULL the user HOME directory is
+ searched for a cookie file <c><![CDATA[.erlang.cookie]]></c>. The path to
+ the home directory is retrieved from the environment variable
+ <c><![CDATA[HOME]]></c> on Unix and from the <c><![CDATA[HOMEDRIVE]]></c> and
+ <c><![CDATA[HOMEPATH]]></c> variables on Windows. Refer to the <c><![CDATA[auth]]></c>
+ module for more details.</p>
+ <p><c><![CDATA[creation]]></c> helps identify a particular instance of a C
+ node. In particular, it can help prevent us from receiving
+ messages sent to an earlier process with the same registered
+ name.</p>
+ <p>A C node acting as a server will be assigned a creation number
+ when it calls <c><![CDATA[erl_publish()]]></c>.</p>
+ <p><c><![CDATA[number]]></c> is used by <c><![CDATA[erl_connect_init()]]></c> to
+ construct the actual node name. In the second example shown
+ below, <em>"[email protected]"</em> will be the resulting node
+ name.</p>
+ <p>Example 1:</p>
+ <code type="none"><![CDATA[
+struct in_addr addr;
+addr = inet_addr("150.236.14.75");
+if (!erl_connect_xinit("chivas",
+ "madonna",
+ &addr;
+ "samplecookiestring..."),
+ 0)
+ erl_err_quit("<ERROR> when initializing !");
+ ]]></code>
+ <p>Example 2:</p>
+ <code type="none"><![CDATA[
+if (!erl_connect_init(17, "samplecookiestring...", 0))
+ erl_err_quit("<ERROR> when initializing !");
+ ]]></code>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>erl_connect(node)</nametext></name>
+ <name><ret>int</ret><nametext>erl_xconnect(addr, alive)</nametext></name>
+ <fsummary>Establishe a connection to an Erlang node</fsummary>
+ <type>
+ <v>char *node, *alive;</v>
+ <v>struct in_addr *addr;</v>
+ </type>
+ <desc>
+ <p>These functions set up a connection to an Erlang node.</p>
+ <p><c><![CDATA[erl_xconnect()]]></c> requires the IP address of the remote
+ host and the alive name of the remote node
+ to be specified. <c><![CDATA[erl_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>
+ <code type="none"><![CDATA[
+#define NODE "[email protected]"
+#define ALIVE "madonna"
+#define IP_ADDR "150.236.14.75"
+
+/*** Variant 1 ***/
+erl_connect( NODE );
+
+/*** Variant 2 ***/
+struct in_addr addr;
+addr = inet_addr(IP_ADDR);
+erl_xconnect( &addr , ALIVE );
+ ]]></code>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>erl_close_connection(fd)</nametext></name>
+ <fsummary>Close a connection to an Erlang node</fsummary>
+ <type>
+ <v>int fd;</v>
+ </type>
+ <desc>
+ <p>This function closes an open connection to an Erlang node.</p>
+ <p><c><![CDATA[Fd]]></c> is a file descriptor obtained from
+ <c><![CDATA[erl_connect()]]></c> or <c><![CDATA[erl_xconnect()]]></c>.</p>
+ <p>On success, 0 is returned. If the call fails, a non-zero value
+ is returned, and the reason for
+ the error can be obtained with the appropriate platform-dependent
+ call.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>erl_receive(fd, bufp, bufsize)</nametext></name>
+ <fsummary>Receive a message</fsummary>
+ <type>
+ <v>int fd;</v>
+ <v>char *bufp;</v>
+ <v>int bufsize;</v>
+ </type>
+ <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.</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 a negative value 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>erl_receive_msg(fd, bufp, bufsize, emsg)</nametext></name>
+ <fsummary>Receive and decodes a message</fsummary>
+ <type>
+ <v>int fd;</v>
+ <v>unsigned char *bufp;</v>
+ <v>int bufsize;</v>
+ <v>ErlMessage *emsg;</v>
+ </type>
+ <desc>
+ <p>This function receives the message into the specified buffer,
+ and decodes into the <c><![CDATA[(ErlMessage *) emsg]]></c>.</p>
+ <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.</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><c><![CDATA[emsg]]></c> is a pointer to an <c><![CDATA[ErlMessage]]></c> structure,
+ into which the message will be decoded. <c><![CDATA[ErlMessage]]></c> is
+ defined as follows:</p>
+ <code type="none"><![CDATA[
+typedef struct {
+ int type;
+ ETERM *msg;
+ ETERM *to;
+ ETERM *from;
+ char to_name[MAXREGLEN];
+} ErlMessage;
+ ]]></code>
+ <note>
+ <p>The definition of <c><![CDATA[ErlMessage]]></c> has changed since
+ earlier versions of Erl_Interface.</p>
+ </note>
+ <p><c><![CDATA[type]]></c> identifies the type of message, 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[type]]></c> contains <c><![CDATA[ERL_SEND]]></c>
+ this indicates that an ordinary send operation has taken
+ place, and <c><![CDATA[emsg->to]]></c> contains the Pid of the
+ recipient. If <c><![CDATA[type]]></c> contains <c><![CDATA[ERL_REG_SEND]]></c> then a
+ registered send operation took place, and <c><![CDATA[emsg->from]]></c>
+ contains the Pid of the sender. In both cases, the actual
+ message will be in <c><![CDATA[emsg->msg]]></c>.
+ </p>
+ <p>If <c><![CDATA[type]]></c> contains one of <c><![CDATA[ERL_LINK]]></c> or
+ <c><![CDATA[ERL_UNLINK]]></c>, then <c><![CDATA[emsg->to]]></c> and <c><![CDATA[emsg->from]]></c>
+ contain the pids of the sender and recipient of the link or unlink.
+ <c><![CDATA[emsg->msg]]></c> is not used in these cases.
+ </p>
+ <p>If <c><![CDATA[type]]></c> contains <c><![CDATA[ERL_EXIT]]></c>, then this
+ indicates that a link has been broken. In this case,
+ <c><![CDATA[emsg->to]]></c> and <c><![CDATA[emsg->from]]></c> contain the pids of the
+ linked processes, and <c><![CDATA[emsg->msg]]></c> contains the reason for
+ the exit.
+ </p>
+ <note>
+ <p>It is the caller's responsibility to release the
+ memory pointed to by <c><![CDATA[emsg->msg]]></c>, <c><![CDATA[emsg->to]]></c> and
+ <c><![CDATA[emsg->from]]></c>.</p>
+ </note>
+ <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>
+ indicating that the tick has been received and responded to,
+ but no message will be placed in the buffer. In this case you
+ should call <c><![CDATA[erl_receive_msg()]]></c> again.</p>
+ <p>On success, the function returns <c><![CDATA[ERL_MSG]]></c> and the
+ <c><![CDATA[Emsg]]></c> struct will be initialized as described above, or
+ <c><![CDATA[ERL_TICK]]></c>, in which case no message is returned. 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[EMSGSIZE]]></c></tag>
+ <item>Buffer too small.</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>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>erl_xreceive_msg(fd, bufpp, bufsizep, emsg)</nametext></name>
+ <fsummary>Receive and decodes a message</fsummary>
+ <type>
+ <v>int fd;</v>
+ <v>unsigned char **bufpp;</v>
+ <v>int *bufsizep;</v>
+ <v>ErlMessage *emsg;</v>
+ </type>
+ <desc>
+ <p>This function is similar to <c><![CDATA[erl_receive_msg]]></c>. The
+ difference is that <c><![CDATA[erl_xreceive_msg]]></c> expects the buffer to
+ have been allocated by <c><![CDATA[malloc]]></c>, and reallocates it if the received
+ message does not fit into the original buffer. For that reason,
+ both buffer and buffer length are given as pointers - their values
+ may change by the call.
+ </p>
+ <p>On success, the function returns <c><![CDATA[ERL_MSG]]></c> and the
+ <c><![CDATA[Emsg]]></c> struct will be initialized as described above, or
+ <c><![CDATA[ERL_TICK]]></c>, in which case no message is returned. 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[EMSGSIZE]]></c></tag>
+ <item>Buffer too small.</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>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>erl_send(fd, to, msg)</nametext></name>
+ <fsummary>Send a message</fsummary>
+ <type>
+ <v>int fd;</v>
+ <v>ETERM *to, *msg;</v>
+ </type>
+ <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 an Erlang term containing the Pid of the
+ intended recipient of the message.</p>
+ <p><c><![CDATA[msg]]></c> is the Erlang term to be sent.</p>
+ <p>The function returns 1 if successful, otherwise 0 --- in
+ which case it will set <c><![CDATA[erl_errno]]></c> to one of:</p>
+ <taglist>
+ <tag><c><![CDATA[EINVAL]]></c></tag>
+ <item>Invalid argument: <c><![CDATA[to]]></c> is not a valid Erlang pid.</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>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>erl_reg_send(fd, to, msg)</nametext></name>
+ <fsummary>Send a message to a registered name</fsummary>
+ <type>
+ <v>int fd;</v>
+ <v>char *to;</v>
+ <v>ETERM *msg;</v>
+ </type>
+ <desc>
+ <p>This function sends an Erlang term to a registered process.</p>
+ <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.</p>
+ <p><c><![CDATA[to]]></c> is a string containing the registered name of
+ the intended recipient of the message.</p>
+ <p><c><![CDATA[msg]]></c> is the Erlang term to be sent.</p>
+ <p>The function returns 1 if successful, otherwise 0 --- in
+ which case it will set <c><![CDATA[erl_errno]]></c> to one of:</p>
+ <taglist>
+ <tag><c><![CDATA[ENOMEM]]></c></tag>
+ <item>No more memory available.</item>
+ <tag><c><![CDATA[EIO]]></c></tag>
+ <item>I/O error.</item>
+ </taglist>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ETERM *</ret><nametext>erl_rpc(fd, mod, fun, args)</nametext></name>
+ <name><ret>int</ret><nametext>erl_rpc_to(fd, mod, fun, args)</nametext></name>
+ <name><ret>int</ret><nametext>erl_rpc_from(fd, timeout, emsg)</nametext></name>
+ <fsummary>Remote Procedure Call</fsummary>
+ <type>
+ <v>int fd, timeout;</v>
+ <v>char *mod, *fun;</v>
+ <v>ETERM *args;</v>
+ <v>ErlMessage *emsg;</v>
+ </type>
+ <desc>
+ <p>These functions support calling Erlang functions on remote nodes.
+ <c><![CDATA[erl_rpc_to()]]></c> sends an rpc request to a remote node and
+ <c><![CDATA[erl_rpc_from()]]></c> receives the results of such a call.
+ <c><![CDATA[erl_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[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.
+ When erl_rpc() calls erl_rpc_from(), the call will never
+ timeout.</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[args]]></c> is an Erlang list, containing the arguments to be
+ passed to the function. </p>
+ <p><c><![CDATA[emsg]]></c> is a message containing the result of the
+ function call.</p>
+ <p>The actual message returned by the rpc server
+ is a 2-tuple <c><![CDATA[{rex,Reply}]]></c>. If you are using
+ <c><![CDATA[erl_rpc_from()]]></c> in your code then this is the message you
+ will need to parse. If you are using <c><![CDATA[erl_rpc()]]></c> then the
+ tuple itself is parsed for you, and the message returned to your
+ program is the erlang term containing <c><![CDATA[Reply]]></c> only. Replies
+ to rpc requests are always ERL_SEND messages.
+ </p>
+ <note>
+ <p>It is the caller's responsibility to free the returned
+ <c><![CDATA[ETERM]]></c> structure as well as the memory pointed to by
+ <c><![CDATA[emsg->msg]]></c> and <c><![CDATA[emsg->to]]></c>. </p>
+ </note>
+ <p><c><![CDATA[erl_rpc()]]></c> returns the remote function's return value (or
+ <c><![CDATA[NULL]]></c> if it failed). <c><![CDATA[erl_rpc_to()]]></c> returns 0 on
+ success, and a negative number on failure. <c><![CDATA[erl_rcp_from()]]></c>
+ returns <c><![CDATA[ERL_MSG]]></c> when successful (with <c><![CDATA[Emsg]]></c> now
+ containing the reply tuple), and 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[ENOMEM]]></c></tag>
+ <item>No more memory available.</item>
+ <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>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>erl_publish(port)</nametext></name>
+ <fsummary>Publish a node name</fsummary>
+ <type>
+ <v>int port;</v>
+ </type>
+ <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[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>To unregister with epmd, simply close the returned
+ descriptor. See also <c><![CDATA[erl_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:</p>
+ <taglist>
+ <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>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>erl_accept(listensock, conp)</nametext></name>
+ <fsummary>Accept a connection</fsummary>
+ <type>
+ <v>int listensock;</v>
+ <v>ErlConnect *conp;</v>
+ </type>
+ <desc>
+ <p>This function is used by a server process to accept a
+ connection from a client process.</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>const char *</ret><nametext>erl_thiscookie()</nametext></name>
+ <name><ret>const char *</ret><nametext>erl_thisnodename()</nametext></name>
+ <name><ret>const char *</ret><nametext>erl_thishostname()</nametext></name>
+ <name><ret>const char *</ret><nametext>erl_thisalivename()</nametext></name>
+ <name><ret>short</ret><nametext>erl_thiscreation()</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[erl_connect_init()]]></c> or <c><![CDATA[erl_connect_xinit()]]></c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>erl_unpublish(alive)</nametext></name>
+ <fsummary>Unpublish a node name</fsummary>
+ <type>
+ <v>char *alive;</v>
+ </type>
+ <desc>
+ <p>This function can be called by a process to unregister a
+ specified node name 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[erl_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[alive]]></c> is the name of the node to unregister, i.e., the
+ first component of the nodename, without the <c><![CDATA[@hostname]]></c>.</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>struct hostent</ret><nametext>*erl_gethostbyname(name)</nametext></name>
+ <name><ret>struct hostent</ret><nametext>*erl_gethostbyaddr(addr, length, type)</nametext></name>
+ <name><ret>struct hostent</ret><nametext>*erl_gethostbyname_r(name, hostp, buffer, buflen, h_errnop)</nametext></name>
+ <name><ret>struct hostent</ret><nametext>*erl_gethostbyaddr_r(addr, length, type, hostp, buffer, buflen, h_errnop)</nametext></name>
+ <fsummary>Name lookup functions</fsummary>
+ <type>
+ <v>const char *name;</v>
+ <v>const char *addr;</v>
+ <v>int length;</v>
+ <v>int type;</v>
+ <v>struct hostent *hostp;</v>
+ <v>char *buffer;</v>
+ <v>int buflen;</v>
+ <v>int *h_errnop;</v>
+ </type>
+ <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[erl_interface]]></c> library.</item>
+ </list>
+ </section>
+</cref>
+
diff --git a/lib/erl_interface/doc/src/erl_error.xml b/lib/erl_interface/doc/src/erl_error.xml
new file mode 100644
index 0000000000..4a3f34fac7
--- /dev/null
+++ b/lib/erl_interface/doc/src/erl_error.xml
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE cref SYSTEM "cref.dtd">
+
+<cref>
+ <header>
+ <copyright>
+ <year>1996</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>erl_error</title>
+ <prepared>Torbj&ouml;rn T&ouml;rnkvist</prepared>
+ <responsible>Torbj&ouml;rn T&ouml;rnkvist</responsible>
+ <docno></docno>
+ <approved>Bjarne D&auml;cker</approved>
+ <checked>Torbj&ouml;rn T&ouml;rnkvist</checked>
+ <date>961014</date>
+ <rev>A</rev>
+ <file>erl_error.sgml</file>
+ </header>
+ <lib>erl_error</lib>
+ <libsummary>Error Print Routines</libsummary>
+ <description>
+ <p>This module contains some error printing routines taken
+ from <em>Advanced Programming in the UNIX Environment</em>
+ by W. Richard Stevens. </p>
+ <p>These functions are all called in the same manner as
+ <c><![CDATA[printf()]]></c>, i.e. with a string containing format specifiers
+ followed by a list of corresponding arguments. All output from
+ these functions is to <c><![CDATA[stderr]]></c>.</p>
+ </description>
+ <funcs>
+ <func>
+ <name><ret>void</ret><nametext>erl_err_msg(FormatStr, ... )</nametext></name>
+ <fsummary>Non-fatal error, and not system call error</fsummary>
+ <type>
+ <v>const char *FormatStr;</v>
+ </type>
+ <desc>
+ <p>The message provided by the caller is printed. This
+ function is simply a wrapper for <c><![CDATA[fprintf()]]></c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>void</ret><nametext>erl_err_quit(FormatStr, ... )</nametext></name>
+ <fsummary>Fatal error, but not system call error</fsummary>
+ <type>
+ <v>const char *FormatStr;</v>
+ </type>
+ <desc>
+ <p>Use this function when a fatal error has occurred that
+ is not due to a system call. The message provided by the
+ caller is printed and the process terminates with an exit
+ value of 1. The function does not return.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>void</ret><nametext>erl_err_ret(FormatStr, ... )</nametext></name>
+ <fsummary>Non-fatal system call error</fsummary>
+ <type>
+ <v>const char *FormatStr;</v>
+ </type>
+ <desc>
+ <p>Use this function after a failed system call. The message
+ provided by the caller is printed followed by a string
+ describing the reason for failure. </p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>void</ret><nametext>erl_err_sys(FormatStr, ... )</nametext></name>
+ <fsummary>Fatal system call error</fsummary>
+ <type>
+ <v>const char *FormatStr;</v>
+ </type>
+ <desc>
+ <p>Use this function after a failed system call. The message
+ provided by the caller is printed followed by a string
+ describing the reason for failure, and the process
+ terminates with an exit value of 1. The function does not
+ return.</p>
+ </desc>
+ </func>
+ </funcs>
+
+ <section>
+ <title>Error Reporting</title>
+ <p>Most functions in erl_interface report failures to the caller by
+ returning some otherwise meaningless value (typically <c><![CDATA[NULL]]></c>
+ or a negative number). As this only tells you that things did not
+ go well, you will have to examine the error code in
+ <c><![CDATA[erl_errno]]></c> if you want to find out more about the failure.</p>
+ </section>
+ <funcs>
+ <func>
+ <name><ret>volatile int</ret><nametext>erl_errno</nametext></name>
+ <fsummary>The variable <c><![CDATA[erl_errno]]></c>contains the erl_interface error number. You can change the value if you wish. </fsummary>
+ <desc>
+ <p><c><![CDATA[erl_errno]]></c> is initially (at program startup) zero and
+ is then set by many erl_interface functions on failure to a
+ non-zero error code to indicate what kind of error it
+ encountered. A successful function call might change
+ <c><![CDATA[erl_errno]]></c> (by calling some other function that
+ fails), but no function will ever set it to zero. This means
+ that you cannot use <c><![CDATA[erl_errno]]></c> to see <em>if</em> a
+ function call failed. Instead, each function reports failure
+ in its own way (usually by returning a negative number or
+ <c><![CDATA[NULL]]></c>), in which case you can examine <c><![CDATA[erl_errno]]></c>
+ for details.</p>
+ <p><c><![CDATA[erl_errno]]></c> uses the error codes defined in your
+ system's <c><![CDATA[<errno.h>]]></c>.</p>
+ <note>
+ <p>Actually, <c><![CDATA[erl_errno]]></c> is a "modifiable lvalue" (just
+ like ISO C defines <c><![CDATA[errno]]></c> to be) rather than a
+ variable. This means it might be implemented as a macro
+ (expanding to, e.g., <c><![CDATA[*_erl_errno()]]></c>). For reasons of
+ thread- (or task-)safety, this is exactly what we do on most
+ platforms.</p>
+ </note>
+ </desc>
+ </func>
+ </funcs>
+</cref>
+
diff --git a/lib/erl_interface/doc/src/erl_eterm.xml b/lib/erl_interface/doc/src/erl_eterm.xml
new file mode 100644
index 0000000000..ce14549672
--- /dev/null
+++ b/lib/erl_interface/doc/src/erl_eterm.xml
@@ -0,0 +1,675 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE cref SYSTEM "cref.dtd">
+
+<cref>
+ <header>
+ <copyright>
+ <year>1996</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>erl_eterm</title>
+ <prepared>Torbj&ouml;rn T&ouml;rnkvist</prepared>
+ <responsible>Torbj&ouml;rn T&ouml;rnkvist</responsible>
+ <docno></docno>
+ <approved>Bjarne D&auml;cker</approved>
+ <checked>Torbj&ouml;rn T&ouml;rnkvist</checked>
+ <date>980703</date>
+ <rev>A</rev>
+ <file>erl_eterm.sgml</file>
+ </header>
+ <lib>erl_eterm</lib>
+ <libsummary>Functions for Erlang Term Construction</libsummary>
+ <description>
+ <p>This module contains functions for creating and manipulating
+ Erlang terms. </p>
+ <p>An Erlang term is represented by a C structure of type
+ <c><![CDATA[ETERM]]></c>. Applications should not reference any fields in this
+ structure directly, because it may be changed in future releases
+ to provide faster and more compact term storage. Instead,
+ applications should us the macros and functions provided. </p>
+ <p>The following macros each take a single ETERM pointer as an
+ argument. They return a non-zero value if the test is true, and 0
+ otherwise:</p>
+ <taglist>
+ <tag><c><![CDATA[ERL_IS_INTEGER(t)]]></c></tag>
+ <item>True if <c><![CDATA[t]]></c> is an integer.</item>
+ <tag><c><![CDATA[ERL_IS_UNSIGNED_INTEGER(t)]]></c></tag>
+ <item>True if <c><![CDATA[t]]></c> is an integer.</item>
+ <tag><c><![CDATA[ERL_IS_FLOAT(t)]]></c></tag>
+ <item>True if <c><![CDATA[t]]></c> is a floating point number.</item>
+ <tag><c><![CDATA[ERL_IS_ATOM(t)]]></c></tag>
+ <item>True if <c><![CDATA[t]]></c> is an atom.</item>
+ <tag><c><![CDATA[ERL_IS_PID(t)]]></c></tag>
+ <item>True if <c><![CDATA[t]]></c> is a Pid (process identifier).</item>
+ <tag><c><![CDATA[ERL_IS_PORT(t)]]></c></tag>
+ <item>True if <c><![CDATA[t]]></c> is a port.</item>
+ <tag><c><![CDATA[ERL_IS_REF(t)]]></c></tag>
+ <item>True if <c><![CDATA[t]]></c> is a reference.</item>
+ <tag><c><![CDATA[ERL_IS_TUPLE(t)]]></c></tag>
+ <item>True if <c><![CDATA[t]]></c> is a tuple.</item>
+ <tag><c><![CDATA[ERL_IS_BINARY(t)]]></c></tag>
+ <item>True if <c><![CDATA[t]]></c> is a binary.</item>
+ <tag><c><![CDATA[ERL_IS_LIST(t)]]></c></tag>
+ <item>True if <c><![CDATA[t]]></c> is a list with zero or more elements.</item>
+ <tag><c><![CDATA[ERL_IS_EMPTY_LIST(t)]]></c></tag>
+ <item>True if <c><![CDATA[t]]></c> is an empty list.</item>
+ <tag><c><![CDATA[ERL_IS_CONS(t)]]></c></tag>
+ <item>True if <c><![CDATA[t]]></c> is a list with at least one element.</item>
+ </taglist>
+ <p>The following macros can be used for retrieving parts of Erlang
+ terms. None of these do any type checking; results are undefined
+ if you pass an ETERM* containing the wrong type. For example,
+ passing a tuple to ERL_ATOM_PTR() will likely result in garbage.
+ </p>
+ <taglist>
+ <tag><c><![CDATA[char *ERL_ATOM_PTR(t)]]></c></tag>
+ <item>A string representing atom <c><![CDATA[t]]></c>.
+ </item>
+ <tag><c><![CDATA[int ERL_ATOM_SIZE(t)]]></c></tag>
+ <item>The length (in characters) of atom t.</item>
+ <tag><c><![CDATA[void *ERL_BIN_PTR(t)]]></c></tag>
+ <item>A pointer to the contents of <c><![CDATA[t]]></c></item>
+ <tag><c><![CDATA[int ERL_BIN_SIZE(t)]]></c></tag>
+ <item>The length (in bytes) of binary object <c><![CDATA[t]]></c>.</item>
+ <tag><c><![CDATA[int ERL_INT_VALUE(t)]]></c></tag>
+ <item>The integer of <c><![CDATA[t]]></c>.</item>
+ <tag><c><![CDATA[unsigned int ERL_INT_UVALUE(t)]]></c></tag>
+ <item>The unsigned integer value of <c><![CDATA[t]]></c>.</item>
+ <tag><c><![CDATA[double ERL_FLOAT_VALUE(t)]]></c></tag>
+ <item>The floating point value of <c><![CDATA[t]]></c>.</item>
+ <tag><c><![CDATA[ETERM *ERL_PID_NODE(t)]]></c></tag>
+ <item>The Node in pid <c><![CDATA[t]]></c>.</item>
+ <tag><c><![CDATA[int ERL_PID_NUMBER(t)]]></c></tag>
+ <item>The sequence number in pid <c><![CDATA[t]]></c>.</item>
+ <tag><c><![CDATA[int ERL_PID_SERIAL(t)]]></c></tag>
+ <item>The serial number in pid <c><![CDATA[t]]></c>.</item>
+ <tag><c><![CDATA[int ERL_PID_CREATION(t)]]></c></tag>
+ <item>The creation number in pid <c><![CDATA[t]]></c>.</item>
+ <tag><c><![CDATA[int ERL_PORT_NUMBER(t)]]></c></tag>
+ <item>The sequence number in port <c><![CDATA[t]]></c>.</item>
+ <tag><c><![CDATA[int ERL_PORT_CREATION(t)]]></c></tag>
+ <item>The creation number in port <c><![CDATA[t]]></c>.</item>
+ <tag><c><![CDATA[ETERM *ERL_PORT_NODE(t)]]></c></tag>
+ <item>The node in port <c><![CDATA[t]]></c>.</item>
+ <tag><c><![CDATA[int ERL_REF_NUMBER(t)]]></c></tag>
+ <item>The first part of the reference number in ref <c><![CDATA[t]]></c>. Use
+ only for compatibility.</item>
+ <tag><c><![CDATA[int ERL_REF_NUMBERS(t)]]></c></tag>
+ <item>Pointer to the array of reference numbers in ref <c><![CDATA[t]]></c>.</item>
+ <tag><c><![CDATA[int ERL_REF_LEN(t)]]></c></tag>
+ <item>The number of used reference numbers in ref <c><![CDATA[t]]></c>.</item>
+ <tag><c><![CDATA[int ERL_REF_CREATION(t)]]></c></tag>
+ <item>The creation number in ref <c><![CDATA[t]]></c>.</item>
+ <tag><c><![CDATA[int ERL_TUPLE_SIZE(t)]]></c></tag>
+ <item>The number of elements in tuple <c><![CDATA[t]]></c>.</item>
+ <tag><c><![CDATA[ETERM *ERL_CONS_HEAD(t)]]></c></tag>
+ <item>The head element of list <c><![CDATA[t]]></c>.</item>
+ <tag><c><![CDATA[ETERM *ERL_CONS_TAIL(t)]]></c></tag>
+ <item>A List representing the tail elements of list <c><![CDATA[t]]></c>.</item>
+ </taglist>
+ </description>
+ <funcs>
+ <func>
+ <name><ret>ETERM *</ret><nametext>erl_cons(head, tail)</nametext></name>
+ <fsummary>Prepends a term to the head of a list.</fsummary>
+ <type>
+ <v>ETERM *head;</v>
+ <v>ETERM *tail;</v>
+ </type>
+ <desc>
+ <p>This function concatenates two Erlang terms, prepending
+ <c><![CDATA[head]]></c> onto <c><![CDATA[tail]]></c> and thereby creating a <c><![CDATA[cons]]></c> cell.
+ To make a proper list, <c><![CDATA[tail]]></c> should always be a
+ list or an empty list. Note that NULL is not a valid list.</p>
+ <p><c><![CDATA[head]]></c> is the new term to be added.</p>
+ <p><c><![CDATA[tail]]></c> is the existing list to which <c><![CDATA[head]]></c> will
+ be concatenated.</p>
+ <p>The function returns a new list.</p>
+ <p><c><![CDATA[ERL_CONS_HEAD(list)]]></c> and <c><![CDATA[ERL_CONS_TAIL(list)]]></c>
+ can be used to retrieve the head and tail components
+ from the list. <c><![CDATA[erl_hd(list)]]></c> and <c><![CDATA[erl_tl(list)]]></c> will do
+ the same thing, but check that the argument really is a list.</p>
+ <p>For example:</p>
+ <code type="none"><![CDATA[
+ETERM *list,*anAtom,*anInt;
+anAtom = erl_mk_atom("madonna");
+anInt = erl_mk_int(21);
+list = erl_mk_empty_list();
+list = erl_cons(anAtom, list);
+list = erl_cons(anInt, list);
+ ... /* do some work */
+erl_free_compound(list);
+ ]]></code>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ETERM *</ret><nametext>erl_copy_term(term)</nametext></name>
+ <fsummary>Creates a copy of an Erlang term</fsummary>
+ <type>
+ <v>ETERM *term;</v>
+ </type>
+ <desc>
+ <p>This function creates and returns a copy of the Erlang term
+ <c><![CDATA[term]]></c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ETERM *</ret><nametext>erl_element(position, tuple)</nametext></name>
+ <fsummary>Extracts an element from an Erlang tuple</fsummary>
+ <type>
+ <v>int position;</v>
+ <v>ETERM *tuple;</v>
+ </type>
+ <desc>
+ <p>This function extracts a specified element from an Erlang
+ tuple. </p>
+ <p><c><![CDATA[position]]></c> specifies which element to retrieve from
+ <c><![CDATA[tuple]]></c>. The elements are numbered starting from 1.</p>
+ <p><c><![CDATA[tuple]]></c> is an Erlang term containing at least
+ <c><![CDATA[position]]></c> elements.</p>
+ <p>The function returns a new Erlang term corresponding to the
+ requested element, or NULL if <c><![CDATA[position]]></c> was greater than
+ the arity of <c><![CDATA[tuple]]></c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>void</ret><nametext>erl_init(NULL, 0)</nametext></name>
+ <fsummary>Initialization routine</fsummary>
+ <type>
+ <v>void *NULL;</v>
+ <v>int 0;</v>
+ </type>
+ <desc>
+ <marker id="erl_init"></marker>
+ <p>This function must be called before any of the others in
+ the <c><![CDATA[erl_interface]]></c> library in order to initialize the
+ library functions. The arguments must be specified as
+ <c><![CDATA[erl_init(NULL,0)]]></c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ETERM *</ret><nametext>erl_hd(list)</nametext></name>
+ <fsummary>Extracts the first element from a list</fsummary>
+ <type>
+ <v>ETERM *list;</v>
+ </type>
+ <desc>
+ <p>Extracts the first element from a list.</p>
+ <p><c><![CDATA[list]]></c> is an Erlang term containing a list.</p>
+ <p>The function returns an Erlang term corresponding to the
+ head element in the list, or a NULL pointer if <c><![CDATA[list]]></c> was
+ not a list.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ETERM *</ret><nametext>erl_iolist_to_binary(term)</nametext></name>
+ <fsummary>Converts an IO list to a binary</fsummary>
+ <type>
+ <v>ETERM *list;</v>
+ </type>
+ <desc>
+ <p>This function converts an IO list to a binary term.</p>
+ <p><c><![CDATA[list]]></c> is an Erlang term containing a list.</p>
+ <p>This function an Erlang binary term, or NULL if <c><![CDATA[list]]></c>
+ was not an IO list. </p>
+ <p>Informally, an IO list is a deep list of characters and
+ binaries which can be sent to an Erlang port. In BNF, an IO
+ list is formally defined as follows: </p>
+ <code type="none"><![CDATA[
+iolist ::= []
+ | Binary
+ | [iohead | iolist]
+ ;
+iohead ::= Binary
+ | Byte (integer in the range [0..255])
+ | iolist
+ ;
+ ]]></code>
+ </desc>
+ </func>
+ <func>
+ <name><ret>char *</ret><nametext>erl_iolist_to_string(list)</nametext></name>
+ <fsummary>Converts an IO list to a zero terminated string</fsummary>
+ <type>
+ <v>ETERM *list;</v>
+ </type>
+ <desc>
+ <p>This function converts an IO list to a '\\0' terminated C
+ string. </p>
+ <p><c><![CDATA[list]]></c> is an Erlang term containing an IO list. The IO
+ list must not contain the integer 0, since C strings may not
+ contain this value except as a terminating marker.</p>
+ <p>This function returns a pointer to a dynamically allocated
+ buffer containing a string. If <c><![CDATA[list]]></c> is not an IO list,
+ or if <c><![CDATA[list]]></c> contains the integer 0, NULL is returned. It
+ is the caller's responsibility free the allocated buffer
+ with <c><![CDATA[erl_free()]]></c>. </p>
+ <p>Refer to <c><![CDATA[erl_iolist_to_binary()]]></c> for the definition of an
+ IO list. </p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>erl_iolist_length(list)</nametext></name>
+ <fsummary>Return the length of an IO list</fsummary>
+ <type>
+ <v>ETERM *list;</v>
+ </type>
+ <desc>
+ <p>Returns the length of an IO list.
+ </p>
+ <p><c><![CDATA[list]]></c> is an Erlang term containing an IO list. </p>
+ <p>The function returns the length of <c><![CDATA[list]]></c>, or -1 if
+ <c><![CDATA[list]]></c> is not an IO list.</p>
+ <p>Refer to <c><![CDATA[erl_iolist_to_binary()]]></c> for the definition of
+ an IO list. </p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>erl_length(list)</nametext></name>
+ <fsummary>Determines the length of a list</fsummary>
+ <type>
+ <v>ETERM *list;</v>
+ </type>
+ <desc>
+ <p>Determines the length of a proper list.</p>
+ <p><c><![CDATA[list]]></c> is an Erlang term containing proper list. In a
+ proper list, all tails except the last point to another list
+ cell, and the last tail points to an empty list.</p>
+ <p>Returns -1 if <c><![CDATA[list]]></c> is not a proper list.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ETERM *</ret><nametext>erl_mk_atom(string)</nametext></name>
+ <fsummary>Creates an atom</fsummary>
+ <type>
+ <v>char *string;</v>
+ </type>
+ <desc>
+ <p>Creates an atom.</p>
+ <p><c><![CDATA[string]]></c> is the sequence of characters that will be
+ used to create the atom.</p>
+ <p>Returns an Erlang term containing an atom. Note that it is
+ the callers responsibility to make sure that <c><![CDATA[string]]></c>
+ contains a valid name for an atom.</p>
+ <p><c><![CDATA[ERL_ATOM_PTR(atom)]]></c> can be used to retrieve the
+ atom name (as a string). Note that the string is not
+ 0-terminated in the atom. <c><![CDATA[ERL_ATOM_SIZE(atom)]]></c>returns
+ the length of the atom name.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ETERM *</ret><nametext>erl_mk_binary(bptr, size)</nametext></name>
+ <fsummary>Creates a binary object</fsummary>
+ <type>
+ <v>char *bptr;</v>
+ <v>int size;</v>
+ </type>
+ <desc>
+ <p>This function produces an Erlang binary object from a
+ buffer containing a sequence of bytes.</p>
+ <p><c><![CDATA[bptr]]></c> is a pointer to a buffer containing data to be converted.</p>
+ <p><c><![CDATA[size]]></c> indicates the length of <c><![CDATA[bptr]]></c>.</p>
+ <p>The function returns an Erlang binary object.</p>
+ <p><c><![CDATA[ERL_BIN_PTR(bin)]]></c> retrieves a pointer to
+ the binary data. <c><![CDATA[ERL_BIN_SIZE(bin)]]></c> retrieves the
+ size. </p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ETERM *</ret><nametext>erl_mk_empty_list()</nametext></name>
+ <fsummary>Creates an empty Erlang list</fsummary>
+ <desc>
+ <p>This function creates and returns an empty Erlang list.
+ Note that NULL is not used to represent an empty list;
+ Use this function instead.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ETERM *</ret><nametext>erl_mk_estring(string, len)</nametext></name>
+ <fsummary>Creates an Erlang string</fsummary>
+ <type>
+ <v>char *string;</v>
+ <v>int len;</v>
+ </type>
+ <desc>
+ <p>This function creates a list from a sequence of bytes.</p>
+ <p><c><![CDATA[string]]></c> is a buffer containing a sequence of
+ bytes. The buffer does not need to be zero-terminated.</p>
+ <p><c><![CDATA[len]]></c> is the length of <c><![CDATA[string]]></c>.</p>
+ <p>The function returns an Erlang list object corresponding to
+ the character sequence in <c><![CDATA[string]]></c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ETERM *</ret><nametext>erl_mk_float(f)</nametext></name>
+ <fsummary>Creates an Erlang float</fsummary>
+ <type>
+ <v>double f;</v>
+ </type>
+ <desc>
+ <p>Creates an Erlang float.</p>
+ <p><c><![CDATA[f]]></c> is a value to be converted to an Erlang float.</p>
+ <p></p>
+ <p>The function returns an Erlang float object with the value
+ specified in <c><![CDATA[f]]></c>.</p>
+ <p><c><![CDATA[ERL_FLOAT_VALUE(t)]]></c> can be used to retrieve the
+ value from an Erlang float.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ETERM *</ret><nametext>erl_mk_int(n)</nametext></name>
+ <fsummary>Creates an Erlang integer</fsummary>
+ <type>
+ <v>int n;</v>
+ </type>
+ <desc>
+ <p>Creates an Erlang integer.</p>
+ <p><c><![CDATA[n]]></c> is a value to be converted to an Erlang integer.</p>
+ <p></p>
+ <p>The function returns an Erlang integer object with the
+ value specified in <c><![CDATA[n]]></c>.</p>
+ <p><c><![CDATA[ERL_INT_VALUE(t)]]></c> can be used to retrieve the value
+ value from an Erlang integer.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ETERM *</ret><nametext>erl_mk_list(array, arrsize)</nametext></name>
+ <fsummary>Creates a list from an array</fsummary>
+ <type>
+ <v>ETERM **array;</v>
+ <v>int arrsize;</v>
+ </type>
+ <desc>
+ <p>Creates an Erlang list from an array of Erlang terms, such
+ that each element in the list corresponds to one element in
+ the array. </p>
+ <p><c><![CDATA[array]]></c> is an array of Erlang terms.</p>
+ <p><c><![CDATA[arrsize]]></c> is the number of elements in <c><![CDATA[array]]></c>.</p>
+ <p>The function creates an Erlang list object, whose length
+ <c><![CDATA[arrsize]]></c> and whose elements are taken from the terms in
+ <c><![CDATA[array]]></c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ETERM *</ret><nametext>erl_mk_pid(node, number, serial, creation)</nametext></name>
+ <fsummary>Creates a process identifier</fsummary>
+ <type>
+ <v>const char *node;</v>
+ <v>unsigned int number;</v>
+ <v>unsigned int serial;</v>
+ <v>unsigned int creation;</v>
+ </type>
+ <desc>
+ <p>This function creates an Erlang process identifier. The
+ resulting pid can be used by Erlang processes wishing to
+ communicate with the C node.</p>
+ <p><c><![CDATA[node]]></c> is the name of the C node.</p>
+ <p><c><![CDATA[number]]></c>, <c><![CDATA[serial]]></c> and <c><![CDATA[creation]]></c> are
+ arbitrary numbers. Note though, that these are limited in
+ precision, so only the low 15, 3 and 2 bits of these numbers
+ are actually used.</p>
+ <p>The function returns an Erlang pid object.</p>
+ <p><c><![CDATA[ERL_PID_NODE(pid)]]></c>, <c><![CDATA[ERL_PID_NUMBER(pid)]]></c>,
+ <c><![CDATA[ERL_PID_SERIAL(pid)]]></c> and <c><![CDATA[ERL_PID_CREATION(pid)]]></c>
+ can be used to retrieve the four values used to create the pid.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ETERM *</ret><nametext>erl_mk_port(node, number, creation)</nametext></name>
+ <fsummary>Creates a port identifier</fsummary>
+ <type>
+ <v>const char *node;</v>
+ <v>unsigned int number;</v>
+ <v>unsigned int creation;</v>
+ </type>
+ <desc>
+ <p>This function creates an Erlang port identifier. </p>
+ <p><c><![CDATA[node]]></c> is the name of the C node.</p>
+ <p><c><![CDATA[number]]></c> and <c><![CDATA[creation]]></c> are arbitrary numbers.
+ Note though, that these are limited in
+ precision, so only the low 18 and 2 bits of these numbers
+ are actually used.</p>
+ <p>The function returns an Erlang port object.</p>
+ <p><c><![CDATA[ERL_PORT_NODE(port)]]></c>, <c><![CDATA[ERL_PORT_NUMBER(port)]]></c>
+ and <c><![CDATA[ERL_PORT_CREATION]]></c> can be used to retrieve the three
+ values used to create the port. </p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ETERM *</ret><nametext>erl_mk_ref(node, number, creation)</nametext></name>
+ <fsummary>Creates an old Erlang reference</fsummary>
+ <type>
+ <v>const char *node;</v>
+ <v>unsigned int number;</v>
+ <v>unsigned int creation;</v>
+ </type>
+ <desc>
+ <p>This function creates an old Erlang reference, with
+ only 18 bits - use <c><![CDATA[erl_mk_long_ref]]></c> instead.</p>
+ <p><c><![CDATA[node]]></c> is the name of the C node.</p>
+ <p><c><![CDATA[number]]></c> should be chosen uniquely for each reference
+ created for a given C node.</p>
+ <p><c><![CDATA[creation]]></c> is an arbitrary number.</p>
+ <p>Note that <c><![CDATA[number]]></c> and <c><![CDATA[creation]]></c> are limited in
+ precision, so only the low 18 and 2 bits of these numbers
+ are actually used.
+ </p>
+ <p>The function returns an Erlang reference object.</p>
+ <p><c><![CDATA[ERL_REF_NODE(ref)]]></c>, <c><![CDATA[ERL_REF_NUMBER(ref)]]></c>, and
+ <c><![CDATA[ERL_REF_CREATION(ref)]]></c> to retrieve the three values used
+ to create the reference. </p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ETERM *</ret><nametext>erl_mk_long_ref(node, n1, n2, n3, creation)</nametext></name>
+ <fsummary>Creates an Erlang reference</fsummary>
+ <type>
+ <v>const char *node;</v>
+ <v>unsigned int n1, n2, n3;</v>
+ <v>unsigned int creation;</v>
+ </type>
+ <desc>
+ <p>This function creates an Erlang reference, with 82 bits.</p>
+ <p><c><![CDATA[node]]></c> is the name of the C node.</p>
+ <p><c><![CDATA[n1]]></c>, <c><![CDATA[n2]]></c> and <c><![CDATA[n3]]></c> can be seen as one big number
+ <c><![CDATA[n1*2^64+n2*2^32+n3]]></c> which should be chosen uniquely for
+ each reference
+ created for a given C node.</p>
+ <p><c><![CDATA[creation]]></c> is an arbitrary number.</p>
+ <p>Note that <c><![CDATA[n3]]></c> and <c><![CDATA[creation]]></c> are limited in
+ precision, so only the low 18 and 2 bits of these numbers
+ are actually used.
+ </p>
+ <p>The function returns an Erlang reference object.</p>
+ <p><c><![CDATA[ERL_REF_NODE(ref)]]></c>, <c><![CDATA[ERL_REF_NUMBERS(ref)]]></c>,
+ <c><![CDATA[ERL_REF_LEN(ref)]]></c> and
+ <c><![CDATA[ERL_REF_CREATION(ref)]]></c> to retrieve the values used
+ to create the reference. </p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ETERM *</ret><nametext>erl_mk_string(string)</nametext></name>
+ <fsummary>Creates a string</fsummary>
+ <type>
+ <v>char *string;</v>
+ </type>
+ <desc>
+ <p>This function creates a list from a zero terminated string.</p>
+ <p><c><![CDATA[string]]></c> is the zero-terminated sequence of characters
+ (i.e. a C string) from which the list will be created.</p>
+ <p>The function returns an Erlang list.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ETERM *</ret><nametext>erl_mk_tuple(array, arrsize)</nametext></name>
+ <fsummary>Creates an Erlang tuple from an array</fsummary>
+ <type>
+ <v>ETERM **array;</v>
+ <v>int arrsize;</v>
+ </type>
+ <desc>
+ <p>Creates an Erlang tuple from an array of Erlang terms.</p>
+ <p><c><![CDATA[array]]></c> is an array of Erlang terms.</p>
+ <p><c><![CDATA[arrsize]]></c> is the number of elements in <c><![CDATA[array]]></c>.</p>
+ <p>The function creates an Erlang tuple, whose arity is
+ <c><![CDATA[size]]></c> and whose elements are taken from the terms in
+ <c><![CDATA[array]]></c>.</p>
+ <p>To retrieve the size of a tuple, either use the
+ <c><![CDATA[erl_size]]></c> function (which checks the type of the checked
+ term and works for a binary as well as for a tuple), or the
+ <c><![CDATA[ERL_TUPLE_SIZE(tuple)]]></c> returns the arity of a tuple.
+ <c><![CDATA[erl_size()]]></c> will do the same thing, but it checks that
+ the argument really is a tuple.
+ <c><![CDATA[erl_element(index,tuple)]]></c> returns the element
+ corresponding to a given position in the tuple. </p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ETERM *</ret><nametext>erl_mk_uint(n)</nametext></name>
+ <fsummary>Creates an unsigned integer</fsummary>
+ <type>
+ <v>unsigned int n;</v>
+ </type>
+ <desc>
+ <p>Creates an Erlang unsigned integer.</p>
+ <p><c><![CDATA[n]]></c> is a value to be converted to an Erlang
+ unsigned integer.</p>
+ <p></p>
+ <p>The function returns an Erlang unsigned integer object with
+ the value specified in <c><![CDATA[n]]></c>.</p>
+ <p><c><![CDATA[ERL_INT_UVALUE(t)]]></c> can be used to retrieve the
+ value from an Erlang unsigned integer.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ETERM *</ret><nametext>erl_mk_var(name)</nametext></name>
+ <fsummary>Creates an Erlang variable</fsummary>
+ <type>
+ <v>char *name;</v>
+ </type>
+ <desc>
+ <p>This function creates an unbound Erlang variable. The
+ variable can later be bound through pattern matching or assignment.</p>
+ <p><c><![CDATA[name]]></c> specifies a name for the variable.</p>
+ <p>The function returns an Erlang variable object with the
+ name <c><![CDATA[name]]></c>. </p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>erl_print_term(stream, term)</nametext></name>
+ <fsummary>Prints an Erlang term</fsummary>
+ <type>
+ <v>FILE *stream;</v>
+ <v>ETERM *term;</v>
+ </type>
+ <desc>
+ <p>This function prints the specified Erlang term to the given
+ output stream.</p>
+ <p><c><![CDATA[stream]]></c> indicates where the function should send its
+ output.</p>
+ <p><c><![CDATA[term]]></c> is the Erlang term to print.</p>
+ <p>The function returns the number of characters written, or a
+ negative value if there was an error.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>void</ret><nametext>erl_set_compat_rel(release_number)</nametext></name>
+ <fsummary>Set the erl_interface library in compatibility mode</fsummary>
+ <type>
+ <v>unsigned release_number;</v>
+ </type>
+ <desc>
+ <marker id="erl_set_compat_rel"></marker>
+ <p>By default, the <c><![CDATA[erl_interface]]></c> library is only guaranteed
+ to be compatible with other Erlang/OTP components from the same
+ release as the <c><![CDATA[erl_interface]]></c> library itself. For example,
+ <c><![CDATA[erl_interface]]></c> from the OTP R10 release is not compatible
+ with an Erlang emulator from the OTP R9 release by default.</p>
+ <p>A call to <c><![CDATA[erl_set_compat_rel(release_number)]]></c> sets the
+ <c><![CDATA[erl_interface]]></c> library in compatibility mode of release
+ <c><![CDATA[release_number]]></c>. Valid range of <c><![CDATA[release_number]]></c>
+ is [7, current release]. This makes it possible to
+ communicate with Erlang/OTP components from earlier releases.</p>
+ <note>
+ <p>If this function is called, it may only be called once
+ directly after the call to the
+ <seealso marker="#erl_init">erl_init()</seealso> function.</p>
+ </note>
+ <warning>
+ <p>You may run into trouble if this feature is used
+ carelessly. Always make sure that all communicating
+ components are either from the same Erlang/OTP release, or
+ from release X and release Y where all components
+ from release Y are in compatibility mode of release X.</p>
+ </warning>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>erl_size(term)</nametext></name>
+ <fsummary>Return the arity of a tuple or binary</fsummary>
+ <type>
+ <v>ETERM *term;</v>
+ </type>
+ <desc>
+ <p>Returns the arity of an Erlang tuple, or the
+ number of bytes in an Erlang binary object. </p>
+ <p><c><![CDATA[term]]></c> is an Erlang tuple or an Erlang binary object.</p>
+ <p>The function returns the size of <c><![CDATA[term]]></c> as described
+ above, or -1 if <c><![CDATA[term]]></c> is not one of the two supported
+ types. </p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ETERM *</ret><nametext>erl_tl(list)</nametext></name>
+ <fsummary>Extracts the tail from a list</fsummary>
+ <type>
+ <v>ETERM *list;</v>
+ </type>
+ <desc>
+ <p>Extracts the tail from a list.</p>
+ <p><c><![CDATA[list]]></c> is an Erlang term containing a list.</p>
+ <p>The function returns an Erlang list corresponding to the
+ original list minus the first element, or NULL pointer if
+ <c><![CDATA[list]]></c> was not a list.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ETERM *</ret><nametext>erl_var_content(term, name)</nametext></name>
+ <fsummary>Extracts the content of a variable</fsummary>
+ <type>
+ <v>ETERM *term;</v>
+ <v>char *name;</v>
+ </type>
+ <desc>
+ <p>This function returns the contents of the specified
+ variable in an Erlang term.
+ </p>
+ <p><c><![CDATA[term]]></c> is an Erlang term. In order for this function
+ to succeed, <c><![CDATA[term]]></c> must be an Erlang variable with the
+ specified name, or it must be an Erlang list or tuple
+ containing a variable with the specified name. Other Erlang
+ types cannot contain variables.</p>
+ <p><c><![CDATA[name]]></c> is the name of an Erlang variable.</p>
+ <p>Returns the Erlang object corresponding to the value of
+ <c><![CDATA[name]]></c> in <c><![CDATA[term]]></c>. If no variable with the name
+ <c><![CDATA[name]]></c> was found in <c><![CDATA[term]]></c>, or if <c><![CDATA[term]]></c> is
+ not a valid Erlang term, NULL is returned.</p>
+ </desc>
+ </func>
+ </funcs>
+</cref>
+
diff --git a/lib/erl_interface/doc/src/erl_format.xml b/lib/erl_interface/doc/src/erl_format.xml
new file mode 100644
index 0000000000..5699485845
--- /dev/null
+++ b/lib/erl_interface/doc/src/erl_format.xml
@@ -0,0 +1,141 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE cref SYSTEM "cref.dtd">
+
+<cref>
+ <header>
+ <copyright>
+ <year>1996</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>erl_format</title>
+ <prepared>Torbj&ouml;rn T&ouml;rnkvist</prepared>
+ <responsible>Torbj&ouml;rn T&ouml;rnkvist</responsible>
+ <docno></docno>
+ <approved>Bjarne D&auml;cker</approved>
+ <checked>Torbj&ouml;rn T&ouml;rnkvist</checked>
+ <date>961016</date>
+ <rev>A</rev>
+ <file>erl_format.sgml</file>
+ </header>
+ <lib>erl_format</lib>
+ <libsummary>Create and Match Erlang Terms</libsummary>
+ <description>
+ <p>This module contains two routines - one general function for
+ creating Erlang terms and one for pattern matching Erlang terms.</p>
+ </description>
+ <funcs>
+ <func>
+ <name><ret>ETERM *</ret><nametext>erl_format(FormatStr, ... )</nametext></name>
+ <fsummary>Creates an Erlang term</fsummary>
+ <type>
+ <v>char *FormatStr;</v>
+ </type>
+ <desc>
+ <p>This is a general function for creating Erlang terms using
+ a format specifier and a corresponding set of arguments, much
+ in the way <c><![CDATA[printf()]]></c> works.</p>
+ <p><c><![CDATA[FormatStr]]></c> is a format specification string. The set
+ of valid format specifiers is as follows:</p>
+ <list type="bulleted">
+ <item>
+ <p>~i - Integer</p>
+ </item>
+ <item>
+ <p>~f - Floating point</p>
+ </item>
+ <item>
+ <p>~a - Atom</p>
+ </item>
+ <item>
+ <p>~s - String</p>
+ </item>
+ <item>
+ <p>~w - Arbitrary Erlang term</p>
+ </item>
+ </list>
+ <p>For each format specifier that appears in <c><![CDATA[FormatStr]]></c>,
+ there must be a corresponding argument following
+ <c><![CDATA[FormatStr]]></c>. An Erlang term is built according to the
+ <c><![CDATA[FormatStr]]></c> with values and Erlang terms substituted from
+ the corresponding arguments and according to the individual
+ format specifiers. For example:</p>
+ <code type="none"><![CDATA[
+erl_format("[{name,~a},{age,~i},{data,~w}]",
+ "madonna",
+ 21,
+ erl_format("[{adr,~s,~i}]","E-street",42));
+ ]]></code>
+ <p>This will create an <c><![CDATA[(ETERM *)]]></c> structure corresponding
+ to the Erlang term:
+ <c><![CDATA[[{name,madonna},{age,21},{data,[{adr,"E-street",42}]}]]]></c></p>
+ <p>The function returns an Erlang term, or NULL if
+ <c><![CDATA[FormatStr]]></c> does not describe a valid Erlang term.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>erl_match(Pattern, Term)</nametext></name>
+ <fsummary>Performs pattern matching</fsummary>
+ <type>
+ <v>ETERM *Pattern,*Term;</v>
+ </type>
+ <desc>
+ <p>This function is used to perform pattern matching similar
+ to that done in Erlang. Refer to an Erlang manual for matching
+ rules and more examples.</p>
+ <p><c><![CDATA[Pattern]]></c> is an Erlang term, possibly containing unbound
+ variables. </p>
+ <p><c><![CDATA[Term]]></c> is an Erlang term that we wish to match against
+ <c><![CDATA[Pattern]]></c>.</p>
+ <p><c><![CDATA[Term]]></c> and <c><![CDATA[Pattern]]></c> are compared, and any
+ unbound variables in <c><![CDATA[Pattern]]></c> are bound to corresponding
+ values in <c><![CDATA[Term]]></c>. </p>
+ <p>If <c><![CDATA[Term]]></c> and <c><![CDATA[Pattern]]></c> can be matched, the
+ function returns a non-zero value and binds any unbound
+ variables in <c><![CDATA[Pattern]]></c>. If <c><![CDATA[Term]]></c><c><![CDATA[Pattern]]></c> do
+ not match, the function returns 0. For example:</p>
+ <code type="none"><![CDATA[
+ETERM *term, *pattern, *pattern2;
+term1 = erl_format("{14,21}");
+term2 = erl_format("{19,19}");
+pattern1 = erl_format("{A,B}");
+pattern2 = erl_format("{F,F}");
+if (erl_match(pattern1, term1)) {
+ /* match succeeds:
+ * A gets bound to 14,
+ * B gets bound to 21
+ */
+ ...
+}
+if (erl_match(pattern2, term1)) {
+ /* match fails because F cannot be
+ * bound to two separate values, 14 and 21
+ */
+ ...
+}
+if (erl_match(pattern2, term2)) {
+ /* match succeeds and F gets bound to 19 */
+ ...
+}
+ ]]></code>
+ <p><c><![CDATA[erl_var_content()]]></c> can be used to retrieve the
+ content of any variables bound as a result of a call to
+ <c><![CDATA[erl_match()]]></c>.</p>
+ </desc>
+ </func>
+ </funcs>
+</cref>
+
diff --git a/lib/erl_interface/doc/src/erl_global.xml b/lib/erl_interface/doc/src/erl_global.xml
new file mode 100644
index 0000000000..8f9a354b4f
--- /dev/null
+++ b/lib/erl_interface/doc/src/erl_global.xml
@@ -0,0 +1,141 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE cref SYSTEM "cref.dtd">
+
+<cref>
+ <header>
+ <copyright>
+ <year>1998</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>erl_global</title>
+ <prepared>Gordon Beaton</prepared>
+ <responsible>Gordon Beaton</responsible>
+ <docno></docno>
+ <approved>Gordon Beaton</approved>
+ <checked>Gordon Beaton</checked>
+ <date>980703</date>
+ <rev>A</rev>
+ <file>erl_global.sgml</file>
+ </header>
+ <lib>erl_global</lib>
+ <libsummary>Access globally registered names</libsummary>
+ <description>
+ <p>This module provides support for registering, looking
+ up and unregistering names in the Erlang Global module. For more
+ information, see the description of Global in the reference manual.</p>
+ <p>Note that the functions below perform an RPC using an open file
+ descriptor provided by the caller. This file descriptor must
+ not be used for other traffic during the global operation or the
+ function may receive unexpected data and fail.</p>
+ </description>
+ <funcs>
+ <func>
+ <name><ret>char **</ret><nametext>erl_global_names(fd,count)</nametext></name>
+ <fsummary>Obtain list of Global names</fsummary>
+ <type>
+ <v>int fd;</v>
+ <v>int *count;</v>
+ </type>
+ <desc>
+ <p>Retrieve a list of all known global names.
+ </p>
+ <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.
+ </p>
+ <p><c><![CDATA[count]]></c> is the address of an integer, or NULL. If
+ <c><![CDATA[count]]></c> is not NULL, it will be set by the function to
+ the number of names found.
+ </p>
+ <p>On success, the function returns an array of strings, each
+ containing a single registered name, and sets <c><![CDATA[count]]></c> to
+ the number of names found. The array is terminated
+ by a single NULL pointer. On failure, the function returns
+ NULL and <c><![CDATA[count]]></c> is not modified.
+ </p>
+ <note>
+ <p>It is the caller's responsibility to free the array
+ afterwards. It has been allocated by the function with a
+ single call to <c><![CDATA[malloc()]]></c>, so a single <c><![CDATA[free()]]></c> is
+ all that is necessary.</p>
+ </note>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>erl_global_register(fd,name,pid)</nametext></name>
+ <fsummary>Register a name in Global</fsummary>
+ <type>
+ <v>int fd;</v>
+ <v>const char *name;</v>
+ <v>ETERM *pid;</v>
+ </type>
+ <desc>
+ <p>This function registers a name in Global.
+ </p>
+ <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.
+ </p>
+ <p><c><![CDATA[name]]></c> is the name to register in Global.
+ </p>
+ <p><c><![CDATA[pid]]></c> is the pid that should be associated with
+ <c><![CDATA[name]]></c>. This is the value that Global will return when
+ processes request the location of <c><![CDATA[name]]></c>.
+ </p>
+ <p>The function returns 0 on success, or -1 on failure.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>erl_global_unregister(fd,name)</nametext></name>
+ <fsummary>Unregister a name in Global</fsummary>
+ <type>
+ <v>int fd;</v>
+ <v>const char *name;</v>
+ </type>
+ <desc>
+ <p>This function unregisters a name from Global.
+ </p>
+ <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.
+ </p>
+ <p><c><![CDATA[name]]></c> is the name to unregister from Global.
+ </p>
+ <p>The function returns 0 on success, or -1 on failure.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ETERM *</ret><nametext>erl_global_whereis(fd,name,node)</nametext></name>
+ <fsummary>Look up a name in global</fsummary>
+ <type>
+ <v>int fd;</v>
+ <v>const char *name;</v>
+ <v>char *node;</v>
+ </type>
+ <desc>
+ <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.
+ </p>
+ <p><c><![CDATA[name]]></c> is the name that is to be looked up in Global.
+ </p>
+ <p>If <c><![CDATA[node]]></c> is not NULL, it is a pointer to a buffer
+ where the function can fill in the name of the node where
+ <c><![CDATA[name]]></c> is found. <c><![CDATA[node]]></c> can be passed directly to
+ <c><![CDATA[erl_connect()]]></c> if necessary.
+ </p>
+ <p>On success, the function returns an Erlang Pid containing the address
+ of the given name, and node will be initialized to
+ the nodename where <c><![CDATA[name]]></c> is found. On failure NULL will be
+ returned and <c><![CDATA[node]]></c> will not be modified.</p>
+ </desc>
+ </func>
+ </funcs>
+</cref>
+
diff --git a/lib/erl_interface/doc/src/erl_interface.xml b/lib/erl_interface/doc/src/erl_interface.xml
new file mode 100644
index 0000000000..850a4127f4
--- /dev/null
+++ b/lib/erl_interface/doc/src/erl_interface.xml
@@ -0,0 +1,625 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>1996</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>The Erl_Interface Library</title>
+ <prepared>Torbj&ouml;rn T&ouml;rnkvist</prepared>
+ <responsible>Torbj&ouml;rn T&ouml;rnkvist</responsible>
+ <docno></docno>
+ <approved>Bjarne D&auml;cker</approved>
+ <checked>K.Lundin</checked>
+ <date>990113</date>
+ <rev>A</rev>
+ <file>erl_interface.sgml</file>
+ </header>
+ <p>The Erl_Interface library contains functions. which help you
+ integrate programs written in C and Erlang. The functions in
+ Erl_Interface support the following:</p>
+ <list type="bulleted">
+ <item>manipulation of data represented as Erlang data types</item>
+ <item>conversion of data between C and Erlang formats</item>
+ <item>encoding and decoding of Erlang data types for transmission or storage</item>
+ <item>communication between C nodes and Erlang processes</item>
+ <item>backup and restore of C node state to and from Mnesia</item>
+ </list>
+ <p>In the following sections, these topics are described:</p>
+ <list type="bulleted">
+ <item>compiling your code for use with Erl_Interface</item>
+ <item>initializing Erl_Interface</item>
+ <item>encoding, decoding, and sending Erlang terms</item>
+ <item>building terms and patterns</item>
+ <item>pattern matching</item>
+ <item>connecting to a distributed Erlang node</item>
+ <item>using EPMD</item>
+ <item>sending and receiving Erlang messages</item>
+ <item>remote procedure calls</item>
+ <item>global names</item>
+ <item>the registry</item>
+ </list>
+
+ <section>
+ <title>Compiling and Linking Your Code</title>
+ <p>In order to use any of the Erl_Interface functions, include the
+ following lines in your code:</p>
+ <code type="none"><![CDATA[
+#include "erl_interface.h"
+#include "ei.h" ]]></code>
+ <p>Determine where the top directory of your OTP installation is. You
+ can find this out by starting Erlang and entering the following
+ command at the Eshell prompt:</p>
+ <code type="none"><![CDATA[
+Eshell V4.7.4 (abort with ^G)
+1> code:root_dir().
+/usr/local/otp ]]></code>
+ <p>To compile your code, make sure that your C compiler knows where
+ to find <c><![CDATA[erl_interface.h]]></c> by specifying an appropriate <c><![CDATA[-I]]></c>
+ argument on the command line, or by adding it to the <c><![CDATA[CFLAGS]]></c>
+ definition in your <c><![CDATA[Makefile]]></c>. The correct value for this path is
+ <c><![CDATA[$OTPROOT/lib/erl_interface]]></c><em>Vsn</em><c><![CDATA[/include]]></c>, where <c><![CDATA[$OTPROOT]]></c> is the path
+ reported by <c><![CDATA[code:root_dir/0]]></c> in the above example, and <em>Vsn</em> is
+ the version of the Erl_interface application, for example
+ <c><![CDATA[erl_interface-3.2.3]]></c></p>
+ <code type="none"><![CDATA[
+$ cc -c -I/usr/local/otp/lib/erl_interface-3.2.3/include myprog.c ]]></code>
+ <p>When linking, you will need to specify the path to
+ <c><![CDATA[liberl_interface.a]]></c> and <c><![CDATA[libei.a]]></c> with
+ <c><![CDATA[-L$OTPROOT/lib/erl_interface-3.2.3/lib]]></c>, and you will need to specify the
+ name of the libraries with <c><![CDATA[-lerl_interface -lei]]></c>. You can do
+ this on the command line or by adding the flags to the <c><![CDATA[LDFLAGS]]></c>
+ definition in your <c><![CDATA[Makefile]]></c>.</p>
+ <code type="none"><![CDATA[
+$ ld -L/usr/local/otp/lib/erl_interface-3.2.3/
+ lib myprog.o -lerl_interface -lei -o myprog ]]></code>
+ <p>Also, on some systems it may be necessary to link with some
+ additional libraries (e.g. <c><![CDATA[libnsl.a]]></c> and <c><![CDATA[libsocket.a]]></c> on
+ Solaris, or <c><![CDATA[wsock32.lib]]></c> on Windows) in order to use the
+ communication facilities of Erl_Interface.</p>
+ <p>If you are using Erl_Interface functions in a threaded
+ application based on POSIX threads or Solaris threads, then
+ Erl_Interface needs access to some of the synchronization
+ facilities in your threads package, and you will need to specify
+ additional compiler flags in order to indicate which of the packages
+ you are using. Define <c><![CDATA[_REENTRANT]]></c> and either <c><![CDATA[STHREADS]]></c> or
+ <c><![CDATA[PTHREADS]]></c>. The default is to use POSIX threads if
+ <c><![CDATA[_REENTRANT]]></c> is specified.</p>
+ <p>Note that both single threaded and default versions of the Erl_interface
+ and Ei libraries are provided. (The single threaded versions are named
+ <c><![CDATA[liberl_interface_st]]></c> and <c><![CDATA[libei_st]]></c>). Whether the default
+ versions of the libraries have support for threads or not is determined by if
+ the platform in question has support for POSIX or Solaris threads. To check this,
+ have a look in the <c><![CDATA[eidefs.mk]]></c> file in the erl_interface src directory.</p>
+ </section>
+
+ <section>
+ <title>Initializing the erl_interface Library</title>
+ <p>Before calling any of the other Erl_Interface functions, you
+ must call <c><![CDATA[erl_init()]]></c> exactly once to initialize the library.
+ <c><![CDATA[erl_init()]]></c> takes two arguments, however the arguments are no
+ longer used by Erl_Interface, and should therefore be specified
+ as <c><![CDATA[erl_init(NULL,0)]]></c>.</p>
+ </section>
+
+ <section>
+ <title>Encoding, Decoding and Sending Erlang Terms</title>
+ <p>Data sent between distributed Erlang nodes is encoded in the
+ Erlang external format. Consequently, you have to encode and decode
+ Erlang terms into byte streams if you want to use the distribution
+ protocol to communicate between a C program and Erlang. </p>
+ <p>The Erl_Interface library supports this activity. It has a
+ number of C functions which create and manipulate Erlang data
+ structures. The library also contains an encode and a decode function.
+ The example below shows how to create and encode an Erlang tuple
+ <c><![CDATA[{tobbe,3928}]]></c>:</p>
+ <code type="none"><![CDATA[
+
+ETERM *arr[2], *tuple;
+char buf[BUFSIZ];
+int i;
+
+arr[0] = erl_mk_atom("tobbe");
+arr[1] = erl_mk_integer(3928);
+tuple = erl_mk_tuple(arr, 2);
+i = erl_encode(tuple, buf); ]]></code>
+ <p>Alternatively, you can use <c><![CDATA[erl_send()]]></c> and
+ <c><![CDATA[erl_receive_msg]]></c>, which handle the encoding and decoding of
+ messages transparently.</p>
+ <p>Refer to the Reference Manual for a complete description of the
+ following modules:</p>
+ <list type="bulleted">
+ <item>the <c><![CDATA[erl_eterm]]></c> module for creating Erlang terms</item>
+ <item>the <c><![CDATA[erl_marshal]]></c> module for encoding and decoding routines.</item>
+ </list>
+ </section>
+
+ <section>
+ <title>Building Terms and Patterns</title>
+ <p>The previous example can be simplified by using
+ <c><![CDATA[erl_format()]]></c> to create an Erlang term.</p>
+ <code type="none"><![CDATA[
+
+ETERM *ep;
+ep = erl_format("{~a,~i}", "tobbe", 3928); ]]></code>
+ <p>Refer to the Reference Manual, the <c><![CDATA[erl_format]]></c> module, for a
+ full description of the different format directives. The following
+ example is more complex:</p>
+ <code type="none"><![CDATA[
+
+ETERM *ep;
+ep = erl_format("[{name,~a},{age,~i},{data,~w}]",
+ "madonna",
+ 21,
+ erl_format("[{adr,~s,~i}]", "E-street", 42));
+erl_free_compound(ep); ]]></code>
+ <p>As in previous examples, it is your responsibility to free the
+ memory allocated for Erlang terms. In this example,
+ <c><![CDATA[erl_free_compound()]]></c> ensures that the complete term pointed to
+ by <c><![CDATA[ep]]></c> is released. This is necessary, because the pointer from
+ the second call to <c><![CDATA[erl_format()]]></c> is lost. </p>
+ <p>The following
+ example shows a slightly different solution:</p>
+ <code type="none"><![CDATA[
+
+ETERM *ep,*ep2;
+ep2 = erl_format("[{adr,~s,~i}]","E-street",42);
+ep = erl_format("[{name,~a},{age,~i},{data,~w}]",
+ "madonna", 21, ep2);
+erl_free_term(ep);
+erl_free_term(ep2); ]]></code>
+ <p>In this case, you free the two terms independently. The order in
+ which you free the terms <c><![CDATA[ep]]></c> and <c><![CDATA[ep2]]></c> is not important,
+ because the Erl_Interface library uses reference counting to
+ determine when it is safe to actually remove objects. </p>
+ <p>If you are not sure whether you have freed the terms properly, you
+ can use the following function to see the status of the fixed term
+ allocator:</p>
+ <code type="none"><![CDATA[
+long allocated, freed;
+
+erl_eterm_statistics(&allocated,&freed);
+printf("currently allocated blocks: %ld\
+",allocated);
+printf("length of freelist: %ld\
+",freed);
+
+/* really free the freelist */
+erl_eterm_release();
+ ]]></code>
+ <p>Refer to the Reference Manual, the <c><![CDATA[erl_malloc]]></c> module for more
+ information.</p>
+ </section>
+
+ <section>
+ <title>Pattern Matching</title>
+ <p>An Erlang pattern is a term that may contain unbound variables or
+ <c><![CDATA["do not care"]]></c> symbols. Such a pattern can be matched against a
+ term and, if the match is successful, any unbound variables in the
+ pattern will be bound as a side effect. The content of a bound
+ variable can then be retrieved.</p>
+ <code type="none"><![CDATA[
+
+ETERM *pattern;
+pattern = erl_format("{madonna,Age,_}"); ]]></code>
+ <p><c><![CDATA[erl_match()]]></c> is used to perform pattern matching. It takes a
+ pattern and a term and tries to match them. As a side effect any unbound
+ variables in the pattern will be bound. In the following example, we
+ create a pattern with a variable <em>Age</em> which appears at two
+ positions in the tuple. The pattern match is performed as follows:</p>
+ <list type="ordered">
+ <item><c><![CDATA[erl_match()]]></c> will bind the contents of
+ <em>Age</em> to <em>21</em> the first time it reaches the variable</item>
+ <item>the second occurrence of <em>Age</em> will cause a test for
+ equality between the terms since <em>Age</em> is already bound to
+ <em>21</em>. Since <em>Age</em> is bound to 21, the equality test will
+ succeed and the match continues until the end of the pattern.</item>
+ <item>if the end of the pattern is reached, the match succeeds and you
+ can retrieve the contents of the variable</item>
+ </list>
+ <code type="none"><![CDATA[
+ETERM *pattern,*term;
+pattern = erl_format("{madonna,Age,Age}");
+term = erl_format("{madonna,21,21}");
+if (erl_match(pattern, term)) {
+ fprintf(stderr, "Yes, they matched: Age = ");
+ ep = erl_var_content(pattern, "Age");
+ erl_print_term(stderr, ep);
+ fprintf(stderr,"\
+");
+ erl_free_term(ep);
+}
+erl_free_term(pattern);
+erl_free_term(term); ]]></code>
+ <p>Refer to the Reference Manual, the <c><![CDATA[erl_match()]]></c> function for
+ more information.</p>
+ </section>
+
+ <section>
+ <title>Connecting to a Distributed Erlang Node</title>
+ <p>In order to connect to a distributed Erlang node you need to first
+ initialize the connection routine with <c><![CDATA[erl_connect_init()]]></c>,
+ which stores information such as the host name, node name, and IP
+ address for later use:</p>
+ <code type="none"><![CDATA[
+int identification_number = 99;
+int creation=1;
+char *cookie="a secret cookie string"; /* An example */
+erl_connect_init(identification_number, cookie, creation); ]]></code>
+ <p>Refer to the Reference Manual, the <c><![CDATA[erl_connect]]></c> module for more information.</p>
+ <p>After initialization, you set up the connection to the Erlang node.
+ Use <c><![CDATA[erl_connect()]]></c> to specify the Erlang node you want to
+ connect to. The following example sets up the connection and should
+ result in a valid socket file descriptor:</p>
+ <code type="none"><![CDATA[
+int sockfd;
+char *nodename="[email protected]"; /* An example */
+if ((sockfd = erl_connect(nodename)) < 0)
+ erl_err_quit("ERROR: erl_connect failed"); ]]></code>
+ <p><c><![CDATA[erl_err_quit()]]></c> prints the specified string and terminates
+ the program. Refer to the Reference Manual, the <c><![CDATA[erl_error()]]></c>
+ function for more information.</p>
+ </section>
+
+ <section>
+ <title>Using EPMD</title>
+ <p><c><![CDATA[Epmd]]></c> is the Erlang Port Mapper Daemon. Distributed Erlang nodes
+ register with <c><![CDATA[epmd]]></c> on the localhost to indicate to other nodes that
+ they exist and can accept connections. <c><![CDATA[Epmd]]></c> maintains a register of
+ node and port number information, and when a node wishes to connect to
+ another node, it first contacts <c><![CDATA[epmd]]></c> in order to find out the correct
+ port number to connect to.</p>
+ <p>When you use <c><![CDATA[erl_connect()]]></c> to connect to an Erlang node, a
+ connection is first made to <c><![CDATA[epmd]]></c> and, if the node is known, a
+ connection is then made to the Erlang node.</p>
+ <p>C nodes can also register themselves with <c><![CDATA[epmd]]></c> if they want other
+ nodes in the system to be able to find and connect to them.</p>
+ <p>Before registering with <c><![CDATA[epmd]]></c>, you need to first create a listen socket
+ and bind it to a port. Then:</p>
+ <code type="none"><![CDATA[
+int pub;
+
+pub = erl_publish(port); ]]></code>
+ <p><c><![CDATA[pub]]></c> is a file descriptor now connected to <c><![CDATA[epmd]]></c>. <c><![CDATA[Epmd]]></c>
+ monitors the other end of the connection, and if it detects that the
+ connection has been closed, the node will be unregistered. So, if you
+ explicitly close the descriptor or if your node fails, it will be
+ unregistered from <c><![CDATA[epmd]]></c>.</p>
+ <p>Be aware that on some systems (such as VxWorks), a failed node will
+ not be detected by this mechanism since the operating system does not
+ automatically close descriptors that were left open when the node
+ failed. If a node has failed in this way, <c><![CDATA[epmd]]></c> will prevent you from
+ registering a new node with the old name, since it thinks that the old
+ name is still in use. In this case, you must unregister the name
+ explicitly:</p>
+ <code type="none"><![CDATA[
+erl_unpublish(node); ]]></code>
+ <p>This will cause <c><![CDATA[epmd]]></c> to close the connection from the far end. Note
+ that if the name was in fact still in use by a node, the results of
+ this operation are unpredictable. Also, doing this does not cause the
+ local end of the connection to close, so resources may be consumed.</p>
+ </section>
+
+ <section>
+ <title>Sending and Receiving Erlang Messages</title>
+ <p>Use one of the following two functions to send messages:</p>
+ <list type="bulleted">
+ <item><c><![CDATA[erl_send()]]></c></item>
+ <item><c><![CDATA[erl_reg_send()]]></c></item>
+ </list>
+ <p>As in Erlang, it is possible to send messages to a
+ <em>Pid</em> or to a registered name. It is easier to send a
+ message to a registered name because it avoids the problem of finding
+ a suitable <em>Pid</em>.</p>
+ <p>Use one of the following two functions to receive messages:</p>
+ <list type="bulleted">
+ <item><c><![CDATA[erl_receive()]]></c></item>
+ <item><c><![CDATA[erl_receive_msg()]]></c></item>
+ </list>
+ <p><c><![CDATA[erl_receive()]]></c> receives the message into a buffer, while
+ <c><![CDATA[erl_receive_msg()]]></c> decodes the message into an Erlang term. </p>
+
+ <section>
+ <title>Example of Sending Messages</title>
+ <p>In the following example, <c><![CDATA[{Pid, hello_world}]]></c> is
+ sent to a registered process <c><![CDATA[my_server]]></c>. The message is encoded
+ by <c><![CDATA[erl_send()]]></c>:</p>
+ <code type="none"><![CDATA[
+extern const char *erl_thisnodename(void);
+extern short erl_thiscreation(void);
+#define SELF(fd) erl_mk_pid(erl_thisnodename(),fd,0,erl_thiscreation())
+ETERM *arr[2], *emsg;
+int sockfd, creation=1;
+
+arr[0] = SELF(sockfd);
+arr[1] = erl_mk_atom("Hello world");
+emsg = erl_mk_tuple(arr, 2);
+
+erl_reg_send(sockfd, "my_server", emsg);
+erl_free_term(emsg); ]]></code>
+ <p>The first element of the tuple that is sent is your own
+ <em>Pid</em>. This enables <c><![CDATA[my_server]]></c> to reply. Refer to the
+ Reference Manual, the <c><![CDATA[erl_connect]]></c> module for more information
+ about send primitives.</p>
+ </section>
+
+ <section>
+ <title>Example of Receiving Messages</title>
+ <p>In this example <c><![CDATA[{Pid, Something}]]></c> is received. The
+ received Pid is then used to return <c><![CDATA[{goodbye,Pid}]]></c></p>
+ <code type="none"><![CDATA[
+ETERM *arr[2], *answer;
+int sockfd,rc;
+char buf[BUFSIZE];
+ErlMessage emsg;
+
+if ((rc = erl_receive_msg(sockfd , buf, BUFSIZE, &emsg)) == ERL_MSG) {
+ arr[0] = erl_mk_atom("goodbye");
+ arr[1] = erl_element(1, emsg.msg);
+ answer = erl_mk_tuple(arr, 2);
+ erl_send(sockfd, arr[1], answer);
+ erl_free_term(answer);
+ erl_free_term(emsg.msg);
+ erl_free_term(emsg.to);
+}
+} ]]></code>
+ <p>In order to provide robustness, a distributed Erlang node
+ occasionally polls all its connected neighbours in an attempt to
+ detect failed nodes or communication links. A node which receives such
+ a message is expected to respond immediately with an <c><![CDATA[ERL_TICK]]></c> message.
+ This is done automatically by <c><![CDATA[erl_receive()]]></c>, however when this
+ has occurred <c><![CDATA[erl_receive]]></c> returns <c><![CDATA[ERL_TICK]]></c> to the caller
+ without storing a message into the <c><![CDATA[ErlMessage]]></c> structure.</p>
+ <p>When a message has been received, it is the caller's responsibility
+ to free the received message <c><![CDATA[emsg.msg]]></c> as well as <c><![CDATA[emsg.to]]></c>
+ or <c><![CDATA[emsg.from]]></c>, depending on the type of message received.</p>
+ <p>Refer to the Reference Manual for additional information about the
+ following modules:</p>
+ <list type="bulleted">
+ <item><c><![CDATA[erl_connect]]></c></item>
+ <item><c><![CDATA[erl_eterm]]></c>.</item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Remote Procedure Calls</title>
+ <p>An Erlang node acting as a client to another Erlang node
+ typically sends a request and waits for a reply. Such a request is
+ included in a function call at a remote node and is called a remote
+ procedure call. The following example shows how the
+ Erl_Interface library supports remote procedure calls:</p>
+ <code type="none"><![CDATA[
+
+char modname[]=THE_MODNAME;
+ETERM *reply,*ep;
+ep = erl_format("[~a,[]]", modname);
+if (!(reply = erl_rpc(fd, "c", "c", ep)))
+ erl_err_msg("<ERROR> when compiling file: %s.erl !\
+", modname);
+erl_free_term(ep);
+ep = erl_format("{ok,_}");
+if (!erl_match(ep, reply))
+ erl_err_msg("<ERROR> compiler errors !\
+");
+erl_free_term(ep);
+erl_free_term(reply); ]]></code>
+ <p><c><![CDATA[c:c/1]]></c> is called to compile the specified module on the
+ remote node. <c><![CDATA[erl_match()]]></c> checks that the compilation was
+ successful by testing for the expected <c><![CDATA[ok]]></c>.</p>
+ <p>Refer to the Reference Manual, the <c><![CDATA[erl_connect]]></c> module for
+ more information about <c><![CDATA[erl_rpc()]]></c>, and its companions
+ <c><![CDATA[erl_rpc_to()]]></c> and <c><![CDATA[erl_rpc_from()]]></c>.</p>
+ </section>
+
+ <section>
+ <title>Using Global Names</title>
+ <p>A C node has access to names registered through the Erlang Global
+ module. Names can be looked up, allowing the C node to send messages
+ to named Erlang services. C nodes can also register global names,
+ allowing them to provide named services to Erlang processes or other C
+ nodes. </p>
+ <p>Erl_Interface does not provide a native implementation of the global
+ service. Instead it uses the global services provided by a "nearby"
+ Erlang node. In order to use the services described in this section,
+ it is necessary to first open a connection to an Erlang node.</p>
+ <p>To see what names there are:</p>
+ <code type="none"><![CDATA[
+char **names;
+int count;
+int i;
+
+names = erl_global_names(fd,&count);
+
+if (names)
+ for (i=0; i<count; i++)
+ printf("%s\
+",names[i]);
+
+free(names); ]]></code>
+ <p><c><![CDATA[erl_global_names()]]></c> allocates and returns a buffer containing
+ all the names known to global. <c><![CDATA[count]]></c> will be initialized to
+ indicate how many names are in the array. The array of strings in
+ names is terminated by a NULL pointer, so it is not necessary to use
+ <c><![CDATA[count]]></c> to determine when the last name is reached.</p>
+ <p>It is the caller's responsibility to free the array.
+ <c><![CDATA[erl_global_names()]]></c> allocates the array and all of the strings
+ using a single call to <c><![CDATA[malloc()]]></c>, so <c><![CDATA[free(names)]]></c> is all
+ that is necessary.</p>
+ <p>To look up one of the names:</p>
+ <code type="none"><![CDATA[
+ETERM *pid;
+char node[256];
+
+pid = erl_global_whereis(fd,"schedule",node); ]]></code>
+ <p>If <c><![CDATA["schedule"]]></c> is known to global, an Erlang pid is returned
+ that can be used to send messages to the schedule service.
+ Additionally, <c><![CDATA[node]]></c> will be initialized to contain the name of
+ the node where the service is registered, so that you can make a
+ connection to it by simply passing the variable to <c><![CDATA[erl_connect()]]></c>.</p>
+ <p>Before registering a name, you should already have registered your
+ port number with <c><![CDATA[epmd]]></c>. This is not strictly necessary, but if you
+ neglect to do so, then other nodes wishing to communicate with your
+ service will be unable to find or connect to your process.</p>
+ <p>Create a pid that Erlang processes can use to communicate with your
+ service:</p>
+ <code type="none"><![CDATA[
+ETERM *pid;
+
+pid = erl_mk_pid(thisnode,14,0,0);
+erl_global_register(fd,servicename,pid); ]]></code>
+ <p>After registering the name, you should use <c><![CDATA[erl_accept()]]></c> to wait for
+ incoming connections.</p>
+ <p>Do not forget to free <c><![CDATA[pid]]></c> later with <c><![CDATA[erl_free_term()]]></c>!</p>
+ <p>To unregister a name:</p>
+ <code type="none"><![CDATA[
+erl_global_unregister(fd,servicename); ]]></code>
+ </section>
+
+ <section>
+ <title>The Registry</title>
+ <p>This section describes the use of the registry, a simple mechanism
+ for storing key-value pairs in a C-node, as well as backing them up or
+ restoring them from a Mnesia table on an Erlang node. More detailed
+ information about the individual API functions can be found in the
+ Reference Manual.</p>
+ <p>Keys are strings, i.e. 0-terminated arrays of characters, and values
+ are arbitrary objects. Although integers and floating point numbers
+ are treated specially by the registry, you can store strings or binary
+ objects of any type as pointers.</p>
+ <p>To start, you need to open a registry:</p>
+ <code type="none"><![CDATA[
+ei_reg *reg;
+
+reg = ei_reg_open(45); ]]></code>
+ <p>The number 45 in the example indicates the approximate number of
+ objects that you expect to store in the registry. Internally the
+ registry uses hash tables with collision chaining, so there is no
+ absolute upper limit on the number of objects that the registry can
+ contain, but if performance or memory usage are important, then you
+ should choose a number accordingly. The registry can be resized later.</p>
+ <p>You can open as many registries as you like (if memory permits).</p>
+ <p>Objects are stored and retrieved through set and get functions. In
+ the following examples you see how to store integers, floats, strings
+ and arbitrary binary objects:</p>
+ <code type="none"><![CDATA[
+struct bonk *b = malloc(sizeof(*b));
+char *name = malloc(7);
+
+ei_reg_setival(reg,"age",29);
+ei_reg_setfval(reg,"height",1.85);
+
+strcpy(name,"Martin");
+ei_reg_setsval(reg,"name",name);
+
+b->l = 42;
+b->m = 12;
+ei_reg_setpval(reg,"jox",b,sizeof(*b)); ]]></code>
+ <p>If you attempt to store an object in the registry and there is an
+ existing object with the same key, the new value will replace the old
+ one. This is done regardless of whether the new object and the old one
+ have the same type, so you can, for example, replace a string with an
+ integer. If the existing value is a string or binary, it will be freed
+ before the new value is assigned.</p>
+ <p>Stored values are retrieved from the registry as follows:</p>
+ <code type="none"><![CDATA[
+long i;
+double f;
+char *s;
+struct bonk *b;
+int size;
+
+i = ei_reg_getival(reg,"age");
+f = ei_reg_getfval(reg,"height");
+s = ei_reg_getsval(reg,"name");
+b = ei_reg_getpval(reg,"jox",&size); ]]></code>
+ <p>In all of the above examples, the object must exist and it must be of
+ the right type for the specified operation. If you do not know the
+ type of a given object, you can ask:</p>
+ <code type="none"><![CDATA[
+struct ei_reg_stat buf;
+
+ei_reg_stat(reg,"name",&buf); ]]></code>
+ <p>Buf will be initialized to contain object attributes.</p>
+ <p>Objects can be removed from the registry:</p>
+ <code type="none"><![CDATA[
+ei_reg_delete(reg,"name"); ]]></code>
+ <p>When you are finished with a registry, close it to remove all the
+ objects and free the memory back to the system:</p>
+ <code type="none"><![CDATA[
+ei_reg_close(reg); ]]></code>
+
+ <section>
+ <title>Backing Up the Registry to Mnesia</title>
+ <p>The contents of a registry can be backed up to Mnesia on a "nearby"
+ Erlang node. You need to provide an open connection to the Erlang node
+ (see <c><![CDATA[erl_connect()]]></c>). Also, Mnesia 3.0 or later must be running
+ on the Erlang node before the backup is initiated:</p>
+ <code type="none"><![CDATA[
+ei_reg_dump(fd, reg, "mtab", dumpflags); ]]></code>
+ <p>The example above will backup the contents of the registry to the
+ specified Mnesia table <c><![CDATA["mtab"]]></c>. Once a registry has been backed
+ up to Mnesia in this manner, additional backups will only affect
+ objects that have been modified since the most recent backup, i.e.
+ objects that have been created, changed or deleted. The backup
+ operation is done as a single atomic transaction, so that the entire
+ backup will be performed or none of it will.</p>
+ <p>In the same manner, a registry can be restored from a Mnesia table:</p>
+ <code type="none"><![CDATA[
+ei_reg_restore(fd, reg, "mtab"); ]]></code>
+ <p>This will read the entire contents of <c><![CDATA["mtab"]]></c> into the specified
+ registry. After the restore, all of the objects in the registry will
+ be marked as unmodified, so a subsequent backup will only affect
+ objects that you have modified since the restore.</p>
+ <p>Note that if you restore to a non-empty registry, objects in the
+ table will overwrite objects in the registry with the same keys. Also,
+ the <em>entire</em> contents of the registry is marked as unmodified
+ after the restore, including any modified objects that were not
+ overwritten by the restore operation. This may not be your intention.</p>
+ </section>
+
+ <section>
+ <title>Storing Strings and Binaries</title>
+ <p>When string or binary objects are stored in the registry it is
+ important that a number of simple guidelines are followed. </p>
+ <p>Most importantly, the object must have been created with a single call
+ to <c><![CDATA[malloc()]]></c> (or similar), so that it can later be removed by a
+ single call to <c><![CDATA[free()]]></c>. Objects will be freed by the registry
+ when it is closed, or when you assign a new value to an object that
+ previously contained a string or binary.</p>
+ <p>You should also be aware that if you store binary objects that are
+ context-dependent (e.g. containing pointers or open file descriptors),
+ they will lose their meaning if they are backed up to a Mnesia table
+ and subsequently restored in a different context.</p>
+ <p>When you retrieve a stored string or binary value from the registry,
+ the registry maintains a pointer to the object and you are passed a
+ copy of that pointer. You should never free an object retrieved in
+ this manner because when the registry later attempts to free it, a
+ runtime error will occur that will likely cause the C-node to crash.</p>
+ <p>You are free to modify the contents of an object retrieved this way.
+ However when you do so, the registry will not be aware of the changes
+ you make, possibly causing it to be missed the next time you make a
+ Mnesia backup of the registry contents. This can be avoided if you
+ mark the object as dirty after any such changes with
+ <c><![CDATA[ei_reg_markdirty()]]></c>, or pass appropriate flags to
+ <c><![CDATA[ei_reg_dump()]]></c>.</p>
+ </section>
+ </section>
+</chapter>
+
diff --git a/lib/erl_interface/doc/src/erl_malloc.xml b/lib/erl_interface/doc/src/erl_malloc.xml
new file mode 100644
index 0000000000..8c8750d62a
--- /dev/null
+++ b/lib/erl_interface/doc/src/erl_malloc.xml
@@ -0,0 +1,200 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE cref SYSTEM "cref.dtd">
+
+<cref>
+ <header>
+ <copyright>
+ <year>1996</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>erl_malloc</title>
+ <prepared>Torbj&ouml;rn T&ouml;rnkvist</prepared>
+ <responsible>Torbj&ouml;rn T&ouml;rnkvist</responsible>
+ <docno></docno>
+ <approved>Bjarne D&auml;cker</approved>
+ <checked>Torbj&ouml;rn T&ouml;rnkvist</checked>
+ <date>980703</date>
+ <rev>A</rev>
+ <file>erl_malloc.sgml</file>
+ </header>
+ <lib>erl_malloc</lib>
+ <libsummary>Memory Allocation Functions</libsummary>
+ <description>
+ <p>This module provides functions for allocating and deallocating
+ memory.</p>
+ </description>
+ <funcs>
+ <func>
+ <name><ret>ETERM *</ret><nametext>erl_alloc_eterm(etype)</nametext></name>
+ <fsummary>Allocates an ETERM structure</fsummary>
+ <type>
+ <v>unsigned char etype;</v>
+ </type>
+ <desc>
+ <p>This function allocates an <c><![CDATA[(ETERM)]]></c> structure.
+ Specify <c><![CDATA[etype]]></c> as one of the following constants:</p>
+ <list type="bulleted">
+ <item>
+ <p>ERL_INTEGER</p>
+ </item>
+ <item>
+ <p>ERL_U_INTEGER <c><![CDATA[/* unsigned integer */]]></c></p>
+ </item>
+ <item>
+ <p>ERL_ATOM</p>
+ </item>
+ <item>
+ <p>ERL_PID <c><![CDATA[/* Erlang process identifier */]]></c></p>
+ </item>
+ <item>
+ <p>ERL_PORT</p>
+ </item>
+ <item>
+ <p>ERL_REF <c><![CDATA[/* Erlang reference */]]></c></p>
+ </item>
+ <item>
+ <p>ERL_LIST</p>
+ </item>
+ <item>
+ <p>ERL_EMPTY_LIST</p>
+ </item>
+ <item>
+ <p>ERL_TUPLE</p>
+ </item>
+ <item>
+ <p>ERL_BINARY</p>
+ </item>
+ <item>
+ <p>ERL_FLOAT</p>
+ </item>
+ <item>
+ <p>ERL_VARIABLE</p>
+ </item>
+ <item>
+ <p>ERL_SMALL_BIG <c><![CDATA[/* bignum */]]></c></p>
+ </item>
+ <item>
+ <p>ERL_U_SMALL_BIG <c><![CDATA[/* bignum */]]></c></p>
+ </item>
+ </list>
+ <p><c><![CDATA[ERL_SMALL_BIG]]></c> and <c><![CDATA[ERL_U_SMALL_BIG]]></c> are for
+ creating Erlang <c><![CDATA[bignums]]></c>, which can contain integers of
+ arbitrary size. The size of an integer in Erlang is machine
+ dependent, but in general any integer larger than 2^28
+ requires a bignum.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>void</ret><nametext>erl_eterm_release(void)</nametext></name>
+ <fsummary>Clears the ETERM freelist</fsummary>
+ <desc>
+ <p>Clears the
+ freelist, where blocks are placed when they are
+ released by <c><![CDATA[erl_free_term()]]></c> and
+ <c><![CDATA[erl_free_compound()]]></c>. </p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>void</ret><nametext>erl_eterm_statistics(allocated, freed)</nametext></name>
+ <fsummary>Reports term allocation statistics</fsummary>
+ <type>
+ <v>long *allocated;</v>
+ <v>long *freed;</v>
+ </type>
+ <desc>
+ <p><c><![CDATA[allocated]]></c> and <c><![CDATA[freed]]></c> are initialized to
+ contain information about the fix-allocator used to allocate
+ ETERM components. <c><![CDATA[allocated]]></c> is the number of blocks
+ currently allocated to ETERM objects. <c><![CDATA[freed]]></c> is the
+ length of the freelist, where blocks are placed when they are
+ released by <c><![CDATA[erl_free_term()]]></c> and
+ <c><![CDATA[erl_free_compound()]]></c>. </p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>void</ret><nametext>erl_free_array(array, size)</nametext></name>
+ <fsummary>Frees an array of ETERM structures</fsummary>
+ <type>
+ <v>ETERM **array;</v>
+ <v>int size;</v>
+ </type>
+ <desc>
+ <p>This function frees an array of Erlang terms.</p>
+ <p><c><![CDATA[array]]></c> is an array of ETERM* objects.
+ </p>
+ <p><c><![CDATA[size]]></c> is the number of terms in the array.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>void</ret><nametext>erl_free_term(t)</nametext></name>
+ <fsummary>Frees an ETERM structure</fsummary>
+ <type>
+ <v>ETERM *t;</v>
+ </type>
+ <desc>
+ <p>Use this function to free an Erlang term.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>void</ret><nametext>erl_free_compound(t)</nametext></name>
+ <fsummary>Frees an array of ETERM structures</fsummary>
+ <type>
+ <v>ETERM *t;</v>
+ </type>
+ <desc>
+ <p>Normally it is the programmer's responsibility to free each
+ Erlang term that has been returned from any of the
+ <c><![CDATA[erl_interface]]></c> functions. However since many of the
+ functions that build new Erlang terms in fact share objects
+ with other existing terms, it may be difficult for the
+ programmer to maintain pointers to all such terms in order to
+ free them individually.
+ </p>
+ <p><c><![CDATA[erl_free_compound()]]></c> will recursively free all of the
+ sub-terms associated with a given Erlang term, regardless of
+ whether we are still holding pointers to the sub-terms.
+ </p>
+ <p>There is an example in the User Manual under "Building
+ Terms and Patterns"
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>void</ret><nametext>erl_malloc(size)</nametext></name>
+ <fsummary>Allocates some memory</fsummary>
+ <type>
+ <v>long size;</v>
+ </type>
+ <desc>
+ <p>This function calls the standard
+ <c><![CDATA[malloc()]]></c> function. </p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>void</ret><nametext>erl_free(ptr)</nametext></name>
+ <fsummary>Frees some memory</fsummary>
+ <type>
+ <v>void *ptr;</v>
+ </type>
+ <desc>
+ <p>This function calls the standard
+ <c><![CDATA[free()]]></c> function. </p>
+ </desc>
+ </func>
+ </funcs>
+</cref>
+
diff --git a/lib/erl_interface/doc/src/erl_marshal.xml b/lib/erl_interface/doc/src/erl_marshal.xml
new file mode 100644
index 0000000000..a7eaf78f35
--- /dev/null
+++ b/lib/erl_interface/doc/src/erl_marshal.xml
@@ -0,0 +1,272 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE cref SYSTEM "cref.dtd">
+
+<cref>
+ <header>
+ <copyright>
+ <year>1996</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>erl_marshal</title>
+ <prepared>Torbj&ouml;rn T&ouml;rnkvist</prepared>
+ <responsible>Torbj&ouml;rn T&ouml;rnkvist</responsible>
+ <docno></docno>
+ <approved>Bjarne D&auml;cker</approved>
+ <checked>Torbj&ouml;rn T&ouml;rnkvist</checked>
+ <date>980703</date>
+ <rev>A</rev>
+ <file>erl_marshal.sgml</file>
+ </header>
+ <lib>erl_marshal</lib>
+ <libsummary>Encoding and Decoding of Erlang terms</libsummary>
+ <description>
+ <p>This module contains functions for encoding Erlang terms into
+ a sequence of bytes, and for decoding Erlang terms from a
+ sequence of bytes.</p>
+ </description>
+ <funcs>
+ <func>
+ <name><ret>int</ret><nametext>erl_compare_ext(bufp1, bufp2)</nametext></name>
+ <fsummary>Compares encoded byte sequences</fsummary>
+ <type>
+ <v>unsigned char *bufp1,*bufp2;</v>
+ </type>
+ <desc>
+ <p>This function compares two encoded terms.
+ </p>
+ <p><c><![CDATA[bufp1]]></c> is a buffer containing an encoded Erlang
+ term term1.
+ </p>
+ <p><c><![CDATA[bufp2]]></c> is a buffer containing an encoded Erlang
+ term term2.
+ </p>
+ <p>The function returns 0 if the terms are equal, -1 if term1
+ is less than term2, or 1 if term2 is less than term1.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ETERM *</ret><nametext>erl_decode(bufp)</nametext></name>
+ <name><ret>ETERM *</ret><nametext>erl_decode_buf(bufpp)</nametext></name>
+ <fsummary>Converts a term from Erlang external format</fsummary>
+ <type>
+ <v>unsigned char *bufp;</v>
+ <v>unsigned char **bufpp;</v>
+ </type>
+ <desc>
+ <p><c><![CDATA[erl_decode()]]></c> and <c><![CDATA[erl_decode_buf()]]></c> decode
+ the contents of a buffer and return the corresponding
+ Erlang term. <c><![CDATA[erl_decode_buf()]]></c> provides a simple
+ mechanism for dealing with several encoded terms stored
+ consecutively in the buffer.</p>
+ <p><c><![CDATA[bufp]]></c> is a pointer to a buffer containing one or
+ more encoded Erlang terms.
+ </p>
+ <p><c><![CDATA[bufpp]]></c> is the address of a buffer pointer. The buffer
+ contains one or more consecutively encoded Erlang terms.
+ Following a successful call to <c><![CDATA[erl_decode_buf()]]></c>,
+ <c><![CDATA[bufpp]]></c> will be updated so that it points to the next
+ encoded term.
+ </p>
+ <p><c><![CDATA[erl_decode()]]></c> returns an Erlang term
+ corresponding to the contents of <c><![CDATA[bufp]]></c> on success, or
+ NULL on failure. <c><![CDATA[erl_decode_buf()]]></c> returns an Erlang
+ term corresponding to the first of the consecutive terms in
+ <c><![CDATA[bufpp]]></c> and moves <c><![CDATA[bufpp]]></c> forward to point to the
+ next term in the buffer. On failure, each of the functions
+ returns NULL.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>erl_encode(term, bufp)</nametext></name>
+ <name><ret>int</ret><nametext>erl_encode_buf(term, bufpp)</nametext></name>
+ <fsummary>Converts a term into Erlang external format</fsummary>
+ <type>
+ <v>ETERM *term;</v>
+ <v>unsigned char *bufp;</v>
+ <v>unsigned char **bufpp;</v>
+ </type>
+ <desc>
+ <p><c><![CDATA[erl_encode()]]></c> and <c><![CDATA[erl_encode_buf()]]></c> encode
+ Erlang terms into external format for storage or transmission.
+ <c><![CDATA[erl_encode_buf()]]></c> provides a simple mechanism for
+ encoding several terms consecutively in the same
+ buffer.
+ </p>
+ <p><c>term</c> is an Erlang term to be encoded.
+ </p>
+ <p><c>bufp</c> is a pointer to a buffer containing one or
+ more encoded Erlang terms.
+ </p>
+ <p><c>bufpp</c> is a pointer to a pointer to a buffer
+ containing one or more consecutively encoded Erlang terms.
+ Following a successful call to <c><![CDATA[erl_encode_buf()]]></c>,
+ <c>bufpp</c> will be updated so that it points to the
+ position for the next encoded term.
+ </p>
+ <p>
+ These functions returns the number of bytes written to buffer
+ if successful, otherwise returns 0.
+ </p>
+ <p>Note that no bounds checking is done on the buffer. It is
+ the caller's responsibility to make sure that the buffer is
+ large enough to hold the encoded terms. You can either use a
+ static buffer that is large enough to hold the terms you
+ expect to need in your program, or use <c><![CDATA[erl_term_len()]]></c>
+ to determine the exact requirements for a given term.
+ </p>
+ <p>The following can help you estimate the buffer
+ requirements for a term. Note that this information is
+ implementation specific, and may change in future versions.
+ If you are unsure, use <c><![CDATA[erl_term_len()]]></c>.
+ </p>
+ <p>Erlang terms are encoded with a 1 byte tag that
+ identifies the type of object, a 2- or 4-byte length field,
+ and then the data itself. Specifically:
+ </p>
+ <taglist>
+ <tag><c><![CDATA[Tuples]]></c></tag>
+ <item>need 5 bytes, plus the space for each element.</item>
+ <tag><c><![CDATA[Lists]]></c></tag>
+ <item>need 5 bytes, plus the space for each element, and 1
+ additional byte for the empty list at the end.</item>
+ <tag><c><![CDATA[Strings and atoms]]></c></tag>
+ <item>need 3 bytes, plus 1 byte for each character (the
+ terminating 0 is not encoded). Really long strings (more
+ than 64k characters) are encoded as lists. Atoms cannot
+ contain more than 256 characters.</item>
+ <tag><c><![CDATA[Integers]]></c></tag>
+ <item>need 5 bytes.</item>
+ <tag><c><![CDATA[Characters]]></c></tag>
+ <item>(integers &lt; 256) need 2 bytes.</item>
+ <tag><c><![CDATA[Floating point numbers]]></c></tag>
+ <item>need 32 bytes.</item>
+ <tag><c><![CDATA[Pids]]></c></tag>
+ <item>need 10 bytes, plus the space for the node name, which
+ is an atom.</item>
+ <tag><c><![CDATA[Ports and Refs]]></c></tag>
+ <item>need 6 bytes, plus the space for the node name, which
+ is an atom.</item>
+ </taglist>
+ <p>The total space required will be the result calculated
+ from the information above, plus 1 additional byte for a
+ version identifier.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>erl_ext_size(bufp)</nametext></name>
+ <fsummary>Counts elements in encoded term</fsummary>
+ <type>
+ <v>unsigned char *bufp;</v>
+ </type>
+ <desc>
+ <p>This function returns the number of elements in an
+ encoded term.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>unsigned char</ret><nametext>erl_ext_type(bufp)</nametext></name>
+ <fsummary>Determines type of an encoded byte sequence</fsummary>
+ <type>
+ <v>unsigned char *bufp;</v>
+ </type>
+ <desc>
+ <p>This function identifies and returns the type of Erlang term encoded
+ in a buffer. It will skip a trailing <em>magic</em> identifier.
+ Returns <c><![CDATA[0]]></c> if the type can't be determined or one of</p>
+ <list type="bulleted">
+ <item>
+ <p>ERL_INTEGER</p>
+ </item>
+ <item>
+ <p>ERL_ATOM</p>
+ </item>
+ <item>
+ <p>ERL_PID <c><![CDATA[/* Erlang process identifier */]]></c></p>
+ </item>
+ <item>
+ <p>ERL_PORT</p>
+ </item>
+ <item>
+ <p>ERL_REF <c><![CDATA[/* Erlang reference */]]></c></p>
+ </item>
+ <item>
+ <p>ERL_EMPTY_LIST</p>
+ </item>
+ <item>
+ <p>ERL_LIST</p>
+ </item>
+ <item>
+ <p>ERL_TUPLE</p>
+ </item>
+ <item>
+ <p>ERL_FLOAT</p>
+ </item>
+ <item>
+ <p>ERL_BINARY</p>
+ </item>
+ <item>
+ <p>ERL_FUNCTION</p>
+ </item>
+ </list>
+ </desc>
+ </func>
+ <func>
+ <name><ret>unsigned char *</ret><nametext>erl_peek_ext(bufp, pos)</nametext></name>
+ <fsummary>Steps over encoded term</fsummary>
+ <type>
+ <v>unsigned char *bufp;</v>
+ <v>int pos;</v>
+ </type>
+ <desc>
+ <p>This function is used for stepping over one or more
+ encoded terms in a buffer, in order to directly access a
+ later term.
+ </p>
+ <p><c><![CDATA[bufp]]></c> is a pointer to a buffer containing one or
+ more encoded Erlang terms.
+ </p>
+ <p><c><![CDATA[pos]]></c> indicates how many terms to step over in the
+ buffer.
+ </p>
+ <p>The function returns a pointer to a sub-term that can be
+ used in a subsequent call to <c><![CDATA[erl_decode()]]></c> in order to retrieve
+ the term at that position. If there is no term, or <c><![CDATA[pos]]></c>
+ would exceed the size of the terms in the buffer, NULL is returned.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>erl_term_len(t)</nametext></name>
+ <fsummary>Determines encoded size of term</fsummary>
+ <type>
+ <v>ETERM *t;</v>
+ </type>
+ <desc>
+ <p>This function determines the buffer space that would be
+ needed by <c><![CDATA[t]]></c> if it were encoded into Erlang external
+ format by <c><![CDATA[erl_encode()]]></c>.
+ </p>
+ <p>The size in bytes is returned.
+ </p>
+ </desc>
+ </func>
+ </funcs>
+</cref>
+
diff --git a/lib/erl_interface/doc/src/fascicules.xml b/lib/erl_interface/doc/src/fascicules.xml
new file mode 100644
index 0000000000..3d6219a2bd
--- /dev/null
+++ b/lib/erl_interface/doc/src/fascicules.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE fascicules SYSTEM "fascicules.dtd">
+
+<fascicules>
+ <fascicule file="part_ei" href="part_ei_frame.html" entry="no">
+ EI User's Guide
+ </fascicule>
+ <fascicule file="ref_man_ei" href="ref_man_ei_frame.html" entry="yes">
+ EI Library Reference
+ </fascicule>
+ <fascicule file="ref_man_erl_interface" href="ref_man_erl_interface_frame.html" entry="no">
+ Erl_interface Library Reference
+ </fascicule>
+ <fascicule file="ref_man" href="ref_man_frame.html" entry="no">
+ Command Reference
+ </fascicule>
+ <fascicule file="part_notes" href="part_notes_frame.html" entry="no">
+ Release Notes
+ </fascicule>
+ <fascicule file="" href="../../../../doc/print.html" entry="no">
+ Off-Print
+ </fascicule>
+</fascicules>
+
diff --git a/lib/erl_interface/doc/src/make.dep b/lib/erl_interface/doc/src/make.dep
new file mode 100644
index 0000000000..3f43cf64fe
--- /dev/null
+++ b/lib/erl_interface/doc/src/make.dep
@@ -0,0 +1,24 @@
+# ----------------------------------------------------
+# >>>> Do not edit this file <<<<
+# This file was automaticly generated by
+# /home/otp/bin//docdepend
+# ----------------------------------------------------
+
+
+# ----------------------------------------------------
+# TeX files that the DVI file depend on
+# ----------------------------------------------------
+
+book.dvi: book.tex ei.tex ei_connect.tex ei_users_guide.tex \
+ erl_call.tex erl_connect.tex erl_error.tex \
+ erl_eterm.tex erl_format.tex erl_global.tex \
+ erl_malloc.tex erl_marshal.tex part_ei.tex \
+ ref_man.tex ref_man_ei.tex ref_man_erl_interface.tex \
+ registry.tex
+
+# ----------------------------------------------------
+# Source inlined when transforming from source to LaTeX
+# ----------------------------------------------------
+
+book.tex: ref_man.xml ref_man_ei.xml ref_man_erl_interface.xml
+
diff --git a/lib/erl_interface/doc/src/note.gif b/lib/erl_interface/doc/src/note.gif
new file mode 100644
index 0000000000..6fffe30419
--- /dev/null
+++ b/lib/erl_interface/doc/src/note.gif
Binary files differ
diff --git a/lib/erl_interface/doc/src/notes.xml b/lib/erl_interface/doc/src/notes.xml
new file mode 100644
index 0000000000..f2519fda0b
--- /dev/null
+++ b/lib/erl_interface/doc/src/notes.xml
@@ -0,0 +1,535 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2004</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>Erl_interface Release Notes</title>
+ <prepared>otp_appnotes</prepared>
+ <docno>nil</docno>
+ <date>nil</date>
+ <rev>nil</rev>
+ <file>notes.xml</file>
+ </header>
+ <p>This document describes the changes made to the Erl_interface application.</p>
+
+<section><title>Erl_Interface 3.6.4</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The documentation is now built with open source tools
+ (xsltproc and fop) that exists on most platforms. One
+ visible change is that the frames are removed.</p>
+ <p>
+ Own Id: OTP-8201</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erl_Interface 3.6.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The manual states that erl_receive() return the reason in
+ the <c>ErlMessage</c> struct. This was not the case and
+ the function is now corrected.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-4969</p>
+ </item>
+ <item>
+ <p>
+ In <c>send_exit.c</c> an errorneous size of memory
+ allocation could occur when reallocating a buffer.</p>
+ <p>
+ In <c>ei_decode_trace.c</c> the index could be updated
+ when the decoding failed.</p>
+ <p>
+ In <c>ei_printterm.c</c> the index could be updated when
+ the decoding failed in lists and tuples.</p>
+ <p>
+ In <c>ei_decode_term.c</c> when decoding a double
+ (ERL_FLOAT_EXT) no check was done to ensure that the last
+ of the 31 bytes was null terminated.</p>
+ <p>
+ In <c>ei_decode_term.c</c> when decoding references, only
+ the first 3 bytes are read, but the index did not
+ increment by the total size.</p>
+ <p>
+ In <c>ei_decode_fun.c</c> no check of correct buffer
+ allocation or data length was done.</p>
+ <p>
+ In <c>ei_decode_string.c</c> the integer list string case
+ did not decode the NIL tail correctly.</p>
+ <p>
+ These errors has now been fixed. (Thanks to Romain
+ Lenglet, Paul Mineiro and Paul Guyot).</p>
+ <p>
+ Own Id: OTP-6117</p>
+ </item>
+ <item>
+ <p>
+ <c>ei_decode_big</c> could be decoded with a garbage
+ byte.</p>
+ <p>
+ <c>ei_encode_big</c> and <c>ei_x_encode_big</c> is now
+ available.</p>
+ <p>
+ Own Id: OTP-7554</p>
+ </item>
+ <item>
+ <p>
+ The function <c>erl_init_resolve()</c> did not conform to
+ C99 standard which caused a build error on some
+ platforms. This has now been fixed.</p>
+ <p>
+ Own Id: OTP-8093</p>
+ </item>
+ <item>
+ <p>
+ <c>Makefile.in</c> has been updated to use the LDFLAGS
+ environment variable (if set). (Thanks to Davide
+ Pesavento.)</p>
+ <p>
+ Own Id: OTP-8157</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Added support for 64-bit integers in encoding/decoding.</p>
+ <p>
+ Added support for better printouts of binaries.</p>
+ <p>
+ Own Id: OTP-6091</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erl_Interface 3.6.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ A problem with <c>gethostbyname</c> in <c>erl_start.c</c>
+ could cause a buffer overflow. This has now been fixed.</p>
+ <p>
+ Clean up of code and removed compiler warnings.</p>
+ <p>
+ Own Id: OTP-7978</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erl_Interface 3.6.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>A faulty validation in <c>ei_reg_getpval</c> caused it
+ to never return the key-value. This has now been fixed.
+ (Thanks to Matt Stancliff)</p>
+ <p>
+ Own Id: OTP-7960</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>Minor update to the <c>configure</c> script.</p>
+ <p>
+ Own Id: OTP-7959</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erl_Interface 3.6.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>Minor update to the <c>configure</c> script.</p>
+ <p>
+ Own Id: OTP-7959</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erl_Interface 3.6</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Nodes belonging to different independent clusters can now
+ co-exist on the same host with the help of a new
+ environment variable setting ERL_EPMD_PORT.</p>
+ <p>
+ Own Id: OTP-7826</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erl_Interface 3.5.9</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ A type-casting bug in ei_skip_term and ei_printterm on
+ 64bit platforms rendering undefined results is now
+ corrected.</p>
+ <p>
+ Own Id: OTP-7577</p>
+ </item>
+ <item>
+ <p>
+ A bug in the hostent copying code of erl_interface on
+ MacOS X/Darwin is now corrected.</p>
+ <p>
+ Own Id: OTP-7593</p>
+ </item>
+ <item>
+ <p>A problem with building <c>erl_interface</c> on
+ FreeBSD has been fixed (Thanks to Akira Kitada).</p>
+ <p>
+ Own Id: OTP-7611</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erl_Interface 3.5.8</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed bug in erl_interface when decoding broken data</p>
+ <p>
+ Own Id: OTP-7448</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+
+<section><title>Erl_Interface 3.5.7</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ An erroneous freeing of memory could occur when using
+ <c>ei_x_format_wo_ver</c> in erl_interface, resulting in
+ a segmentation fault.</p>
+ <p>
+ Own Id: OTP-6795</p>
+ </item>
+ <item>
+ <p>
+ A faulty compare in <c>erl_marshal</c> has now been
+ fixed. (Thanks to Simon Cornish and Paul Mineiro)</p>
+ <p>
+ Own Id: OTP-7368</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erl_Interface 3.5.6</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Minor documentation fixes.</p>
+ <p>
+ Own Id: OTP-7183 Aux Id: OTP-7118 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erl_Interface 3.5.5.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The symbol __erl_errno was undefined in the single thread
+ version of the ei library, but is now defined.</p>
+ <p>
+ Own Id: OTP-6887</p>
+ </item>
+ <item>
+ <p>
+ Corrected FreeBSD build error.</p>
+ <p>
+ Own Id: OTP-7093</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+ <section>
+ <title>Erl_Interface 3.5.5.3</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>Calls to alloca in erl_marshal.c have been removed. A
+ static buffer is now used instead to store node names
+ temporarily.</p>
+ <p>Own Id: OTP-6331 Aux Id: seq10468 </p>
+ </item>
+ <item>
+ <p>ei_print_term interprets a list of integers with values
+ from 0 to 255 as a string. If the original list contains
+ the integer 0, this is considered terminator of the
+ string. This is incorrect. The function has now been
+ modified to not look for '\\0' in a string, but always
+ print all characters.</p>
+ <p>Own Id: OTP-6339 Aux Id: seq10492 </p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Erl_Interface 3.5.5.2</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>The combination of xeon processors with 64bit x86
+ extensions and a 32bit linux could cause ei_decode_long
+ and ei_decode_longlong to fail for the value LONG_MIN and
+ LONGLONG_MIN. The conversion is now made more portable.</p>
+ <p>Own Id: OTP-6216</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Erl_Interface 3.5.5.1</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>Portability enhancements.</p>
+ <p>Own Id: OTP-6132</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Erl_Interface 3.5.5</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Different (and old) <c><![CDATA[config.guess]]></c> files in the
+ <c><![CDATA[erts]]></c> and <c><![CDATA[erl_interface]]></c> applications would
+ cause build problems on the new Intel-based iMacs.
+ (Thanks to Sebastion Strollo.)</p>
+ <p>Own Id: OTP-5967</p>
+ </item>
+ <item>
+ <p>pthread header and library mismatch on linux systems (at
+ least some SuSE and Debian) with both NPTL and
+ Linuxthreads libraries installed.</p>
+ <p>Own Id: OTP-5981</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>Support for a C node to connect to an Erlang node on a
+ standalone host has been added.</p>
+ <p>Own Id: OTP-5883 Aux Id: seq10170 </p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Erl_interface 3.5.2</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>A configuration test error caused erl_interface to be
+ built without support for threads. This has been
+ corrected.</p>
+ <p>Own Id: OTP-5456</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Erl_interface 3.5.1</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>Changes and improvements have been made to the build and
+ test environment to solve problems with failing
+ erl_interface test cases.</p>
+ <p>Own Id: OTP-5295 Aux Id: OTP-5387 </p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Erl_interface 3.5</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>Process identifiers and port identifiers have been
+ made more unique. Previously 18 bits were used as id in
+ the internal representation of process and port
+ identifiers. Now 28 bits are used. </p>
+ <p>The maximum
+ limit on the number of concurrently existing processes
+ due to the representation of pids has been increased to
+ 268435456 processes. The same is true for ports. This
+ limit will at least on a 32-bit architecture be
+ impossible to reach due to memory shortage. </p>
+ <p><em>NOTE:</em> By default, the <c><![CDATA[ERTS]]></c>, and the
+ <c><![CDATA[erl_interface]]></c>, <c><![CDATA[ei]]></c>, and <c><![CDATA[jinterface]]></c>
+ libraries are now only guaranteed to be compatible with
+ other Erlang/OTP components from the same release. It is
+ possible to set each component in compatibility mode of
+ an earlier release, though. See the documentation for
+ respective component on how to set it in compatibility
+ mode. </p>
+ <p>*** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>Own Id: OTP-4968 Aux Id: OTP-4196 </p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Erl_interface 3.4.5</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Corrections for mistakes done for patch erl_605/OTP-4874.</p>
+ <p>Own Id: OTP-4995 Aux Id: OTP-4874 </p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Erl_interface 3.4.4</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>A small optimization in ei_rpc*() was added and a bug in
+ ei_decode_longlong() was corrected.</p>
+ <p>Own Id: OTP-4784</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Erl_interface 3.4.2</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Strings longer than 65535 bytes were encoded wrong in
+ ei/erl_interface.</p>
+ <p>Own Id: OTP-4865 Aux Id: EABln07451 </p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Erl_interface 3.4.1</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>erl_call -a parsed erlang terms incorrectly due to a bug
+ in ei_format, which is now corrected.</p>
+ <p>Own Id: OTP-4777 Aux Id: seq8099 </p>
+ </item>
+ </list>
+ </section>
+ </section>
+</chapter>
+
diff --git a/lib/erl_interface/doc/src/notes_history.xml b/lib/erl_interface/doc/src/notes_history.xml
new file mode 100644
index 0000000000..f484f3c04e
--- /dev/null
+++ b/lib/erl_interface/doc/src/notes_history.xml
@@ -0,0 +1,367 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2006</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>Erl_Interface Release Notes History</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ </header>
+
+ <section>
+ <title>Erl_Interface 3.4</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p><c><![CDATA[erl_print_term()]]></c> and <c><![CDATA[erl_copy_term()]]></c> could not
+ previously handle uints. This bug has now been fixed.</p>
+ <p>Own Id: OTP-4061 Aux Id: seq7079</p>
+ </item>
+ <item>
+ <p><c><![CDATA[ei_x_format()]]></c> was not working correctly for floating
+ point arguments on some platforms. This is now corrected.</p>
+ <p>Own Id: OTP-4379</p>
+ </item>
+ <item>
+ <p><c><![CDATA[erl_compare_ext()]]></c> did not compare the node parts of
+ pids, ports, and references. This has now been fixed.
+ Comparison between two pids, ports, or references does now
+ conform to the Erlang specification.</p>
+ <p>Own Id: OTP-4512 Aux Id: OTP-4511</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>Erl_Interface and EI now supports 64 bit architectures.</p>
+ <p>Own Id: OTP-4772</p>
+ </item>
+ <item>
+ <p>There are new functions that support the GCC and Visual
+ C++ 64 bit extended integer types.</p>
+ <code type="none"><![CDATA[
+int ei_decode_longlong(const char *buf, int *index, EI_LONGLONG *p);
+int ei_decode_ulonglong(const char *buf, int *index, EI_ULONGLONG *p);
+int ei_encode_longlong(char *buf, int *index, EI_LONGLONG p);
+int ei_encode_ulonglong(char *buf, int *index, EI_ULONGLONG p);
+int ei_x_encode_longlong(ei_x_buff* x, EI_LONGLONG n);
+int ei_x_encode_ulonglong(ei_x_buff* x, EI_ULONGLONG n);
+ ]]></code>
+ <p>Own Id: OTP-4772</p>
+ </item>
+ <item>
+ <p>If you compile the library from source you can use the ei
+ library together with GMP, the GNU multi precision
+ library, to convert integers larger than 64 bits from and
+ to the external format.</p>
+ <code type="none"><![CDATA[
+int ei_decode_bignum(const char *buf, int *index, mpz_t obj);
+int ei_encode_bignum(char *buf, int *index, mpz_t obj);
+int ei_x_encode_bignum(ei_x_buff *x, mpz_t obj);
+ ]]></code>
+ <p>Own Id: OTP-4772</p>
+ </item>
+ <item>
+ <p>Some general code improvements where done like correcting
+ buffer sizes, added more error checking etc.</p>
+ <p>Own Id: OTP-4772</p>
+ </item>
+ <item>
+ <p>In order to conform to the Erlang specification,
+ comparison between two pids was changed in the R9B
+ release. This change did however break a deadlock
+ prevention algorithm used by Mnesia during release
+ upgrade. Therefore, comparison between two pids has been
+ changed back so that R9B nodes are compatible with Erlang
+ nodes running pre-R9 releases.</p>
+ <p>Pre-R9 comparison between two pids which now is used
+ again: If t1 and t2 are both pids, t1 will precede t2 if
+ and only if either</p>
+ <list type="bulleted">
+ <item>the node local id of t1 precedes the node local id
+ of t2, or</item>
+ <item>the node local ids of t1 and t2 are equal, and
+ node(t1) precedes node(t2), or</item>
+ <item>the node local ids of t1 and t2 are equal, and also
+ node(t1) and node(t2) are equal, and node(t1) was
+ created before node(t2).</item>
+ </list>
+ <p>The node local id consist of two integers; serial which
+ is most significant, and number.</p>
+ <p>The Erlang specification states: If t1 and t2 are both
+ refs, both PIDs, or both ports, then t1 precedes t2 if
+ and only if either</p>
+ <list type="bulleted">
+ <item>node(t1) precedes node(t2), or</item>
+ <item>node(t1) equals node(t2) and t1 was created before
+ t2.</item>
+ </list>
+ <p>Note that comparisons between two refs, or two ports will
+ still conform to the Erlang specification.</p>
+ <p>*** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>Own Id: OTP-4715 Aux Id: OTP-4511, OTP-4512</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>ErlInterface 3.3</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>Erl_Interface has been rewritten extensively. The library
+ <c><![CDATA[ei]]></c> is now documented and supported. The old
+ <c><![CDATA[erl_interface]]></c> is considered obsolete, and provided
+ only for backward compatibility.</p>
+ </item>
+ <item>
+ <p>Erl_Interface is now thread-safe, and multiple C-nodes may
+ run from the same process.</p>
+ </item>
+ <item>
+ <p>New functions are added for connecting and accepting
+ connections from <c><![CDATA[ei]]></c>; these are documented in
+ <c><![CDATA[ei_connect]]></c>.</p>
+ </item>
+ <item>
+ <p>New functions are added for converting to and from Erlang
+ binary format; these are documented in <c><![CDATA[ei]]></c>.</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Erl_Interface 3.2.9</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Changed back the return values from <c><![CDATA[erl_send()]]></c> and
+ <c><![CDATA[erl_reg_send()]]></c> to 1 (as they used to be).
+ Incompatible with plain R7, compatible with previous
+ versions.</p>
+ <p>*** INCOMPATIBILITY with R7B ***</p>
+ <p>Own Id: OTP-3772</p>
+ </item>
+ <item>
+ <p>A race-condition bug in the term allocation routines was
+ corrected.</p>
+ <p>Own Id: OTP-3809</p>
+ </item>
+ <item>
+ <p>Erl_Interface could not be linked with pthreads.</p>
+ <p>Own Id: OTP-3810 Aux Id: Seq 5032</p>
+ </item>
+ <item>
+ <p>The TCB of VxWorks processes no longer grows when
+ <c><![CDATA[erl_errno]]></c> is accessed. On Pthreads platforms
+ the use of <c><![CDATA[erl_errno]]></c> no longer crashes programs
+ using multithreading.</p>
+ <p>Own Id: OTP-3820</p>
+ </item>
+ <item>
+ <p>Name clashes between Erlang emulator and Erl_Interface
+ on VxWorks removed.</p>
+ <p>Own Id: OTP-3824</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Erl_Interface 3.2.3</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Memory lossage affecting pids, ports and refs fixed.</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Erl_Interface 3.2.2</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>An error reporting facility <c><![CDATA[erl_errno]]></c> has been
+ introduced.</p>
+ <p>Own Id: OTP-3641</p>
+ </item>
+ <item>
+ <p>ETERMs are now shrunk to a more reasonable size.</p>
+ <p>Own Id: OTP-3648</p>
+ <p></p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Erl_Interface 3.2.1</title>
+
+ <section>
+ <title>Fixed Errors and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Lists containing negative numbers were incorrectly
+ encoded by <c><![CDATA[erl_encode()]]></c>. This has been corrected.</p>
+ <p>Own Id: OTP-3535</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Erl_Interface 3.2</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>The reference type has been extended from 18 bits to
+ 82 bits. For compatibility with older nodes, an R6 node
+ can send a ref to an older node; if the older node sends
+ it back, it has lost all but its 18 least significant
+ bits, but still compares equal to the original ref.
+ The external format has been extended to represent the new
+ longer refs; that means for example that binaries with
+ refs, produced on an R6 node, cannot be converted to a
+ term on an older node.
+ In <c><![CDATA[erl_interface]]></c>, a function <c><![CDATA[erl_mk_long_ref]]></c>
+ has been added, and macros <c><![CDATA[ERL_REF_NUMBERS]]></c> and
+ <c><![CDATA[ERL_REF_LEN]]></c>.</p>
+ <p>*** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>Own Id: OTP-3140 Aux Id: OTP-3139</p>
+ </item>
+ <item>
+ <p>The function <c><![CDATA[erl_receive_msg]]></c> has the problem that
+ a fixed buffer must be given - a larger message than
+ expected is simply discarded. A function
+ <c><![CDATA[erl_xreceive_msg]]></c> has been introduced, which
+ dynamically resizes the buffer given to it, if needed.</p>
+ <p>Own Id: OTP-3313 Aux Id: OTP-2927</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Erl_Interface 3.1.1</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p><c><![CDATA[#ifdef __cplusplus extern C {]]></c> is added to all the
+ <c><![CDATA[erl*.h]]></c> and <c><![CDATA[ei*.h]]></c> files in order to support
+ use from C++.</p>
+ <p>On Unix the object files are now produced with
+ the <c><![CDATA[-fPIC]]></c> option to make it possible to include
+ them in a shared library.</p>
+ <p>Own Id: OTP-3138 Aux Id: Seq 1722</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Erl_Interface 3.1</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>A buffer overflow in <c><![CDATA[erl_connect()]]></c> was causing
+ C-node crashes on Linux.</p>
+ <p>Own Id: OTP-2743</p>
+ </item>
+ <item>
+ <p>When decoding very long strings (more than 65535
+ characters) the terminating 0 was left out.</p>
+ <p>Own Id: OTP-2744</p>
+ </item>
+ <item>
+ <p><c><![CDATA[erl_accept()]]></c> was not handshaking properly with
+ Erlang, causing incoming connection attempts to fail.</p>
+ <p>Own Id: OTP-2862</p>
+ </item>
+ <item>
+ <p>Very large negative numbers are no longer encoded
+ incorrectly.</p>
+ <p>Own Id: OTP-2897</p>
+ </item>
+ <item>
+ <p>Atoms could sometimes contain an unterminated string.
+ This is fixed.</p>
+ <p>Own Id: OTP-2956</p>
+ </item>
+ <item>
+ <p>Erl_Interface now uses the SENS resolver functions if
+ they are available at runtime. This primarily concerns
+ use on the VxWorks platform.</p>
+ <p>Own Id: OTP-3034 Aux Id: Seq 1559</p>
+ </item>
+ <item>
+ <p>The documentation for <c><![CDATA[erl_connect_init()]]></c> no longer
+ makes erroneous reference to the remote node.</p>
+ <p>Own Id: OTP-3102 Aux Id: Seq 1671</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>Erl_Interface has been moved out of the Erlang runtime
+ system (ERTS) and is now a separate application. This has
+ implications for all users of Erl_Interface, who will
+ need to make changes to the Makefiles used to build
+ applications based on Erl_Interface. In particular,
+ header and library files are no longer in
+ <c><![CDATA[$(OTPROOT)/usr/]]></c>. The <c><![CDATA[include]]></c> and <c><![CDATA[lib]]></c>
+ directories are now located in the directory
+ <c><![CDATA[$(OTPROOT)/lib/erl_interface-3.1]]></c> (i.e.
+ the directory name is now version specific).</p>
+ <p>Own Id: OTP-3082</p>
+ </item>
+ </list>
+ </section>
+ </section>
+</chapter>
+
diff --git a/lib/erl_interface/doc/src/part.xml b/lib/erl_interface/doc/src/part.xml
new file mode 100644
index 0000000000..e38b9164b8
--- /dev/null
+++ b/lib/erl_interface/doc/src/part.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE part SYSTEM "part.dtd">
+
+<part xmlns:xi="http://www.w3.org/2001/XInclude">
+ <header>
+ <copyright>
+ <year>2002</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 User's Guide</title>
+ <prepared>Gordon Beaton</prepared>
+ <docno></docno>
+ <date>1998-11-30</date>
+ <rev>1.2</rev>
+ <file>part.xml</file>
+ </header>
+ <xi:include href="ei_users_guide.xml"/>
+</part>
+
diff --git a/lib/erl_interface/doc/src/part_erl_interface.xml b/lib/erl_interface/doc/src/part_erl_interface.xml
new file mode 100644
index 0000000000..c69cc85c63
--- /dev/null
+++ b/lib/erl_interface/doc/src/part_erl_interface.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE part SYSTEM "part.dtd">
+
+<part xmlns:xi="http://www.w3.org/2001/XInclude">
+ <header>
+ <copyright>
+ <year>1996</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>Erl_Interface User's Guide</title>
+ <prepared>Gordon Beaton</prepared>
+ <docno></docno>
+ <date>1998-11-30</date>
+ <rev>1.2</rev>
+ <file>part_erl_interface.sgml</file>
+ </header>
+ <xi:include href="erl_interface.xml"/>
+</part>
+
diff --git a/lib/erl_interface/doc/src/part_notes.xml b/lib/erl_interface/doc/src/part_notes.xml
new file mode 100644
index 0000000000..14c1de1d6e
--- /dev/null
+++ b/lib/erl_interface/doc/src/part_notes.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE part SYSTEM "part.dtd">
+
+<part xmlns:xi="http://www.w3.org/2001/XInclude">
+ <header>
+ <copyright>
+ <year>2004</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>Erl_Interface Release Notes</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ </header>
+ <description>
+ <p><em>Erl_Interface</em> is a C interface library for communication
+ with Erlang.</p>
+ <p>For information about older versions, see
+ <url href="part_notes_history_frame.html">Release Notes History</url>.</p>
+ </description>
+ <xi:include href="notes.xml"/>
+</part>
+
diff --git a/lib/erl_interface/doc/src/part_notes_history.xml b/lib/erl_interface/doc/src/part_notes_history.xml
new file mode 100644
index 0000000000..612b4a9e1e
--- /dev/null
+++ b/lib/erl_interface/doc/src/part_notes_history.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE part SYSTEM "part.dtd">
+
+<part xmlns:xi="http://www.w3.org/2001/XInclude">
+ <header>
+ <copyright>
+ <year>2006</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>Erl_Interface Release Notes History</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ </header>
+ <description>
+ <p><em>Erl_Interface</em> is a C interface library for communication
+ with Erlang.</p>
+ </description>
+ <xi:include href="notes_history.xml"/>
+</part>
+
diff --git a/lib/erl_interface/doc/src/ref_man.xml b/lib/erl_interface/doc/src/ref_man.xml
new file mode 100644
index 0000000000..9ae4cf27f5
--- /dev/null
+++ b/lib/erl_interface/doc/src/ref_man.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE application SYSTEM "application.dtd">
+
+<application xmlns:xi="http://www.w3.org/2001/XInclude">
+ <header>
+ <copyright>
+ <year>1998</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>Erl_Interface Command Reference</title>
+ <prepared>Gordon Beaton</prepared>
+ <docno></docno>
+ <date>1998-11.30</date>
+ <rev>1.2</rev>
+ <file>ref_man.xml</file>
+ </header>
+ <description>
+ <p>The <c>ei</c> and <c>erl_interface</c> are <c>C</c> interface libraries for
+ communication with <c>Erlang</c>.</p>
+ <note>
+ <p>By default, the <c>ei</c> and <c>erl_interface</c> libraries are only guaranteed
+ to be compatible with other Erlang/OTP components from the same
+ release as the libraries themself. See the documentation of the
+ <seealso marker="ei#ei_set_compat_rel">ei_set_compat_rel()</seealso> and
+ <seealso marker="erl_eterm#erl_set_compat_rel">erl_set_compat_rel()</seealso>
+ functions on how to communicate with Erlang/OTP components from earlier
+ releases.</p>
+ </note>
+ </description>
+ <xi:include href="ei.xml"/>
+ <xi:include href="ei_connect.xml"/>
+ <xi:include href="registry.xml"/>
+ <xi:include href="erl_connect.xml"/>
+ <xi:include href="erl_error.xml"/>
+ <xi:include href="erl_eterm.xml"/>
+ <xi:include href="erl_format.xml"/>
+ <xi:include href="erl_global.xml"/>
+ <xi:include href="erl_malloc.xml"/>
+ <xi:include href="erl_marshal.xml"/>
+ <xi:include href="erl_call.xml"/>
+</application>
+
diff --git a/lib/erl_interface/doc/src/ref_man_ei.xml b/lib/erl_interface/doc/src/ref_man_ei.xml
new file mode 100644
index 0000000000..ff161f9e7f
--- /dev/null
+++ b/lib/erl_interface/doc/src/ref_man_ei.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE application SYSTEM "application.dtd">
+
+<application xmlns:xi="http://www.w3.org/2001/XInclude">
+ <header>
+ <copyright>
+ <year>2002</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 Library Reference</title>
+ <prepared>Gordon Beaton</prepared>
+ <docno></docno>
+ <date>1998-11-30</date>
+ <rev>1.2</rev>
+ <file>ref_man_ei.xml</file>
+ </header>
+ <description>
+ <p>The <c><![CDATA[ei]]></c> library is a <c><![CDATA[C]]></c> interface library for
+ communication with <c><![CDATA[Erlang]]></c>.</p>
+ <note>
+ <p>By default, the <c><![CDATA[ei]]></c> library is only guaranteed
+ to be compatible with other Erlang/OTP components from the same
+ release as the <c><![CDATA[ei]]></c> library itself. See the documentation of the
+ <seealso marker="ei#ei_set_compat_rel">ei_set_compat_rel()</seealso>
+ function on how to communicate with Erlang/OTP components from earlier
+ releases.</p>
+ </note>
+ </description>
+ <xi:include href="ei.xml"/>
+ <xi:include href="ei_connect.xml"/>
+ <xi:include href="registry.xml"/>
+</application>
+
diff --git a/lib/erl_interface/doc/src/ref_man_erl_interface.xml b/lib/erl_interface/doc/src/ref_man_erl_interface.xml
new file mode 100644
index 0000000000..7ffa0cfb23
--- /dev/null
+++ b/lib/erl_interface/doc/src/ref_man_erl_interface.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE application SYSTEM "application.dtd">
+
+<application xmlns:xi="http://www.w3.org/2001/XInclude">
+ <header>
+ <copyright>
+ <year>1996</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>Erl_Interface Library Reference</title>
+ <prepared>Gordon Beaton</prepared>
+ <docno></docno>
+ <date>1998-11-30</date>
+ <rev>1.2</rev>
+ <file>ref_man_erl_interface.xml</file>
+ </header>
+ <description>
+ <p>The <c>erl_interface</c> library is a <c>C</c> interface library
+ for communication with <c>Erlang</c>.</p>
+ <note>
+ <p>By default, the <c>erl_interface</c> library is only guaranteed
+ to be compatible with other Erlang/OTP components from the same
+ release as the <c>erl_interface</c> library. See the documentation
+ of the
+ <seealso marker="erl_eterm#erl_set_compat_rel">erl_set_compat_rel()</seealso>
+ function on how to communicate with Erlang/OTP components from earlier
+ releases.</p>
+ </note>
+ </description>
+ <xi:include href="erl_connect.xml"/>
+ <xi:include href="erl_error.xml"/>
+ <xi:include href="erl_eterm.xml"/>
+ <xi:include href="erl_format.xml"/>
+ <xi:include href="erl_global.xml"/>
+ <xi:include href="erl_malloc.xml"/>
+ <xi:include href="erl_marshal.xml"/>
+</application>
+
diff --git a/lib/erl_interface/doc/src/registry.xml b/lib/erl_interface/doc/src/registry.xml
new file mode 100644
index 0000000000..8aeb378d95
--- /dev/null
+++ b/lib/erl_interface/doc/src/registry.xml
@@ -0,0 +1,611 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE cref SYSTEM "cref.dtd">
+
+<cref>
+ <header>
+ <copyright>
+ <year>1998</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>registry</title>
+ <prepared>Gordon Beaton</prepared>
+ <responsible>Gordon Beaton</responsible>
+ <docno></docno>
+ <approved>Gordon Beaton</approved>
+ <checked>Gordon Beaton</checked>
+ <date>980707</date>
+ <rev>A</rev>
+ <file>registry.sgml</file>
+ </header>
+ <lib>registry</lib>
+ <libsummary>Store and backup key-value pairs</libsummary>
+ <description>
+ <p>This module provides support for storing key-value
+ pairs in a table known as a registry, backing up registries to
+ Mnesia in an atomic manner, and later restoring the contents of a
+ registry from Mnesia.</p>
+ </description>
+ <funcs>
+ <func>
+ <name><ret>ei_reg *</ret><nametext>ei_reg_open(size)</nametext></name>
+ <fsummary>Create and open a registry</fsummary>
+ <type>
+ <v>int size;</v>
+ </type>
+ <desc>
+ <p>Open (create) a registry. The registry will be
+ initially empty. Use <c><![CDATA[ei_reg_close()]]></c> to close the registry
+ later.
+ </p>
+ <p><c><![CDATA[size]]></c> is the approximate number of objects you intend
+ to store in the registry. Since the registry uses a hash table
+ with collision chaining, there is no absolute upper limit on the
+ number of objects that can be stored in it. However for reasons
+ of efficiency, it is a good idea to choose a number that is
+ appropriate for your needs. It is possible to use
+ <c><![CDATA[ei_reg_resize()]]></c> to change the size later. Note that the
+ number you provide will be increased to the nearest larger prime
+ number.
+ </p>
+ <p>On success, an empty registry will be returned. On failure, NULL
+ will be returned.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_reg_resize(reg,newsize)</nametext></name>
+ <fsummary>Resize a registry</fsummary>
+ <type>
+ <v>ei_reg *reg;</v>
+ <v>int newsize;</v>
+ </type>
+ <desc>
+ <p>Change the size of a registry.
+ </p>
+ <p><c><![CDATA[newsize]]></c> is the new size to make the registry. The
+ number will be increased to the nearest larger prime number.
+ </p>
+ <p>On success, the registry will be resized, all contents
+ rehashed, and the function will return 0. On failure, the
+ registry will be left unchanged and the function will return -1.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_reg_close(reg)</nametext></name>
+ <fsummary>Close a registry </fsummary>
+ <type>
+ <v>ei_reg *reg;</v>
+ </type>
+ <desc>
+ <p>A registry that has previously been created with
+ <c><![CDATA[ei_reg_open()]]></c> is closed, and all the objects it contains
+ are freed.
+ </p>
+ <p><c><![CDATA[reg]]></c> is the registry to close.
+ </p>
+ <p>The function returns 0.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_reg_setival(reg,key,i)</nametext></name>
+ <fsummary>Assign an integer object</fsummary>
+ <type>
+ <v>ei_reg *reg;</v>
+ <v>const char *key;</v>
+ <v>int i;</v>
+ </type>
+ <desc>
+ <p>Create a key-value pair with the specified <c><![CDATA[key]]></c> and integer
+ value <c><![CDATA[i]]></c>. If an object already existed with the same
+ <c><![CDATA[key]]></c>, the new value replaces the old one. If the previous
+ value was a binary or string, it is freed with <c><![CDATA[free()]]></c>.
+ </p>
+ <p><c><![CDATA[reg]]></c> is the registry where the object should be placed.
+ </p>
+ <p><c><![CDATA[key]]></c> is the name of the object.
+ </p>
+ <p><c><![CDATA[i]]></c> is the integer value to assign.
+ </p>
+ <p>The function returns 0 on success, or -1 on failure.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_reg_setfval(reg,key,f)</nametext></name>
+ <fsummary>Assign a floating point object</fsummary>
+ <type>
+ <v>ei_reg *reg;</v>
+ <v>const char *key;</v>
+ <v>double f;</v>
+ </type>
+ <desc>
+ <p>Create a key-value pair with the specified <c><![CDATA[key]]></c> and
+ floating point value <c><![CDATA[f]]></c>. If an object already existed with
+ the same <c><![CDATA[key]]></c>, the new value replaces the old one. If the
+ previous value was a binary or string, it is freed with <c><![CDATA[free()]]></c>.
+ </p>
+ <p><c><![CDATA[reg]]></c> is the registry where the object should be placed.
+ </p>
+ <p><c><![CDATA[key]]></c> is the name of the object.
+ </p>
+ <p><c><![CDATA[f]]></c> is the floating point value to assign.
+ </p>
+ <p>The function returns 0 on success, or -1 on failure.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_reg_setsval(reg,key,s)</nametext></name>
+ <fsummary>Assign a string object</fsummary>
+ <type>
+ <v>ei_reg *reg;</v>
+ <v>const char *key;</v>
+ <v>const char *s;</v>
+ </type>
+ <desc>
+ <p>Create a key-value pair with the specified <c><![CDATA[key]]></c> whose
+ "value" is the specified string <c><![CDATA[s]]></c>. If an object already
+ existed with the same <c><![CDATA[key]]></c>, the new value replaces the old
+ one. If the previous value was a binary or string, it is freed
+ with <c><![CDATA[free()]]></c>.
+ </p>
+ <p><c><![CDATA[reg]]></c> is the registry where the object should be placed.
+ </p>
+ <p><c><![CDATA[key]]></c> is the name of the object.
+ </p>
+ <p><c><![CDATA[s]]></c> is the string to assign. The string itself
+ must have been created through a single call to <c><![CDATA[malloc()]]></c> or
+ similar function, so that the registry can later delete it if
+ necessary by calling <c><![CDATA[free()]]></c>.
+ </p>
+ <p>The function returns 0 on success, or -1 on failure.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_reg_setpval(reg,key,p,size)</nametext></name>
+ <fsummary>Assign a binary object</fsummary>
+ <type>
+ <v>ei_reg *reg;</v>
+ <v>const char *key;</v>
+ <v>const void *p;</v>
+ <v>int size;</v>
+ </type>
+ <desc>
+ <p>Create a key-value pair with the specified <c><![CDATA[key]]></c> whose
+ "value" is the binary object pointed to by <c><![CDATA[p]]></c>. If an
+ object already existed with the same <c><![CDATA[key]]></c>, the new value
+ replaces the old one. If the previous value was a binary or
+ string, it is freed with <c><![CDATA[free()]]></c>.
+ </p>
+ <p><c><![CDATA[reg]]></c> is the registry where the object should be placed.
+ </p>
+ <p><c><![CDATA[key]]></c> is the name of the object.
+ </p>
+ <p><c><![CDATA[p]]></c> is a pointer to the binary object. The object itself
+ must have been created through a single call to <c><![CDATA[malloc()]]></c> or
+ similar function, so that the registry can later delete it if
+ necessary by calling <c><![CDATA[free()]]></c>.
+ </p>
+ <p><c><![CDATA[size]]></c> is the length in bytes of the binary object.
+ </p>
+ <p>The function returns 0 on success, or -1 on failure.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_reg_setval(reg,key,flags,v,...)</nametext></name>
+ <fsummary>Assign a value to any object type</fsummary>
+ <type>
+ <v>ei_reg *reg;</v>
+ <v>const char *key;</v>
+ <v>int flags;</v>
+ <v>v (see below)</v>
+ </type>
+ <desc>
+ <p>Create a key-value pair with the specified <c><![CDATA[key]]></c> whose
+ value is specified by <c><![CDATA[v]]></c>. If an object already
+ existed with the same <c><![CDATA[key]]></c>, the new value replaces the old
+ one. If the previous value was a binary or string, it is freed
+ with <c><![CDATA[free()]]></c>.
+ </p>
+ <p><c><![CDATA[reg]]></c> is the registry where the object should be placed.
+ </p>
+ <p><c><![CDATA[key]]></c> is the name of the object.
+ </p>
+ <p><c><![CDATA[flags]]></c> indicates the type of the object specified by
+ <c><![CDATA[v]]></c>. Flags must be one of EI_INT, EI_FLT, EI_STR and
+ EI_BIN, indicating whether <c><![CDATA[v]]></c> is <c><![CDATA[int]]></c>, <c><![CDATA[double]]></c>,
+ <c><![CDATA[char*]]></c> or <c><![CDATA[void*]]></c>. If <c><![CDATA[flags]]></c> is EI_BIN, then a
+ fifth argument <c><![CDATA[size]]></c> is required, indicating the size
+ in bytes of the object pointed to by <c><![CDATA[v]]></c>.
+ </p>
+ <p>If you wish to store an arbitrary pointer in the registry,
+ specify a <c><![CDATA[size]]></c> of 0. In this case, the object itself will
+ not be transferred by an <c><![CDATA[ei_reg_dump()]]></c> operation, just
+ the pointer value.
+ </p>
+ <p>The function returns 0 on success, or -1 on failure.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_reg_getival(reg,key)</nametext></name>
+ <fsummary>Get an integer object</fsummary>
+ <type>
+ <v>ei_reg *reg;</v>
+ <v>const char *key;</v>
+ </type>
+ <desc>
+ <p>Get the value associated with <c><![CDATA[key]]></c> in the
+ registry. The value must be an integer.
+ </p>
+ <p><c><![CDATA[reg]]></c> is the registry where the object will be looked
+ up.
+ </p>
+ <p><c><![CDATA[key]]></c> is the name of the object to look up.
+ </p>
+ <p>On success, the function returns the value associated with <c><![CDATA[key]]></c>.
+ If the object was not found or it was not an integer
+ object, -1 is returned. To avoid problems with in-band error
+ reporting (i.e. if you cannot distinguish between -1 and a
+ valid result) use the more general function <c><![CDATA[ei_reg_getval()]]></c>
+ instead.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>double</ret><nametext>ei_reg_getfval(reg,key)</nametext></name>
+ <fsummary>Get a floating point object</fsummary>
+ <type>
+ <v>ei_reg *reg;</v>
+ <v>const char *key;</v>
+ </type>
+ <desc>
+ <p>Get the value associated with <c><![CDATA[key]]></c> in the
+ registry. The value must be a floating point type.
+ </p>
+ <p><c><![CDATA[reg]]></c> is the registry where the object will be looked
+ up.
+ </p>
+ <p><c><![CDATA[key]]></c> is the name of the object to look up.
+ </p>
+ <p>On success, the function returns the value associated with <c><![CDATA[key]]></c>.
+ If the object was not found or it was not a floating point
+ object, -1.0 is returned. To avoid problems with in-band error
+ reporting (i.e. if you cannot distinguish between -1.0 and a
+ valid result) use the more general function <c><![CDATA[ei_reg_getval()]]></c>
+ instead.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>const char *</ret><nametext>ei_reg_getsval(reg,key)</nametext></name>
+ <fsummary>Get a string object</fsummary>
+ <type>
+ <v>ei_reg *reg;</v>
+ <v>const char *key;</v>
+ </type>
+ <desc>
+ <p>Get the value associated with <c><![CDATA[key]]></c> in the
+ registry. The value must be a string.
+ </p>
+ <p><c><![CDATA[reg]]></c> is the registry where the object will be looked
+ up.
+ </p>
+ <p><c><![CDATA[key]]></c> is the name of the object to look up.
+ </p>
+ <p>On success, the function returns the value associated with
+ <c><![CDATA[key]]></c>. If the object was not found or it was not a string,
+ NULL is returned. To avoid problems with in-band error
+ reporting (i.e. if you cannot distinguish between NULL and a
+ valid result) use the more general function <c><![CDATA[ei_reg_getval()]]></c>
+ instead.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>const void *</ret><nametext>ei_reg_getpval(reg,key,size)</nametext></name>
+ <fsummary>Get a binary object</fsummary>
+ <type>
+ <v>ei_reg *reg;</v>
+ <v>const char *key;</v>
+ <v>int size;</v>
+ </type>
+ <desc>
+ <p>Get the value associated with <c><![CDATA[key]]></c> in the
+ registry. The value must be a binary (pointer) type.
+ </p>
+ <p><c><![CDATA[reg]]></c> is the registry where the object will be looked
+ up.
+ </p>
+ <p><c><![CDATA[key]]></c> is the name of the object to look up.
+ </p>
+ <p><c><![CDATA[size]]></c> will be initialized to contain the length in
+ bytes of the object, if it is found.
+ </p>
+ <p>On success, the function returns the value associated with
+ <c><![CDATA[key]]></c> and indicates its length in <c><![CDATA[size]]></c>.
+ If the object was not found or it was not a binary object,
+ NULL is returned. To avoid problems with in-band error
+ reporting (i.e. if you cannot distinguish between NULL and a
+ valid result) use the more general function <c><![CDATA[ei_reg_getval()]]></c>
+ instead.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_reg_getval(reg,key,flags,v,...)</nametext></name>
+ <fsummary>Get any object</fsummary>
+ <type>
+ <v>ei_reg *reg;</v>
+ <v>const char *key;</v>
+ <v>int flags;</v>
+ <v>void *v (see below)</v>
+ </type>
+ <desc>
+ <p>This is a general function for retrieving any kind of
+ object from the registry.
+ </p>
+ <p><c><![CDATA[reg]]></c> is the registry where the object will be looked
+ up.
+ </p>
+ <p><c><![CDATA[key]]></c> is the name of the object to look up.
+ </p>
+ <p><c><![CDATA[flags]]></c> indicates the type of object that you are
+ looking for. If <c><![CDATA[flags]]></c> is 0, then any kind of object will
+ be returned. If <c><![CDATA[flags]]></c> is one of EI_INT, EI_FLT, EI_STR or
+ EI_BIN, then only values of that kind will be returned. The
+ buffer pointed to by <c><![CDATA[v]]></c> must be large enough to hold the return
+ data, i.e. it must be a pointer to one of <c><![CDATA[int]]></c>,
+ <c><![CDATA[double]]></c>, <c><![CDATA[char*]]></c> or <c><![CDATA[void*]]></c>, respectively. Also,
+ if <c><![CDATA[flags]]></c> is EI_BIN, then a fifth argument <c><![CDATA[int *size]]></c> is required, so that the size of the object can be
+ returned.
+ </p>
+ <p>If the function succeeds, <c><![CDATA[v]]></c> (and <c><![CDATA[size]]></c> if the
+ object is binary) will be initialized with the value associated
+ with <c><![CDATA[key]]></c>, and the function will return one of EI_INT,
+ EI_FLT, EI_STR or EI_BIN, indicating the type of object. On failure the
+ function will return -1 and the arguments will not be updated.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_reg_markdirty(reg,key)</nametext></name>
+ <fsummary>Mark an object as dirty </fsummary>
+ <type>
+ <v>ei_reg *reg;</v>
+ <v>const char *key;</v>
+ </type>
+ <desc>
+ <p>Mark a registry object as dirty. This will ensure that
+ it is included in the next backup to Mnesia. Normally this
+ operation will not be necessary since all of the normal registry
+ 'set' functions do this automatically. However if you have
+ retrieved the value of a string or binary object from the
+ registry and modified the contents, then the change will be
+ invisible to the registry and the object will be assumed to be
+ unmodified. This function allows you to make such modifications
+ and then let the registry know about them.
+ </p>
+ <p><c><![CDATA[reg]]></c> is the registry containing the object.
+ </p>
+ <p><c><![CDATA[key]]></c> is the name of the object to mark.
+ </p>
+ <p>The function returns 0 on success, or -1 on failure.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_reg_delete(reg,key)</nametext></name>
+ <fsummary>Delete an object from the registry</fsummary>
+ <type>
+ <v>ei_reg *reg;</v>
+ <v>const char *key;</v>
+ </type>
+ <desc>
+ <p>Delete an object from the registry. The object is not
+ actually removed from the registry, it is only marked for later
+ removal so that on subsequent backups to Mnesia, the
+ corresponding object can be removed from the Mnesia table as
+ well. If another object is later created with the same key, the
+ object will be reused.
+ </p>
+ <p>The object will be removed from the registry after a call to
+ <c><![CDATA[ei_reg_dump()]]></c> or <c><![CDATA[ei_reg_purge()]]></c>.
+ </p>
+ <p><c><![CDATA[reg]]></c> is the registry containing <c><![CDATA[key]]></c>.
+ </p>
+ <p><c><![CDATA[key]]></c> is the object to remove.
+ </p>
+ <p>If the object was found, the function returns 0 indicating
+ success. Otherwise the function returns -1.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_reg_stat(reg,key,obuf)</nametext></name>
+ <fsummary>Get object information</fsummary>
+ <type>
+ <v>ei_reg *reg;</v>
+ <v>const char *key;</v>
+ <v>struct ei_reg_stat *obuf;</v>
+ </type>
+ <desc>
+ <p>Return information about an object.
+ </p>
+ <p><c><![CDATA[reg]]></c> is the registry containing the object.
+ </p>
+ <p><c><![CDATA[key]]></c> is the name of the object.
+ </p>
+ <p><c><![CDATA[obuf]]></c> is a pointer to an <c><![CDATA[ei_reg_stat]]></c> structure,
+ defined below:
+ </p>
+ <code type="none"><![CDATA[
+struct ei_reg_stat {
+ int attr;
+ int size;
+};
+ ]]></code>
+ <p>In <c><![CDATA[attr]]></c> the object's attributes are stored as the logical
+ OR of its type (one of EI_INT, EI_FLT, EI_BIN and EI_STR),
+ whether it is marked for deletion (EI_DELET) and whether it has
+ been modified since the last backup to Mnesia (EI_DIRTY).
+ </p>
+ <p>The <c><![CDATA[size]]></c> field indicates the size in bytes required to store
+ EI_STR (including the terminating 0) and EI_BIN objects, or 0
+ for EI_INT and EI_FLT.
+ </p>
+ <p>The function returns 0 and initializes <c><![CDATA[obuf]]></c> on
+ success, or returns -1 on failure.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_reg_tabstat(reg,obuf)</nametext></name>
+ <fsummary>Get registry information</fsummary>
+ <type>
+ <v>ei_reg *reg;</v>
+ <v>struct ei_reg_tabstat *obuf;</v>
+ </type>
+ <desc>
+ <p>Return information about a registry. Using information
+ returned by this function, you can see whether the size of the
+ registry is suitable for the amount of data it contains.
+ </p>
+ <p><c><![CDATA[reg]]></c> is the registry to return information about.
+ </p>
+ <p><c><![CDATA[obuf]]></c> is a pointer to an <c><![CDATA[ei_reg_tabstat]]></c> structure,
+ defined below:
+ </p>
+ <code type="none"><![CDATA[
+struct ei_reg_tabstat {
+ int size;
+ int nelem;
+ int npos;
+ int collisions;
+};
+ ]]></code>
+ <p>The <c><![CDATA[size]]></c> field indicates the number of hash positions
+ in the registry. This is the number you provided when you
+ created or last resized the registry, rounded up to the nearest
+ prime.
+ </p>
+ <p><c><![CDATA[nelem]]></c> indicates the number of elements stored in the
+ registry. It includes objects that are deleted but not purged.
+ </p>
+ <p><c><![CDATA[npos]]></c> indicates the number of unique positions that are
+ occupied in the registry.
+ </p>
+ <p><c><![CDATA[collisions]]></c> indicates how many elements are sharing
+ positions in the registry.
+ </p>
+ <p>On success, the function returns 0 and <c><![CDATA[obuf]]></c> is
+ initialized to contain table statistics. On failure, the function
+ returns -1.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_reg_dump(fd,reg,mntab,flags)</nametext></name>
+ <fsummary>Back up a registry to Mnesia</fsummary>
+ <type>
+ <v>int fd;</v>
+ <v>ei_reg *reg;</v>
+ <v>const char *mntab;</v>
+ <v>int flags;</v>
+ </type>
+ <desc>
+ <p>Dump the contents of a registry to a Mnesia table in an
+ atomic manner, i.e. either all data will be updated, or none of
+ it will. If any errors are encountered while backing up
+ the data, the entire operation is aborted.
+ </p>
+ <p><c><![CDATA[fd]]></c> is an open connection to Erlang.
+ Mnesia 3.0 or later must be running on the Erlang node.
+ </p>
+ <p><c><![CDATA[reg]]></c> is the registry to back up.
+ </p>
+ <p><c><![CDATA[mntab]]></c> is the name of the Mnesia table where the backed
+ up data should be placed. If the table does not exist, it will
+ be created automatically using configurable defaults. See your
+ Mnesia documentation for information about configuring this
+ behaviour.
+ </p>
+ <p>If <c><![CDATA[flags]]></c> is 0, the backup will include only those
+ objects which have been created, modified or deleted since the
+ last backup or restore (i.e. an incremental backup). After the
+ backup, any objects that were marked dirty are now clean, and any
+ objects that had been marked for deletion are deleted.
+ </p>
+ <p>Alternatively, setting flags to EI_FORCE will cause a full
+ backup to be done, and EI_NOPURGE will cause the deleted objects
+ to be left in the registry afterwards. These can be bitwise ORed
+ together if both behaviours are desired. If EI_NOPURGE was
+ specified, you can use <c><![CDATA[ei_reg_purge()]]></c> to explicitly remove
+ the deleted items from the registry later.
+ </p>
+ <p>The function returns 0 on success, or -1 on failure.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_reg_restore(fd,reg,mntab)</nametext></name>
+ <fsummary>Restore a registry from Mnesia</fsummary>
+ <type>
+ <v>int fd;</v>
+ <v>ei_reg *reg;</v>
+ <v>const char *mntab;</v>
+ </type>
+ <desc>
+ <p>The contents of a Mnesia table are read into the
+ registry.
+ </p>
+ <p><c><![CDATA[fd]]></c> is an open connection to Erlang.
+ Mnesia 3.0 or later must be running on the Erlang node.
+ </p>
+ <p><c><![CDATA[reg]]></c> is the registry where the data should be placed.
+ </p>
+ <p><c><![CDATA[mntab]]></c> is the name of the Mnesia table to read data
+ from.
+ </p>
+ <p>Note that only tables of a certain format can be
+ restored, i.e. those that have been created and backed up to
+ with <c><![CDATA[ei_reg_dump()]]></c>. If the registry was not empty before
+ the operation, then the contents of the table are added to the
+ contents of the registry. If the table contains objects with the
+ same keys as those already in the registry, the registry objects
+ will be overwritten with the new values. If the registry
+ contains objects that were not in the table, they will be
+ unchanged by this operation.
+ </p>
+ <p>After the restore operation, the entire contents of the
+ registry is marked as unmodified. Note that this includes any
+ objects that were modified before the restore and not
+ overwritten by the restore.
+ </p>
+ <p>The function returns 0 on success, or -1 on failure.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>ei_reg_purge(reg)</nametext></name>
+ <fsummary>Remove deleted objects</fsummary>
+ <type>
+ <v>ei_reg *reg;</v>
+ </type>
+ <desc>
+ <p>Remove all objects marked for deletion. When objects
+ are deleted with <c><![CDATA[ei_reg_delete()]]></c> they are not actually
+ removed from the registry, only marked for later removal. This
+ is so that on a subsequent backup to Mnesia, the
+ objects can also be removed from the Mnesia table. If you are
+ not backing up to Mnesia then you may wish to remove the objects
+ manually with this function.
+ </p>
+ <p><c><![CDATA[reg]]></c> is a registry containing objects marked for
+ deletion.
+ </p>
+ <p>The function returns 0 on success, or -1 on failure.</p>
+ </desc>
+ </func>
+ </funcs>
+</cref>
+
diff --git a/lib/erl_interface/doc/src/warning.gif b/lib/erl_interface/doc/src/warning.gif
new file mode 100644
index 0000000000..96af52360e
--- /dev/null
+++ b/lib/erl_interface/doc/src/warning.gif
Binary files differ