summaryrefslogtreecommitdiff
path: root/lib/erl_interface
diff options
context:
space:
mode:
Diffstat (limited to 'lib/erl_interface')
-rw-r--r--lib/erl_interface/Makefile2
-rw-r--r--lib/erl_interface/configure.in4
-rw-r--r--lib/erl_interface/doc/src/Makefile79
-rw-r--r--lib/erl_interface/doc/src/ei.xml51
-rw-r--r--lib/erl_interface/doc/src/ei_connect.xml25
-rw-r--r--lib/erl_interface/doc/src/ei_global.xml (renamed from lib/erl_interface/doc/src/erl_global.xml)43
-rw-r--r--lib/erl_interface/doc/src/ei_users_guide.xml438
-rw-r--r--lib/erl_interface/doc/src/erl_call_cmd.xml (renamed from lib/erl_interface/doc/src/erl_call.xml)25
-rw-r--r--lib/erl_interface/doc/src/erl_connect.xml662
-rw-r--r--lib/erl_interface/doc/src/erl_error.xml145
-rw-r--r--lib/erl_interface/doc/src/erl_eterm.xml776
-rw-r--r--lib/erl_interface/doc/src/erl_format.xml138
-rw-r--r--lib/erl_interface/doc/src/erl_interface.xml637
-rw-r--r--lib/erl_interface/doc/src/erl_malloc.xml212
-rw-r--r--lib/erl_interface/doc/src/erl_marshal.xml276
-rw-r--r--lib/erl_interface/doc/src/part_erl_interface.xml33
-rw-r--r--lib/erl_interface/doc/src/ref_man.xml16
-rw-r--r--lib/erl_interface/doc/src/ref_man_ei.xml53
-rw-r--r--lib/erl_interface/doc/src/ref_man_erl_interface.xml60
-rw-r--r--lib/erl_interface/include/ei.h74
-rw-r--r--lib/erl_interface/include/ei_global.h (renamed from lib/erl_interface/src/legacy/erl_global.h)15
-rw-r--r--lib/erl_interface/include/erl_interface.h473
-rw-r--r--lib/erl_interface/src/Makefile.in196
-rw-r--r--lib/erl_interface/src/README4
-rw-r--r--lib/erl_interface/src/connect/ei_connect.c716
-rw-r--r--lib/erl_interface/src/connect/ei_connect_int.h27
-rw-r--r--lib/erl_interface/src/connect/ei_resolve.c257
-rw-r--r--lib/erl_interface/src/connect/send.c7
-rw-r--r--lib/erl_interface/src/connect/send_reg.c4
-rw-r--r--lib/erl_interface/src/decode/decode_big.c7
-rw-r--r--lib/erl_interface/src/encode/encode_pid.c11
-rw-r--r--lib/erl_interface/src/encode/encode_port.c11
-rw-r--r--lib/erl_interface/src/encode/encode_ref.c10
-rw-r--r--lib/erl_interface/src/epmd/ei_epmd.h8
-rw-r--r--lib/erl_interface/src/epmd/epmd_port.c22
-rw-r--r--lib/erl_interface/src/epmd/epmd_publish.c38
-rw-r--r--lib/erl_interface/src/epmd/epmd_unpublish.c10
-rw-r--r--lib/erl_interface/src/global/global_names.c (renamed from lib/erl_interface/src/legacy/global_names.c)8
-rw-r--r--lib/erl_interface/src/global/global_register.c (renamed from lib/erl_interface/src/legacy/global_register.c)16
-rw-r--r--lib/erl_interface/src/global/global_unregister.c (renamed from lib/erl_interface/src/legacy/global_unregister.c)8
-rw-r--r--lib/erl_interface/src/global/global_whereis.c (renamed from lib/erl_interface/src/legacy/global_whereis.c)29
-rw-r--r--lib/erl_interface/src/legacy/decode_term.c144
-rw-r--r--lib/erl_interface/src/legacy/encode_term.c54
-rw-r--r--lib/erl_interface/src/legacy/erl_config.h23
-rw-r--r--lib/erl_interface/src/legacy/erl_connect.c467
-rw-r--r--lib/erl_interface/src/legacy/erl_error.c181
-rw-r--r--lib/erl_interface/src/legacy/erl_error.h26
-rw-r--r--lib/erl_interface/src/legacy/erl_eterm.c1413
-rw-r--r--lib/erl_interface/src/legacy/erl_eterm.h64
-rw-r--r--lib/erl_interface/src/legacy/erl_fix_alloc.c198
-rw-r--r--lib/erl_interface/src/legacy/erl_fix_alloc.h27
-rw-r--r--lib/erl_interface/src/legacy/erl_format.c742
-rw-r--r--lib/erl_interface/src/legacy/erl_format.h23
-rw-r--r--lib/erl_interface/src/legacy/erl_internal.h48
-rw-r--r--lib/erl_interface/src/legacy/erl_malloc.c252
-rw-r--r--lib/erl_interface/src/legacy/erl_malloc.h27
-rw-r--r--lib/erl_interface/src/legacy/erl_marshal.c2267
-rw-r--r--lib/erl_interface/src/legacy/erl_marshal.h30
-rw-r--r--lib/erl_interface/src/legacy/erl_resolve.c107
-rw-r--r--lib/erl_interface/src/legacy/erl_timeout.c163
-rw-r--r--lib/erl_interface/src/legacy/erl_timeout.h75
-rw-r--r--lib/erl_interface/src/legacy/portability.h34
-rw-r--r--lib/erl_interface/src/misc/ei_format.c4
-rw-r--r--lib/erl_interface/src/misc/ei_locking.c25
-rw-r--r--lib/erl_interface/src/misc/ei_locking.h11
-rw-r--r--lib/erl_interface/src/misc/ei_portio.c26
-rw-r--r--lib/erl_interface/src/misc/ei_portio.h2
-rw-r--r--lib/erl_interface/src/misc/ei_printterm.c4
-rw-r--r--lib/erl_interface/src/misc/ei_pthreads.c25
-rw-r--r--lib/erl_interface/src/misc/ei_x_encode.c4
-rw-r--r--lib/erl_interface/src/misc/eidef.h5
-rw-r--r--lib/erl_interface/src/not_used/ei_send.c105
-rw-r--r--lib/erl_interface/src/not_used/ei_send_reg.c108
-rw-r--r--lib/erl_interface/src/not_used/send_link.c104
-rw-r--r--lib/erl_interface/src/not_used/whereis.c71
-rw-r--r--lib/erl_interface/src/prog/ei_fake_prog.c10
-rw-r--r--lib/erl_interface/src/prog/erl_call.c139
-rw-r--r--lib/erl_interface/src/prog/erl_fake_prog.c251
-rw-r--r--lib/erl_interface/src/prog/erl_start.c119
-rw-r--r--lib/erl_interface/src/registry/reg_get.c4
-rw-r--r--lib/erl_interface/src/registry/reg_set.c4
-rw-r--r--lib/erl_interface/test/Makefile7
-rw-r--r--lib/erl_interface/test/all_SUITE_data/Makefile.src2
-rw-r--r--lib/erl_interface/test/all_SUITE_data/init_tc.erl4
-rw-r--r--lib/erl_interface/test/all_SUITE_data/my_ussi.c198
-rw-r--r--lib/erl_interface/test/all_SUITE_data/my_ussi.h (renamed from lib/erl_interface/src/legacy/erl_connect.h)19
-rw-r--r--lib/erl_interface/test/all_SUITE_data/runner.c459
-rw-r--r--lib/erl_interface/test/all_SUITE_data/runner.h51
-rw-r--r--lib/erl_interface/test/ei_accept_SUITE.erl50
-rw-r--r--lib/erl_interface/test/ei_accept_SUITE_data/Makefile.src1
-rw-r--r--lib/erl_interface/test/ei_accept_SUITE_data/ei_accept_test.c28
-rw-r--r--lib/erl_interface/test/ei_accept_SUITE_data/eiaccnode.c60
-rw-r--r--lib/erl_interface/test/ei_connect_SUITE.erl68
-rw-r--r--lib/erl_interface/test/ei_connect_SUITE_data/Makefile.src6
-rw-r--r--lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c51
-rw-r--r--lib/erl_interface/test/ei_connect_SUITE_data/einode.c23
-rw-r--r--lib/erl_interface/test/ei_decode_SUITE.erl35
-rw-r--r--lib/erl_interface/test/ei_decode_SUITE_data/ei_decode_test.c18
-rw-r--r--lib/erl_interface/test/ei_decode_encode_SUITE_data/ei_decode_encode_test.c4
-rw-r--r--lib/erl_interface/test/ei_encode_SUITE.erl84
-rw-r--r--lib/erl_interface/test/ei_encode_SUITE_data/ei_encode_test.c12
-rw-r--r--lib/erl_interface/test/ei_format_SUITE_data/ei_format_test.c4
-rw-r--r--lib/erl_interface/test/ei_global_SUITE.erl (renamed from lib/erl_interface/test/erl_global_SUITE.erl)93
-rw-r--r--lib/erl_interface/test/ei_global_SUITE_data/Makefile.first (renamed from lib/erl_interface/test/erl_global_SUITE_data/Makefile.first)4
-rw-r--r--lib/erl_interface/test/ei_global_SUITE_data/Makefile.src (renamed from lib/erl_interface/test/erl_global_SUITE_data/Makefile.src)19
-rw-r--r--lib/erl_interface/test/ei_global_SUITE_data/ei_global_test.c239
-rw-r--r--lib/erl_interface/test/ei_print_SUITE_data/ei_print_test.c4
-rw-r--r--lib/erl_interface/test/ei_tmo_SUITE.erl311
-rw-r--r--lib/erl_interface/test/ei_tmo_SUITE_data/Makefile.src3
-rw-r--r--lib/erl_interface/test/ei_tmo_SUITE_data/ei_tmo_test.c172
-rw-r--r--lib/erl_interface/test/erl_call_SUITE.erl97
-rw-r--r--lib/erl_interface/test/erl_connect_SUITE.erl131
-rw-r--r--lib/erl_interface/test/erl_connect_SUITE_data/Makefile.first22
-rw-r--r--lib/erl_interface/test/erl_connect_SUITE_data/Makefile.src41
-rw-r--r--lib/erl_interface/test/erl_connect_SUITE_data/erl_connect_test.c203
-rw-r--r--lib/erl_interface/test/erl_eterm_SUITE.erl1084
-rw-r--r--lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.first22
-rw-r--r--lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.src50
-rw-r--r--lib/erl_interface/test/erl_eterm_SUITE_data/cnode.c173
-rw-r--r--lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c1604
-rw-r--r--lib/erl_interface/test/erl_eterm_SUITE_data/print_term.c131
-rw-r--r--lib/erl_interface/test/erl_format_SUITE.erl135
-rw-r--r--lib/erl_interface/test/erl_format_SUITE_data/Makefile.first22
-rw-r--r--lib/erl_interface/test/erl_format_SUITE_data/Makefile.src43
-rw-r--r--lib/erl_interface/test/erl_format_SUITE_data/format_test.c133
-rw-r--r--lib/erl_interface/test/erl_global_SUITE_data/erl_global_test.c264
-rw-r--r--lib/erl_interface/test/erl_match_SUITE.erl280
-rw-r--r--lib/erl_interface/test/erl_match_SUITE_data/Makefile.first22
-rw-r--r--lib/erl_interface/test/erl_match_SUITE_data/Makefile.src42
-rw-r--r--lib/erl_interface/test/erl_match_SUITE_data/match_test.c114
-rw-r--r--lib/erl_interface/test/port_call_SUITE_data/Makefile.src3
-rw-r--r--lib/erl_interface/test/port_call_SUITE_data/port_call_drv.c2
132 files changed, 2133 insertions, 17526 deletions
diff --git a/lib/erl_interface/Makefile b/lib/erl_interface/Makefile
index 9471b0df18..633e705b3f 100644
--- a/lib/erl_interface/Makefile
+++ b/lib/erl_interface/Makefile
@@ -31,3 +31,5 @@ SPECIAL_TARGETS =
# Default Subdir Targets
# ----------------------------------------------------
include $(ERL_TOP)/make/otp_subdir.mk
+
+include $(ERL_TOP)/make/app_targets.mk
diff --git a/lib/erl_interface/configure.in b/lib/erl_interface/configure.in
index 230dba25d6..55baae7479 100644
--- a/lib/erl_interface/configure.in
+++ b/lib/erl_interface/configure.in
@@ -336,6 +336,10 @@ if test "X$host" = "Xwin32"; then
LIB_CFLAGS="$CFLAGS"
else
if test "x$GCC" = xyes; then
+ # Remove all PIE stuff
+ CFLAGS=`echo $CFLAGS | sed 's/-f\(no-\)\?PIE//g'`
+ LDFLAGS=`echo $LDFLAGS | sed 's/-\(no-\)\?pie//g'`
+
LIB_CFLAGS="$CFLAGS -fPIC"
else
LIB_CFLAGS="$CFLAGS"
diff --git a/lib/erl_interface/doc/src/Makefile b/lib/erl_interface/doc/src/Makefile
index 03044a0ddd..95f3e77c61 100644
--- a/lib/erl_interface/doc/src/Makefile
+++ b/lib/erl_interface/doc/src/Makefile
@@ -36,93 +36,24 @@ 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 \
+XML_REF1_FILES = erl_call_cmd.xml
+XML_REF3_FILES = ei_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
XML_CHAPTER_FILES = ei_users_guide.xml notes.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
+NO_CHUNKS=$(XML_REF3_FILES)
# ----------------------------------------------------
-# 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 lcnt:
-
-clean clean_docs clean_tex:
- rm -rf $(HTMLDIR)/*
- rm -rf $(XMLDIR)
- 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:
+include $(ERL_TOP)/make/doc.mk
diff --git a/lib/erl_interface/doc/src/ei.xml b/lib/erl_interface/doc/src/ei.xml
index 70af5642da..232871e864 100644
--- a/lib/erl_interface/doc/src/ei.xml
+++ b/lib/erl_interface/doc/src/ei.xml
@@ -49,14 +49,9 @@
<p><c>ei</c> 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>ei</c>
- and <c>erl_interface</c> is that <c>ei</c> uses
- the binary format directly when sending and receiving terms. It is also
+ Erlang distribution format.The <c>ei</c> library is
thread safe, and using threads, one process can handle multiple
- C-nodes. The <c>erl_interface</c> library is built on top of
- <c>ei</c>, but of legacy reasons, it does not allow for
- multiple C-nodes. In general, <c>ei</c> is the preferred way
- of doing C-nodes.</p>
+ C-nodes.</p>
<p>The decode and encode functions use a buffer and an index into the
buffer, which points at the point where to encode and
@@ -378,22 +373,6 @@ typedef enum {
</func>
<func>
- <name since=""><ret>int</ret><nametext>ei_decode_term(const char *buf, int *index, void *t)</nametext></name>
- <fsummary>Decode a <c>ETERM</c>.</fsummary>
- <desc>
- <p>Decodes a term from the binary format. The term
- is return in <c>t</c> as a <c>ETERM*</c>, so
- <c>t</c> is actually an <c>ETERM**</c> (see
- <seealso marker="erl_eterm"><c>erl_eterm</c></seealso>).
- The term is later to be deallocated.</p>
- <note><p>This function is deprecated as of OTP 22 and will be removed in
- OTP 23 together with the old legacy <c>erl_interface</c> library (functions
- with prefix <c>erl_</c>).</p>
- </note>
- </desc>
- </func>
-
- <func>
<name since=""><ret>int</ret><nametext>ei_decode_trace(const char *buf, int *index, erlang_trace *p)</nametext></name>
<fsummary>Decode a trace token.</fsummary>
<desc>
@@ -707,22 +686,6 @@ ei_x_encode_string(&amp;x, "Banana");</pre>
the <c>ei_x_encode_string_len()</c> function.</p>
</desc>
</func>
-
- <func>
- <name since=""><ret>int</ret><nametext>ei_encode_term(char *buf, int *index, void *t)</nametext></name>
- <name since=""><ret>int</ret><nametext>ei_x_encode_term(ei_x_buff* x, void *t)</nametext></name>
- <fsummary>Encode an <c>erl_interface</c> term.</fsummary>
- <desc>
- <p>Encodes an <c>ETERM</c>, as obtained from
- <c>erl_interface</c>. Parameter <c>t</c> is
- actually an <c>ETERM</c> pointer. This function
- does not free the <c>ETERM</c>.</p>
- <note><p>These functions are deprecated as of OTP 22 and will be removed in
- OTP 23 together with the old legacy <c>erl_interface</c> library
- (functions with prefix <c>erl_</c>).</p>
- </note>
- </desc>
- </func>
<func>
<name since=""><ret>int</ret><nametext>ei_encode_trace(char *buf, int *index, const erlang_trace *p)</nametext></name>
<name since=""><ret>int</ret><nametext>ei_x_encode_trace(ei_x_buff* x, const erlang_trace *p)</nametext></name>
@@ -806,11 +769,7 @@ ei_encode_tuple_header(buf, &amp;i, 0);</pre>
<desc>
<p>Initialize the <c>ei</c> library. This function should be called once
(and only once) before calling any other functionality in the <c>ei</c>
- library. However, note the exception below.</p>
- <p>If the <c>ei</c> library is used together with the <c>erl_interface</c>
- library, this function should <em>not</em> be called directly. It will be
- called by the <c>erl_init()</c> function which should be used to initialize
- the combination of the two libraries instead.</p>
+ library.</p>
<p>On success zero is returned. On failure a posix error code is returned.</p>
</desc>
</func>
@@ -990,8 +949,4 @@ encodes the tuple {numbers,12,3.14159}</pre>
</list>
</section>
- <section>
- <title>See Also</title>
- <p><seealso marker="erl_eterm"><c>erl_eterm</c></seealso></p>
- </section>
</cref>
diff --git a/lib/erl_interface/doc/src/ei_connect.xml b/lib/erl_interface/doc/src/ei_connect.xml
index 795f1249b3..06fe9d1960 100644
--- a/lib/erl_interface/doc/src/ei_connect.xml
+++ b/lib/erl_interface/doc/src/ei_connect.xml
@@ -422,6 +422,8 @@ typedef struct {
<func>
<name since=""><ret>int</ret><nametext>ei_connect(ei_cnode* ec, char *nodename)</nametext></name>
<name since=""><ret>int</ret><nametext>ei_xconnect(ei_cnode* ec, Erl_IpAddr adr, char *alivename)</nametext></name>
+ <name since="OTP @OTP-16251@"><ret>int</ret><nametext>ei_connect_host_port(ei_cnode* ec, char *hostname, int port)</nametext></name>
+ <name since="OTP @OTP-16251@"><ret>int</ret><nametext>ei_xconnect_host_port(ei_cnode* ec, Erl_IpAddr adr, int port)</nametext></name>
<fsummary>Establish a connection to an Erlang node.</fsummary>
<desc>
<p>Sets up a connection to an Erlang node.</p>
@@ -429,13 +431,21 @@ typedef struct {
remote host and the alive name of the remote node to be
specified. <c>ei_connect()</c> provides an alternative
interface and determines the information from the node name
- provided.</p>
+ provided. The <c>ei_xconnect_host_port()</c> function provides
+ yet another alternative that will work even if there is no
+ EPMD instance on the host where the remote node is running. The
+ <c>ei_xconnect_host_port()</c> function requires the IP
+ address and port of the remote node to be specified.
+ The <c>ei_connect_host_port()</c> function is an alternative
+ to <c>ei_xconnect_host_port()</c> that lets the user specify
+ a hostname instead of an IP address.</p>
<list type="bulleted">
- <item><c>addr</c> is the 32-bit IP address of the remote
+ <item><c>adr</c> is the 32-bit IP address of the remote
host.</item>
<item><c>alive</c> is the alivename of the remote node.
</item>
<item><c>node</c> is the name of the remote node.</item>
+ <item><c>port</c> is the port number of the remote node.</item>
</list>
<p>These functions return an open file descriptor on success, or
a negative value indicating that an error occurred. In the latter
@@ -571,13 +581,16 @@ if (ei_connect_init(&ec, "madonna", "cookie...", n++) < 0) {
<func>
<name since=""><ret>int</ret><nametext>ei_connect_tmo(ei_cnode* ec, char *nodename, unsigned timeout_ms)</nametext></name>
<name since=""><ret>int</ret><nametext>ei_xconnect_tmo(ei_cnode* ec, Erl_IpAddr adr, char *alivename, unsigned timeout_ms)</nametext></name>
+ <name since="OTP @OTP-16251@"><ret>int</ret><nametext>ei_connect_host_port_tmo(ei_cnode* ec, char *hostname, int port, unsigned ms)</nametext></name>
+ <name since="OTP @OTP-16251@"><ret>int</ret><nametext>ei_xconnect_host_port_tmo(ei_cnode* ec, Erl_IpAddr adr, int port, unsigned ms)</nametext></name>
<fsummary>Establish a connection to an Erlang node with optional
time-out.</fsummary>
<desc>
- <p>Equivalent to
- <c>ei_connect</c> and <c>ei_xconnect</c> with an optional time-out
- argument, see the description at the beginning of this manual
- page.</p>
+ <p>Equivalent to <c>ei_connect</c>, <c>ei_xconnect</c>,
+ <c>ei_connect_host_port</c> and
+ <c>ei_xconnect_host_port</c> with an optional time-out
+ argument, see the description at the beginning of this manual
+ page.</p>
</desc>
</func>
diff --git a/lib/erl_interface/doc/src/erl_global.xml b/lib/erl_interface/doc/src/ei_global.xml
index 39085b46f0..4c6b94f7dd 100644
--- a/lib/erl_interface/doc/src/erl_global.xml
+++ b/lib/erl_interface/doc/src/ei_global.xml
@@ -22,7 +22,7 @@
</legalnotice>
- <title>erl_global</title>
+ <title>ei_global</title>
<prepared>Gordon Beaton</prepared>
<responsible>Gordon Beaton</responsible>
<docno></docno>
@@ -30,20 +30,14 @@
<checked>Gordon Beaton</checked>
<date>1998-07-03</date>
<rev>A</rev>
- <file>erl_global.xml</file>
+ <file>ei_global.xml</file>
</header>
- <lib>erl_global</lib>
+ <lib>ei_global</lib>
<libsummary>Access globally registered names.</libsummary>
<description>
<note><p>The support for VxWorks is deprecated as of OTP 22, and
will be removed in OTP 23.</p></note>
- <note><p>The old legacy <c>erl_interface</c> library (functions
- with prefix <c>erl_</c>) is deprecated as of OTP 22, and will be
- removed in OTP 23. This does not apply to the <c>ei</c>
- library. Reasonably new <c>gcc</c> compilers will issue deprecation
- warnings. In order to disable these warnings, define the macro
- <c>EI_NO_DEPR_WARN</c>.</p></note>
-
+
<p>This module provides support for registering, looking
up, and unregistering names in the <c>global</c> module.
For more information, see
@@ -57,15 +51,17 @@
<funcs>
<func>
- <name since=""><ret>char **</ret><nametext>erl_global_names(fd,count)</nametext></name>
+ <name since=""><ret>char **</ret><nametext>ei_global_names(ec,fd,count)</nametext></name>
<fsummary>Obtain list of global names.</fsummary>
<type>
+ <v>ei_cnode *ec;</v>
<v>int fd;</v>
<v>int *count;</v>
</type>
<desc>
<p>Retrieves a list of all known global names.</p>
<list type="bulleted">
+ <item><c>ec</c> is the ei_cnode representing the current cnode.</item>
<item><c>fd</c> is an open descriptor to an Erlang
connection.</item>
<item><c>count</c> is the address of an integer, or
@@ -88,12 +84,12 @@
</func>
<func>
- <name since=""><ret>int</ret><nametext>erl_global_register(fd,name,pid)</nametext></name>
+ <name since=""><ret>int</ret><nametext>ei_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>
+ <v>erlang_pid *pid;</v>
</type>
<desc>
<p>Registers a name in <c>global</c>.</p>
@@ -112,15 +108,17 @@
</func>
<func>
- <name since=""><ret>int</ret><nametext>erl_global_unregister(fd,name)</nametext></name>
+ <name since=""><ret>int</ret><nametext>ei_global_unregister(ec,fd,name)</nametext></name>
<fsummary>Unregister a name from global.</fsummary>
<type>
+ <v>ei_cnode *ec;</v>
<v>int fd;</v>
<v>const char *name;</v>
</type>
<desc>
<p>Unregisters a name from <c>global</c>.</p>
<list type="bulleted">
+ <item><c>ec</c> is the ei_cnode representing the current cnode.</item>
<item><c>fd</c> is an open descriptor to an Erlang
connection.</item>
<item><c>name</c> is the name to unregister from
@@ -131,30 +129,35 @@
</func>
<func>
- <name since=""><ret>ETERM *</ret><nametext>erl_global_whereis(fd,name,node)</nametext></name>
+ <name since=""><ret>int</ret><nametext>ei_global_whereis(ec,fd,name,pid,node)</nametext></name>
<fsummary>Look up a name in global.</fsummary>
<type>
+ <v>ei_cnode *ec;</v>
<v>int fd;</v>
<v>const char *name;</v>
+ <v>erlang_pid* pid;</v>
<v>char *node;</v>
</type>
<desc>
<p>Looks up a name in <c>global</c>.</p>
<list type="bulleted">
+ <item><c>ec</c> is the ei_cnode representing the current cnode.</item>
<item><c>fd</c> is an open descriptor to an Erlang
connection.</item>
<item><c>name</c> is the name that is to be looked up in
<c>global</c>.</item>
</list>
+ <p>The <c>pid</c> parameter is a pointer to a
+ <c>erlang_pid</c> that the function will update with the pid associated
+ with the global name, if successful.</p>
<p>If <c>node</c> is not <c>NULL</c>, it is a pointer to a
buffer where the function can fill in the name of the node where
<c>name</c> is found. <c>node</c> can be
- passed directly to <c>erl_connect()</c> if necessary.</p>
- <p>On success, the function returns an Erlang pid containing the address
- of the specified name, and the node is initialized to
+ passed directly to <c>ei_connect()</c> if necessary.</p>
+ <p>On success, the function returns 0, updates the <c>erlang_pid</c>
+ pointed to by the pid parameter, and the <c>node</c> parameter is initialized to
the node name where <c>name</c> is found. On failure,
- <c>NULL</c> is returned and <c>node</c> is not
- modified.</p>
+ a negative number is returned.</p>
</desc>
</func>
</funcs>
diff --git a/lib/erl_interface/doc/src/ei_users_guide.xml b/lib/erl_interface/doc/src/ei_users_guide.xml
index 7ca10d1a99..4ce8b9237f 100644
--- a/lib/erl_interface/doc/src/ei_users_guide.xml
+++ b/lib/erl_interface/doc/src/ei_users_guide.xml
@@ -37,12 +37,6 @@
<title>Deprecation and Removal</title>
<note><p>The support for VxWorks is deprecated as of OTP 22, and
will be removed in OTP 23.</p></note>
- <note><p>The old legacy <c>erl_interface</c> library (functions
- with prefix <c>erl_</c>) is deprecated as of OTP 22, and will be
- removed in OTP 23. This does not apply to the <c>ei</c>
- library. Reasonably new <c>gcc</c> compilers will issue deprecation
- warnings. In order to disable these warnings, define the macro
- <c>EI_NO_DEPR_WARN</c>.</p></note>
</section>
<section>
@@ -60,14 +54,12 @@
<seealso marker="mnesia:mnesia">Mnesia</seealso></item>
</list>
<note>
- <p>By default, the <c>Erl_Interface</c> libraries are only guaranteed
+ <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 libraries themselves. For information about how to
communicate with Erlang/OTP components from earlier releases, see
function <seealso marker="ei#ei_set_compat_rel">
- <c>ei:ei_set_compat_rel</c></seealso> and
- <seealso marker="erl_eterm#erl_set_compat_rel">
- <c>erl_eterm:erl_set_compat_rel</c></seealso>.</p>
+ <c>ei_set_compat_rel</c></seealso>.</p>
</note>
<section>
@@ -98,10 +90,9 @@
<section>
<title>Compiling and Linking Your Code</title>
<p>To use any of the <c>Erl_Interface</c> functions, include the
- following lines in your code:</p>
+ following line 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.
@@ -114,7 +105,7 @@ Eshell V4.7.4 (abort with ^G)
/usr/local/otp ]]></code>
<p>To compile your code, ensure that your C compiler knows where
- to find <c>erl_interface.h</c> by specifying an appropriate
+ to find <c>ei.h</c> by specifying an appropriate
<c>-I</c> argument on the command line, or add it to
the <c>CFLAGS</c> definition in your
<c>Makefile</c>. The correct value for this path is
@@ -140,11 +131,9 @@ $ cc -c -I/usr/local/otp/lib/erl_interface-3.2.3/include myprog.c ]]></code>
<p>When linking:</p>
<list type="bulleted">
- <item>Specify the path to <c>liberl_interface.a</c> and
- <c>libei.a</c> with
+ <item>Specify the path to <c>libei.a</c> with
<c>-L$OTPROOT/lib/erl_interface-3.2.3/lib</c>.</item>
- <item>Specify the name of the libraries with
- <c>-lerl_interface -lei</c>.</item>
+ <item>Specify the name of the library with <c>-lei</c>.</item>
</list>
<p>Do this on the command line or add the flags to the
@@ -155,7 +144,7 @@ $ cc -c -I/usr/local/otp/lib/erl_interface-3.2.3/include myprog.c ]]></code>
<code type="none"><![CDATA[
$ ld -L/usr/local/otp/lib/erl_interface-3.2.3/
- lib myprog.o -lerl_interface -lei -o myprog ]]></code>
+ lib myprog.o -lei -o myprog ]]></code>
<p>On some systems it can be necessary to link with some more
libraries (for example, <c>libnsl.a</c> and
@@ -174,19 +163,11 @@ $ ld -L/usr/local/otp/lib/erl_interface-3.2.3/
</section>
<section>
- <title>Initializing the Libraries</title>
+ <title>Initializing the Library</title>
<p>
- Before calling any of the other functions in the <c>erl_interface</c>
- and <c>ei</c> libraries, call <c>erl_init()</c> exactly once to initialize
- both libraries.
- <c>erl_init()</c> takes two arguments. However, the arguments
- are no longer used by <c>erl_interface</c> and are therefore to be
- specified as <c>erl_init(NULL,0)</c>.
- </p>
- <p>
- If you only use the <c>ei</c> library, instead initialize it by calling
- <c>ei_init()</c> exactly once before calling any other functions in
- the <c>ei</c> library.
+ Before calling any of the other functions in the library,
+ initialize it by calling
+ <c>ei_init()</c> exactly once.
</p>
</section>
@@ -199,187 +180,93 @@ $ ld -L/usr/local/otp/lib/erl_interface-3.2.3/
<p>The <c>Erl_Interface</c> library supports this activity. It has
several C functions that create and manipulate Erlang data
- structures. The library also contains an encode and a decode function.
- The following example shows how to create and encode an Erlang tuple
- <c>{tobbe,3928}</c>:</p>
+ structures. The following example shows how to create and encode
+ an Erlang tuple <c>{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>erl_send()</c> and
- <c>erl_receive_msg</c>, which handle the encoding and
- decoding of messages transparently.</p>
-
- <p>For a complete description, see the following modules:</p>
- <list type="bulleted">
- <item><seealso marker="erl_eterm"><c>erl_eterm</c></seealso>
- for creating Erlang terms</item>
- <item><seealso marker="erl_marshal"><c>erl_marshal</c></seealso>
- for encoding and decoding routines</item>
- </list>
+ei_x_buff buf;
+ei_x_new(&buf);
+int i = 0;
+ei_x_encode_tuple_header(&buf, 2);
+ei_x_encode_atom(&buf, "tobbe");
+ei_x_encode_long(&buf, 3928); ]]></code>
+
+ <p>For a complete description, see the
+ <seealso marker="ei"><c>ei</c></seealso> module.</p>
</section>
<section>
<marker id="building_terms_and_patterns"/>
- <title>Building Terms and Patterns</title>
+ <title>Building Terms</title>
<p>The previous example can be simplified by using the
- <seealso marker="erl_format"><c>erl_format</c></seealso> module
+ <seealso marker="ei#ei_x_format_wo_ver"><c>ei_x_format_wo_ver</c></seealso> function
to create an Erlang term:</p>
<code type="none"><![CDATA[
-ETERM *ep;
-ep = erl_format("{~a,~i}", "tobbe", 3928); ]]></code>
+ei_x_buff buf;
+ei_x_new(&buf);
+ei_x_format_wo_ver(&buf, "{~a,~i}", "tobbe", 3928); ]]></code>
- <p>For a complete description of the different format directives, see
- the <seealso marker="erl_format"><c>erl_format</c></seealso> module.</p>
+ <p>For a complete description of the different format directives, see the
+ the <seealso marker="ei#ei_x_format_wo_ver"><c>ei_x_format_wo_ver</c></seealso> function.</p>
<p>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>
+ei_x_buff buf;
+int i = 0;
+ei_x_new(&buf);
+ei_x_format_wo_ver(&buf,
+ "[{name,~a},{age,~i},{data,[{adr,~s,~i}]}]",
+ "madonna",
+ 21,
+ "E-street", 42);
+ei_print_term(stdout, buf.buff, &i);
+ei_x_free(&buf); ]]></code>
<p>As in the previous examples, it is your responsibility to free the
memory allocated for Erlang terms. In this example,
- <c>erl_free_compound()</c> ensures that the complete term
- pointed to by <c>ep</c> is released. This is necessary
- because the pointer from the second call to <c>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>ep</c> and <c>ep2</c>
- is not important,
- because the <c>Erl_Interface</c> library uses reference counting to
- determine when it is safe to remove objects.</p>
-
- <p>If you are unsure 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>For more information, see the
- <seealso marker="erl_malloc"><c>erl_malloc</c></seealso> module.</p>
- </section>
-
- <section>
- <title>Pattern Matching</title>
- <p>An Erlang pattern is a term that can contain unbound variables or
- <c>"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>The <seealso marker="erl_format#erl_match">
- <c>erl_format:erl_match</c></seealso> function
- performs 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, a
- pattern is created with a variable <c>Age</c>, which is included at two
- positions in the tuple. The pattern match is performed as follows:</p>
-
- <list type="bulleted">
- <item>
- <p><c>erl_match</c> binds the contents of <c>Age</c> to <c>21</c>
- the first time it reaches the variable.</p>
- </item>
- <item>
- <p>The second occurrence of <c>Age</c> causes a test for
- equality between the terms, as <c>Age</c> is already bound to
- <c>21</c>. As <c>Age</c> is bound to <c>21</c>, the equality test
- succeeds and the match continues until the end of the pattern.</p>
- </item>
- <item>
- <p>If the end of the pattern is reached, the match succeeds and you
- can retrieve the contents of the variable.</p>
- </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>
+ <c>ei_x_free()</c> ensures that the data
+ pointed to by <c>buf</c> is released.</p>
- <p>For more information, see the
- <seealso marker="erl_format#erl_match">
- <c>erl_format:erl_match</c></seealso> function.</p>
</section>
<section>
<title>Connecting to a Distributed Erlang Node</title>
<p>To connect to a distributed Erlang node, you must first
- initialize the connection routine with
- <seealso marker="erl_connect#erl_connect_init">
- <c>erl_connect:erl_connect_init</c></seealso>,
- which stores information, such as the hostname, node name, and IP
- address for later use:</p>
+ initialize the connection routine with one of the
+ <seealso marker="ei_connect#ei_connect_init">
+ <c>ei_connect_init_*</c></seealso> functions,
+ which stores information, such as the hostname, and node name
+ 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>
+const char* node_name = "einode@durin";
+const char *cookie = NULL;
+short creation = time(NULL) + 1;
+ei_cnode ec;
+ei_connect_init(ec,
+ node_name,
+ cookie,
+ creation); ]]></code>
<p>For more information, see the
- <seealso marker="erl_connect"><c>erl_connect</c></seealso> module.</p>
+ <seealso marker="ei_connect"><c>ei_connect</c></seealso> module.</p>
<p>After initialization, you set up the connection to the Erlang node.
- To specify the Erlang node you want to connect to, use
- <c>erl_connect()</c>. The following example sets up the
+ To specify the Erlang node you want to connect to, use the
+ <c>ei_connect_*()</c> family of functions. The following example sets up the
connection and is to result in a valid socket file descriptor:</p>
<code type="none"><![CDATA[
int sockfd;
-char *nodename="xyz@chivas.du.etx.ericsson.se"; /* An example */
-if ((sockfd = erl_connect(nodename)) < 0)
- erl_err_quit("ERROR: erl_connect failed"); ]]></code>
+const char* node_name = "einode@durin"; /* An example */
+if ((sockfd = ei_connect(ec, nodename)) < 0)
+ fprintf(stderr, "ERROR: ei_connect failed"); ]]></code>
- <p><c>erl_err_quit()</c> prints the specified string and
- terminates the program. For more information, see the
- <seealso marker="erl_error"><c>erl_error</c></seealso> module.</p>
</section>
<section>
@@ -394,7 +281,7 @@ if ((sockfd = erl_connect(nodename)) < 0)
correct port number to connect to.</p>
<p>When you use
- <seealso marker="erl_connect"><c>erl_connect</c></seealso>
+ <seealso marker="ei_connect"><c>ei_connect</c></seealso>
to connect to an Erlang node, a connection is first made to
<c>epmd</c> and, if the node is known, a
connection is then made to the Erlang node.</p>
@@ -409,7 +296,7 @@ if ((sockfd = erl_connect(nodename)) < 0)
<code type="none"><![CDATA[
int pub;
-pub = erl_publish(port); ]]></code>
+pub = ei_publish(ec, port); ]]></code>
<p><c>pub</c> is a file descriptor now connected to
<c>epmd</c>. <c>epmd</c>
@@ -424,17 +311,9 @@ pub = erl_publish(port); ]]></code>
failed. If a node has failed in this way, <c>epmd</c>
prevents you from
registering a new node with the old name, as it thinks that the old
- name is still in use. In this case, you must unregister the name
- explicitly:</p>
+ name is still in use. In this case, you must close the port
+ explicitly</p>
- <code type="none"><![CDATA[
-erl_unpublish(node); ]]></code>
-
- <p>This causes <c>epmd</c> to close the connection from the
- far end. Notice
- 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 can be consumed.</p>
</section>
<section>
@@ -442,10 +321,10 @@ erl_unpublish(node); ]]></code>
<p>Use one of the following two functions to send messages:</p>
<list type="bulleted">
- <item><seealso marker="erl_connect#erl_send">
- <c>erl_connect:erl_send</c></seealso></item>
- <item><seealso marker="erl_connect#erl_reg_send">
- <c>erl_connect:erl_reg_send</c></seealso></item>
+ <item><seealso marker="ei_connect#ei_send">
+ <c>ei_send</c></seealso></item>
+ <item><seealso marker="ei_connect#ei_reg_send">
+ <c>ei_reg_send</c></seealso></item>
</list>
<p>As in Erlang, messages can be sent to a
@@ -456,82 +335,79 @@ erl_unpublish(node); ]]></code>
<p>Use one of the following two functions to receive messages:</p>
<list type="bulleted">
- <item><seealso marker="erl_connect#erl_receive">
- <c>erl_connect:erl_receive</c></seealso></item>
- <item><seealso marker="erl_connect#erl_receive_msg">
- <c>erl_connect:erl_receive_msg</c></seealso></item>
+ <item><seealso marker="ei_connect#ei_receive">
+ <c>ei_receive</c></seealso></item>
+ <item><seealso marker="ei_connect#ei_receive_msg">
+ <c>ei_receive_msg</c></seealso></item>
</list>
- <p><c>erl_receive()</c> receives the message into a buffer,
- while <c>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>{Pid, hello_world}</c> is
- sent to a registered process <c>my_server</c>. The message
- is encoded by <c>erl_send()</c>:</p>
+ sent to a registered process <c>my_server</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>
+ei_x_buff buf;
+ei_x_new_with_version(&buf);
+
+ei_x_encode_tuple_header(&buf, 2);
+ei_x_encode_pid(&buf, ei_self(ec));
+ei_x_encode_atom(&buf, "Hello world");
+
+ei_reg_send(ec,fd,"my_server",buf,buf.index);]]></code>
<p>The first element of the tuple that is sent is your own
pid. This enables <c>my_server</c> to reply.
For more information about the primitives, see the
- <seealso marker="erl_connect"><c>erl_connect</c></seealso> module.</p>
+ <seealso marker="ei_connect"><c>ei_connect</c></seealso> module.</p>
</section>
<section>
<title>Example of Receiving Messages</title>
- <p>In this example, <c>{Pid, Something}</c> is received. The
- received pid is then used to return
- <c>{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 this example, <c>{Pid, Something}</c> is received.</p>
+
+ <code type="none"><![CDATA[
+erlang_msg msg;
+int index = 0;
+int version;
+int arity = 0;
+erlang_pid pid;
+ei_x_buff buf;
+ei_x_new(&buf);
+for (;;) {
+ int got = ei_xreceive_msg(fd, &msg, &x);
+ if (got == ERL_TICK)
+ continue;
+ if (got == ERL_ERROR) {
+ fprintf(stderr, "ei_xreceive_msg, got==%d", got);
+ exit(1);
+ }
+ break;
+}
+ei_decode_version(buf.buff, &index, &version);
+ei_decode_tuple_header(buf.buff, &index, &arity);
+if (arity != 2) {
+ fprintf(stderr, "got wrong message");
+ exit(1);
+}
+ei_decode_pid(buf.buff, &index, &pid); ]]></code>
<p>To provide robustness, a distributed Erlang node
occasionally polls all its connected neighbors in an attempt to
detect failed nodes or communication links. A node that receives such
a message is expected to respond immediately with an
<c>ERL_TICK</c> message. This is done automatically by
- <c>erl_receive()</c>. However, when this has occurred,
- <c>erl_receive</c> returns <c>ERL_TICK</c> to
+ <c>ei_xreceive_msg()</c>. However, when this has occurred,
+ <c>ei_xreceive_msg</c> returns <c>ERL_TICK</c> to
the caller without storing a message into the
- <c>ErlMessage</c> structure.</p>
+ <c>erlang_msg</c> structure.</p>
<p>When a message has been received, it is the caller's responsibility
- to free the received message <c>emsg.msg</c> and
- <c>emsg.to</c> or <c>emsg.from</c>,
- depending on the type of message received.</p>
+ to free the received message.</p>
<p>For more information, see the
- <seealso marker="erl_connect"><c>erl_connect</c></seealso> and
- <seealso marker="erl_eterm"><c>erl_eterm</c></seealso> modules.</p>
+ <seealso marker="ei_connect"><c>ei_connect</c></seealso> and
+ <seealso marker="ei"><c>ei</c></seealso> modules.</p>
</section>
</section>
@@ -542,31 +418,30 @@ if ((rc = erl_receive_msg(sockfd , buf, BUFSIZE, &emsg)) == ERL_MSG) {
included in a function call at a remote node and is called a remote
procedure call.</p>
- <p>The following example shows how the
- <c>Erl_Interface</c> library supports remote procedure calls:</p>
+ <p>The following example checks if a specific Erlang process is alive:</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>c:c/1</c> is called to compile the specified module on
- the remote node. <c>erl_match()</c> checks that the
- compilation was
- successful by testing for the expected <c>ok</c>.</p>
-
- <p>For more information about <c>erl_rpc()</c> and its
- companions <c>erl_rpc_to()</c> and
- <c>erl_rpc_from()</c>, see the
- <seealso marker="erl_connect"><c>erl_connect</c></seealso> module.</p>
+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>
+
+ <p>For more information about <c>ei_rpc()</c> and its
+ companions <c>ei_rpc_to()</c> and
+ <c>ei_rpc_from()</c>, see the
+ <seealso marker="ei_connect"><c>ei_connect</c></seealso> module.</p>
</section>
<section>
@@ -590,7 +465,7 @@ char **names;
int count;
int i;
-names = erl_global_names(fd,&count);
+names = ei_global_names(ec,fd,&count);
if (names)
for (i=0; i<count; i++)
@@ -598,8 +473,8 @@ if (names)
free(names); ]]></code>
- <p><seealso marker="erl_global#erl_global_names">
- <c>erl_global:erl_global_names</c></seealso>
+ <p><seealso marker="ei_global#ei_global_names">
+ <c>ei_global_names</c></seealso>
allocates and returns a buffer containing
all the names known to the <c>global</c> module in <c>Kernel</c>.
<c>count</c> is initialized to
@@ -608,7 +483,7 @@ free(names); ]]></code>
<c>count</c> to determine when the last name is reached.</p>
<p>It is the caller's responsibility to free the array.
- <c>erl_global_names</c> allocates the array and all the strings
+ <c>ei_global_names</c> allocates the array and all the strings
using a single call to <c>malloc()</c>, so
<c>free(names)</c> is all that is necessary.</p>
@@ -617,16 +492,18 @@ free(names); ]]></code>
<code type="none"><![CDATA[
ETERM *pid;
char node[256];
+erlang_pid the_pid;
-pid = erl_global_whereis(fd,"schedule",node); ]]></code>
+if (ei_global_whereis(ec,fd,"schedule",&the_pid,node) < 0)
+ fprintf(stderr, "ei_global_whereis error\n"); ]]></code>
<p>If <c>"schedule"</c> is known to the
<c>global</c> module in <c>Kernel</c>, an Erlang pid is
- returned that can be used to send messages to the schedule service.
+ written to the_pid. This pid that can be used to send messages to the schedule service.
Also, <c>node</c> is 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
- <seealso marker="erl_connect"><c>erl_connect</c></seealso>.</p>
+ <seealso marker="ei_connect"><c>ei_connect</c></seealso>.</p>
<p>Before registering a name, you should already have registered your
port number with <c>epmd</c>. This is not strictly necessary,
@@ -634,30 +511,27 @@ pid = erl_global_whereis(fd,"schedule",node); ]]></code>
neglect to do so, then other nodes wishing to communicate with your
service cannot find or connect to your process.</p>
- <p>Create a pid that Erlang processes can use to communicate with your
+ <p>Create a name 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>
+ei_global_register(fd,servicename,ei_self(ec)); ]]></code>
<p>After registering the name, use
- <seealso marker="erl_connect#erl_accept">
- <c>erl_connect:erl_accept</c></seealso>
+ <seealso marker="ei_connect#ei_accept">
+ <c>ei_accept</c></seealso>
to wait for incoming connections.</p>
<note>
<p>Remember to free <c>pid</c> later with
- <seealso marker="erl_malloc#erl_free_term">
- <c>erl_malloc:erl_free_term</c></seealso>.</p>
+ <seealso marker="ei#ei_x_free">
+ <c>ei_x_free</c></seealso>.</p>
</note>
<p>To unregister a name:</p>
<code type="none"><![CDATA[
-erl_global_unregister(fd,servicename); ]]></code>
+ei_global_unregister(ec,fd,servicename); ]]></code>
</section>
<section>
@@ -755,7 +629,7 @@ ei_reg_close(reg); ]]></code>
<p>The contents of a registry can be backed up to
<seealso marker="mnesia:mnesia"><c>Mnesia</c></seealso> on a "nearby" Erlang
node. You must provide an open connection to the Erlang node
- (see <seealso marker="erl_connect"><c>erl_connect</c></seealso>).
+ (see <seealso marker="ei_connect"><c>ei_connect</c></seealso>).
Also, <c>Mnesia</c> 3.0 or later must be running
on the Erlang node before the backup is initiated:</p>
@@ -818,9 +692,9 @@ ei_reg_restore(fd, reg, "mtab"); ]]></code>
<c>Mnesia</c> backup of the registry contents. This can be avoided if
you mark the object as dirty after any such changes with
<seealso marker="registry#ei_reg_markdirty">
- <c>registry:ei_reg_markdirty</c></seealso>, or pass appropriate flags to
+ <c>ei_reg_markdirty</c></seealso>, or pass appropriate flags to
<seealso marker="registry#ei_reg_dump">
- <c>registry:ei_reg_dump</c></seealso>.</p>
+ <c>ei_reg_dump</c></seealso>.</p>
</section>
</section>
</chapter>
diff --git a/lib/erl_interface/doc/src/erl_call.xml b/lib/erl_interface/doc/src/erl_call_cmd.xml
index 73b9b13e4d..91cb9dbd32 100644
--- a/lib/erl_interface/doc/src/erl_call.xml
+++ b/lib/erl_interface/doc/src/erl_call_cmd.xml
@@ -78,6 +78,22 @@
<c>Fun</c>, and <c>Args</c> in a manner
dependent on the behavior of your command shell.</p>
</item>
+ <tag><c>-address [Hostname:]Port</c></tag>
+ <item>
+ <p>(One of <c>-n</c>, <c>-name</c>, <c>-sname</c> or
+ <c>-address</c> is required.) <c>Hostname</c> is the
+ hostname of the machine that is running the node that
+ <c>erl_call</c> shall communicate with. The default
+ hostname is the hostname of the local machine. <c>Port</c>
+ is the port number of the node that <c>erl_call</c> shall
+ communicate with. The <c>-address</c> flag cannot be
+ combined with any of the flags <c>-n</c>, <c>-name</c>,
+ <c>-sname</c> or <c>-s</c>.</p>
+ <p>The <c>-address</c> flag is typically useful when one
+ wants to call a node that is running on machine without an
+ accessible <seealso marker="erts:epmd">epmd</seealso>
+ instance.</p>
+ </item>
<tag><c>-c Cookie</c></tag>
<item>
<p>(<em>Optional.</em>) Use this option to specify a certain cookie.
@@ -112,13 +128,15 @@
</item>
<tag><c>-n Node</c></tag>
<item>
- <p>(One of <c>-n, -name, -sname</c> is required.)
+ <p>(One of <c>-n</c>, <c>-name</c>, <c>-sname</c> or
+ <c>-address</c> is required.)
Has the same meaning as <c>-name</c> and can still be
used for backward compatibility reasons.</p>
</item>
<tag><c>-name Node</c></tag>
<item>
- <p>(One of <c>-n, -name, -sname</c> is required.)
+ <p>(One of <c>-n</c>, <c>-name</c>, <c>-sname</c> or
+ <c>-address</c> is required.)
<c>Node</c> is the name of the node to be
started or communicated with. It is assumed that
<c>Node</c> is started with
@@ -149,7 +167,8 @@
</item>
<tag><c>-sname Node</c></tag>
<item>
- <p>(One of <c>-n, -name, -sname</c> is required.)
+ <p>(One of <c>-n</c>, <c>-name</c>, <c>-sname</c> or
+ <c>-address</c> is required.)
<c>Node</c> is the name of the node to be started
or communicated with. It is assumed that <c>Node</c>
is started with <c>erl -sname</c>, which means that
diff --git a/lib/erl_interface/doc/src/erl_connect.xml b/lib/erl_interface/doc/src/erl_connect.xml
deleted file mode 100644
index 9492a82864..0000000000
--- a/lib/erl_interface/doc/src/erl_connect.xml
+++ /dev/null
@@ -1,662 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE cref SYSTEM "cref.dtd">
-
-<cref>
- <header>
- <copyright>
- <year>1996</year><year>2016</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions 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>1998-07-03</date>
- <rev>A</rev>
- <file>erl_connect.xml</file>
- </header>
- <lib>erl_connect</lib>
- <libsummary>Communicate with distributed Erlang.</libsummary>
- <description>
- <note><p>The support for VxWorks is deprecated as of OTP 22, and
- will be removed in OTP 23.</p></note>
- <note><p>The old legacy <c>erl_interface</c> library (functions
- with prefix <c>erl_</c>) is deprecated as of OTP 22, and will be
- removed in OTP 23. This does not apply to the <c>ei</c>
- library. Reasonably new <c>gcc</c> compilers will issue deprecation
- warnings. In order to disable these warnings, define the macro
- <c>EI_NO_DEPR_WARN</c>.</p></note>
-
- <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 can communicate with it in a normal manner, but
- the node name does not appear in the listing provided by
- <seealso marker="erts:erlang#nodes/0"><c>erlang:nodes/0</c></seealso>
- in <c>ERTS</c>.</p>
- </description>
-
- <funcs>
- <func>
- <name since=""><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>
- <list type="bulleted">
- <item><c>listensock</c> is an open socket descriptor on
- which <c>listen()</c> has previously been called.</item>
- <item><c>conp</c> is a pointer to an
- <c>ErlConnect</c> struct, described as follows:</item>
- </list>
- <code type="none"><![CDATA[
-typedef struct {
- char ipadr[4];
- char nodename[MAXNODELEN];
-} ErlConnect;
- ]]></code>
- <p>On success, <c>conp</c> is filled in with the address and
- node name of the connecting client and a file descriptor is
- returned. On failure, <c>ERL_ERROR</c> is returned and
- <c>erl_errno</c> is set to <c>EIO</c>.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><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>Closes an open connection to an Erlang node.</p>
- <p><c>Fd</c> is a file descriptor obtained from
- <c>erl_connect()</c> or
- <c>erl_xconnect()</c>.</p>
- <p>Returns <c>0</c> on success. 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 since=""><ret>int</ret><nametext>erl_connect(node)</nametext></name>
- <name since=""><ret>int</ret><nametext>erl_xconnect(addr, alive)</nametext></name>
- <fsummary>Establish a connection to an Erlang node.</fsummary>
- <type>
- <v>char *node, *alive;</v>
- <v>struct in_addr *addr;</v>
- </type>
- <desc>
- <p>Sets up a connection to an Erlang node.</p>
- <p><c>erl_xconnect()</c> requires the IP address of the
- remote host and the alivename of the remote node to be
- specified. <c>erl_connect()</c> provides an alternative
- interface, and determines the information from the node name
- provided.</p>
- <list type="bulleted">
- <item><c>addr</c> is the 32-bit IP address of the remote
- host.</item>
- <item><c>alive</c> is the alivename of the remote node.
- </item>
- <item><c>node</c> is the name of the remote node.</item>
- </list>
- <p>Returns an open file descriptor on success, otherwise a negative
- value. In the latter case <c>erl_errno</c> is set to one
- of:</p>
- <taglist>
- <tag><c>EHOSTUNREACH</c></tag>
- <item>The remote host <c>node</c> is unreachable.</item>
- <tag><c>ENOMEM</c></tag>
- <item>No more memory is available.</item>
- <tag><c>EIO</c></tag>
- <item>I/O error.</item>
- </taglist>
- <p>Also, <c>errno</c> values from
- <c>socket</c><em>(2)</em> and
- <c>connect</c><em>(2)</em>
- system calls can be propagated into <c>erl_errno</c>.</p>
- <p><em>Example:</em></p>
- <code type="none"><![CDATA[
-#define NODE "madonna@chivas.du.etx.ericsson.se"
-#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 since=""><ret>int</ret><nametext>erl_connect_init(number, cookie, creation)</nametext></name>
- <name since=""><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>Initializes the <c>erl_connect</c> module.
- In particular, these functions 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 <c>erl_connect</c>
- module are used.</p>
- <p><c>erl_connect_xinit()</c> stores for later use
- information about:</p>
- <list type="bulleted">
- <item>Hostname of the node, <c>host</c></item>
- <item>Alivename, <c>alive</c></item>
- <item>Node name, <c>node</c></item>
- <item>IP address, <c>addr</c></item>
- <item>Cookie, <c>cookie</c></item>
- <item>Creation number, <c>creation</c></item>
- </list>
- <p><c>erl_connect_init()</c>
- provides an alternative interface that does not require as much
- information from the caller. Instead,
- <c>erl_connect_init()</c>
- uses <c>gethostbyname()</c> to obtain default values.</p>
- <p>If you use <c>erl_connect_init()</c>, your node will
- have a short name, that is, it will not be fully qualified. If you
- need to use fully qualified (long) names, use
- <c>erl_connect_xinit()</c> instead.</p>
- <list type="bulleted">
- <item>
- <p><c>host</c> is the name of the host on which the node
- is running.</p>
- </item>
- <item>
- <p><c>alive</c> is the alivename of the node.</p>
- </item>
- <item>
- <p><c>node</c> is the node name. It is to
- be of the form <em>alivename@hostname</em>.</p>
- </item>
- <item>
- <p><c>addr</c> is the 32-bit IP address of
- <c>host</c>.</p>
- </item>
- <item>
- <p><c>cookie</c> is the authorization string required
- for access to the remote node. If <c>NULL</c>, the user
- <c>HOME</c> directory is searched for a cookie file
- <c>.erlang.cookie</c>. The path to
- the home directory is retrieved from environment variable
- <c>HOME</c> on Unix and from the
- <c>HOMEDRIVE</c> and
- <c>HOMEPATH</c> variables on Windows. For more
- details, see the <seealso marker="kernel:auth">
- <c>auth</c></seealso> module in Kernel.</p>
- </item>
- <item>
- <p><c>creation</c> helps identifying 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>
- </item>
- </list>
- <p>A C-node acting as a server is assigned a creation number
- when it calls <c>erl_publish()</c>.</p>
- <p><c>number</c> is used by
- <c>erl_connect_init()</c> to
- construct the actual node name. In Example 2
- below, <em>"c17@a.DNS.name"</em> is the resulting node name.</p>
- <p><em>Example 1:</em></p>
- <code type="none"><![CDATA[
-struct in_addr addr;
-addr = inet_addr("150.236.14.75");
-if (!erl_connect_xinit("chivas",
- "madonna",
- "madonna@chivas.du.etx.ericsson.se",
- &addr;
- "samplecookiestring..."),
- 0)
- erl_err_quit("<ERROR> when initializing !");
- ]]></code>
- <p><em>Example 2:</em></p>
- <code type="none"><![CDATA[
-if (!erl_connect_init(17, "samplecookiestring...", 0))
- erl_err_quit("<ERROR> when initializing !");
- ]]></code>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>int</ret><nametext>erl_publish(port)</nametext></name>
- <fsummary>Publish a node name.</fsummary>
- <type>
- <v>int port;</v>
- </type>
- <desc>
- <p>This function is used by a server process to register
- with the local name server EPMD, thereby allowing
- other processes to send messages by using the registered name.
- Before calling this function, the process should
- have called <c>bind()</c> and <c>listen()</c>
- on an open socket.</p>
- <p><c>port</c> is the local name to register, and is to 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.</p>
- <p>On success, a descriptor connecting the calling process to EPMD is
- returned. On failure, <c>-1</c> is returned and
- <c>erl_errno</c> is set to:</p>
- <taglist>
- <tag><c>EIO</c></tag>
- <item>I/O error.</item>
- </taglist>
- <p>Also, <c>errno</c> values from
- <c>socket</c><em>(2)</em>
- and <c>connect</c><em>(2)</em> system calls can be
- propagated into <c>erl_errno</c>.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><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>Receives a message consisting of a sequence
- of bytes in the Erlang external format.</p>
- <list type="bulleted">
- <item><c>fd</c> is an open descriptor to an Erlang
- connection.</item>
- <item><c>bufp</c> is a buffer large enough to hold the
- expected message.</item>
- <item><c>bufsize</c> indicates the size of
- <c>bufp</c>.</item>
- </list>
- <p>If a <em>tick</em> occurs, that is, the Erlang node on the
- other end of the connection has polled this node to see if it
- is still alive, the function returns <c>ERL_TICK</c> and
- no message is placed in the buffer. Also,
- <c>erl_errno</c> is set to <c>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 sets
- <c>erl_errno</c> to one of:</p>
- <taglist>
- <tag><c>EAGAIN</c></tag>
- <item>Temporary error: Try again.</item>
- <tag><c>EMSGSIZE</c></tag>
- <item>Buffer is too small.</item>
- <tag><c>EIO</c></tag>
- <item>I/O error.</item>
- </taglist>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>int</ret><nametext>erl_receive_msg(fd, bufp, bufsize, emsg)</nametext></name>
- <fsummary>Receive and decode a message.</fsummary>
- <type>
- <v>int fd;</v>
- <v>unsigned char *bufp;</v>
- <v>int bufsize;</v>
- <v>ErlMessage *emsg;</v>
- </type>
- <desc>
- <p>Receives the message into the specified buffer
- and decodes into <c>(ErlMessage *) emsg</c>.</p>
- <list type="bulleted">
- <item><c>fd</c> is an open descriptor to an Erlang
- connection.</item>
- <item><c>bufp</c> is a buffer large enough to hold the
- expected message.</item>
- <item><c>bufsize</c> indicates the size of
- <c>bufp</c>.</item>
- <item>><c>emsg</c> is a pointer to an
- <c>ErlMessage</c> structure
- into which the message will be decoded.
- <c>ErlMessage</c> is defined as follows:</item>
- </list>
- <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>ErlMessage</c> has changed since
- earlier versions of <c>Erl_Interface</c>.</p>
- </note>
- <p><c>type</c> identifies the type of message, one of the
- following:</p>
- <taglist>
- <tag><c>ERL_SEND</c></tag>
- <item>
- <p>An ordinary send operation has occurred and
- <c>emsg->to</c> contains the pid of the recipient.
- The message is in <c>emsg->msg</c>.</p>
- </item>
- <tag><c>ERL_REG_SEND</c></tag>
- <item>
- <p>A registered send operation has occurred and
- <c>emsg->from</c> contains the pid of the sender.
- The message is in <c>emsg->msg</c>.</p>
- </item>
- <tag><c>ERL_LINK</c> or <c>ERL_UNLINK</c>
- </tag>
- <item>
- <p><c>emsg->to</c> and <c>emsg->from</c>
- contain the pids of the sender and recipient of the link or
- unlink. <c>emsg->msg</c> is not used.</p>
- </item>
- <tag><c>ERL_EXIT</c></tag>
- <item>
- <p>A link is broken. <c>emsg->to</c> and
- <c>emsg->from</c> contain the pids of the linked
- processes, and <c>emsg->msg</c> contains the reason
- for the exit.</p>
- </item>
- </taglist>
- <note>
- <p>It is the caller's responsibility to release the
- memory pointed to by <c>emsg->msg</c>,
- <c>emsg->to</c>, and
- <c>emsg->from</c>.</p>
- </note>
- <p>If a <em>tick</em> occurs, that is, the Erlang node on the
- other end of the connection has polled this node to see if it
- is still alive, the function returns <c>ERL_TICK</c>
- indicating that the tick has been received and responded to,
- but no message is placed in the buffer. In this case you
- are to call <c>erl_receive_msg()</c> again.</p>
- <p>On success, the function returns <c>ERL_MSG</c> and the
- <c>Emsg</c> struct is initialized as described above, or
- <c>ERL_TICK</c>, in which case no message is returned. On
- failure, the function returns <c>ERL_ERROR</c> and sets
- <c>erl_errno</c> to one of:</p>
- <taglist>
- <tag><c>EMSGSIZE</c></tag>
- <item>Buffer is too small.</item>
- <tag><c>ENOMEM</c></tag>
- <item>No more memory is available.</item>
- <tag><c>EIO</c></tag>
- <item>I/O error.</item>
- </taglist>
- </desc>
- </func>
-
- <func>
- <name since=""><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>Sends an Erlang term to a registered process.</p>
- <list type="bulleted">
- <item><c>fd</c> is an open descriptor to an Erlang
- connection.</item>
- <item><c>to</c> is a string containing the registered name
- of the intended recipient of the message.</item>
- <item><c>msg</c> is the Erlang term to be sent.</item>
- </list>
- <p>Returns <c>1</c> on success, otherwise <c>0</c>. In
- the latter case <c>erl_errno</c> is set to one of:</p>
- <taglist>
- <tag><c>ENOMEM</c></tag>
- <item>No more memory is available.</item>
- <tag><c>EIO</c></tag>
- <item>I/O error.</item>
- </taglist>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>ETERM *</ret><nametext>erl_rpc(fd, mod, fun, args)</nametext></name>
- <name since=""><ret>int</ret><nametext>erl_rpc_from(fd, timeout, emsg)</nametext></name>
- <name since=""><ret>int</ret><nametext>erl_rpc_to(fd, mod, fun, args)</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>Supports calling Erlang functions on remote nodes.
- <c>erl_rpc_to()</c> sends an RPC request to a remote node
- and <c>erl_rpc_from()</c> receives the results of such a
- call. <c>erl_rpc()</c> combines the functionality of
- these two functions by sending an RPC request and waiting for the
- results. See also <seealso marker="kernel:rpc#call/4">
- <c>rpc:call/4</c></seealso> in <c>Kernel</c>.</p>
- <list type="bulleted">
- <item><c>fd</c> is an open descriptor to an Erlang
- connection.</item>
- <item><c>timeout</c> is the maximum time (in milliseconds)
- to wait for
- results. To wait forever, specify <c>ERL_NO_TIMEOUT</c>.
- When <c>erl_rpc()</c> calls <c>erl_rpc_from()</c>, the call will
- never timeout.</item>
- <item><c>mod</c> is the name of the module containing the
- function to be run on the remote node.</item>
- <item><c>fun</c> is the name of the function to run.
- </item>
- <item><c>args</c> is an Erlang list, containing the
- arguments to be passed to the function.</item>
- <item><c>emsg</c> is a message containing the result of
- the function call.</item>
- </list>
- <p>The actual message returned by the RPC server
- is a 2-tuple <c>{rex,Reply}</c>. If you use
- <c>erl_rpc_from()</c> in your code, this is the message
- you will need to parse. If you use <c>erl_rpc()</c>, the
- tuple itself is parsed for you, and the message returned to your
- program is the Erlang term containing <c>Reply</c> only.
- Replies to RPC requests are always <c>ERL_SEND</c> messages.</p>
- <note>
- <p>It is the caller's responsibility to free the returned
- <c>ETERM</c> structure and the memory pointed to by
- <c>emsg->msg</c> and <c>emsg->to</c>.</p>
- </note>
- <p><c>erl_rpc()</c> returns the remote function's return
- value on success, otherwise <c>NULL</c>.</p>
- <p><c>erl_rpc_to()</c> returns <c>0</c> on
- success, otherwise a negative number.</p>
- <p><c>erl_rcp_from()</c> returns <c>ERL_MSG</c>
- on success (with <c>Emsg</c> now
- containing the reply tuple), otherwise one of
- <c>ERL_TICK</c>, <c>ERL_TIMEOUT</c>, or
- <c>ERL_ERROR</c>.</p>
- <p>When failing,
- all three functions set <c>erl_errno</c> to one of:</p>
- <taglist>
- <tag><c>ENOMEM</c></tag>
- <item>No more memory is available.</item>
- <tag><c>EIO</c></tag>
- <item>I/O error.</item>
- <tag><c>ETIMEDOUT</c></tag>
- <item>Timeout has expired.</item>
- <tag><c>EAGAIN</c></tag>
- <item>Temporary error: Try again.</item>
- </taglist>
- </desc>
- </func>
-
- <func>
- <name since=""><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>Sends an Erlang term to a process.</p>
- <list type="bulleted">
- <item><c>fd</c> is an open descriptor to an Erlang
- connection.</item>
- <item><c>to</c> is an Erlang term containing the pid of
- the intended recipient of the message.</item>
- <item>><c>msg</c> is the Erlang term to be sent.</item>
- </list>
- <p>Returns <c>1</c> on success, otherwise <c>0</c>. In
- the latter case <c>erl_errno</c> is set to one of:</p>
- <taglist>
- <tag><c>EINVAL</c></tag>
- <item>Invalid argument: <c>to</c> is not a valid Erlang
- pid.</item>
- <tag><c>ENOMEM</c></tag>
- <item>No more memory is available.</item>
- <tag><c>EIO</c></tag>
- <item>I/O error.</item>
- </taglist>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>const char *</ret><nametext>erl_thisalivename()</nametext></name>
- <name since=""><ret>const char *</ret><nametext>erl_thiscookie()</nametext></name>
- <name since=""><ret>short</ret><nametext>erl_thiscreation()</nametext></name>
- <name since=""><ret>const char *</ret><nametext>erl_thishostname()</nametext></name>
- <name since=""><ret>const char *</ret><nametext>erl_thisnodename()</nametext></name>
- <fsummary>Retrieve some values.</fsummary>
- <desc>
- <p>Retrieves information about
- the C-node. These values are initially set with
- <c>erl_connect_init()</c> or
- <c>erl_connect_xinit()</c>.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>int</ret><nametext>erl_unpublish(alive)</nametext></name>
- <fsummary>Forcefully 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 from EPMD on the local host. This is, however, usually
- not allowed, unless EPMD was started with flag
- <c>-relaxed_command_check</c>, which it normally is not.</p>
- <p>To unregister a node you have published, you should instead
- close the descriptor that was returned by
- <c>ei_publish()</c>.</p>
- <warning>
- <p>This function is deprecated and will be removed in a future
- release.</p>
- </warning>
- <p><c>alive</c> is the name of the node to unregister, that
- is, the first component of the node name, without
- <c>@hostname</c>.</p>
- <p>If the node was successfully unregistered from EPMD, <c>0</c> is
- returned, otherwise <c>-1</c> is returned and
- <c>erl_errno</c> is set to <c>EIO</c>.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>int</ret><nametext>erl_xreceive_msg(fd, bufpp, bufsizep, emsg)</nametext></name>
- <fsummary>Receive and decode a message.</fsummary>
- <type>
- <v>int fd;</v>
- <v>unsigned char **bufpp;</v>
- <v>int *bufsizep;</v>
- <v>ErlMessage *emsg;</v>
- </type>
- <desc>
- <p>Similar to <c>erl_receive_msg</c>. The difference is
- that <c>erl_xreceive_msg</c> expects the buffer to
- have been allocated by <c>malloc</c>, and reallocates it
- if the received
- message does not fit into the original buffer. Therefore
- both buffer and buffer length are given as pointers; their values
- can change by the call.</p>
- <p>On success, the function returns <c>ERL_MSG</c> and the
- <c>Emsg</c> struct is initialized as described above, or
- <c>ERL_TICK</c>, in which case no message is returned. On
- failure, the function returns <c>ERL_ERROR</c> and sets
- <c>erl_errno</c> to one of:</p>
- <taglist>
- <tag><c>EMSGSIZE</c></tag>
- <item>Buffer is too small.</item>
- <tag><c>ENOMEM</c></tag>
- <item>No more memory is available.</item>
- <tag><c>EIO</c></tag>
- <item>I/O error.</item>
- </taglist>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>struct hostent *</ret><nametext>erl_gethostbyaddr(addr, length, type)</nametext></name>
- <name since=""><ret>struct hostent *</ret><nametext>erl_gethostbyaddr_r(addr, length, type, hostp, buffer, buflen, h_errnop)</nametext></name>
- <name since=""><ret>struct hostent *</ret><nametext>erl_gethostbyname(name)</nametext></name>
- <name since=""><ret>struct hostent *</ret><nametext>erl_gethostbyname_r(name, 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>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>erl_errno</c></item>
- <item>That the correct cookie was used</item>
- <item>That EPMD is running</item>
- <item>That the remote Erlang node on the other side is running the same
- version of Erlang as the <c>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
deleted file mode 100644
index 6fac94e442..0000000000
--- a/lib/erl_interface/doc/src/erl_error.xml
+++ /dev/null
@@ -1,145 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE cref SYSTEM "cref.dtd">
-
-<cref>
- <header>
- <copyright>
- <year>1996</year><year>2016</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions 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>1996-10-14</date>
- <rev>A</rev>
- <file>erl_error.xml</file>
- </header>
- <lib>erl_error</lib>
- <libsummary>Error print routines.</libsummary>
- <description>
- <p>This module contains some error printing routines taken
- from "Advanced Programming in the UNIX Environment"
- by W. Richard Stevens.</p>
-
- <p>These functions are all called in the same manner as
- <c>printf()</c>, that is, with a string containing format
- specifiers followed by a list of corresponding arguments. All output from
- these functions is to <c>stderr</c>.</p>
- </description>
-
- <funcs>
- <func>
- <name since=""><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>fprintf()</c>.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><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 because of a system call. The message provided by the
- caller is printed and the process terminates with exit
- value <c>1</c>. This function does not return.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><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 since=""><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 exit value <c>1</c>. This function does not
- return.</p>
- </desc>
- </func>
- </funcs>
-
- <section>
- <title>Error Reporting</title>
- <p>Most functions in <c>Erl_Interface</c> report failures to the caller by
- returning some otherwise meaningless value (typically
- <c>NULL</c>
- or a negative number). As this only tells you that things did not
- go well, examine the error code in <c>erl_errno</c> if you
- want to find out more about the failure.</p>
- </section>
-
- <funcs>
- <func>
- <name since=""><ret>volatile int</ret><nametext>erl_errno</nametext></name>
- <fsummary>Variable <c>erl_errno</c> contains the
- Erl_Interface error number. You can change the value if you wish.
- </fsummary>
- <desc>
- <p><c>erl_errno</c> is initially (at program startup) zero
- and is then set by many <c>Erl_Interface</c> functions on failure to
- a non-zero error code to indicate what kind of error it
- encountered. A successful function call can change
- <c>erl_errno</c> (by calling some other function that
- fails), but no function does never set it to zero. This means
- that you cannot use <c>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>NULL</c>), in which case you can examine
- <c>erl_errno</c> for details.</p>
- <p><c>erl_errno</c> uses the error codes defined in your
- system's <c>&lt;errno.h&gt;</c>.</p>
- <note>
- <p><c>erl_errno</c> is a "modifiable lvalue" (just
- like ISO C defines <c>errno</c> to be) rather than a
- variable. This means it can be implemented as a macro
- (expanding to, for example, <c>*_erl_errno()</c>).
- For reasons of thread safety (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
deleted file mode 100644
index 295760b4e6..0000000000
--- a/lib/erl_interface/doc/src/erl_eterm.xml
+++ /dev/null
@@ -1,776 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE cref SYSTEM "cref.dtd">
-
-<cref>
- <header>
- <copyright>
- <year>1996</year><year>2016</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions 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>1998-07-03</date>
- <rev>A</rev>
- <file>erl_eterm.xml</file>
- </header>
- <lib>erl_eterm</lib>
- <libsummary>Functions for Erlang term construction.</libsummary>
- <description>
- <note><p>The support for VxWorks is deprecated as of OTP 22, and
- will be removed in OTP 23.</p></note>
- <note><p>The old legacy <c>erl_interface</c> library (functions
- with prefix <c>erl_</c>) is deprecated as of OTP 22, and will be
- removed in OTP 23. This does not apply to the <c>ei</c>
- library. Reasonably new <c>gcc</c> compilers will issue deprecation
- warnings. In order to disable these warnings, define the macro
- <c>EI_NO_DEPR_WARN</c>.</p></note>
-
- <p>This module provides functions for creating and manipulating
- Erlang terms.</p>
-
- <p>An Erlang term is represented by a C structure of type
- <c>ETERM</c>. Applications should not reference any fields
- in this structure directly, as it can be changed in future releases
- to provide faster and more compact term storage. Instead,
- applications should use the macros and functions provided.</p>
-
- <p>Each of the following macros takes a single <c>ETERM</c> pointer as an
- argument. The macros return a non-zero value if the test is true,
- otherwise <c>0</c>.</p>
-
- <taglist>
- <tag><c>ERL_IS_INTEGER(t)</c></tag>
- <item>True if <c>t</c> is an integer.</item>
- <tag><c>ERL_IS_UNSIGNED_INTEGER(t)</c></tag>
- <item>True if <c>t</c> is an integer.</item>
- <tag><c>ERL_IS_FLOAT(t)</c></tag>
- <item>True if <c>t</c> is a floating point number.</item>
- <tag><c>ERL_IS_ATOM(t)</c></tag>
- <item>True if <c>t</c> is an atom.</item>
- <tag><c>ERL_IS_PID(t)</c></tag>
- <item>True if <c>t</c> is a pid (process identifier).</item>
- <tag><c>ERL_IS_PORT(t)</c></tag>
- <item>True if <c>t</c> is a port.</item>
- <tag><c>ERL_IS_REF(t)</c></tag>
- <item>True if <c>t</c> is a reference.</item>
- <tag><c>ERL_IS_TUPLE(t)</c></tag>
- <item>True if <c>t</c> is a tuple.</item>
- <tag><c>ERL_IS_BINARY(t)</c></tag>
- <item>True if <c>t</c> is a binary.</item>
- <tag><c>ERL_IS_LIST(t)</c></tag>
- <item>True if <c>t</c> is a list with zero or more
- elements.</item>
- <tag><c>ERL_IS_EMPTY_LIST(t)</c></tag>
- <item>True if <c>t</c> is an empty list.</item>
- <tag><c>ERL_IS_CONS(t)</c></tag>
- <item>True if <c>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 <c>ETERM*</c> containing the wrong type. For example,
- passing a tuple to <c>ERL_ATOM_PTR()</c> likely results in garbage.</p>
-
- <taglist>
- <tag><c>char *ERL_ATOM_PTR(t)</c></tag>
- <item></item>
- <tag><c>char *ERL_ATOM_PTR_UTF8(t)</c></tag>
- <item>A string representing atom <c>t</c>.</item>
- <tag><c>int ERL_ATOM_SIZE(t)</c></tag>
- <item></item>
- <tag><c>int ERL_ATOM_SIZE_UTF8(t)</c></tag>
- <item>The length (in bytes) of atom <c>t</c>.</item>
- <tag><c>void *ERL_BIN_PTR(t)</c></tag>
- <item>A pointer to the contents of <c>t</c>.</item>
- <tag><c>int ERL_BIN_SIZE(t)</c></tag>
- <item>The length (in bytes) of binary object <c>t</c>.</item>
- <tag><c>int ERL_INT_VALUE(t)</c></tag>
- <item>The integer of <c>t</c>.</item>
- <tag><c>unsigned int ERL_INT_UVALUE(t)</c></tag>
- <item>The unsigned integer value of <c>t</c>.</item>
- <tag><c>double ERL_FLOAT_VALUE(t)</c></tag>
- <item>The floating point value of <c>t</c>.</item>
- <tag><c>ETERM *ERL_PID_NODE(t)</c></tag>
- <item></item>
- <tag><c>ETERM *ERL_PID_NODE_UTF8(t)</c></tag>
- <item>The node in pid <c>t</c>.</item>
- <tag><c>int ERL_PID_NUMBER(t)</c></tag>
- <item>The sequence number in pid <c>t</c>.</item>
- <tag><c>int ERL_PID_SERIAL(t)</c></tag>
- <item>The serial number in pid <c>t</c>.</item>
- <tag><c>int ERL_PID_CREATION(t)</c></tag>
- <item>The creation number in pid <c>t</c>.</item>
- <tag><c>int ERL_PORT_NUMBER(t)</c></tag>
- <item>The sequence number in port <c>t</c>.</item>
- <tag><c>int ERL_PORT_CREATION(t)</c></tag>
- <item>The creation number in port <c>t</c>.</item>
- <tag><c>ETERM *ERL_PORT_NODE(t)</c></tag>
- <item></item>
- <tag><c>ETERM *ERL_PORT_NODE_UTF8(t)</c></tag>
- <item>The node in port <c>t</c>.</item>
- <tag><c>int ERL_REF_NUMBER(t)</c></tag>
- <item>The first part of the reference number in ref <c>t</c>.
- Use only for compatibility.</item>
- <tag><c>int ERL_REF_NUMBERS(t)</c></tag>
- <item>Pointer to the array of reference numbers in ref
- <c>t</c>.</item>
- <tag><c>int ERL_REF_LEN(t)</c></tag>
- <item>The number of used reference numbers in ref
- <c>t</c>.</item>
- <tag><c>int ERL_REF_CREATION(t)</c></tag>
- <item>The creation number in ref <c>t</c>.</item>
- <tag><c>int ERL_TUPLE_SIZE(t)</c></tag>
- <item>The number of elements in tuple <c>t</c>.</item>
- <tag><c>ETERM *ERL_CONS_HEAD(t)</c></tag>
- <item>The head element of list <c>t</c>.</item>
- <tag><c>ETERM *ERL_CONS_TAIL(t)</c></tag>
- <item>A list representing the tail elements of list
- <c>t</c>.</item>
- </taglist>
- </description>
-
- <funcs>
- <func>
- <name since=""><ret>ETERM *</ret><nametext>erl_cons(head, tail)</nametext></name>
- <fsummary>Prepend a term to the head of a list.</fsummary>
- <type>
- <v>ETERM *head;</v>
- <v>ETERM *tail;</v>
- </type>
- <desc>
- <p>Concatenates two Erlang terms, prepending <c>head</c>
- onto <c>tail</c> and thereby creating a
- <c>cons</c> cell.
- To make a proper list, <c>tail</c> is always to be a list
- or an empty list. Notice that <c>NULL</c> is not a valid list.</p>
- <list type="bulleted">
- <item><c>head</c> is the new term to be added.</item>
- <item><c>tail</c> is the existing list to which
- <c>head</c> is concatenated.</item>
- </list>
- <p>The function returns a new list.</p>
- <p><c>ERL_CONS_HEAD(list)</c> and
- <c>ERL_CONS_TAIL(list)</c>
- can be used to retrieve the head and tail components
- from the list. <c>erl_hd(list)</c> and
- <c>erl_tl(list)</c> do
- the same thing, but check that the argument really is a list.</p>
- <p><em>Example:</em></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 since=""><ret>ETERM *</ret><nametext>erl_copy_term(term)</nametext></name>
- <fsummary>Create a copy of an Erlang term.</fsummary>
- <type>
- <v>ETERM *term;</v>
- </type>
- <desc>
- <p>Creates and returns a copy of the Erlang term
- <c>term</c>.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>ETERM *</ret><nametext>erl_element(position, tuple)</nametext></name>
- <fsummary>Extract an element from an Erlang tuple.</fsummary>
- <type>
- <v>int position;</v>
- <v>ETERM *tuple;</v>
- </type>
- <desc>
- <p>Extracts a specified element from an Erlang tuple.</p>
- <list type="bulleted">
- <item><c>position</c> specifies which element to retrieve
- from <c>tuple</c>. The elements are numbered starting
- from 1.</item>
- <item><c>tuple</c> is an Erlang term containing at least
- <c>position</c> elements.</item>
- </list>
- <p>Returns a new Erlang term corresponding to the requested element, or
- <c>NULL</c> if <c>position</c> was greater
- than the arity of <c>tuple</c>.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>ETERM *</ret><nametext>erl_hd(list)</nametext></name>
- <fsummary>Extract 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>list</c> is an Erlang term containing a list.</p>
- <p>Returns an Erlang term corresponding to the head
- head element in the list, or a <c>NULL</c> pointer if
- <c>list</c> was not a list.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><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>
- <p>This function must be called before any of the others in the
- <c>Erl_Interface</c> library to initialize the
- library functions. The arguments must be specified as
- <c>erl_init(NULL,0)</c>.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>int</ret><nametext>erl_iolist_length(list)</nametext></name>
- <fsummary>Return the length of an I/O list.</fsummary>
- <type>
- <v>ETERM *list;</v>
- </type>
- <desc>
- <p>Returns the length of an I/O list.</p>
- <p><c>list</c> is an Erlang term containing an I/O list.</p>
- <p>Returns the length of <c>list</c>, or
- <c>-1</c> if <c>list</c> is not an I/O list.</p>
- <p>For the definition of an I/O list, see
- <seealso marker="#erl_iolist_to_binary">
- <c>erl_iolist_to_binary</c></seealso>.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>ETERM *</ret><nametext>erl_iolist_to_binary(term)</nametext></name>
- <fsummary>Convert an I/O list to a binary.</fsummary>
- <type>
- <v>ETERM *list;</v>
- </type>
- <desc>
- <p>Converts an I/O list to a binary term.</p>
- <p><c>list</c> is an Erlang term containing a list.</p>
- <p>Returns an Erlang binary term, or <c>NULL</c> if
- <c>list</c> was not an I/O list.</p>
- <p>Informally, an I/O list is a deep list of characters and
- binaries that can be sent to an Erlang port. In BNF, an I/O
- 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 since=""><ret>char *</ret><nametext>erl_iolist_to_string(list)</nametext></name>
- <fsummary>Convert an I/O list to a <c>NULL</c>-terminated string.</fsummary>
- <type>
- <v>ETERM *list;</v>
- </type>
- <desc>
- <p>Converts an I/O list to a <c>NULL</c>-terminated C string.</p>
- <p><c>list</c> is an Erlang term containing an I/O list.
- The I/O list must not contain the integer 0, as C strings may not
- contain this value except as a terminating marker.</p>
- <p>Returns a pointer to a dynamically allocated
- buffer containing a string. If <c>list</c> is not an I/O
- list, or if <c>list</c> contains the integer 0,
- <c>NULL</c> is returned. It
- is the caller's responsibility to free the allocated buffer
- with <c>erl_free()</c>.</p>
- <p>For the definition of an I/O list, see
- <seealso marker="#erl_iolist_to_binary">
- <c>erl_iolist_to_binary</c></seealso>.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>int</ret><nametext>erl_length(list)</nametext></name>
- <fsummary>Determine the length of a list.</fsummary>
- <type>
- <v>ETERM *list;</v>
- </type>
- <desc>
- <p>Determines the length of a proper list.</p>
- <p><c>list</c> is an Erlang term containing a 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 <c>-1</c> if <c>list</c> is not a proper
- list.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>ETERM *</ret><nametext>erl_mk_atom(string)</nametext></name>
- <fsummary>Create an atom.</fsummary>
- <type>
- <v>const char *string;</v>
- </type>
- <desc>
- <p>Creates an atom.</p>
- <p><c>string</c> is the sequence of characters that will be
- used to create the atom.</p>
- <p>Returns an Erlang term containing an atom. Notice that it is
- the caller's responsibility to ensure that <c>string</c>
- contains a valid name for an atom.</p>
- <p><c>ERL_ATOM_PTR(atom)</c> and
- <c>ERL_ATOM_PTR_UTF8(atom)</c>
- can be used to retrieve the atom name (as a <c>NULL</c>-terminated string).
- <c>ERL_ATOM_SIZE(atom)</c>
- and <c>ERL_ATOM_SIZE_UTF8(atom)</c> return the length
- of the atom name.</p>
- <note>
- <p>The UTF-8 variants were introduced in Erlang/OTP R16 and the
- string returned by <c>ERL_ATOM_PTR(atom)</c> was not
- <c>NULL</c>-terminated on older releases.</p>
- </note>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>ETERM *</ret><nametext>erl_mk_binary(bptr, size)</nametext></name>
- <fsummary>Create a binary object.</fsummary>
- <type>
- <v>char *bptr;</v>
- <v>int size;</v>
- </type>
- <desc>
- <p>Produces an Erlang binary object from a
- buffer containing a sequence of bytes.</p>
- <list type="bulleted">
- <item><c>bptr</c> is a pointer to a buffer containing
- data to be converted.</item>
- <item><c>size</c> indicates the length of
- <c>bptr</c>.</item>
- </list>
- <p>Returns an Erlang binary object.</p>
- <p><c>ERL_BIN_PTR(bin)</c> retrieves a pointer to
- the binary data. <c>ERL_BIN_SIZE(bin)</c> retrieves the
- size.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>ETERM *</ret><nametext>erl_mk_empty_list()</nametext></name>
- <fsummary>Create an empty Erlang list.</fsummary>
- <desc>
- <p>Creates and returns an empty Erlang list.
- Notice that <c>NULL</c> is not used to represent an empty list;
- Use this function instead.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>ETERM *</ret><nametext>erl_mk_estring(string, len)</nametext></name>
- <fsummary>Create an Erlang string.</fsummary>
- <type>
- <v>char *string;</v>
- <v>int len;</v>
- </type>
- <desc>
- <p>Creates a list from a sequence of bytes.</p>
- <list type="bulleted">
- <item><c>string</c> is a buffer containing a sequence of
- bytes. The buffer does not need to be <c>NULL</c>-terminated.</item>
- <item><c>len</c> is the length of
- <c>string</c>.</item>
- </list>
- <p>Returns an Erlang list object corresponding to
- the character sequence in <c>string</c>.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>ETERM *</ret><nametext>erl_mk_float(f)</nametext></name>
- <fsummary>Create an Erlang float.</fsummary>
- <type>
- <v>double f;</v>
- </type>
- <desc>
- <p>Creates an Erlang float.</p>
- <p><c>f</c> is a value to be converted to an Erlang
- float.</p>
- <p>Returns an Erlang float object with the value
- specified in <c>f</c> or <c>NULL</c> if
- <c>f</c> is not finite.</p>
- <p><c>ERL_FLOAT_VALUE(t)</c> can be used to retrieve the
- value from an Erlang float.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>ETERM *</ret><nametext>erl_mk_int(n)</nametext></name>
- <fsummary>Create an Erlang integer.</fsummary>
- <type>
- <v>int n;</v>
- </type>
- <desc>
- <p>Creates an Erlang integer.</p>
- <p><c>n</c> is a value to be converted to an Erlang
- integer.</p>
- <p>Returns an Erlang integer object with the
- value specified in <c>n</c>.</p>
- <p><c>ERL_INT_VALUE(t)</c> can be used to retrieve the
- value from an Erlang integer.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>ETERM *</ret><nametext>erl_mk_list(array, arrsize)</nametext></name>
- <fsummary>Create 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>
- <list type="bulleted">
- <item><c>array</c> is an array of Erlang terms.</item>
- <item><c>arrsize</c> is the number of elements in
- <c>array</c>.</item>
- </list>
- <p>The function creates an Erlang list object, whose length
- <c>arrsize</c> and whose elements are taken from the
- terms in <c>array</c>.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>ETERM *</ret><nametext>erl_mk_long_ref(node, n1, n2, n3, creation)</nametext></name>
- <fsummary>Create 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>Creates an Erlang reference, with 82 bits.</p>
- <list type="bulleted">
- <item><c>node</c> is the name of the C-node.</item>
- <item><c>n1</c>, <c>n2</c>, and
- <c>n3</c> can be seen as one big number
- <c>n1*2^64+n2*2^32+n3</c>, which is to be chosen
- uniquely for each reference created for a given C-node.</item>
- <item><c>creation</c> is an arbitrary number.</item>
- </list>
- <p>Notice that <c>n3</c> and <c>creation</c>
- are limited in precision, so only the low 18 and 2 bits of these
- numbers are used.</p>
- <p>Returns an Erlang reference object.</p>
- <p><c>ERL_REF_NODE(ref)</c>,
- <c>ERL_REF_NUMBERS(ref)</c>,
- <c>ERL_REF_LEN(ref)</c>, and
- <c>ERL_REF_CREATION(ref)</c> can be used to retrieve the
- values used to create the reference.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>ETERM *</ret><nametext>erl_mk_pid(node, number, serial, creation)</nametext></name>
- <fsummary>Create 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>Creates an Erlang process identifier (pid). The
- resulting pid can be used by Erlang processes wishing to
- communicate with the C-node.</p>
- <list type="bulleted">
- <item><c>node</c> is the name of the C-node.</item>
- <item><c>number</c>, <c>serial</c>, and
- <c>creation</c> are
- arbitrary numbers. Notice that these are limited in
- precision, so only the low 15, 3, and 2 bits of these numbers
- are used.</item>
- </list>
- <p>Returns an Erlang pid object.</p>
- <p><c>ERL_PID_NODE(pid)</c>,
- <c>ERL_PID_NUMBER(pid)</c>,
- <c>ERL_PID_SERIAL(pid)</c>, and
- <c>ERL_PID_CREATION(pid)</c>
- can be used to retrieve the four values used to create the pid.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>ETERM *</ret><nametext>erl_mk_port(node, number, creation)</nametext></name>
- <fsummary>Create a port identifier.</fsummary>
- <type>
- <v>const char *node;</v>
- <v>unsigned int number;</v>
- <v>unsigned int creation;</v>
- </type>
- <desc>
- <p>Creates an Erlang port identifier.</p>
- <list type="bulleted">
- <item><c>node</c> is the name of the C-node.</item>
- <item><c>number</c> and <c>creation</c> are
- arbitrary numbers. Notice that these are limited in
- precision, so only the low 18 and 2 bits of these numbers
- are used.</item>
- </list>
- <p>Returns an Erlang port object.</p>
- <p><c>ERL_PORT_NODE(port)</c>,
- <c>ERL_PORT_NUMBER(port)</c>,
- and <c>ERL_PORT_CREATION</c> can be used to retrieve the
- three values used to create the port.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>ETERM *</ret><nametext>erl_mk_ref(node, number, creation)</nametext></name>
- <fsummary>Create an old Erlang reference.</fsummary>
- <type>
- <v>const char *node;</v>
- <v>unsigned int number;</v>
- <v>unsigned int creation;</v>
- </type>
- <desc>
- <p>Creates an old Erlang reference, with
- only 18 bits - use <c>erl_mk_long_ref</c> instead.</p>
- <list type="bulleted">
- <item><c>node</c> is the name of the C-node.</item>
- <item><c>number</c> is to be chosen uniquely for each
- reference created for a given C-node.</item>
- <item><c>creation</c> is an arbitrary number.</item>
- </list>
- <p>Notice that <c>number</c> and <c>creation</c>
- are limited in precision, so only the low 18 and 2 bits of these
- numbers are used.</p>
- <p>Returns an Erlang reference object.</p>
- <p><c>ERL_REF_NODE(ref)</c>,
- <c>ERL_REF_NUMBER(ref)</c>, and
- <c>ERL_REF_CREATION(ref)</c> can be used to retrieve the
- three values used to create the reference.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>ETERM *</ret><nametext>erl_mk_string(string)</nametext></name>
- <fsummary>Create a string.</fsummary>
- <type>
- <v>char *string;</v>
- </type>
- <desc>
- <p>Creates a list from a <c>NULL</c>-terminated string.</p>
- <p><c>string</c> is a <c>NULL</c>-terminated sequence of
- characters
- (that is, a C string) from which the list will be created.</p>
- <p>Returns an Erlang list.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>ETERM *</ret><nametext>erl_mk_tuple(array, arrsize)</nametext></name>
- <fsummary>Create 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>
- <list type="bulleted">
- <item><c>array</c> is an array of Erlang terms.</item>
- <item><c>arrsize</c> is the number of elements in
- <c>array</c>.</item>
- </list>
- <p>The function creates an Erlang tuple, whose arity is
- <c>size</c> and whose elements are taken from the terms
- in <c>array</c>.</p>
- <p>To retrieve the size of a tuple, either use function
- <c>erl_size</c> (which checks the type of the
- checked term and works for a binary as well as for a tuple) or
- <c>ERL_TUPLE_SIZE(tuple)</c> returns the arity of a tuple.
- <c>erl_size()</c> does the same thing, but it checks
- that the argument is a tuple.
- <c>erl_element(index,tuple)</c> returns the element
- corresponding to a given position in the tuple.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>ETERM *</ret><nametext>erl_mk_uint(n)</nametext></name>
- <fsummary>Create an unsigned integer.</fsummary>
- <type>
- <v>unsigned int n;</v>
- </type>
- <desc>
- <p>Creates an Erlang unsigned integer.</p>
- <p><c>n</c> is a value to be converted to an Erlang
- unsigned integer.</p>
- <p>Returns an Erlang unsigned integer object with
- the value specified in <c>n</c>.</p>
- <p><c>ERL_INT_UVALUE(t)</c> can be used to retrieve the
- value from an Erlang unsigned integer.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>ETERM *</ret><nametext>erl_mk_var(name)</nametext></name>
- <fsummary>Create an Erlang variable.</fsummary>
- <type>
- <v>char *name;</v>
- </type>
- <desc>
- <p>Creates an unbound Erlang variable. The variable can later be bound
- through pattern matching or assignment.</p>
- <p><c>name</c> specifies a name for the variable.</p>
- <p>Returns an Erlang variable object with the
- name <c>name</c>.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>int</ret><nametext>erl_print_term(stream, term)</nametext></name>
- <fsummary>Print an Erlang term.</fsummary>
- <type>
- <v>FILE *stream;</v>
- <v>ETERM *term;</v>
- </type>
- <desc>
- <p>Prints the specified Erlang term to the specified output stream.</p>
- <list type="bulleted">
- <item><c>stream</c> indicates where the function is to
- send its output.</item>
- <item><c>term</c> is the Erlang term to print.</item>
- </list>
- <p>Returns the number of characters written on success, otherwise a
- negative value.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><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>
- <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 itself.
- For example, <c>Erl_Interface</c> from Erlang/OTP R10
- is not compatible
- with an Erlang emulator from Erlang/OTP R9 by default.</p>
- <p>A call to <c>erl_set_compat_rel(release_number)</c> sets
- the <c>Erl_Interface</c> library in compatibility mode of
- release <c>release_number</c>. Valid range of
- <c>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 function
- <seealso marker="#erl_init">erl_init()</seealso>.</p>
- </note>
- <warning>
- <p>You may run into trouble if this feature is used
- carelessly. Always ensure 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 since=""><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 either the arity of an Erlang tuple or the
- number of bytes in an Erlang binary object.</p>
- <p><c>term</c> is an Erlang tuple or an Erlang binary
- object.</p>
- <p>Returns the size of <c>term</c> as described
- above, or <c>-1</c> if <c>term</c> is not one of the two
- supported types.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>ETERM *</ret><nametext>erl_tl(list)</nametext></name>
- <fsummary>Extract the tail from a list.</fsummary>
- <type>
- <v>ETERM *list;</v>
- </type>
- <desc>
- <p>Extracts the tail from a list.</p>
- <p><c>list</c> is an Erlang term containing a list.</p>
- <p>Returns an Erlang list corresponding to the
- original list minus the first element, or <c>NULL</c> pointer if
- <c>list</c> was not a list.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>ETERM *</ret><nametext>erl_var_content(term, name)</nametext></name>
- <fsummary>Extract the content of a variable.</fsummary>
- <type>
- <v>ETERM *term;</v>
- <v>char *name;</v>
- </type>
- <desc>
- <p>Returns the contents of the specified variable in an Erlang term.</p>
- <list type="bulleted">
- <item><c>term</c> is an Erlang term. In order for this
- function to succeed,
- <c>term</c> must either 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.</item>
- <item><c>name</c> is the name of an Erlang variable.
- </item>
- </list>
- <p>Returns the Erlang object corresponding to the value of
- <c>name</c> in <c>term</c>. If no variable
- with the name <c>name</c> is found in
- <c>term</c>, or if <c>term</c> is
- not a valid Erlang term, <c>NULL</c> 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
deleted file mode 100644
index b5e895c720..0000000000
--- a/lib/erl_interface/doc/src/erl_format.xml
+++ /dev/null
@@ -1,138 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE cref SYSTEM "cref.dtd">
-
-<cref>
- <header>
- <copyright>
- <year>1996</year><year>2016</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions 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>1996-10-16</date>
- <rev>A</rev>
- <file>erl_format.xml</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 since=""><ret>ETERM *</ret><nametext>erl_format(FormatStr, ...)</nametext></name>
- <fsummary>Create an Erlang term.</fsummary>
- <type>
- <v>char *FormatStr;</v>
- </type>
- <desc>
- <p>A general function for creating Erlang terms using
- a format specifier and a corresponding set of arguments, much
- in the way <c>printf()</c> works.</p>
- <p><c>FormatStr</c> is a format specification string.
- The valid format specifiers are as follows:</p>
- <list type="bulleted">
- <item><c>~i</c> - Integer</item>
- <item><c>~f</c> - Floating point</item>
- <item><c>~a</c> - Atom</item>
- <item><c>~s</c> - String</item>
- <item><c>~w</c> - Arbitrary Erlang term</item>
- </list>
- <p>For each format specifier included in <c>FormatStr</c>,
- there must be a corresponding argument following
- <c>FormatStr</c>. An Erlang term is built according to
- <c>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 creates an <c>(ETERM *)</c> structure corresponding
- to the Erlang term
- <c>[{name,madonna},{age,21},{data,[{adr,"E-street",42}]}]</c></p>
- <p>The function returns an Erlang term, or <c>NULL</c> if
- <c>FormatStr</c> does not describe a valid Erlang
- term.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>int</ret><nametext>erl_match(Pattern, Term)</nametext></name>
- <fsummary>Perform 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. For matching rules and more examples, see
- section <seealso marker="doc/reference_manual:patterns">
- Pattern Matching</seealso> in the Erlang Reference Manual.</p>
- <list type="bulleted">
- <item><c>Pattern</c> is an Erlang term, possibly
- containing unbound variables.</item>
- <item><c>Term</c> is an Erlang term that we wish to match
- against <c>Pattern</c>.</item>
- </list>
- <p><c>Term</c> and <c>Pattern</c> are compared
- and any unbound variables in <c>Pattern</c> are bound to
- corresponding values in <c>Term</c>.</p>
- <p>If <c>Term</c> and <c>Pattern</c> can be
- matched, the function returns a non-zero value and binds any unbound
- variables in <c>Pattern</c>. If <c>Term</c>
- and <c>Pattern</c> do
- not match, <c>0</c> is returned. 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>erl_var_content()</c> can be used to retrieve the
- content of any variables bound as a result of a call to
- <c>erl_match()</c>.</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
deleted file mode 100644
index decd66046a..0000000000
--- a/lib/erl_interface/doc/src/erl_interface.xml
+++ /dev/null
@@ -1,637 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>1996</year><year>2016</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions 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>Deprecation and Removal</title>
- <note><p>The support for VxWorks is deprecated as of OTP 22, and
- will be removed in OTP 23.</p></note>
- <note><p>The old legacy <c>erl_interface</c> library (functions
- with prefix <c>erl_</c>) is deprecated as of OTP 22, and will be
- removed in OTP 23. This does not apply to the <c>ei</c>
- library. Reasonably new <c>gcc</c> compilers will issue deprecation
- warnings. In order to disable these warnings, define the macro
- <c>EI_NO_DEPR_WARN</c>.</p></note>
- </section>
-
- <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>erl_interface.h</c> by specifying an appropriate <c>-I</c>
- argument on the command line, or by adding it to the <c>CFLAGS</c>
- definition in your <c>Makefile</c>. The correct value for this path is
- <c>$OTPROOT/lib/erl_interface</c><em>Vsn</em><c>/include</c>, where <c>$OTPROOT</c> is the path
- reported by <c>code:root_dir/0</c> in the above example, and <em>Vsn</em> is
- the version of the Erl_interface application, for example
- <c>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>liberl_interface.a</c> and <c>libei.a</c> with
- <c>-L$OTPROOT/lib/erl_interface-3.2.3/lib</c>, and you will need to specify the
- name of the libraries with <c>-lerl_interface -lei</c>. You can do
- this on the command line or by adding the flags to the <c>LDFLAGS</c>
- definition in your <c>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>libnsl.a</c> and <c>libsocket.a</c> on
- Solaris, or <c>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>_REENTRANT</c> and either <c>STHREADS</c> or
- <c>PTHREADS</c>. The default is to use POSIX threads if
- <c>_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>liberl_interface_st</c> and <c>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>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>erl_init()</c> exactly once to initialize the library.
- <c>erl_init()</c> takes two arguments, however the arguments are no
- longer used by Erl_Interface, and should therefore be specified
- as <c>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>{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>erl_send()</c> and
- <c>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>erl_eterm</c> module for creating Erlang terms</item>
- <item>the <c>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>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>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>erl_free_compound()</c> ensures that the complete term pointed to
- by <c>ep</c> is released. This is necessary, because the pointer from
- the second call to <c>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>ep</c> and <c>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>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>"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>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>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>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>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>erl_connect</c> module for more information.</p>
- <p>After initialization, you set up the connection to the Erlang node.
- Use <c>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="xyz@chivas.du.etx.ericsson.se"; /* An example */
-if ((sockfd = erl_connect(nodename)) < 0)
- erl_err_quit("ERROR: erl_connect failed"); ]]></code>
- <p><c>erl_err_quit()</c> prints the specified string and terminates
- the program. Refer to the Reference Manual, the <c>erl_error()</c>
- function for more information.</p>
- </section>
-
- <section>
- <title>Using EPMD</title>
- <p><c>Epmd</c> is the Erlang Port Mapper Daemon. Distributed Erlang nodes
- register with <c>epmd</c> on the localhost to indicate to other nodes that
- they exist and can accept connections. <c>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>epmd</c> in order to find out the correct
- port number to connect to.</p>
- <p>When you use <c>erl_connect()</c> to connect to an Erlang node, a
- connection is first made to <c>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>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>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>pub</c> is a file descriptor now connected to <c>epmd</c>. <c>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>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>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>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>erl_send()</c></item>
- <item><c>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>erl_receive()</c></item>
- <item><c>erl_receive_msg()</c></item>
- </list>
- <p><c>erl_receive()</c> receives the message into a buffer, while
- <c>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>{Pid, hello_world}</c> is
- sent to a registered process <c>my_server</c>. The message is encoded
- by <c>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>my_server</c> to reply. Refer to the
- Reference Manual, the <c>erl_connect</c> module for more information
- about send primitives.</p>
- </section>
-
- <section>
- <title>Example of Receiving Messages</title>
- <p>In this example <c>{Pid, Something}</c> is received. The
- received Pid is then used to return <c>{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>ERL_TICK</c> message.
- This is done automatically by <c>erl_receive()</c>, however when this
- has occurred <c>erl_receive</c> returns <c>ERL_TICK</c> to the caller
- without storing a message into the <c>ErlMessage</c> structure.</p>
- <p>When a message has been received, it is the caller's responsibility
- to free the received message <c>emsg.msg</c> as well as <c>emsg.to</c>
- or <c>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>erl_connect</c></item>
- <item><c>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>c:c/1</c> is called to compile the specified module on the
- remote node. <c>erl_match()</c> checks that the compilation was
- successful by testing for the expected <c>ok</c>.</p>
- <p>Refer to the Reference Manual, the <c>erl_connect</c> module for
- more information about <c>erl_rpc()</c>, and its companions
- <c>erl_rpc_to()</c> and <c>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>erl_global_names()</c> allocates and returns a buffer containing
- all the names known to global. <c>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>count</c> to determine when the last name is reached.</p>
- <p>It is the caller's responsibility to free the array.
- <c>erl_global_names()</c> allocates the array and all of the strings
- using a single call to <c>malloc()</c>, so <c>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>"schedule"</c> is known to global, an Erlang pid is returned
- that can be used to send messages to the schedule service.
- Additionally, <c>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>erl_connect()</c>.</p>
- <p>Before registering a name, you should already have registered your
- port number with <c>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>erl_accept()</c> to wait for
- incoming connections.</p>
- <p>Do not forget to free <c>pid</c> later with <c>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. <c>NULL</c>-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>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>"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>"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>malloc()</c> (or similar), so that it can later be removed by a
- single call to <c>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>ei_reg_markdirty()</c>, or pass appropriate flags to
- <c>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
deleted file mode 100644
index 6650620064..0000000000
--- a/lib/erl_interface/doc/src/erl_malloc.xml
+++ /dev/null
@@ -1,212 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE cref SYSTEM "cref.dtd">
-
-<cref>
- <header>
- <copyright>
- <year>1996</year><year>2016</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions 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>1998-07-03</date>
- <rev>A</rev>
- <file>erl_malloc.xml</file>
- </header>
- <lib>erl_malloc</lib>
- <libsummary>Memory allocation functions.</libsummary>
- <description>
- <note><p>The support for VxWorks is deprecated as of OTP 22, and
- will be removed in OTP 23.</p></note>
- <note><p>The old legacy <c>erl_interface</c> library (functions
- with prefix <c>erl_</c>) is deprecated as of OTP 22, and will be
- removed in OTP 23. This does not apply to the <c>ei</c>
- library. Reasonably new <c>gcc</c> compilers will issue deprecation
- warnings. In order to disable these warnings, define the macro
- <c>EI_NO_DEPR_WARN</c>.</p></note>
- <p>This module provides functions for allocating and deallocating
- memory.</p>
- </description>
-
- <funcs>
- <func>
- <name since=""><ret>ETERM *</ret><nametext>erl_alloc_eterm(etype)</nametext></name>
- <fsummary>Allocate an ETERM structure.</fsummary>
- <type>
- <v>unsigned char etype;</v>
- </type>
- <desc>
- <p>Allocates an <c>(ETERM)</c> structure.</p>
- <p>Specify <c>etype</c> as one of the following
- constants:</p>
- <list type="bulleted">
- <item><c>ERL_INTEGER</c>
- </item>
- <item><c>ERL_U_INTEGER</c> (unsigned integer)
- </item>
- <item><c>ERL_ATOM</c>
- </item>
- <item><c>ERL_PID</c> (Erlang process identifier)
- </item>
- <item><c>ERL_PORT</c>
- </item>
- <item><c>ERL_REF</c> (Erlang reference)
- </item>
- <item><c>ERL_LIST</c>
- </item>
- <item><c>ERL_EMPTY_LIST</c>
- </item>
- <item><c>ERL_TUPLE</c>
- </item>
- <item><c>ERL_BINARY</c>
- </item>
- <item><c>ERL_FLOAT</c>
- </item>
- <item><c>ERL_VARIABLE</c>
- </item>
- <item><c>ERL_SMALL_BIG</c> (bignum)
- </item>
- <item><c>ERL_U_SMALL_BIG</c> (bignum)
- </item>
- </list>
- <p><c>ERL_SMALL_BIG</c> and
- <c>ERL_U_SMALL_BIG</c> are for
- creating Erlang <c>bignums</c>, which can contain integers
- of any size. The size of an integer in Erlang is machine-dependent,
- but any integer &gt; 2^28 requires a bignum.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>void</ret><nametext>erl_eterm_release(void)</nametext></name>
- <fsummary>Clear the ETERM freelist.</fsummary>
- <desc>
- <p>Clears the freelist, where blocks are placed when they are
- released by <c>erl_free_term()</c> and
- <c>erl_free_compound()</c>.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>void</ret><nametext>erl_eterm_statistics(allocated, freed)</nametext></name>
- <fsummary>Report term allocation statistics.</fsummary>
- <type>
- <v>long *allocated;</v>
- <v>long *freed;</v>
- </type>
- <desc>
- <p>Reports term allocation statistics.</p>
- <p><c>allocated</c> and <c>freed</c> are
- initialized to
- contain information about the fix-allocator used to allocate
- <c>ETERM</c> components.</p>
- <list type="bulleted">
- <item>
- <p><c>allocated</c> is the number of blocks currently
- allocated to <c>ETERM</c> objects.</p>
- </item>
- <item>
- <p><c>freed</c> is the length of the freelist, where
- blocks are placed when they are
- released by <c>erl_free_term()</c> and
- <c>erl_free_compound()</c>.</p>
- </item>
- </list>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>void</ret><nametext>erl_free(ptr)</nametext></name>
- <fsummary>Free some memory.</fsummary>
- <type>
- <v>void *ptr;</v>
- </type>
- <desc>
- <p>Calls the standard
- <c>free()</c> function.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>void</ret><nametext>erl_free_array(array, size)</nametext></name>
- <fsummary>Free an array of ETERM structures.</fsummary>
- <type>
- <v>ETERM **array;</v>
- <v>int size;</v>
- </type>
- <desc>
- <p>Frees an array of Erlang terms.</p>
- <list type="bulleted">
- <item><c>array</c> is an array of ETERM* objects.</item>
- <item><c>size</c> is the number of terms in the array.
- </item>
- </list>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>void</ret><nametext>erl_free_compound(t)</nametext></name>
- <fsummary>Free 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>Erl_Interface</c> functions. However, as many of the
- functions that build new Erlang terms in fact share objects
- with other existing terms, it can be difficult for the
- programmer to maintain pointers to all such terms to
- free them individually.</p>
- <p><c>erl_free_compound()</c> recursively frees all of the
- subterms associated with a specified Erlang term, regardless of
- whether we are still holding pointers to the subterms.</p>
- <p>For an example, see section
- <seealso marker="ei_users_guide#building_terms_and_patterns">Building Terms and Patterns</seealso>
- in the User's Guide.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>void</ret><nametext>erl_free_term(t)</nametext></name>
- <fsummary>Free an ETERM structure.</fsummary>
- <type>
- <v>ETERM *t;</v>
- </type>
- <desc>
- <p>Frees an Erlang term.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>void</ret><nametext>erl_malloc(size)</nametext></name>
- <fsummary>Allocate some memory.</fsummary>
- <type>
- <v>long size;</v>
- </type>
- <desc>
- <p>Calls the standard
- <c>malloc()</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
deleted file mode 100644
index 33d359d871..0000000000
--- a/lib/erl_interface/doc/src/erl_marshal.xml
+++ /dev/null
@@ -1,276 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE cref SYSTEM "cref.dtd">
-
-<cref>
- <header>
- <copyright>
- <year>1996</year><year>2016</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions 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>1998-07-03</date>
- <rev>A</rev>
- <file>erl_marshal.xml</file>
- </header>
- <lib>erl_marshal</lib>
- <libsummary>Encoding and decoding of Erlang terms.</libsummary>
- <description>
- <note><p>The support for VxWorks is deprecated as of OTP 22, and
- will be removed in OTP 23.</p></note>
- <note><p>The old legacy <c>erl_interface</c> library (functions
- with prefix <c>erl_</c>) is deprecated as of OTP 22, and will be
- removed in OTP 23. This does not apply to the <c>ei</c>
- library. Reasonably new <c>gcc</c> compilers will issue deprecation
- warnings. In order to disable these warnings, define the macro
- <c>EI_NO_DEPR_WARN</c>.</p></note>
- <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 since=""><ret>int</ret><nametext>erl_compare_ext(bufp1, bufp2)</nametext></name>
- <fsummary>Compare encoded byte sequences.</fsummary>
- <type>
- <v>unsigned char *bufp1,*bufp2;</v>
- </type>
- <desc>
- <p>Compares two encoded terms.</p>
- <list type="bulleted">
- <item><c>bufp1</c> is a buffer containing an encoded
- Erlang term term1.</item>
- <item><c>bufp2</c> is a buffer containing an encoded
- Erlang term term2.</item>
- </list>
- <p>Returns <c>0</c> if the terms are equal, <c>-1</c> if
- <c>term1</c> &lt; <c>term2</c>, or <c>1</c> if <c>term2</c> &lt;
- <c>term1</c>.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>ETERM *</ret><nametext>erl_decode(bufp)</nametext></name>
- <name since=""><ret>ETERM *</ret><nametext>erl_decode_buf(bufpp)</nametext></name>
- <fsummary>Convert a term from Erlang external format.</fsummary>
- <type>
- <v>unsigned char *bufp;</v>
- <v>unsigned char **bufpp;</v>
- </type>
- <desc>
- <p><c>erl_decode()</c> and
- <c>erl_decode_buf()</c> decode
- the contents of a buffer and return the corresponding
- Erlang term. <c>erl_decode_buf()</c> provides a simple
- mechanism for dealing with several encoded terms stored
- consecutively in the buffer.</p>
- <list type="bulleted">
- <item>
- <p><c>bufp</c> is a pointer to a buffer containing one
- or more encoded Erlang terms.</p>
- </item>
- <item>
- <p><c>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>erl_decode_buf()</c>, <c>bufpp</c> is
- updated so that it points to the next encoded term.</p>
- </item>
- </list>
- <p><c>erl_decode()</c> returns an Erlang term
- corresponding to the contents of <c>bufp</c> on success,
- otherwise <c>NULL</c>. <c>erl_decode_buf()</c>
- returns an Erlang
- term corresponding to the first of the consecutive terms in
- <c>bufpp</c> and moves <c>bufpp</c> forward
- to point to the
- next term in the buffer. On failure, each of the functions
- return <c>NULL</c>.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>int</ret><nametext>erl_encode(term, bufp)</nametext></name>
- <name since=""><ret>int</ret><nametext>erl_encode_buf(term, bufpp)</nametext></name>
- <fsummary>Convert 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>erl_encode()</c> and
- <c>erl_encode_buf()</c> encode
- Erlang terms into external format for storage or transmission.
- <c>erl_encode_buf()</c> provides a simple mechanism for
- encoding several terms consecutively in the same buffer.</p>
- <list type="bulleted">
- <item>
- <p><c>term</c> is an Erlang term to be encoded.</p>
- </item>
- <item>
- <p><c>bufp</c> is a pointer to a buffer containing one or
- more encoded Erlang terms.</p>
- </item>
- <item>
- <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>erl_encode_buf()</c>, <c>bufpp</c> is updated so
- that it points to the
- position for the next encoded term.</p>
- </item>
- </list>
- <p>These functions return the number of bytes written to buffer
- on success, otherwise <c>0</c>.</p>
- <p>Notice that no bounds checking is done on the buffer. It is
- the caller's responsibility to ensure 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>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. Notice that this information is
- implementation-specific, and can change in future versions.
- If you are unsure, use <c>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>Tuples</c></tag>
- <item>Need 5 bytes, plus the space for each element.</item>
- <tag><c>Lists</c></tag>
- <item>Need 5 bytes, plus the space for each element, and 1
- more byte for the empty list at the end.</item>
- <tag><c>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>Integers</c></tag>
- <item>Need 5 bytes.</item>
- <tag><c>Characters</c></tag>
- <item>(Integers &lt; 256) need 2 bytes.</item>
- <tag><c>Floating point numbers</c></tag>
- <item>Need 32 bytes.</item>
- <tag><c>Pids</c></tag>
- <item>Need 10 bytes, plus the space for the node name, which
- is an atom.</item>
- <tag><c>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 is the result calculated
- from the information above, plus 1 more byte for a
- version identifier.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>int</ret><nametext>erl_ext_size(bufp)</nametext></name>
- <fsummary>Count elements in encoded term.</fsummary>
- <type>
- <v>unsigned char *bufp;</v>
- </type>
- <desc>
- <p>Returns the number of elements in an encoded term.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>unsigned char</ret><nametext>erl_ext_type(bufp)</nametext></name>
- <fsummary>Determine type of an encoded byte sequence.</fsummary>
- <type>
- <v>unsigned char *bufp;</v>
- </type>
- <desc>
- <p>Identifies and returns the type of Erlang term encoded
- in a buffer. It skips a trailing <em>magic</em> identifier.</p>
- <p>Returns <c>0</c> if the type cannot be determined or
- one of:</p>
- <list type="bulleted">
- <item><c>ERL_INTEGER</c>
- </item>
- <item><c>ERL_ATOM</c>
- </item>
- <item><c>ERL_PID</c> (Erlang process identifier)
- </item>
- <item><c>ERL_PORT</c>
- </item>
- <item><c>ERL_REF</c> (Erlang reference)
- </item>
- <item><c>ERL_EMPTY_LIST</c>
- </item>
- <item><c>ERL_LIST</c>
- </item>
- <item><c>ERL_TUPLE</c>
- </item>
- <item><c>ERL_FLOAT</c>
- </item>
- <item><c>ERL_BINARY</c>
- </item>
- <item><c>ERL_FUNCTION</c>
- </item>
- </list>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>unsigned char *</ret><nametext>erl_peek_ext(bufp, pos)</nametext></name>
- <fsummary>Step 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, to directly access later term.</p>
- <list type="bulleted">
- <item><c>bufp</c> is a pointer to a buffer containing one
- or more encoded Erlang terms.</item>
- <item><c>pos</c> indicates how many terms to step over in
- the buffer.</item>
- </list>
- <p>Returns a pointer to a subterm that can be
- used in a later call to <c>erl_decode()</c> to retrieve
- the term at that position. If there is no term, or
- <c>pos</c> would exceed the size of the terms in the
- buffer, <c>NULL</c> is returned.</p>
- </desc>
- </func>
-
- <func>
- <name since=""><ret>int</ret><nametext>erl_term_len(t)</nametext></name>
- <fsummary>Determine encoded size of term.</fsummary>
- <type>
- <v>ETERM *t;</v>
- </type>
- <desc>
- <p>Determines the buffer space that would be
- needed by <c>t</c> if it were encoded into Erlang external
- format by <c>erl_encode()</c>.</p>
- <p>Returns the size in bytes.</p>
- </desc>
- </func>
- </funcs>
-</cref>
diff --git a/lib/erl_interface/doc/src/part_erl_interface.xml b/lib/erl_interface/doc/src/part_erl_interface.xml
deleted file mode 100644
index e256cfa193..0000000000
--- a/lib/erl_interface/doc/src/part_erl_interface.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE part SYSTEM "part.dtd">
-
-<part xmlns:xi="http://www.w3.org/2001/XInclude">
- <header>
- <copyright>
- <year>1996</year><year>2016</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions 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/ref_man.xml b/lib/erl_interface/doc/src/ref_man.xml
index a4f947c79f..d00868562f 100644
--- a/lib/erl_interface/doc/src/ref_man.xml
+++ b/lib/erl_interface/doc/src/ref_man.xml
@@ -31,22 +31,10 @@
<description>
<note><p>The support for VxWorks is deprecated as of OTP 22, and
will be removed in OTP 23.</p></note>
- <note><p>The old legacy <c>erl_interface</c> library (functions
- with prefix <c>erl_</c>) is deprecated as of OTP 22, and will be
- removed in OTP 23. This does not apply to the <c>ei</c>
- library. Reasonably new <c>gcc</c> compilers will issue deprecation
- warnings. In order to disable these warnings, define the macro
- <c>EI_NO_DEPR_WARN</c>.</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"/>
+ <xi:include href="ei_global.xml"/>
+ <xi:include href="erl_call_cmd.xml"/>
</application>
diff --git a/lib/erl_interface/doc/src/ref_man_ei.xml b/lib/erl_interface/doc/src/ref_man_ei.xml
deleted file mode 100644
index d8d1deaea1..0000000000
--- a/lib/erl_interface/doc/src/ref_man_ei.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE application SYSTEM "application.dtd">
-
-<application xmlns:xi="http://www.w3.org/2001/XInclude">
- <header>
- <copyright>
- <year>2002</year><year>2016</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions 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>
- <note><p>The support for VxWorks is deprecated as of OTP 22, and
- will be removed in OTP 23.</p></note>
- <note><p>The old legacy <c>erl_interface</c> library (functions
- with prefix <c>erl_</c>) is deprecated as of OTP 22, and will be
- removed in OTP 23. This does not apply to the <c>ei</c>
- library. Reasonably new <c>gcc</c> compilers will issue deprecation
- warnings. In order to disable these warnings, define the macro
- <c>EI_NO_DEPR_WARN</c>.</p></note>
- <note>
- <p>By default, the <c>ei</c> library is only guaranteed
- to be compatible with other Erlang/OTP components from the same
- release as the <c>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
deleted file mode 100644
index 2b69d0fa74..0000000000
--- a/lib/erl_interface/doc/src/ref_man_erl_interface.xml
+++ /dev/null
@@ -1,60 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE application SYSTEM "application.dtd">
-
-<application xmlns:xi="http://www.w3.org/2001/XInclude">
- <header>
- <copyright>
- <year>1996</year><year>2016</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions 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>
- <note><p>The support for VxWorks is deprecated as of OTP 22, and
- will be removed in OTP 23.</p></note>
- <note><p>The old legacy <c>erl_interface</c> library (functions
- with prefix <c>erl_</c>) is deprecated as of OTP 22, and will be
- removed in OTP 23. This does not apply to the <c>ei</c>
- library. Reasonably new <c>gcc</c> compilers will issue deprecation
- warnings. In order to disable these warnings, define the macro
- <c>EI_NO_DEPR_WARN</c>.</p></note>
- <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/include/ei.h b/lib/erl_interface/include/ei.h
index b138118f04..7d96dac560 100644
--- a/lib/erl_interface/include/ei.h
+++ b/lib/erl_interface/include/ei.h
@@ -43,7 +43,7 @@ typedef LONG_PTR ssize_t; /* Sigh... */
#include <stdio.h> /* Need type FILE */
#include <errno.h> /* Need EHOSTUNREACH, ENOMEM, ... */
-#if !(defined(__WIN32__) || defined(_WIN32)) && !defined(VXWORKS) || (defined(VXWORKS) && defined(HAVE_SENS))
+#if !(defined(__WIN32__) || defined(_WIN32))
# include <netdb.h>
#endif
@@ -188,20 +188,20 @@ extern "C" {
* the 'ei' interface as well.... :-(
*/
-#if defined(_REENTRANT) || defined(VXWORKS) || defined(__WIN32__)
+#if defined(_REENTRANT) || defined(__WIN32__)
/* 'erl_errno' as a function return value */
volatile int* __erl_errno_place(void) __attribute__ ((__const__));
#define erl_errno (*__erl_errno_place ())
-#else /* !_REENTRANT && !VXWORKS && !__WIN32__ */
+#else /* !_REENTRANT && !__WIN32__ */
extern volatile int __erl_errno;
#define erl_errno __erl_errno
-#endif /* !_REENTRANT && !VXWORKS && !__WIN32__ */
+#endif /* !_REENTRANT && !__WIN32__ */
/* -------------------------------------------------------------------- */
@@ -323,13 +323,24 @@ typedef struct {
#define EI_SCLBK_FLG_FULL_IMPL (1 << 0)
+/*
+ * HACK: AIX defines many socket functions like accept to be naccept, which
+ * pollutes the global namespace. Set up an ugly ifdef for consumers of this
+ * API here so they get a mangled name for AIX and the sane name elsewhere.
+ */
+#ifdef _AIX
+#define EI_ACCEPT_NAME accept_ei
+#else
+#define EI_ACCEPT_NAME accept
+#endif
+
typedef struct {
int flags;
int (*socket)(void **ctx, void *setup_ctx);
int (*close)(void *ctx);
int (*listen)(void *ctx, void *addr, int *len, int backlog);
- int (*accept)(void **ctx, void *addr, int *len, unsigned tmo);
+ int (*EI_ACCEPT_NAME)(void **ctx, void *addr, int *len, unsigned tmo);
int (*connect)(void *ctx, void *addr, int len, unsigned tmo);
int (*writev)(void *ctx, const void *iov, int iovcnt, ssize_t *len, unsigned tmo);
int (*write)(void *ctx, const char *buf, ssize_t *len, unsigned tmo);
@@ -351,7 +362,7 @@ typedef struct ei_cnode_s {
/* Currently this_ipaddr isn't used */
/* struct in_addr this_ipaddr; */
char ei_connect_cookie[EI_MAX_COOKIE_SIZE+1];
- short creation;
+ unsigned int creation;
erlang_pid self;
ei_socket_callbacks *cbs;
void *setup_context;
@@ -393,8 +404,12 @@ int ei_connect_xinit_ussi(ei_cnode* ec, const char *thishostname,
int ei_connect(ei_cnode* ec, char *nodename);
int ei_connect_tmo(ei_cnode* ec, char *nodename, unsigned ms);
+int ei_connect_host_port(ei_cnode* ec, char *hostname, int port);
+int ei_connect_host_port_tmo(ei_cnode* ec, char *hostname, int port, unsigned ms);
int ei_xconnect(ei_cnode* ec, Erl_IpAddr adr, char *alivename);
int ei_xconnect_tmo(ei_cnode* ec, Erl_IpAddr adr, char *alivename, unsigned ms);
+int ei_xconnect_host_port(ei_cnode* ec, Erl_IpAddr adr, int port);
+int ei_xconnect_host_port_tmo(ei_cnode* ec, Erl_IpAddr adr, int port, unsigned ms);
int ei_receive(int fd, unsigned char *bufp, int bufsize);
int ei_receive_tmo(int fd, unsigned char *bufp, int bufsize, unsigned ms);
@@ -444,41 +459,6 @@ int ei_get_tracelevel(void);
* We have erl_gethost*() so we include ei versions as well.
*/
-#if defined(VXWORKS)
-
-extern int h_errno;
-
-/*
- * We need these definitions - if the user has SENS then he gets them
- * from netdb.h, otherwise we define them ourselves.
- *
- * If you are getting "multiple definition" errors here,
- * make sure you have included <netdb.h> BEFORE "erl_interface.h"
- * or define HAVE_SENS in your CFLAGS.
- */
-
-#if !defined(HAVE_SENS) && !defined(HOST_NOT_FOUND) /* just in case */
-
-struct hostent {
- char *h_name; /* official name of host */
- char **h_aliases; /* alias list */
- int h_addrtype; /* host address type */
- int h_length; /* length of address */
- char **h_addr_list; /* list of addresses from name server */
-#define h_addr h_addr_list[0] /* address, for backward compatiblity */
- unsigned int unused; /* SENS defines this as ttl */
-};
-
-#define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */
-#define TRY_AGAIN 2 /* Non-Authoritive Host not found, or SERVERFAIL */
-#define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
-#define NO_DATA 4 /* Valid name, no data record of requested type */
-#define NO_ADDRESS NO_DATA /* no address, look for MX record */
-
-#endif /* !HAVE_SENS && !HOST_NOT_FOUND */
-#endif /* VXWORKS */
-
-
struct hostent *ei_gethostbyname(const char *name);
struct hostent *ei_gethostbyaddr(const char *addr, int len, int type);
struct hostent *ei_gethostbyname_r(const char *name,
@@ -537,8 +517,6 @@ int ei_encode_port(char *buf, int *index, const erlang_port *p);
int ei_x_encode_port(ei_x_buff* x, const erlang_port *p);
int ei_encode_ref(char *buf, int *index, const erlang_ref *p);
int ei_x_encode_ref(ei_x_buff* x, const erlang_ref *p);
-int ei_encode_term(char *buf, int *index, void *t) EI_DEPRECATED_ATTR;
-int ei_x_encode_term(ei_x_buff* x, void* t) EI_DEPRECATED_ATTR;
int ei_encode_trace(char *buf, int *index, const erlang_trace *p);
int ei_x_encode_trace(ei_x_buff* x, const erlang_trace *p);
int ei_encode_tuple_header(char *buf, int *index, int arity);
@@ -586,7 +564,6 @@ void free_fun(erlang_fun* f);
int ei_decode_pid(const char *buf, int *index, erlang_pid *p);
int ei_decode_port(const char *buf, int *index, erlang_port *p);
int ei_decode_ref(const char *buf, int *index, erlang_ref *p);
-int ei_decode_term(const char *buf, int *index, void *t) EI_DEPRECATED_ATTR;
int ei_decode_trace(const char *buf, int *index, erlang_trace *p);
int ei_decode_tuple_header(const char *buf, int *index, int *arity);
int ei_decode_list_header(const char *buf, int *index, int *arity);
@@ -802,6 +779,13 @@ int ei_reg_dump(int fd, ei_reg *reg, const char *mntab, int flags);
int ei_reg_restore(int fd, ei_reg *reg, const char *mntab);
int ei_reg_purge(ei_reg *reg);
+/* -------------------------------------------------------------------- */
+/* The ei_global functions */
+/* -------------------------------------------------------------------- */
+char **ei_global_names(ei_cnode *ec, int fd, int *count);
+int ei_global_whereis(ei_cnode *ec, int fd, const char *name, erlang_pid* pid, char *node);
+int ei_global_register(int fd, const char *name, erlang_pid *self);
+int ei_global_unregister(ei_cnode *ec, int fd, const char *name);
/* -------------------------------------------------------------------- */
/* Encoding/decoding bugnums to GNU MP format */
@@ -832,14 +816,12 @@ int ei_x_encode_bignum(ei_x_buff *x, mpz_t obj);
#define EI_ULONGLONG unsigned long long
#endif
-#ifndef VXWORKS
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);
-#endif
#ifdef USE_EI_UNDOCUMENTED
diff --git a/lib/erl_interface/src/legacy/erl_global.h b/lib/erl_interface/include/ei_global.h
index d2eec08b35..b85a31217d 100644
--- a/lib/erl_interface/src/legacy/erl_global.h
+++ b/lib/erl_interface/include/ei_global.h
@@ -17,12 +17,13 @@
*
* %CopyrightEnd%
*/
-#ifndef _ERL_GLOBAL_H
-#define _ERL_GLOBAL_H
+#ifndef _EI_GLOBAL_H
+#define _EI_GLOBAL_H
+#include "ei.h"
-char **erl_global_names(int fd, int *count);
-ETERM *erl_global_whereis(int fd, const char *name, char *node);
-int erl_global_register(int fd, const char *name, ETERM *pid);
-int erl_global_unregister(int fd, const char *name);
+char **ei_global_names(ei_cnode *ec, int fd, int *count);
+int ei_global_whereis(ei_cnode *ec, int fd, const char *name, erlang_pid* pid, char *node);
+int ei_global_register(int fd, const char *name, erlang_pid *self);
+int ei_global_unregister(ei_cnode *ec, int fd, const char *name);
-#endif /* _ERL_GLOBAL_H */
+#endif /* _EI_GLOBAL_H */
diff --git a/lib/erl_interface/include/erl_interface.h b/lib/erl_interface/include/erl_interface.h
deleted file mode 100644
index 7c87223a38..0000000000
--- a/lib/erl_interface/include/erl_interface.h
+++ /dev/null
@@ -1,473 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-#ifndef _ERL_INTERFACE_H
-#define _ERL_INTERFACE_H
-
-/************************************************************************/
-/* This file defines the complete interface to erl_interface */
-/* Note: the 'ei' interface is the prefered C API. */
-/************************************************************************/
-
-#include "ei.h" /* ei is the base */
-
-/* -------------------------------------------------------------------- */
-/* Public defines */
-/* -------------------------------------------------------------------- */
-
-#define ERL_COMPOUND (1 << 7)
-
-#define ERL_UNDEF 0
-#define ERL_INTEGER 1
-#define ERL_U_INTEGER 2 /* unsigned int */
-#define ERL_ATOM 3
-#define ERL_PID 4
-#define ERL_PORT 5
-#define ERL_REF 6
-#define ERL_CONS (7 | ERL_COMPOUND)
-#define ERL_LIST ERL_CONS
-#define ERL_NIL 8
-#define ERL_EMPTY_LIST ERL_NIL
-#define ERL_TUPLE (9 | ERL_COMPOUND)
-#define ERL_BINARY 10
-#define ERL_FLOAT 11
-#define ERL_VARIABLE (12 | ERL_COMPOUND) /* used in patterns */
-#define ERL_SMALL_BIG 13
-#define ERL_U_SMALL_BIG 14
-#define ERL_FUNCTION (15 | ERL_COMPOUND)
-#define ERL_BIG 16
-#define ERL_LONGLONG 17
-#define ERL_U_LONGLONG 18
-
-
-#define ERL_TYPE(x) (ERL_HEADER(x)->type)
-
-/* FIXME some macros left in erl_eterm.h should probably be documented */
-
-#define ERL_IS_INTEGER(x) (ERL_TYPE(x) == ERL_INTEGER)
-#define ERL_IS_UNSIGNED_INTEGER(x) (ERL_TYPE(x) == ERL_U_INTEGER)
-#define ERL_IS_LONGLONG(x) (ERL_TYPE(x) == ERL_LONGLONG)
-#define ERL_IS_UNSIGNED_LONGLONG(x) (ERL_TYPE(x) == ERL_U_LONGLONG)
-#define ERL_IS_FLOAT(x) (ERL_TYPE(x) == ERL_FLOAT)
-#define ERL_IS_ATOM(x) (ERL_TYPE(x) == ERL_ATOM)
-#define ERL_IS_PID(x) (ERL_TYPE(x) == ERL_PID)
-#define ERL_IS_PORT(x) (ERL_TYPE(x) == ERL_PORT)
-#define ERL_IS_REF(x) (ERL_TYPE(x) == ERL_REF)
-#define ERL_IS_TUPLE(x) (ERL_TYPE(x) == ERL_TUPLE)
-#define ERL_IS_BINARY(x) (ERL_TYPE(x) == ERL_BINARY)
-#define ERL_IS_NIL(x) (ERL_TYPE(x) == ERL_NIL)
-#define ERL_IS_EMPTY_LIST(x) ERL_IS_NIL(x)
-#define ERL_IS_CONS(x) (ERL_TYPE(x) == ERL_CONS)
-#define ERL_IS_LIST(x) (ERL_IS_CONS(x) || ERL_IS_EMPTY_LIST(x))
-
-/*
- * Macros used for XXXX
- */
-
-#define ERL_HEADER(x) ((Erl_Header *)x)
-#define ERL_COUNT(x) (ERL_HEADER(x)->count)
-
-/*
- * Macros used for retrieving values from Erlang terms.
- */
-
-#define ERL_INT_VALUE(x) ((x)->uval.ival.i)
-#define ERL_INT_UVALUE(x) ((x)->uval.uival.u)
-#define ERL_LL_VALUE(x) ((x)->uval.llval.i)
-#define ERL_LL_UVALUE(x) ((x)->uval.ullval.u)
-
-#define ERL_FLOAT_VALUE(x) ((x)->uval.fval.f)
-
-#define ERL_ATOM_PTR(x) erl_atom_ptr_latin1((Erl_Atom_data*) &(x)->uval.aval.d)
-#define ERL_ATOM_PTR_UTF8(x) erl_atom_ptr_utf8((Erl_Atom_data*) &(x)->uval.aval.d)
-#define ERL_ATOM_SIZE(x) erl_atom_size_latin1((Erl_Atom_data*) &(x)->uval.aval.d)
-#define ERL_ATOM_SIZE_UTF8(x) erl_atom_size_utf8((Erl_Atom_data*) &(x)->uval.aval.d)
-
-#define ERL_PID_NODE(x) erl_atom_ptr_latin1((Erl_Atom_data*) &(x)->uval.pidval.node)
-#define ERL_PID_NODE_UTF8(x) erl_atom_ptr_utf8((Erl_Atom_data*) &(x)->uval.pidval.node)
-#define ERL_PID_NUMBER(x) ((x)->uval.pidval.number)
-#define ERL_PID_SERIAL(x) ((x)->uval.pidval.serial)
-#define ERL_PID_CREATION(x) ((x)->uval.pidval.creation)
-
-#define ERL_PORT_NODE(x) erl_atom_ptr_latin1((Erl_Atom_data*) &(x)->uval.portval.node)
-#define ERL_PORT_NODE_UTF8(x) erl_atom_ptr_utf8((Erl_Atom_data*) &(x)->uval.portval.node)
-#define ERL_PORT_NUMBER(x) ((x)->uval.portval.number)
-#define ERL_PORT_CREATION(x) ((x)->uval.portval.creation)
-
-#define ERL_REF_NODE(x) erl_atom_ptr_latin1((Erl_Atom_data*) &(x)->uval.refval.node)
-#define ERL_REF_NODE_UTF8(x) erl_atom_ptr_utf8((Erl_Atom_data*) &(x)->uval.refval.node)
-#define ERL_REF_NUMBER(x) ((x)->uval.refval.n[0])
-#define ERL_REF_NUMBERS(x) ((x)->uval.refval.n)
-#define ERL_REF_LEN(x) ((x)->uval.refval.len)
-#define ERL_REF_CREATION(x) ((x)->uval.refval.creation)
-
-#define ERL_TUPLE_SIZE(x) ((x)->uval.tval.size)
-
-/* NOTE!!! This is 0-based!! (first item is number 0)
- * Note too that element/2 (in Erlang) and
- * erl_element() are both 1-based.
- */
-#define ERL_TUPLE_ELEMS(x) ((x)->uval.tval.elems)
-#define ERL_TUPLE_ELEMENT(x, i) (ERL_TUPLE_ELEMS(x)[(i)])
-
-#define ERL_BIN_SIZE(x) ((x)->uval.bval.size)
-#define ERL_BIN_PTR(x) ((x)->uval.bval.b)
-
-#define ERL_CONS_HEAD(x) ((x)->uval.lval.head)
-#define ERL_CONS_TAIL(x) ((x)->uval.lval.tail)
-
-#define ERL_VAR_LEN(x) ((x)->uval.vval.len)
-#define ERL_VAR_NAME(x) ((x)->uval.vval.name)
-#define ERL_VAR_VALUE(x) ((x)->uval.vval.v)
-
-#define ERL_CLOSURE_SIZE(x) ((x)->uval.funcval.size)
-#define ERL_FUN_CREATOR(x) ((x)->uval.funcval.creator)
-#define ERL_FUN_MODULE(x) ((x)->uval.funcval.module)
-#define ERL_FUN_UNIQ(x) ((x)->uval.funcval.uniq)
-#define ERL_FUN_INDEX(x) ((x)->uval.funcval.index)
-#define ERL_FUN_ARITY(x) ((x)->uval.funcval.arity)
-#define ERL_FUN_NEW_INDEX(x) ((x)->uval.funcval.new_index)
-#define ERL_FUN_MD5(x) ((x)->uval.funcval.md5)
-#define ERL_CLOSURE(x) ((x)->uval.funcval.closure)
-#define ERL_CLOSURE_ELEMENT(x,i) (ERL_CLOSURE(x)[(i)])
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* -------------------------------------------------------------------- */
-/* Type definitions of Erlang terms in C */
-/* -------------------------------------------------------------------- */
-
-typedef struct {
- unsigned int count:24; /* reference counter */
- unsigned int type:8; /* type of Erlang term */
-} Erl_Header;
-
-typedef struct {
- Erl_Header h;
- int i;
-} Erl_Integer;
-
-typedef struct {
- Erl_Header h;
- unsigned int u;
-} Erl_Uinteger;
-
-typedef struct {
- Erl_Header h;
- long long i;
-} Erl_LLInteger;
-
-typedef struct {
- Erl_Header h;
- unsigned long long u;
-} Erl_ULLInteger;
-
-typedef struct {
- Erl_Header h;
- double f;
-} Erl_Float;
-
-typedef struct {
- char *utf8;
- int lenU;
- char *latin1;
- int lenL;
-} Erl_Atom_data;
-
-char* erl_atom_ptr_latin1(Erl_Atom_data*) EI_DEPRECATED_ATTR;
-char* erl_atom_ptr_utf8(Erl_Atom_data*) EI_DEPRECATED_ATTR;
-int erl_atom_size_latin1(Erl_Atom_data*) EI_DEPRECATED_ATTR;
-int erl_atom_size_utf8(Erl_Atom_data*) EI_DEPRECATED_ATTR;
-char* erl_atom_init_latin1(Erl_Atom_data*, const char*) EI_DEPRECATED_ATTR;
-
-typedef struct {
- Erl_Header h;
- Erl_Atom_data d;
-} Erl_Atom;
-
-typedef struct {
- Erl_Header h;
- Erl_Atom_data node;
- unsigned int number;
- unsigned int serial;
- unsigned int creation;
-} Erl_Pid;
-
-typedef struct {
- Erl_Header h;
- Erl_Atom_data node;
- unsigned int number;
- unsigned int creation;
-} Erl_Port;
-
-typedef struct {
- Erl_Header h;
- Erl_Atom_data node;
- int len;
- unsigned int n[3];
- unsigned int creation;
-} Erl_Ref;
-
-typedef struct {
- Erl_Header h;
- int arity;
- int is_neg;
- unsigned short *digits;
-} Erl_Big;
-
-struct _eterm; /* forward */
-
-typedef struct {
- Erl_Header h;
- struct _eterm *head;
- struct _eterm *tail;
-} Erl_List;
-
-typedef struct {
- Erl_Header h;
-} Erl_EmptyList;
-
-typedef struct {
- Erl_Header h;
- int size;
- struct _eterm **elems;
-} Erl_Tuple;
-
-typedef struct {
- Erl_Header h;
- int size;
- unsigned char *b;
-} Erl_Binary;
-
-/* Variables may only exist in patterns.
- * Note: identical variable names in a pattern
- * denotes the same value.
- */
-typedef struct {
- Erl_Header h;
- int len;
- char *name;
- struct _eterm *v;
-} Erl_Variable;
-
-
-typedef struct {
- Erl_Header h;
- int size; /* size of closure */
- int arity; /* arity for new (post R7) external funs */
- unsigned char md5[16]; /* md5 for new funs */
- int new_index; /* new funs */
- struct _eterm* creator; /* pid */
- struct _eterm* module; /* module */
- struct _eterm* index;
- struct _eterm* uniq;
- struct _eterm** closure;
-} Erl_Function;
-
-typedef struct _eterm {
- union {
- Erl_Integer ival;
- Erl_Uinteger uival;
- Erl_LLInteger llval;
- Erl_ULLInteger ullval;
- Erl_Float fval;
- Erl_Atom aval;
- Erl_Pid pidval;
- Erl_Port portval;
- Erl_Ref refval;
- Erl_List lval;
- Erl_EmptyList nval;
- Erl_Tuple tval;
- Erl_Binary bval;
- Erl_Variable vval;
- Erl_Function funcval;
- Erl_Big bigval;
- } uval;
-} ETERM;
-
-
-#define MAXREGLEN (255*4) /* max length of registered (atom) name */
-
-typedef struct {
- int type; /* one of the message type constants in eiext.h */
- ETERM *msg; /* the actual message */
- ETERM *from;
- ETERM *to;
- char to_name[MAXREGLEN+1];
-} ErlMessage;
-
-typedef unsigned char Erl_Heap;
-
-
-/* -------------------------------------------------------------------- */
-/* The functions */
-/* -------------------------------------------------------------------- */
-
-void erl_init(void *x, long y) EI_DEPRECATED_ATTR;
-void erl_set_compat_rel(unsigned) EI_DEPRECATED_ATTR;
-int erl_connect_init(int, char*,short) EI_DEPRECATED_ATTR;
-int erl_connect_xinit(char*,char*,char*,struct in_addr*,char*,short) EI_DEPRECATED_ATTR;
-int erl_connect(char*) EI_DEPRECATED_ATTR;
-int erl_xconnect(struct in_addr*,char *) EI_DEPRECATED_ATTR;
-int erl_close_connection(int) EI_DEPRECATED_ATTR;
-int erl_receive(int, unsigned char*, int) EI_DEPRECATED_ATTR;
-int erl_receive_msg(int, unsigned char*, int, ErlMessage*) EI_DEPRECATED_ATTR;
-int erl_xreceive_msg(int, unsigned char**, int*, ErlMessage*) EI_DEPRECATED_ATTR;
-int erl_send(int, ETERM*, ETERM*) EI_DEPRECATED_ATTR;
-int erl_reg_send(int, char*, ETERM*) EI_DEPRECATED_ATTR;
-ETERM *erl_rpc(int,char*,char*,ETERM*) EI_DEPRECATED_ATTR;
-int erl_rpc_to(int,char*,char*,ETERM*) EI_DEPRECATED_ATTR;
-int erl_rpc_from(int,int,ErlMessage*) EI_DEPRECATED_ATTR;
-
-/* erl_publish returns open descriptor on success, or -1 */
-int erl_publish(int port) EI_DEPRECATED_ATTR;
-int erl_accept(int,ErlConnect*) EI_DEPRECATED_ATTR;
-
-const char *erl_thiscookie(void) EI_DEPRECATED_ATTR;
-const char *erl_thisnodename(void) EI_DEPRECATED_ATTR;
-const char *erl_thishostname(void) EI_DEPRECATED_ATTR;
-const char *erl_thisalivename(void) EI_DEPRECATED_ATTR;
-short erl_thiscreation(void) EI_DEPRECATED_ATTR;
-
-/* returns 0 on success, -1 if node not known to epmd or epmd not reached */
-int erl_unpublish(const char *alive) EI_DEPRECATED_ATTR;
-
-#ifdef EI_HAVE_DEPRECATED_ATTR__
-#define EI_DEPR_ATTR_EXTRA , EI_DEPRECATED_ATTR_NAME
-#else
-#define EI_DEPR_ATTR_EXTRA
-#endif
-
-
-/* Report generic error to stderr. */
-void erl_err_msg(const char * __template, ...)
- __attribute__ ((__format__ (printf, 1, 2) EI_DEPR_ATTR_EXTRA)) ;
-/* Report generic error to stderr and die. */
-void erl_err_quit(const char * __template, ...)
- __attribute__ ((__format__ (printf, 1, 2), __noreturn__ EI_DEPR_ATTR_EXTRA));
-/* Report system/libc error to stderr. */
-void erl_err_ret(const char * __template, ...)
- __attribute__ ((__format__ (printf, 1, 2) EI_DEPR_ATTR_EXTRA));
-/* Report system/libc error to stderr and die. */
-void erl_err_sys(const char * __template, ...)
- __attribute__ ((__format__ (printf, 1, 2), __noreturn__ EI_DEPR_ATTR_EXTRA));
-
-ETERM *erl_cons(ETERM*,ETERM*) EI_DEPRECATED_ATTR;
-ETERM *erl_copy_term(const ETERM*) EI_DEPRECATED_ATTR;
-ETERM *erl_element(int,const ETERM*) EI_DEPRECATED_ATTR;
-
-ETERM *erl_hd(const ETERM*) EI_DEPRECATED_ATTR;
-ETERM* erl_iolist_to_binary(const ETERM* term) EI_DEPRECATED_ATTR;
-char* erl_iolist_to_string(const ETERM* term) EI_DEPRECATED_ATTR;
-int erl_iolist_length(const ETERM*) EI_DEPRECATED_ATTR;
-int erl_length(const ETERM*) EI_DEPRECATED_ATTR;
-ETERM *erl_mk_atom(const char*) EI_DEPRECATED_ATTR;
-ETERM *erl_mk_binary(const char*,int) EI_DEPRECATED_ATTR;
-ETERM *erl_mk_empty_list(void) EI_DEPRECATED_ATTR;
-ETERM *erl_mk_estring(const char*, int) EI_DEPRECATED_ATTR;
-ETERM *erl_mk_float(double) EI_DEPRECATED_ATTR;
-ETERM *erl_mk_int(int) EI_DEPRECATED_ATTR;
-ETERM *erl_mk_longlong(long long) EI_DEPRECATED_ATTR;
-ETERM *erl_mk_list(ETERM**,int) EI_DEPRECATED_ATTR;
-ETERM *erl_mk_pid(const char*,unsigned int,unsigned int,unsigned char) EI_DEPRECATED_ATTR;
-ETERM *erl_mk_port(const char*,unsigned int,unsigned char) EI_DEPRECATED_ATTR;
-ETERM *erl_mk_ref(const char*,unsigned int,unsigned char) EI_DEPRECATED_ATTR;
-ETERM *erl_mk_long_ref(const char*,unsigned int,unsigned int,
- unsigned int,unsigned char) EI_DEPRECATED_ATTR;
-ETERM *erl_mk_string(const char*) EI_DEPRECATED_ATTR;
-ETERM *erl_mk_tuple(ETERM**,int) EI_DEPRECATED_ATTR;
-ETERM *erl_mk_uint(unsigned int) EI_DEPRECATED_ATTR;
-ETERM *erl_mk_ulonglong(unsigned long long) EI_DEPRECATED_ATTR;
-ETERM *erl_mk_var(const char*) EI_DEPRECATED_ATTR;
-int erl_print_term(FILE*,const ETERM*) EI_DEPRECATED_ATTR;
-/* int erl_sprint_term(char*,const ETERM*) EI_DEPRECATED_ATTR; */
-int erl_size(const ETERM*) EI_DEPRECATED_ATTR;
-ETERM *erl_tl(const ETERM*) EI_DEPRECATED_ATTR;
-ETERM *erl_var_content(const ETERM*, const char*) EI_DEPRECATED_ATTR;
-
-ETERM *erl_format(char*, ... ) EI_DEPRECATED_ATTR;
-int erl_match(ETERM*, ETERM*) EI_DEPRECATED_ATTR;
-
-char **erl_global_names(int fd, int *count) EI_DEPRECATED_ATTR;
-int erl_global_register(int fd, const char *name, ETERM *pid) EI_DEPRECATED_ATTR;
-int erl_global_unregister(int fd, const char *name) EI_DEPRECATED_ATTR;
-ETERM *erl_global_whereis(int fd, const char *name, char *node) EI_DEPRECATED_ATTR;
-
-void erl_init_malloc(Erl_Heap*,long) EI_DEPRECATED_ATTR;
-ETERM *erl_alloc_eterm(unsigned char) EI_DEPRECATED_ATTR;
-void erl_eterm_release(void) EI_DEPRECATED_ATTR;
-void erl_eterm_statistics(unsigned long*,unsigned long*) EI_DEPRECATED_ATTR;
-void erl_free_array(ETERM**,int) EI_DEPRECATED_ATTR;
-void erl_free_term(ETERM*) EI_DEPRECATED_ATTR;
-void erl_free_compound(ETERM*) EI_DEPRECATED_ATTR;
-void *erl_malloc(long) EI_DEPRECATED_ATTR;
-void erl_free(void*) EI_DEPRECATED_ATTR;
-
-int erl_compare_ext(unsigned char*, unsigned char*) EI_DEPRECATED_ATTR;
-ETERM *erl_decode(unsigned char*) EI_DEPRECATED_ATTR;
-ETERM *erl_decode_buf(unsigned char**) EI_DEPRECATED_ATTR;
-int erl_encode(ETERM*,unsigned char*t) EI_DEPRECATED_ATTR;
-int erl_encode_buf(ETERM*,unsigned char**) EI_DEPRECATED_ATTR;
-int erl_ext_size(unsigned char*) EI_DEPRECATED_ATTR;
-unsigned char erl_ext_type(unsigned char*) EI_DEPRECATED_ATTR; /* Note: returned 'char' before R9C */
-unsigned char *erl_peek_ext(unsigned char*,int) EI_DEPRECATED_ATTR;
-int erl_term_len(ETERM*) EI_DEPRECATED_ATTR;
-
-int cmp_latin1_vs_utf8(const char* sL, int lenL, const char* sU, int lenU) EI_DEPRECATED_ATTR;
-
-/* -------------------------------------------------------------------- */
-/* Wrappers around ei functions */
-/* -------------------------------------------------------------------- */
-
-/*
- * Undocumented before R9C, included for compatibility with old code
- */
-
-struct hostent *erl_gethostbyname(const char *name) EI_DEPRECATED_ATTR;
-struct hostent *erl_gethostbyaddr(const char *addr, int len, int type) EI_DEPRECATED_ATTR;
-struct hostent *erl_gethostbyname_r(const char *name,
- struct hostent *hostp,
- char *buffer,
- int buflen,
- int *h_errnop) EI_DEPRECATED_ATTR;
-struct hostent *erl_gethostbyaddr_r(const char *addr,
- int length,
- int type,
- struct hostent *hostp,
- char *buffer,
- int buflen,
- int *h_errnop) EI_DEPRECATED_ATTR;
-
-/*
- * Undocumented, included for compatibility with old code
- */
-
-void erl_init_resolve(void) EI_DEPRECATED_ATTR;
-int erl_distversion(int fd) EI_DEPRECATED_ATTR;
-int erl_epmd_connect(struct in_addr *inaddr) EI_DEPRECATED_ATTR;
-int erl_epmd_port(struct in_addr *inaddr, const char *alive, int *dist) EI_DEPRECATED_ATTR;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/erl_interface/src/Makefile.in b/lib/erl_interface/src/Makefile.in
index 6e0d3476c7..122cc560cc 100644
--- a/lib/erl_interface/src/Makefile.in
+++ b/lib/erl_interface/src/Makefile.in
@@ -52,9 +52,7 @@ APPUP_FILE= erl_interface.appup
APPUP_SRC= $(APPUP_FILE).src
APPUP_TARGET= $(EBINDIR)/$(APPUP_FILE)
-USING_MINGW=@MIXED_CYGWIN_MINGW@
-USING_MSYS_VC==@MIXED_MSYS_VC@
-USING_CYGWIN_VC==@MIXED_MSYS_VC@
+USING_MINGW=@MIXED_MINGW@
USING_VC=@MIXED_VC@
ifdef TESTROOT
@@ -130,12 +128,7 @@ endif
WARNFLAGS += -DEI_NO_DEPR_WARN
CFLAGS = @LIB_CFLAGS@ $(WARNFLAGS) $(INCFLAGS) $(TYPE_FLAGS)
-PROG_CFLAGS = @CFLAGS@ $(WARNFLAGS) $(INCFLAGS) $(TYPE_FLAGS) -Ilegacy
-
-ifeq ($(findstring vxworks,$(TARGET)),vxworks)
-PROG_CFLAGS += -nostartfiles -Wl,-r,-d
-endif
-
+PROG_CFLAGS = @CFLAGS@ $(WARNFLAGS) $(INCFLAGS) $(TYPE_FLAGS) -Iglobal
INSTALL = @INSTALL@
INSTALL_DIR = @INSTALL_DIR@
@@ -161,7 +154,7 @@ BINDIR = $(ERL_TOP)/lib/erl_interface/bin/$(TARGET)
# -Wno-char-subscripts
# -Wshadow
-vpath %.c connect:encode:decode:misc:epmd:legacy:registry
+vpath %.c connect:encode:decode:misc:epmd:global:registry
###########################################################################
# List targets
@@ -193,17 +186,12 @@ ERL_CALL = $(BINDIR)/erl_call$(EXE)
ifdef THR_DEFS
ST_EILIB = $(OBJDIR)/$(LIBPRE)ei_st$(LIBEXT)
-ST_ERLLIB = $(OBJDIR)/$(LIBPRE)erl_interface_st$(LIBEXT)
MT_EILIB = $(OBJDIR)/$(LIBPRE)ei$(LIBEXT)
-MT_ERLLIB = $(OBJDIR)/$(LIBPRE)erl_interface$(LIBEXT)
else
ST_EILIB = $(OBJDIR)/$(LIBPRE)ei$(LIBEXT)
-ST_ERLLIB = $(OBJDIR)/$(LIBPRE)erl_interface$(LIBEXT)
endif
MD_EILIB = $(OBJDIR)/$(LIBPRE)ei_md$(LIBEXT)
MDD_EILIB = $(OBJDIR)/$(LIBPRE)ei_mdd$(LIBEXT)
-MD_ERLLIB = $(OBJDIR)/$(LIBPRE)erl_interface_md$(LIBEXT)
-MDD_ERLLIB = $(OBJDIR)/$(LIBPRE)erl_interface_mdd$(LIBEXT)
###########################################################################
# Specify targets to build
@@ -225,10 +213,7 @@ TARGETS = \
OBJ_TARGETS = \
$(MT_EILIB) \
$(MD_EILIB) \
- $(MDD_EILIB) \
- $(MT_ERLLIB) \
- $(MD_ERLLIB) \
- $(MDD_ERLLIB)
+ $(MDD_EILIB)
FAKE_TARGETS = \
$(OBJDIR)/erl_fake_prog_mt$(EXE) \
@@ -254,8 +239,7 @@ TARGETS = \
$(APPUP_TARGET)
OBJ_TARGETS = \
- $(MD_EILIB) \
- $(MD_ERLLIB)
+ $(MD_EILIB)
FAKE_TARGETS = \
$(OBJDIR)/erl_fake_prog_md$(EXE) \
@@ -275,9 +259,7 @@ TARGETS = \
OBJ_TARGETS = \
$(ST_EILIB) \
- $(ST_ERLLIB) \
- $(MT_EILIB) \
- $(MT_ERLLIB)
+ $(MT_EILIB)
FAKE_TARGETS = \
$(ST_OBJDIR)/erl_fake_prog_st$(EXE) \
@@ -298,8 +280,7 @@ TARGETS = \
$(APPUP_TARGET)
OBJ_TARGETS = \
- $(ST_EILIB) \
- $(ST_ERLLIB)
+ $(ST_EILIB)
FAKE_TARGETS = \
$(ST_OBJDIR)/erl_fake_prog_st$(EXE) \
@@ -321,8 +302,7 @@ endif
HEADERS = \
../include/ei.h \
../include/ei_connect.h \
- ../include/eicode.h \
- ../include/erl_interface.h
+ ../include/eicode.h
EISOURCES = \
$(CONNECTSRC) \
@@ -330,7 +310,8 @@ EISOURCES = \
$(ENCODESRC) \
$(EPMDSRC) \
$(MISCSRC) \
- $(REGISTRYSRC)
+ $(REGISTRYSRC) \
+ $(GLOBALSOURCES)
CONNECTSRC = \
connect/ei_connect.c \
@@ -363,14 +344,9 @@ DECODESRC = \
decode/decode_version.c \
$(DECODESRC_LONGLONG)
-ifneq ($(findstring vxworks,$(TARGET)),vxworks)
DECODESRC_LONGLONG = \
decode/decode_longlong.c \
decode/decode_ulonglong.c
-else
-DECODESRC_LONGLONG =
-endif
-
ENCODESRC = \
encode/encode_atom.c \
@@ -393,13 +369,9 @@ ENCODESRC = \
encode/encode_version.c \
$(ENCODESRC_LONGLONG)
-ifneq ($(findstring vxworks,$(TARGET)),vxworks)
ENCODESRC_LONGLONG = \
encode/encode_longlong.c \
encode/encode_ulonglong.c
-else
-ENCODESRC_LONGLONG =
-endif
EPMDSRC = \
@@ -457,24 +429,13 @@ REGISTRYSRC = \
registry/reg_stat.c \
registry/reg_tabstat.c
-ERLSOURCES = \
- legacy/decode_term.c \
- legacy/encode_term.c \
- legacy/erl_connect.c \
- legacy/erl_error.c \
- legacy/erl_eterm.c \
- legacy/erl_fix_alloc.c \
- legacy/erl_format.c \
- legacy/erl_malloc.c \
- legacy/erl_marshal.c \
- legacy/erl_resolve.c \
- legacy/erl_timeout.c \
- legacy/global_names.c \
- legacy/global_register.c \
- legacy/global_unregister.c \
- legacy/global_whereis.c
-
-SOURCES = $(EISOURCES) $(ERLSOURCES)
+GLOBALSOURCES = \
+ global/global_names.c \
+ global/global_register.c \
+ global/global_unregister.c \
+ global/global_whereis.c
+
+SOURCES = $(EISOURCES)
NEVERUSED = \
whereis.c \
@@ -491,13 +452,9 @@ ERLCALL = \
# located in the erl_interface library, not ei library.
ST_EIOBJECTS = $(addprefix $(ST_OBJDIR)/,$(notdir $(EISOURCES:.c=.o)))
-ST_ERLOBJECTS = $(addprefix $(ST_OBJDIR)/,$(notdir $(ERLSOURCES:.c=.o)))
MT_EIOBJECTS = $(addprefix $(MT_OBJDIR)/,$(notdir $(EISOURCES:.c=.o)))
-MT_ERLOBJECTS = $(addprefix $(MT_OBJDIR)/,$(notdir $(ERLSOURCES:.c=.o)))
MD_EIOBJECTS = $(addprefix $(MD_OBJDIR)/,$(notdir $(EISOURCES:.c=.o)))
-MD_ERLOBJECTS = $(addprefix $(MD_OBJDIR)/,$(notdir $(ERLSOURCES:.c=.o)))
MDD_EIOBJECTS = $(addprefix $(MDD_OBJDIR)/,$(notdir $(EISOURCES:.c=.o)))
-MDD_ERLOBJECTS = $(addprefix $(MDD_OBJDIR)/,$(notdir $(ERLSOURCES:.c=.o)))
###########################################################################
# Main targets
@@ -513,10 +470,10 @@ docs:
tests:
clean:
- rm -f $(ST_EIOBJECTS) $(ST_ERLOBJECTS) $(ST_EILIB) $(ST_ERLLIB)
- rm -f $(MT_EIOBJECTS) $(MT_ERLOBJECTS) $(MT_EILIB) $(MT_ERLLIB)
- rm -f $(MD_EIOBJECTS) $(MD_ERLOBJECTS) $(MD_EILIB) $(MD_ERLLIB)
- rm -f $(MDD_EIOBJECTS) $(MDD_ERLOBJECTS) $(MDD_EILIB) $(MDD_ERLLIB)
+ rm -f $(ST_EIOBJECTS) $(ST_EILIB)
+ rm -f $(MT_EIOBJECTS) $(MT_EILIB)
+ rm -f $(MD_EIOBJECTS) $(MD_EILIB)
+ rm -f $(MDD_EIOBJECTS) $(MDD_EILIB)
rm -f $(ERL_CALL)
rm -f $(FAKE_TARGETS)
rm -f $(APP_TARGET)
@@ -527,20 +484,6 @@ distclean: clean
###########################################################################
-# FIXME move this VxWorks stuff to configure or something
-###########################################################################
-
-# FIXME depend on $(TARGET)/Makefile ???
-
-ifeq ($(findstring vxworks,$(TARGET)),vxworks)
-$(TARGET)/config.h:
- $(gen_verbose)
- $(V_at)echo "/* Generated by Makefile */" > $@
- $(V_at)echo "#define HAVE_STRERROR 1" >> $@
- $(V_at)echo "#define HAVE_SOCKLEN_T 1" >> $@
-endif
-
-###########################################################################
# Default rules, normal and threaded
###########################################################################
@@ -582,34 +525,18 @@ $(ST_EILIB) : $(ST_EIOBJECTS)
$(V_AR) -out:$@ $(ST_EIOBJECTS)
$(V_RANLIB) $@
-$(ST_ERLLIB) : $(ST_ERLOBJECTS)
- $(V_AR) -out:$@ $(ST_ERLOBJECTS)
- $(V_RANLIB) $@
-
$(MT_EILIB) : $(MT_EIOBJECTS)
$(V_AR) -out:$@ $(MT_EIOBJECTS)
$(V_RANLIB) $@
-$(MT_ERLLIB) : $(MT_ERLOBJECTS)
- $(V_AR) -out:$@ $(MT_ERLOBJECTS)
- $(V_RANLIB) $@
-
$(MD_EILIB) : $(MD_EIOBJECTS)
$(V_AR) -out:$@ $(MD_EIOBJECTS)
$(V_RANLIB) $@
-$(MD_ERLLIB) : $(MD_ERLOBJECTS)
- $(V_AR) -out:$@ $(MD_ERLOBJECTS)
- $(V_RANLIB) $@
-
$(MDD_EILIB) : $(MDD_EIOBJECTS)
$(V_AR) -out:$@ $(MDD_EIOBJECTS)
$(V_RANLIB) $@
-$(MDD_ERLLIB) : $(MDD_ERLOBJECTS)
- $(V_AR) -out:$@ $(MDD_ERLOBJECTS)
- $(V_RANLIB) $@
-
else
# Unix archive creation
@@ -621,12 +548,6 @@ ifdef RANLIB
$(V_RANLIB) $@
endif
-$(ST_ERLLIB) : $(ST_ERLOBJECTS)
- $(V_at)rm -f $@
- $(V_AR) $(AR_FLAGS) $@ $(ST_ERLOBJECTS)
-ifdef RANLIB
- $(V_RANLIB) $@
-endif
$(MT_EILIB) : $(MT_EIOBJECTS)
$(V_at)rm -f $@
@@ -635,13 +556,6 @@ ifdef RANLIB
$(V_RANLIB) $@
endif
-$(MT_ERLLIB) : $(MT_ERLOBJECTS)
- $(V_at)rm -f $@
- $(V_AR) $(AR_FLAGS) $@ $(MT_ERLOBJECTS)
-ifdef RANLIB
- $(V_RANLIB) $@
-endif
-
endif
###########################################################################
@@ -653,17 +567,6 @@ $(ERL_CALL): $(ERLCALL) ../include/ei.h $(MD_EILIB)
$(ld_verbose)$(PURIFY) $(CC) -MD $(PROG_CFLAGS) $(THR_DEFS) -o $@ $(ERLCALL) \
-L$(OBJDIR) -lei_md $(THR_LIBS) $(LIBS) -lsocket
else
-ifeq ($(findstring vxworks,$(TARGET)),vxworks)
-$(ERL_CALL): $(ST_OBJDIR)/erl_call.o $(ST_OBJDIR)/erl_start.o ../include/ei.h $(ST_EILIB)
- $(V_LD) -r -d -o $@ $(ST_OBJDIR)/erl_call.o $(ST_OBJDIR)/erl_start.o -L$(OBJDIR) -lei $(LIBS)
-
-$(ST_OBJDIR)/erl_call.o: prog/erl_call.c
- $(V_CC) $(CFLAGS) -c $< -o $@
-
-$(ST_OBJDIR)/erl_start.o: prog/erl_start.c
- $(V_CC) $(CFLAGS) -c $< -o $@
-
-else
ifdef THR_DEFS
$(ERL_CALL): $(ERLCALL) ../include/ei.h $(MT_EILIB)
$(ld_verbose)$(PURIFY) $(CC) $(PROG_CFLAGS) $(THR_DEFS) $(LDFLAGS) -o $@ $(ERLCALL) \
@@ -674,7 +577,6 @@ $(ERL_CALL): $(ERLCALL) ../include/ei.h $(ST_EILIB)
-L$(OBJDIR) -lei $(LIBS)
endif
endif
-endif
###########################################################################
# Fake application targets used to test header files and linking
@@ -683,7 +585,7 @@ endif
check: $(FAKE_TARGETS)
ifndef THR_DEFS
-$(ST_OBJDIR)/erl_fake_prog_st$(EXE): prog/erl_fake_prog.c $(ST_ERLLIB) $(ST_EILIB)
+$(ST_OBJDIR)/erl_fake_prog_st$(EXE): prog/erl_fake_prog.c $(ST_EILIB)
$(V_CC) $(PROG_CFLAGS) -o $@ $< -L$(OBJDIR) -lerl_interface -lei \
$(LIBS)
@@ -691,7 +593,7 @@ $(ST_OBJDIR)/ei_fake_prog_st$(EXE): prog/ei_fake_prog.c $(ST_EILIB)
$(V_CC) $(PROG_CFLAGS) -o $@ $< -L$(OBJDIR) -lei $(LIBS)
$(ST_OBJDIR)/erl_fake_prog_cxx_st$(EXE): prog/erl_fake_prog.c \
- $(ST_ERLLIB) $(ST_EILIB)
+ $(ST_EILIB)
$(V_CC) $(PROG_CFLAGS) -o $@ -xc++ $< -L$(OBJDIR) \
-lerl_interface -lei $(LIBS)
@@ -700,7 +602,7 @@ $(ST_OBJDIR)/ei_fake_prog_cxx_st$(EXE): prog/ei_fake_prog.c $(ST_EILIB)
else
-$(ST_OBJDIR)/erl_fake_prog_st$(EXE): prog/erl_fake_prog.c $(ST_ERLLIB) $(ST_EILIB)
+$(ST_OBJDIR)/erl_fake_prog_st$(EXE): prog/erl_fake_prog.c $(ST_EILIB)
$(V_CC) $(PROG_CFLAGS) -o $@ $< -L$(OBJDIR) -lerl_interface_st -lei_st \
$(LIBS)
@@ -708,7 +610,7 @@ $(ST_OBJDIR)/ei_fake_prog_st$(EXE): prog/ei_fake_prog.c $(ST_EILIB)
$(V_CC) $(PROG_CFLAGS) -o $@ $< -L$(OBJDIR) -lei_st $(LIBS)
$(ST_OBJDIR)/erl_fake_prog_cxx_st$(EXE): prog/erl_fake_prog.c \
- $(ST_ERLLIB) $(ST_EILIB)
+ $(ST_EILIB)
$(V_CC) $(PROG_CFLAGS) -o $@ -xc++ $< -L$(OBJDIR) \
-lerl_interface_st -lei_st $(LIBS)
@@ -720,7 +622,7 @@ endif
####
$(MT_OBJDIR)/erl_fake_prog_mt$(EXE): prog/erl_fake_prog.c \
- $(MT_ERLLIB) $(MT_EILIB)
+ $(MT_EILIB)
$(V_CC) $(MTFLAG) $(PROG_CFLAGS) $(THR_DEFS) -o $@ $< -L$(OBJDIR) \
-lerl_interface -lei $(THR_LIBS) $(LIBS)
@@ -729,7 +631,7 @@ $(MT_OBJDIR)/ei_fake_prog_mt$(EXE): prog/ei_fake_prog.c $(MT_EILIB)
-L$(OBJDIR) -lei $(THR_LIBS) $(LIBS)
$(MT_OBJDIR)/erl_fake_prog_mt_cxx$(EXE): prog/erl_fake_prog.c \
- $(MT_ERLLIB) $(MT_EILIB)
+ $(MT_EILIB)
$(V_CC) $(MTFLAG) $(PROG_CFLAGS) $(THR_DEFS) -o $@ -xc++ $< \
-L$(OBJDIR) -lerl_interface -lei \
$(THR_LIBS) $(LIBS)
@@ -741,7 +643,7 @@ $(MT_OBJDIR)/ei_fake_prog_mt_cxx$(EXE): prog/ei_fake_prog.c $(MT_EILIB)
####
$(MD_OBJDIR)/erl_fake_prog_md$(EXE): prog/erl_fake_prog.c \
- $(MD_ERLLIB) $(MD_EILIB)
+ $(MD_EILIB)
$(V_CC) -MD $(PROG_CFLAGS) $(THR_DEFS) -o $@ $< -L$(OBJDIR) \
-lerl_interface_r -lei_r $(THR_LIBS) $(LIBS)
@@ -750,7 +652,7 @@ $(MD_OBJDIR)/ei_fake_prog_md$(EXE): prog/ei_fake_prog.c $(MD_EILIB)
-L$(OBJDIR) -lei_r $(THR_LIBS) $(LIBS)
$(MD_OBJDIR)/erl_fake_prog_md_cxx$(EXE): prog/erl_fake_prog.c \
- $(MD_ERLLIB) $(MD_EILIB)
+ $(MD_EILIB)
$(V_CC) -MD $(PROG_CFLAGS) $(THR_DEFS) -o $@ -xc++ $< \
-L$(OBJDIR) -lerl_interface_r -lei_r \
$(THR_LIBS) $(LIBS)
@@ -762,7 +664,7 @@ $(MD_OBJDIR)/ei_fake_prog_md_cxx$(EXE): prog/ei_fake_prog.c $(MD_EILIB)
####
$(MDD_OBJDIR)/erl_fake_prog_mdd$(EXE): prog/erl_fake_prog.c \
- $(MDD_ERLLIB) $(MDD_EILIB)
+ $(MDD_EILIB)
$(V_CC) -MDD $(PROG_CFLAGS) $(THR_DEFS) -o $@ $< -L$(OBJDIR) \
-lerl_interface_r -lei_r $(THR_LIBS) $(LIBS)
@@ -771,7 +673,7 @@ $(MDD_OBJDIR)/ei_fake_prog_mdd$(EXE): prog/ei_fake_prog.c $(MDD_EILIB)
-L$(OBJDIR) -lei_r $(THR_LIBS) $(LIBS)
$(MDD_OBJDIR)/erl_fake_prog_mdd_cxx$(EXE): prog/erl_fake_prog.c \
- $(MDD_ERLLIB) $(MDD_EILIB)
+ $(MDD_EILIB)
$(V_CC) -MDD $(PROG_CFLAGS) $(THR_DEFS) -o $@ -xc++ $< \
-L$(OBJDIR) -lerl_interface_r -lei_r \
$(THR_LIBS) $(LIBS)
@@ -784,32 +686,30 @@ $(MDD_OBJDIR)/ei_fake_prog_mdd_cxx$(EXE): prog/ei_fake_prog.c $(MDD_EILIB)
# Create dependency file using gcc -MM
###########################################################################
+ifneq ($(ERTS_SKIP_DEPEND),true)
depend: $(TARGET)/depend.mk
$(TARGET)/depend.mk: $(TARGET)/config.h
$(gen_verbose)
$(V_colon)echo "Generating dependency file depend.mk..."
@echo "# Generated dependency rules" > $@
- $(V_CC) $(CFLAGS) -MM $(SOURCES) | \
- sed 's&$(TARGET)&\$$\(TARGET\)&g' | \
- sed 's/^.*:/\$$\(ST_OBJDIR\)\/&/' >> $@
- @echo >> $@
- $(V_CC) $(CFLAGS) -MM $(SOURCES) | \
- sed 's&$(TARGET)&\$$\(TARGET\)&g' | \
- sed 's/^.*:/\$$\(MT_OBJDIR\)\/&/' >> $@
- @echo >> $@
- $(V_CC) $(CFLAGS) -MM $(SOURCES) | \
- sed 's&$(TARGET)&\$$\(TARGET\)&g' | \
- sed 's/^.*:/\$$\(MD_OBJDIR\)\/&/' >> $@
- @echo >> $@
- $(V_CC) $(CFLAGS) -MM $(SOURCES) | \
- sed 's&$(TARGET)&\$$\(TARGET\)&g' | \
- sed 's/^.*:/\$$\(MDD_OBJDIR\)\/&/' >> $@
- @echo >> $@
+ $(V_CC) $(CFLAGS) -MM $(SOURCES) | \
+ sed 's&$(TARGET)&\$$\(TARGET\)&g' > $@.$$$$; \
+ sed 's/^.*:/\$$\(ST_OBJDIR\)\/&/' < $@.$$$$ >> $@; \
+ echo >> $@; \
+ sed 's/^.*:/\$$\(MT_OBJDIR\)\/&/' < $@.$$$$ >> $@; \
+ echo >> $@; \
+ sed 's/^.*:/\$$\(MD_OBJDIR\)\/&/' < $@.$$$$ >> $@; \
+ echo >> $@; \
+ sed 's/^.*:/\$$\(MDD_OBJDIR\)\/&/' < $@.$$$$ >> $@; \
+ echo >> $@; \
+ rm -f $@.$$$$
# For some reason this has to be after 'opt' target
-include $(TARGET)/depend.mk
-
+else
+depend:
+endif
# ----------------------------------------------------
# Release Target
# ----------------------------------------------------
@@ -832,7 +732,7 @@ release: opt
$(INSTALL_DIR) "$(RELSYSDIR)/src/decode"
$(INSTALL_DIR) "$(RELSYSDIR)/src/encode"
$(INSTALL_DIR) "$(RELSYSDIR)/src/epmd"
- $(INSTALL_DIR) "$(RELSYSDIR)/src/legacy"
+ $(INSTALL_DIR) "$(RELSYSDIR)/src/global"
$(INSTALL_DIR) "$(RELSYSDIR)/src/misc"
$(INSTALL_DIR) "$(RELSYSDIR)/src/prog"
$(INSTALL_DIR) "$(RELSYSDIR)/src/registry"
@@ -854,7 +754,7 @@ endif
$(INSTALL_DATA) epmd/*.[ch] "$(RELSYSDIR)/src/epmd"
$(INSTALL_DATA) misc/*.[ch] "$(RELSYSDIR)/src/misc"
$(INSTALL_DATA) registry/*.[ch] "$(RELSYSDIR)/src/registry"
- $(INSTALL_DATA) legacy/*.[ch] "$(RELSYSDIR)/src/legacy"
+ $(INSTALL_DATA) global/*.[ch] "$(RELSYSDIR)/src/global"
$(INSTALL_DATA) prog/*.[ch] "$(RELSYSDIR)/src/prog"
release_docs:
diff --git a/lib/erl_interface/src/README b/lib/erl_interface/src/README
index 7591615f78..823575c6b7 100644
--- a/lib/erl_interface/src/README
+++ b/lib/erl_interface/src/README
@@ -21,7 +21,7 @@ The cause of an assertion can be either errors in the application
program (for instance, passing NULL pointers to any function that
expects an ETERM pointer) or in erl_interface itself.
-If you encounter any assertion failures which think you originate in
+If you encounter any assertion failures which you think originate in
erl_interface, I'll need the following information to track it down:
1a) The printout from the assertion, especially filename and line number.
@@ -35,7 +35,7 @@ erl_interface, I'll need the following information to track it down:
Changes in this version
-----------------------
-There is now *one* representation for an empty list, not two as is used
+There is now *one* representation for an empty list, not two as it used
to be. An empty list is represented by the Erl_EmptyList structure.
There are new macros, ERL_IS_EMPTY_LIST(ep), to test for an empty list,
and ERL_IS_CONS(ep) to test for a cons cell (more on that below).
diff --git a/lib/erl_interface/src/connect/ei_connect.c b/lib/erl_interface/src/connect/ei_connect.c
index 96823b4ee7..d97b77d3e8 100644
--- a/lib/erl_interface/src/connect/ei_connect.c
+++ b/lib/erl_interface/src/connect/ei_connect.c
@@ -32,26 +32,7 @@
#include <windows.h>
#include <winbase.h>
-#elif VXWORKS
-#include <vxWorks.h>
-#include <hostLib.h>
-#include <selectLib.h>
-#include <ifLib.h>
-#include <sockLib.h>
-#include <taskLib.h>
-#include <inetLib.h>
-
-#include <unistd.h>
-#include <sys/times.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <timers.h>
-
-#define getpid() taskIdSelf()
-
-#else /* some other unix */
+#else /* some unix */
#include <unistd.h>
#include <sys/times.h>
@@ -106,7 +87,8 @@ int ei_tracelevel = 0;
(offsetof(ei_socket_callbacks, get_fd) \
+ sizeof(int (*)(void *)))
-/* FIXME why not macro? */
+typedef EI_ULONGLONG DistFlags;
+
static char *null_cookie = "";
static int get_cookie(char *buf, int len);
@@ -120,15 +102,17 @@ static int send_status(ei_socket_callbacks *cbs, void *ctx,
int pkt_sz, char *status, unsigned ms);
static int recv_status(ei_socket_callbacks *cbs, void *ctx,
int pkt_sz, unsigned ms);
-static int send_challenge(ei_socket_callbacks *cbs, void *ctx, int pkt_sz,
- char *nodename, unsigned challenge,
- unsigned version, unsigned ms);
+static int send_challenge(ei_cnode *ec, void *ctx, int pkt_sz,
+ unsigned challenge,
+ DistFlags version, unsigned ms);
static int recv_challenge(ei_socket_callbacks *cbs, void *ctx, int pkt_sz,
unsigned *challenge, unsigned *version,
- unsigned *flags, char *namebuf, unsigned ms);
+ DistFlags *flags, char *namebuf, unsigned ms);
static int send_challenge_reply(ei_socket_callbacks *cbs, void *ctx,
int pkt_sz, unsigned char digest[16],
unsigned challenge, unsigned ms);
+static int recv_complement(ei_socket_callbacks *cbs, void *ctx,
+ int pkt_sz, unsigned ms);
static int recv_challenge_reply(ei_socket_callbacks *cbs, void *ctx,
int pkt_sz, unsigned our_challenge,
char cookie[],
@@ -139,12 +123,20 @@ static int send_challenge_ack(ei_socket_callbacks *cbs, void *ctx,
static int recv_challenge_ack(ei_socket_callbacks *cbs, void *ctx,
int pkt_sz, unsigned our_challenge,
char cookie[], unsigned ms);
-static int send_name(ei_socket_callbacks *cbs, void *ctx, int pkt_sz,
- char *nodename, unsigned version, unsigned ms);
-
+static int send_name(ei_cnode *ec, void *ctx, int pkt_sz,
+ unsigned version, unsigned ms);
+static int send_complement(ei_cnode *ec, void *ctx, int pkt_sz,
+ unsigned epmd_says_version, DistFlags her_flags,
+ unsigned ms);
static int recv_name(ei_socket_callbacks *cbs, void *ctx, int pkt_sz,
- unsigned *version, unsigned *flags, char *namebuf,
- unsigned ms);
+ char* send_name_tag, DistFlags *flags,
+ char *namebuf, unsigned ms);
+static int ei_connect_helper(ei_cnode* ec,
+ Erl_IpAddr ip_addr,
+ char *alivename,
+ unsigned ms,
+ int rport,
+ int epmd_says_version);
static struct hostent*
dyn_gethostbyname_r(const char *name, struct hostent *hostp, char **buffer_p,
@@ -659,7 +651,7 @@ int ei_connect_xinit_ussi(ei_cnode* ec, const char *thishostname,
return ERL_ERROR;
}
- ec->creation = creation & 0x3; /* 2 bits */
+ ec->creation = creation;
if (cookie) {
if (strlen(cookie) >= sizeof(ec->ei_connect_cookie)) {
@@ -698,7 +690,7 @@ int ei_connect_xinit_ussi(ei_cnode* ec, const char *thishostname,
strcpy(ec->self.node,thisnodename);
ec->self.num = 0;
ec->self.serial = 0;
- ec->self.creation = creation & 0x3; /* 2 bits */
+ ec->self.creation = creation;
ec->cbs = cbs;
ec->setup_context = setup_context;
@@ -874,78 +866,57 @@ struct hostent *dyn_gethostbyname_r(const char *name,
#endif
}
- /*
- * Set up a connection to a given Node, and
- * interchange hand shake messages with it.
- * Returns a valid file descriptor at success,
- * otherwise a negative error code.
-*/
-int ei_connect_tmo(ei_cnode* ec, char *nodename, unsigned ms)
+/* Finds the the IP address for hostname and saves that IP address at
+ the location that ip_wb points to. Returns a negative error code if
+ the IP address cannot be found for the hostname. */
+static int ip_address_from_hostname(char* hostname,
+ char** buffer_p,
+ size_t buffer_size,
+ Erl_IpAddr* ip_wb)
{
- char *hostname, alivename[BUFSIZ];
struct hostent *hp;
-#if !defined (__WIN32__)
+#ifndef __WIN32__
/* these are needed for the call to gethostbyname_r */
struct hostent host;
- char buffer[1024];
- char *buf = buffer;
int ei_h_errno;
-#endif /* !win32 */
- int res;
-
- if (strlen(nodename) > MAXNODELEN) {
- EI_TRACE_ERR0("ei_connect","Too long nodename");
- return ERL_ERROR;
- }
-
- /* extract the host and alive parts from nodename */
- if (!(hostname = strchr(nodename,'@'))) {
- EI_TRACE_ERR0("ei_connect","Node name has no @ in name");
- return ERL_ERROR;
- } else {
- strncpy(alivename, nodename, hostname - nodename);
- alivename[hostname - nodename] = 0x0;
- hostname++;
- }
-
-#ifndef __WIN32__
- hp = dyn_gethostbyname_r(hostname,&host,&buf,sizeof(buffer),&ei_h_errno);
+ hp = dyn_gethostbyname_r(hostname,&host,buffer_p,buffer_size,&ei_h_errno);
if (hp == NULL) {
char thishostname[EI_MAXHOSTNAMELEN+1];
/* gethostname requies len to be max(hostname) + 1*/
if (gethostname(thishostname,EI_MAXHOSTNAMELEN+1) < 0) {
- EI_TRACE_ERR0("ei_connect_tmo",
+ EI_TRACE_ERR0("ip_address_from_hostname",
"Failed to get name of this host");
erl_errno = EHOSTUNREACH;
return ERL_ERROR;
} else {
char *ct;
- /* We use a short node name */
+ /* We use a short node name */
if ((ct = strchr(thishostname, '.')) != NULL) *ct = '\0';
}
if (strcmp(hostname,thishostname) == 0)
/* Both nodes on same standalone host, use loopback */
- hp = dyn_gethostbyname_r("localhost",&host,&buf,sizeof(buffer),&ei_h_errno);
+ hp = dyn_gethostbyname_r("localhost",&host,buffer_p,buffer_size,&ei_h_errno);
if (hp == NULL) {
EI_TRACE_ERR2("ei_connect",
- "Can't find host for %s: %d\n",nodename,ei_h_errno);
+ "Can't find host for %s: %d\n",hostname,ei_h_errno);
erl_errno = EHOSTUNREACH;
return ERL_ERROR;
}
}
+ *ip_wb = (Erl_IpAddr) *hp->h_addr_list;
#else /* __WIN32__ */
if ((hp = ei_gethostbyname(hostname)) == NULL) {
char thishostname[EI_MAXHOSTNAMELEN+1];
/* gethostname requires len to be max(hostname) + 1 */
if (gethostname(thishostname,EI_MAXHOSTNAMELEN+1) < 0) {
- EI_TRACE_ERR1("ei_connect_tmo",
- "Failed to get name of this host: %d",
+ EI_TRACE_ERR1("ip_address_from_hostname",
+ "Failed to get name of this host: %d",
WSAGetLastError());
erl_errno = EHOSTUNREACH;
return ERL_ERROR;
} else {
char *ct;
- /* We use a short node name */
+ /* We use a short node name */
if ((ct = strchr(thishostname, '.')) != NULL) *ct = '\0';
}
if (strcmp(hostname,thishostname) == 0)
@@ -955,42 +926,29 @@ int ei_connect_tmo(ei_cnode* ec, char *nodename, unsigned ms)
char reason[1024];
win32_error(reason,sizeof(reason));
EI_TRACE_ERR2("ei_connect",
- "Can't find host for %s: %s",nodename,reason);
+ "Can't find host for %s: %s",hostname,reason);
erl_errno = EHOSTUNREACH;
return ERL_ERROR;
}
}
+ *ip_wb = (Erl_IpAddr) *hp->h_addr_list;
#endif /* win32 */
-
- res = ei_xconnect_tmo(ec, (Erl_IpAddr) *hp->h_addr_list, alivename, ms);
-
-#ifndef __WIN32__
- if (buf != buffer)
- free(buf);
-#endif
- return res;
-} /* ei_connect */
-
-int ei_connect(ei_cnode* ec, char *nodename)
-{
- return ei_connect_tmo(ec, nodename, 0);
+ return 0;
}
-
- /* ip_addr is now in network byte order
- *
- * first we have to get hold of the portnumber to
- * the node through epmd at that host
- *
-*/
-int ei_xconnect_tmo(ei_cnode* ec, Erl_IpAddr ip_addr, char *alivename, unsigned ms)
+/* Helper function for ei_connect family of functions */
+static int ei_connect_helper(ei_cnode* ec,
+ Erl_IpAddr ip_addr, /* network byte order */
+ char *alivename,
+ unsigned ms,
+ int rport,
+ int epmd_says_version)
{
ei_socket_callbacks *cbs = ec->cbs;
void *ctx;
- int rport = 0; /*uint16 rport = 0;*/
int sockd;
- int dist = 0;
- unsigned her_flags, her_version;
+ unsigned her_version;
+ DistFlags her_flags;
unsigned our_challenge, her_challenge;
unsigned char our_digest[16];
int err;
@@ -999,18 +957,18 @@ int ei_xconnect_tmo(ei_cnode* ec, Erl_IpAddr ip_addr, char *alivename, unsigned
unsigned tmo = ms == 0 ? EI_SCLBK_INF_TMO : ms;
erl_errno = EIO; /* Default error code */
-
- EI_TRACE_CONN1("ei_xconnect","-> CONNECT attempt to connect to %s",
- alivename);
-
- if ((rport = ei_epmd_port_tmo(ip_addr,alivename,&dist, tmo)) < 0) {
- EI_TRACE_ERR0("ei_xconnect","-> CONNECT can't get remote port");
- /* ei_epmd_port_tmo() has set erl_errno */
- return ERL_NO_PORT;
+
+ if (alivename != NULL) {
+ EI_TRACE_CONN1("ei_xconnect","-> CONNECT attempt to connect to %s",
+ alivename);
+ } else {
+ EI_TRACE_CONN1("ei_xconnect","-> CONNECT attempt to connect to port %d",
+ rport);
}
- if (dist <= 4) {
- EI_TRACE_ERR0("ei_xconnect","-> CONNECT remote version not compatible");
+ if (epmd_says_version < EI_DIST_LOW) {
+ EI_TRACE_ERR1("ei_xconnect","-> CONNECT remote version %d not compatible",
+ epmd_says_version);
return ERL_ERROR;
}
@@ -1050,21 +1008,24 @@ int ei_xconnect_tmo(ei_cnode* ec, Erl_IpAddr ip_addr, char *alivename, unsigned
goto error;
}
- if (send_name(cbs, ctx, pkt_sz, ec->thisnodename, (unsigned) dist, tmo))
+ if (send_name(ec, ctx, pkt_sz, epmd_says_version, tmo))
goto error;
if (recv_status(cbs, ctx, pkt_sz, tmo))
goto error;
- if (recv_challenge(cbs, ctx, pkt_sz, &her_challenge,
- &her_version, &her_flags, NULL, tmo))
+ if (recv_challenge(cbs, ctx, pkt_sz, &her_challenge, &her_version,
+ &her_flags, NULL, tmo))
goto error;
+ her_version = (her_flags & DFLAG_HANDSHAKE_23) ? EI_DIST_6 : EI_DIST_5;
our_challenge = gen_challenge();
gen_digest(her_challenge, ec->ei_connect_cookie, our_digest);
+ if (send_complement(ec, ctx, pkt_sz, epmd_says_version, her_flags, tmo))
+ goto error;
if (send_challenge_reply(cbs, ctx, pkt_sz, our_digest, our_challenge, tmo))
goto error;
if (recv_challenge_ack(cbs, ctx, pkt_sz, our_challenge,
ec->ei_connect_cookie, tmo))
goto error;
- if (put_ei_socket_info(sockd, dist, null_cookie, ec, cbs, ctx) != 0)
+ if (put_ei_socket_info(sockd, her_version, null_cookie, ec, cbs, ctx) != 0)
goto error;
if (cbs->connect_handshake_complete) {
@@ -1077,8 +1038,12 @@ int ei_xconnect_tmo(ei_cnode* ec, Erl_IpAddr ip_addr, char *alivename, unsigned
return ERL_ERROR;
}
}
-
- EI_TRACE_CONN1("ei_xconnect","-> CONNECT (ok) remote = %s",alivename);
+
+ if (alivename != NULL) {
+ EI_TRACE_CONN1("ei_xconnect","-> CONNECT (ok) remote = %s",alivename);
+ } else {
+ EI_TRACE_CONN1("ei_xconnect","-> CONNECT (ok) remote port = %d",rport);
+ }
erl_errno = 0;
return sockd;
@@ -1089,11 +1054,103 @@ error:
return ERL_ERROR;
} /* ei_xconnect */
+ /*
+ * Set up a connection to a given Node, and
+ * interchange hand shake messages with it.
+ * Returns a valid file descriptor at success,
+ * otherwise a negative error code.
+*/
+int ei_connect_tmo(ei_cnode* ec, char *nodename, unsigned ms)
+{
+ char *hostname, alivename[BUFSIZ];
+ Erl_IpAddr ip;
+ int res;
+ char buffer[1024];
+ char* buf = buffer;
+
+ if (strlen(nodename) > MAXNODELEN) {
+ EI_TRACE_ERR0("ei_connect","Too long nodename");
+ return ERL_ERROR;
+ }
+
+ /* extract the host and alive parts from nodename */
+ if (!(hostname = strchr(nodename,'@'))) {
+ EI_TRACE_ERR0("ei_connect","Node name has no @ in name");
+ return ERL_ERROR;
+ } else {
+ strncpy(alivename, nodename, hostname - nodename);
+ alivename[hostname - nodename] = 0x0;
+ hostname++;
+ }
+
+ res = ip_address_from_hostname(hostname, &buf, sizeof(buffer), &ip);
+
+ if (res < 0) {
+ return res;
+ }
+
+ res = ei_xconnect_tmo(ec, ip, alivename, ms);
+
+ if(buf != buffer) {
+ free(buf);
+ }
+
+ return res;
+} /* ei_connect */
+
+int ei_connect(ei_cnode* ec, char *nodename)
+{
+ return ei_connect_tmo(ec, nodename, 0);
+}
+
+int ei_connect_host_port_tmo(ei_cnode* ec, char *host, int port, unsigned ms)
+{
+ Erl_IpAddr ip;
+ char buffer[1024];
+ char* buf = buffer;
+ int res = ip_address_from_hostname(host, &buf, sizeof(buffer), &ip);
+ if (res < 0) {
+ return res;
+ }
+ if(buf != buffer) {
+ free(buf);
+ }
+ return ei_xconnect_host_port_tmo(ec, ip, port, ms);
+}
+
+int ei_connect_host_port(ei_cnode* ec, char *host, int port)
+{
+ return ei_connect_host_port_tmo(ec, host, port, 0);
+}
+
+int ei_xconnect_tmo(ei_cnode* ec, Erl_IpAddr ip_addr, char *alivename, unsigned ms)
+{
+ int epmd_says_version = 0;
+ int port;
+ unsigned tmo = ms == 0 ? EI_SCLBK_INF_TMO : ms;
+ if ((port = ei_epmd_port_tmo(ip_addr,alivename,&epmd_says_version, tmo)) < 0) {
+ EI_TRACE_ERR0("ei_xconnect","-> CONNECT can't get remote port");
+ /* ei_epmd_port_tmo() has set erl_errno */
+ return ERL_NO_PORT;
+ }
+ return ei_connect_helper(ec, ip_addr, alivename, ms, port, epmd_says_version);
+}
+
int ei_xconnect(ei_cnode* ec, Erl_IpAddr ip_addr, char *alivename)
{
return ei_xconnect_tmo(ec, ip_addr, alivename, 0);
}
+int ei_xconnect_host_port_tmo(ei_cnode* ec, Erl_IpAddr ip_addr, int port, unsigned ms)
+{
+ return ei_connect_helper(ec, ip_addr, NULL, ms, port, EI_DIST_LOW);
+}
+
+int ei_xconnect_host_port(ei_cnode* ec, Erl_IpAddr ip_addr, int port)
+{
+ return ei_xconnect_host_port_tmo(ec, ip_addr, port, 0);
+}
+
int ei_listen(ei_cnode *ec, int *port, int backlog)
{
struct in_addr ip_addr;
@@ -1209,8 +1266,9 @@ int ei_accept(ei_cnode* ec, int lfd, ErlConnect *conp)
int ei_accept_tmo(ei_cnode* ec, int lfd, ErlConnect *conp, unsigned ms)
{
int fd;
- unsigned her_version, her_flags;
+ DistFlags her_flags;
char tmp_nodename[MAXNODELEN+1];
+ char send_name_tag;
char *her_name;
int pkt_sz, err;
struct sockaddr_in addr;
@@ -1235,6 +1293,10 @@ int ei_accept_tmo(ei_cnode* ec, int lfd, ErlConnect *conp, unsigned ms)
ctx = EI_FD_AS_CTX__(lfd);
}
+ if (ec->cbs != cbs) {
+ EI_CONN_SAVE_ERRNO__(EINVAL);
+ return ERL_ERROR;
+ }
EI_TRACE_CONN0("ei_accept","<- ACCEPT waiting for connection");
@@ -1281,16 +1343,14 @@ int ei_accept_tmo(ei_cnode* ec, int lfd, ErlConnect *conp, unsigned ms)
EI_TRACE_CONN0("ei_accept","<- ACCEPT connected to remote");
- if (recv_name(cbs, ctx, pkt_sz, &her_version, &her_flags, her_name, tmo)) {
+ if (recv_name(cbs, ctx, pkt_sz, &send_name_tag, &her_flags,
+ her_name, tmo)) {
EI_TRACE_ERR0("ei_accept","<- ACCEPT initial ident failed");
goto error;
}
- if (her_version <= 4) {
- EI_TRACE_ERR0("ei_accept","<- ACCEPT remote version not compatible");
- goto error;
- }
- else {
+ {
+ unsigned her_version = (her_flags & DFLAG_HANDSHAKE_23) ? 6 : 5;
unsigned our_challenge;
unsigned her_challenge;
unsigned char our_digest[16];
@@ -1298,9 +1358,12 @@ int ei_accept_tmo(ei_cnode* ec, int lfd, ErlConnect *conp, unsigned ms)
if (send_status(cbs, ctx, pkt_sz, "ok", tmo))
goto error;
our_challenge = gen_challenge();
- if (send_challenge(cbs, ctx, pkt_sz, ec->thisnodename,
- our_challenge, her_version, tmo))
+ if (send_challenge(ec, ctx, pkt_sz, our_challenge, her_flags, tmo))
goto error;
+ if (send_name_tag == 'n' && (her_flags & DFLAG_HANDSHAKE_23)) {
+ if (recv_complement(cbs, ctx, pkt_sz, tmo))
+ goto error;
+ }
if (recv_challenge_reply(cbs, ctx, pkt_sz, our_challenge,
ec->ei_connect_cookie, &her_challenge, tmo))
goto error;
@@ -1629,21 +1692,6 @@ unsigned int gen_challenge(void)
return md_32((char*) &s, sizeof(s));
}
-#elif defined(VXWORKS)
-
-static unsigned int gen_challenge(void)
-{
- struct {
- struct timespec tv;
- clock_t cpu;
- int pid;
- } s;
- s.cpu = clock();
- clock_gettime(CLOCK_REALTIME, &s.tv);
- s.pid = getpid();
- return md_32((char*) &s, sizeof(s));
-}
-
#else /* some unix */
static unsigned int gen_challenge(void)
@@ -1846,26 +1894,50 @@ error:
return -1;
}
-static int send_name_or_challenge(ei_socket_callbacks *cbs,
- void *ctx,
- int pkt_sz,
- char *nodename,
- int f_chall,
- unsigned challenge,
- unsigned version,
- unsigned ms)
+static DistFlags preferred_flags(void)
+{
+ DistFlags flags =
+ DFLAG_EXTENDED_REFERENCES
+ | DFLAG_DIST_MONITOR
+ | DFLAG_EXTENDED_PIDS_PORTS
+ | DFLAG_FUN_TAGS
+ | DFLAG_NEW_FUN_TAGS
+ | DFLAG_NEW_FLOATS
+ | DFLAG_SMALL_ATOM_TAGS
+ | DFLAG_UTF8_ATOMS
+ | DFLAG_MAP_TAG
+ | DFLAG_BIG_CREATION
+ | DFLAG_EXPORT_PTR_TAG
+ | DFLAG_BIT_BINARIES
+ | DFLAG_HANDSHAKE_23;
+ if (ei_internal_use_21_bitstr_expfun()) {
+ flags &= ~(DFLAG_EXPORT_PTR_TAG
+ | DFLAG_BIT_BINARIES);
+ }
+ return flags;
+}
+
+static int send_name(ei_cnode *ec,
+ void *ctx,
+ int pkt_sz,
+ unsigned version,
+ unsigned ms)
{
char *buf;
unsigned char *s;
char dbuf[DEFBUF_SIZ];
- int siz = pkt_sz + 1 + 2 + 4 + strlen(nodename);
- const char* function[] = {"SEND_NAME", "SEND_CHALLENGE"};
+ const unsigned int nodename_len = strlen(ec->thisnodename);
+ int siz;
int err;
ssize_t len;
- unsigned int flags;
+ DistFlags flags;
+ const char tag = (version == EI_DIST_5) ? 'n' : 'N';
+
+ if (tag == 'n')
+ siz = pkt_sz + 1 + 2 + 4 + nodename_len;
+ else
+ siz = pkt_sz + 1 + 8 + 4 + 2 + nodename_len;
- if (f_chall)
- siz += 4;
buf = (siz > DEFBUF_SIZ) ? malloc(siz) : dbuf;
if (!buf) {
erl_errno = ENOMEM;
@@ -1882,35 +1954,95 @@ static int send_name_or_challenge(ei_socket_callbacks *cbs,
default:
return -1;
}
- put8(s, 'n');
- put16be(s, version);
- flags = (DFLAG_EXTENDED_REFERENCES
- | DFLAG_DIST_MONITOR
- | DFLAG_EXTENDED_PIDS_PORTS
- | DFLAG_FUN_TAGS
- | DFLAG_NEW_FUN_TAGS
- | DFLAG_NEW_FLOATS
- | DFLAG_SMALL_ATOM_TAGS
- | DFLAG_UTF8_ATOMS
- | DFLAG_MAP_TAG
- | DFLAG_BIG_CREATION
- | DFLAG_EXPORT_PTR_TAG
- | DFLAG_BIT_BINARIES);
- if (ei_internal_use_21_bitstr_expfun()) {
- flags &= ~(DFLAG_EXPORT_PTR_TAG
- | DFLAG_BIT_BINARIES);
+ flags = preferred_flags();
+
+ put8(s, tag);
+ if (tag == 'n') {
+ put16be(s, EI_DIST_5); /* some impl (jinterface) demand ver==5 */
+ put32be(s, flags);
+ }
+ else { /* tag == 'N' */
+ put64be(s, flags);
+ put32be(s, ec->creation);
+ put16be(s, nodename_len);
}
- put32be(s, flags);
- if (f_chall)
- put32be(s, challenge);
- memcpy(s, nodename, strlen(nodename));
+ memcpy(s, ec->thisnodename, nodename_len);
len = (ssize_t) siz;
- err = ei_write_fill_ctx_t__(cbs, ctx, buf, &len, ms);
+ err = ei_write_fill_ctx_t__(ec->cbs, ctx, buf, &len, ms);
if (!err && len != (ssize_t) siz)
err = EIO;
if (err) {
- EI_TRACE_ERR1("send_name_or_challenge",
- "-> %s socket write failed", function[f_chall]);
+ EI_TRACE_ERR0("send_name", "SEND_NAME -> socket write failed");
+ if (buf != dbuf)
+ free(buf);
+ EI_CONN_SAVE_ERRNO__(err);
+ return -1;
+ }
+
+ if (buf != dbuf)
+ free(buf);
+ return 0;
+}
+
+static int send_challenge(ei_cnode *ec,
+ void *ctx,
+ int pkt_sz,
+ unsigned challenge,
+ DistFlags her_flags,
+ unsigned ms)
+{
+ char *buf;
+ unsigned char *s;
+ char dbuf[DEFBUF_SIZ];
+ const unsigned int nodename_len = strlen(ec->thisnodename);
+ int siz;
+ int err;
+ ssize_t len;
+ DistFlags flags;
+ const char tag = (her_flags & DFLAG_HANDSHAKE_23) ? 'N' : 'n';
+
+ if (tag == 'n')
+ siz = pkt_sz + 1 + 2 + 4 + 4 + nodename_len;
+ else
+ siz = pkt_sz + 1 + 8 + 4 + 4 + 2 + nodename_len;
+
+ buf = (siz > DEFBUF_SIZ) ? malloc(siz) : dbuf;
+ if (!buf) {
+ erl_errno = ENOMEM;
+ return -1;
+ }
+ s = (unsigned char *)buf;
+ switch (pkt_sz) {
+ case 2:
+ put16be(s,siz - 2);
+ break;
+ case 4:
+ put32be(s,siz - 4);
+ break;
+ default:
+ return -1;
+ }
+
+ flags = preferred_flags();
+ put8(s, tag);
+ if (tag == 'n') {
+ put16be(s, EI_DIST_5); /* choosen version */
+ put32be(s, flags);
+ put32be(s, challenge);
+ }
+ else {
+ put64be(s, flags);
+ put32be(s, challenge);
+ put32be(s, ec->creation);
+ put16be(s, nodename_len);
+ }
+ memcpy(s, ec->thisnodename, nodename_len);
+ len = (ssize_t) siz;
+ err = ei_write_fill_ctx_t__(ec->cbs, ctx, buf, &len, ms);
+ if (!err && len != (ssize_t) siz)
+ err = EIO;
+ if (err) {
+ EI_TRACE_ERR0("send_challenge", "-> SEND_CHALLENGE socket write failed");
if (buf != dbuf)
free(buf);
EI_CONN_SAVE_ERRNO__(err);
@@ -1924,13 +2056,13 @@ static int send_name_or_challenge(ei_socket_callbacks *cbs,
static int recv_challenge(ei_socket_callbacks *cbs, void *ctx,
int pkt_sz, unsigned *challenge, unsigned *version,
- unsigned *flags, char *namebuf, unsigned ms)
+ DistFlags *flags, char *namebuf, unsigned ms)
{
char dbuf[DEFBUF_SIZ];
char *buf = dbuf;
int is_static = 1;
int buflen = DEFBUF_SIZ;
- int rlen;
+ int rlen, nodename_len;
char *s;
char tag;
char tmp_nodename[MAXNODELEN+1];
@@ -1943,21 +2075,57 @@ static int recv_challenge(ei_socket_callbacks *cbs, void *ctx,
"<- RECV_CHALLENGE socket read failed (%d)",rlen);
goto error;
}
- if ((rlen - 11) > MAXNODELEN) {
- EI_TRACE_ERR1("recv_challenge",
- "<- RECV_CHALLENGE nodename too long (%d)",rlen - 11);
- goto error;
- }
s = buf;
- if ((tag = get8(s)) != 'n') {
+ tag = get8(s);
+ if (tag != 'n' && tag != 'N') {
EI_TRACE_ERR2("recv_challenge",
"<- RECV_CHALLENGE incorrect tag, "
- "expected 'n' got '%c' (%u)",tag,tag);
+ "expected 'n' or 'N', got '%c' (%u)",tag,tag);
goto error;
}
- *version = get16be(s);
- *flags = get32be(s);
- *challenge = get32be(s);
+ if (tag == 'n') { /* OLD */
+ unsigned int version;
+ if (rlen < 1+2+4+4) {
+ EI_TRACE_ERR1("recv_challenge","<- RECV_CHALLENGE 'n' packet too short (%d)",
+ rlen)
+ goto error;
+ }
+
+ version = get16be(s);
+ if (version != EI_DIST_5) {
+ EI_TRACE_ERR1("recv_challenge",
+ "<- RECV_CHALLENGE 'n' incorrect version=%d",
+ version);
+ goto error;
+ }
+ *flags = get32be(s);
+ *challenge = get32be(s);
+ nodename_len = (buf + rlen) - s;
+ }
+ else { /* NEW */
+ if (rlen < 1+8+4+4+2) {
+ EI_TRACE_ERR1("recv_challenge","<- RECV_CHALLENGE 'N' packet too short (%d)",
+ rlen)
+ goto error;
+ }
+ *version = EI_DIST_6;
+ *flags = get64be(s);
+ *challenge = get32be(s);
+ s += 4; /* ignore peer 'creation' */
+ nodename_len = get16be(s);
+ if (nodename_len > (buf + rlen) - s) {
+ EI_TRACE_ERR1("recv_challenge",
+ "<- RECV_CHALLENGE 'N' nodename too long (%d)",
+ nodename_len);
+ goto error;
+ }
+ }
+
+ if (nodename_len > MAXNODELEN) {
+ EI_TRACE_ERR1("recv_challenge",
+ "<- RECV_CHALLENGE nodename too long (%d)", nodename_len);
+ goto error;
+ }
if (!(*flags & DFLAG_EXTENDED_REFERENCES)) {
EI_TRACE_ERR0("recv_challenge","<- RECV_CHALLENGE peer cannot "
@@ -1981,8 +2149,8 @@ static int recv_challenge(ei_socket_callbacks *cbs, void *ctx,
if (!namebuf)
namebuf = &tmp_nodename[0];
- memcpy(namebuf, s, rlen - 11);
- namebuf[rlen - 11] = '\0';
+ memcpy(namebuf, s, nodename_len);
+ namebuf[nodename_len] = '\0';
if (!is_static)
free(buf);
@@ -2003,6 +2171,63 @@ error:
return -1;
}
+static int send_complement(ei_cnode *ec,
+ void *ctx,
+ int pkt_sz,
+ unsigned epmd_says_version,
+ DistFlags her_flags,
+ unsigned ms)
+{
+ if (epmd_says_version == EI_DIST_5 && (her_flags & DFLAG_HANDSHAKE_23)) {
+ char *buf;
+ unsigned char *s;
+ char dbuf[DEFBUF_SIZ];
+ int err;
+ ssize_t len;
+ unsigned int flagsHigh;
+ const int siz = pkt_sz + 1 + 4 + 4;
+
+ buf = (siz > DEFBUF_SIZ) ? malloc(siz) : dbuf;
+ if (!buf) {
+ erl_errno = ENOMEM;
+ return -1;
+ }
+ s = (unsigned char *)buf;
+ switch (pkt_sz) {
+ case 2:
+ put16be(s,siz - 2);
+ break;
+ case 4:
+ put32be(s,siz - 4);
+ break;
+ default:
+ return -1;
+ }
+ flagsHigh = preferred_flags() >> 32;
+
+ put8(s, 'c');
+ put32be(s, flagsHigh);
+ put32be(s, ec->creation);
+
+ len = (ssize_t) siz;
+ err = ei_write_fill_ctx_t__(ec->cbs, ctx, buf, &len, ms);
+ if (!err && len != (ssize_t) siz)
+ err = EIO;
+ if (err) {
+ EI_TRACE_ERR0("send_name", "SEND_NAME -> socket write failed");
+ if (buf != dbuf)
+ free(buf);
+ EI_CONN_SAVE_ERRNO__(err);
+ return -1;
+ }
+
+ if (buf != dbuf)
+ free(buf);
+ }
+ return 0;
+}
+
+
static int send_challenge_reply(ei_socket_callbacks *cbs, void *ctx,
int pkt_sz, unsigned char digest[16],
unsigned challenge, unsigned ms)
@@ -2049,6 +2274,54 @@ static int send_challenge_reply(ei_socket_callbacks *cbs, void *ctx,
return 0;
}
+static int recv_complement(ei_socket_callbacks *cbs,
+ void *ctx,
+ int pkt_sz,
+ unsigned ms)
+{
+ char dbuf[DEFBUF_SIZ];
+ char *buf = dbuf;
+ int is_static = 1;
+ int buflen = DEFBUF_SIZ;
+ int rlen;
+ char *s;
+ char tag;
+ unsigned int creation;
+
+ erl_errno = EIO; /* Default */
+
+ if ((rlen = read_hs_package(cbs, ctx, pkt_sz, &buf, &buflen, &is_static, ms)) != 21) {
+ EI_TRACE_ERR1("recv_complement",
+ "<- RECV_COMPLEMENT socket read failed (%d)",rlen);
+ goto error;
+ }
+
+ s = buf;
+ if ((tag = get8(s)) != 'c') {
+ EI_TRACE_ERR2("recv_complement",
+ "<- RECV_COMPLEMENT incorrect tag, "
+ "expected 'c' got '%c' (%u)",tag,tag);
+ goto error;
+ }
+ creation = get32be(s);
+ if (!is_static)
+ free(buf);
+
+ if (ei_tracelevel >= 3) {
+ EI_TRACE_CONN1("recv_complement",
+ "<- RECV_COMPLEMENT (ok) creation = %u",
+ creation);
+ }
+ /* We don't have any use for 'creation' of other node, so we drop it */
+ erl_errno = 0;
+ return 0;
+
+error:
+ if (!is_static)
+ free(buf);
+ return -1;
+}
+
static int recv_challenge_reply(ei_socket_callbacks *cbs,
void *ctx,
int pkt_sz,
@@ -2204,30 +2477,16 @@ error:
return -1;
}
-static int send_name(ei_socket_callbacks *cbs, void *ctx, int pkt_sz,
- char *nodename, unsigned version, unsigned ms)
-{
- return send_name_or_challenge(cbs, ctx, pkt_sz, nodename, 0,
- 0, version, ms);
-}
-
-static int send_challenge(ei_socket_callbacks *cbs, void *ctx, int pkt_sz,
- char *nodename, unsigned challenge, unsigned version,
- unsigned ms)
-{
- return send_name_or_challenge(cbs, ctx, pkt_sz, nodename, 1,
- challenge, version, ms);
-}
-
static int recv_name(ei_socket_callbacks *cbs, void *ctx,
- int pkt_sz, unsigned *version,
- unsigned *flags, char *namebuf, unsigned ms)
+ int pkt_sz, char *send_name_tag,
+ DistFlags *flags, char *namebuf, unsigned ms)
{
char dbuf[DEFBUF_SIZ];
char *buf = dbuf;
int is_static = 1;
int buflen = DEFBUF_SIZ;
int rlen;
+ unsigned int namelen;
char *s;
char tmp_nodename[MAXNODELEN+1];
char tag;
@@ -2239,19 +2498,40 @@ static int recv_name(ei_socket_callbacks *cbs, void *ctx,
EI_TRACE_ERR1("recv_name","<- RECV_NAME socket read failed (%d)",rlen);
goto error;
}
- if ((rlen - 7) > MAXNODELEN) {
- EI_TRACE_ERR1("recv_name","<- RECV_NAME nodename too long (%d)",rlen-7);
- goto error;
- }
s = buf;
tag = get8(s);
- if (tag != 'n') {
+ *send_name_tag = tag;
+ if (tag != 'n' && tag != 'N') {
EI_TRACE_ERR2("recv_name","<- RECV_NAME incorrect tag, "
- "expected 'n' got '%c' (%u)",tag,tag);
+ "expected 'n' or 'N', got '%c' (%u)",tag,tag);
goto error;
}
- *version = get16be(s);
- *flags = get32be(s);
+ if (tag == 'n') {
+ unsigned int version;
+ if (rlen < 1+2+4) {
+ EI_TRACE_ERR1("recv_name","<- RECV_NAME 'n' packet too short (%d)",
+ rlen)
+ goto error;
+ }
+ version = get16be(s);
+ if (version < EI_DIST_5) {
+ EI_TRACE_ERR1("recv_name","<- RECV_NAME 'n' invalid version=%d",
+ version)
+ goto error;
+ }
+ *flags = get32be(s);
+ namelen = rlen - (1+2+4);
+ }
+ else { /* tag == 'N' */
+ if (rlen < 1+8+4+2) {
+ EI_TRACE_ERR1("recv_name","<- RECV_NAME 'N' packet too short (%d)",
+ rlen)
+ goto error;
+ }
+ *flags = get64be(s);
+ s += 4; /* ignore peer 'creation' */
+ namelen = get16be(s);
+ }
if (!(*flags & DFLAG_EXTENDED_REFERENCES)) {
EI_TRACE_ERR0("recv_name","<- RECV_NAME peer cannot handle"
@@ -2269,14 +2549,20 @@ static int recv_name(ei_socket_callbacks *cbs, void *ctx,
if (!namebuf)
namebuf = &tmp_nodename[0];
- memcpy(namebuf, s, rlen - 7);
- namebuf[rlen - 7] = '\0';
+ if (namelen > MAXNODELEN || s+namelen > buf+rlen) {
+ EI_TRACE_ERR2("recv_name","<- RECV_NAME '%c' nodename too long (%d)",
+ tag, namelen);
+ goto error;
+ }
+
+ memcpy(namebuf, s, namelen);
+ namebuf[namelen] = '\0';
if (!is_static)
free(buf);
EI_TRACE_CONN3("recv_name",
- "<- RECV_NAME (ok) node = %s, version = %u, flags = %u",
- namebuf,*version,*flags);
+ "<- RECV_NAME (ok) node = %s, tag = %c, flags = %u",
+ namebuf,tag,*flags);
erl_errno = 0;
return 0;
diff --git a/lib/erl_interface/src/connect/ei_connect_int.h b/lib/erl_interface/src/connect/ei_connect_int.h
index b41a5f2b23..05cec3c824 100644
--- a/lib/erl_interface/src/connect/ei_connect_int.h
+++ b/lib/erl_interface/src/connect/ei_connect_int.h
@@ -38,30 +38,7 @@
#include <windows.h>
#include <winbase.h>
-#elif VXWORKS
-#include <vxWorks.h>
-#include <hostLib.h>
-#include <selectLib.h>
-#include <ifLib.h>
-#include <sockLib.h>
-#include <taskLib.h>
-#include <inetLib.h>
-#include <ioLib.h>
-
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/times.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <timers.h>
-
-#define getpid() taskIdSelf()
-extern int h_errno;
-
-#else /* some other unix */
+#else /* some unix */
#include <unistd.h>
#include <sys/types.h>
#include <sys/times.h>
@@ -109,6 +86,8 @@ extern int h_errno;
#define DFLAG_UTF8_ATOMS 0x10000
#define DFLAG_MAP_TAG 0x20000
#define DFLAG_BIG_CREATION 0x40000
+#define DFLAG_HANDSHAKE_23 0x1000000
+#define DFLAG_HANDSHAKE_XX 0xfe000000 /* bits reserved for handshake changes */
ei_cnode *ei_fd_to_cnode(int fd);
int ei_distversion(int fd);
diff --git a/lib/erl_interface/src/connect/ei_resolve.c b/lib/erl_interface/src/connect/ei_resolve.c
index 225fddc784..f6182ccaf0 100644
--- a/lib/erl_interface/src/connect/ei_resolve.c
+++ b/lib/erl_interface/src/connect/ei_resolve.c
@@ -21,19 +21,7 @@
* Interface functions to different versions of gethostbyname
*/
-#ifdef VXWORKS
-#include <vxWorks.h>
-#include <stdio.h>
-#include <semLib.h>
-#include <hostLib.h>
-#include <resolvLib.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <errno.h>
-#include <symLib.h>
-#include <sysSymTbl.h>
-
-#elif __WIN32__
+#ifdef __WIN32__
#include <winsock2.h>
#include <windows.h>
#include <winbase.h>
@@ -55,6 +43,16 @@
#include "ei_resolve.h"
#include "ei_locking.h"
+/* AIX has a totally different signature (allegedly shared with some other
+ * Unices) that isn't compatible. It turns out that the _r version isn't
+ * thread-safe according to curl - but bizarrely, since AIX 4.3, libc
+ * is thread-safe in a manner that makes the normal gethostbyname OK
+ * for re-entrant use.
+ */
+#ifdef _AIX
+#undef HAVE_GETHOSTBYNAME_R
+#endif
+
#ifdef HAVE_GETHOSTBYNAME_R
int ei_init_resolve(void)
@@ -75,7 +73,7 @@ int ei_init_resolve(void)
static ei_mutex_t *ei_gethost_sem = NULL;
#endif /* _REENTRANT */
static int ei_resolve_initialized = 0;
-#ifndef __WIN32__
+#if !defined(__WIN32__) && !defined(_AIX)
int h_errno;
#endif
@@ -85,18 +83,6 @@ int h_errno;
#define DEBUGF(X) /* Nothing */
#endif
-#ifdef VXWORKS
-/* FIXME problem for threaded ? */
-static struct hostent *(*sens_gethostbyname)(const char *name,
- char *, int) = NULL;
-static struct hostent *(*sens_gethostbyaddr)(const char *addr,
- char *, int) = NULL;
-#endif
-
-#ifdef VXWORKS
-static int verify_dns_configuration(void);
-#endif
-
/*
* If we find SENS resolver, use the functions found there, i.e.
* resolvGetHostByName() and resolvGetHostByAddr(). Otherwise we use
@@ -106,32 +92,6 @@ static int verify_dns_configuration(void);
int ei_init_resolve(void)
{
-#ifdef VXWORKS
- void *sym;
- SYM_TYPE symtype;
-
- if (symFindByName(sysSymTbl,"resolvGetHostByName",
- (char **)&sym,&symtype) == OK &&
- verify_dns_configuration()) {
- sens_gethostbyname = sym;
- DEBUGF((stderr,"found SENS resolver - using it for gethostbyname()\n"));
- if (symFindByName(sysSymTbl,"resolvGetHostByAddr",
- (char **)&sym,&symtype) == OK) {
- sens_gethostbyaddr = sym;
- DEBUGF((stderr,"found SENS resolver - "
- "using it for gethostbyaddr()\n"));
- }
- else {
- DEBUGF((stderr,"SENS resolver not found - "
- "using default gethostbyaddr()\n"));
- }
- }
- else {
- DEBUGF((stderr,"SENS resolver not found - "
- "using default gethostbyname()\n"));
- }
-#endif /* VXWORKS */
-
#ifdef _REENTRANT
ei_gethost_sem = ei_mutex_create();
if (!ei_gethost_sem)
@@ -142,42 +102,7 @@ int ei_init_resolve(void)
return 0;
}
-#ifdef VXWORKS
-/*
-** Function to verify the DNS configuration on VwXorks SENS.
-** Actually configures to a default value if unconfigured...
-*/
-static int verify_dns_configuration(void)
-{
- /* FIXME problem for threaded ? */
- static char resolv_params[sizeof(RESOLV_PARAMS_S)];
- void (*rpg)(char *);
- STATUS (*rps)(char *);
- SYM_TYPE dummy;
- int get_result, set_result;
-
- get_result = symFindByName(sysSymTbl,"resolvParamsGet", (char **) &rpg, &dummy);
- set_result = symFindByName(sysSymTbl,"resolvParamsSet", (char **) &rps, &dummy);
-
- if (!(get_result == OK &&
- set_result == OK))
- return -1;
- (*rpg)(resolv_params);
- if (*resolv_params == '\0') {
- /* It exists, but is not configured, ei_connect would fail
- if we left it this way... The best we can do is to configure
- it to use the local host database on the card, as a fallback */
- *resolv_params = (char) 1;
- fprintf(stderr,"Trying to fix up DNS configuration.\n");
- if (((*rps)(resolv_params)) != OK)
- return -1;
- }
- return 0;
-}
-
-#endif
-
-#if defined(VXWORKS) || _REENTRANT
+#if _REENTRANT
/*
* Copy the contents of one struct hostent to another, i.e. don't just
@@ -365,9 +290,9 @@ static struct hostent *my_gethostbyname_r(const char *name,
return rval;
}
-#endif /* defined(VXWORKS) || _REENTRANT */
+#endif /* _REENTRANT */
-#if defined(VXWORKS) || EI_THREADS != false
+#if EI_THREADS != false
static struct hostent *my_gethostbyaddr_r(const char *addr,
int length,
@@ -433,7 +358,7 @@ static struct hostent *my_gethostbyaddr_r(const char *addr,
return rval;
}
-#endif /* defined(VXWORKS) || EI_THREADS != false */
+#endif /* EI_THREADS != false */
#endif /* !HAVE_GETHOSTBYNAME_R */
@@ -449,154 +374,6 @@ struct hostent *ei_gethostbyaddr(const char *addr, int len, int type)
return gethostbyaddr(addr, len, type);
}
-#elif VXWORKS
-
-
-/* these are a couple of substitutes for the real thing when we run on
- * stock vxworks (i.e. no sens).
- *
- * len and type are ignored, but we make up some reasonable values and
- * insert them
- */
-static struct hostent *my_gethostbyname(const char *name)
-{
- /* FIXME problem for threaded ? */
- static struct hostent h;
- static char hostname[EI_MAXHOSTNAMELEN+1];
- static char *aliases[1] = {NULL};
- static char *addrp[2] = {NULL,NULL};
- static unsigned long addr = 0;
-
- strcpy(hostname,name);
- if ((addr = (unsigned long)hostGetByName(hostname)) == ERROR) {
- h_errno = HOST_NOT_FOUND;
- return NULL;
- }
-
- h_errno = 0;
- h.h_name = hostname;
- h.h_aliases = aliases;
- h.h_length = 4;
- h.h_addrtype = AF_INET;
- addrp[0] = (char *)&addr;
- h.h_addr_list = addrp;
-
- return &h;
-}
-
-static struct hostent *my_gethostbyaddr(const char *addr, int len, int type)
-{
- /* FIXME problem for threaded ? */
- static struct hostent h;
- static char hostname[EI_MAXHOSTNAMELEN+1];
- static char *aliases[1] = { NULL };
- static unsigned long inaddr;
- static char *addrp[2] = {(char *)&inaddr, NULL};
-
- memmove(&inaddr,addr,sizeof(inaddr));
-
- if ((hostGetByAddr(inaddr,hostname)) == ERROR) {
- h_errno = HOST_NOT_FOUND;
- return NULL;
- }
-
- h_errno = 0;
- h.h_name = hostname;
- h.h_aliases = aliases;
- h.h_length = 4;
- h.h_addrtype = AF_INET;
- h.h_addr_list = addrp;
-
- return &h;
-}
-
-/* use sens functions for these, if found. */
-struct hostent *ei_gethostbyname(const char *name)
-{
- struct hostent *h = NULL;
-
- if (!sens_gethostbyname) {
- h = my_gethostbyname(name);
- }
- else {
- /* FIXME problem for threaded ? */
- static char buf[1024];
- h = sens_gethostbyname(name,buf,1024);
- }
-
- return h;
-}
-
-struct hostent *ei_gethostbyaddr(const char *addr, int len, int type)
-{
- struct hostent *h = NULL;
-
- if (!sens_gethostbyaddr) {
- h = my_gethostbyaddr(addr,len,type);
- }
- else {
- /* FIXME problem for threaded ? */
- static char buf[1024];
- h = sens_gethostbyaddr(addr,buf,1024);
- }
-
- return h;
-}
-
-struct hostent *ei_gethostbyaddr_r(const char *addr,
- int length,
- int type,
- struct hostent *hostp,
- char *buffer,
- int buflen,
- int *h_errnop)
-{
- struct hostent *h = NULL;
-
- /* use own func if sens function not available */
- if (!sens_gethostbyaddr) {
- h = my_gethostbyaddr_r(addr,length,type,hostp,buffer,buflen,h_errnop);
- }
- else {
- if (!(h = sens_gethostbyaddr(addr,buffer,buflen))) {
- /* sens returns status via errno */
- *h_errnop = errno;
- }
- else {
- *hostp = *h;
- *h_errnop = 0;
- }
- }
-
- return h;
-}
-
-struct hostent *ei_gethostbyname_r(const char *name,
- struct hostent *hostp,
- char *buffer,
- int buflen,
- int *h_errnop)
-{
- struct hostent *h = NULL;
-
- /* use own func if sens function not available */
- if (!sens_gethostbyname) {
- h = my_gethostbyname_r(name,hostp,buffer,buflen,h_errnop);
- }
- else {
- if (!(h = sens_gethostbyname(name,buffer,buflen))) {
- /* sens returns status via errno */
- *h_errnop = errno;
- }
- else {
- *hostp = *h;
- *h_errnop = 0;
- }
- }
-
- return h;
-}
-
#else /* unix of some kind */
struct hostent *ei_gethostbyname(const char *name)
@@ -667,5 +444,5 @@ struct hostent *ei_gethostbyname_r(const char *name,
#endif
}
-#endif /* vxworks, win, unix */
+#endif /* win, unix */
diff --git a/lib/erl_interface/src/connect/send.c b/lib/erl_interface/src/connect/send.c
index d97532d123..8535b2a206 100644
--- a/lib/erl_interface/src/connect/send.c
+++ b/lib/erl_interface/src/connect/send.c
@@ -24,13 +24,6 @@
# include <windows.h>
# include <winbase.h>
-#elif VXWORKS
-
-# include <sys/types.h>
-# include <unistd.h>
-# include <sysLib.h>
-# include <tickLib.h>
-
#else /* unix */
# include <sys/types.h>
diff --git a/lib/erl_interface/src/connect/send_reg.c b/lib/erl_interface/src/connect/send_reg.c
index 80d61e57b5..b34432fb6e 100644
--- a/lib/erl_interface/src/connect/send_reg.c
+++ b/lib/erl_interface/src/connect/send_reg.c
@@ -22,10 +22,6 @@
#include <windows.h>
#include <winbase.h>
-#elif VXWORKS
-#include <sys/types.h>
-#include <unistd.h>
-
#else /* unix */
#include <sys/types.h>
#include <unistd.h>
diff --git a/lib/erl_interface/src/decode/decode_big.c b/lib/erl_interface/src/decode/decode_big.c
index cbbbd3f0b7..bd2d6662a5 100644
--- a/lib/erl_interface/src/decode/decode_big.c
+++ b/lib/erl_interface/src/decode/decode_big.c
@@ -144,13 +144,6 @@ int ei_big_comp(erlang_big *x, erlang_big *y)
* Handling of floating point exceptions.
*/
-#if defined(VXWORKS) && CPU == PPC860
-#undef NO_FPE_SIGNALS
-#define NO_FPE_SIGNALS 1
-#undef INLINED_FP_CONVERSION
-#define INLINED_FP_CONVERSION 1
-#endif
-
#ifdef NO_FPE_SIGNALS
# define ERTS_FP_CHECK_INIT() do {} while (0)
# define ERTS_FP_ERROR(f, Action) if (!isfinite(f)) { Action; } else {}
diff --git a/lib/erl_interface/src/encode/encode_pid.c b/lib/erl_interface/src/encode/encode_pid.c
index d14746b40f..0dfdb16372 100644
--- a/lib/erl_interface/src/encode/encode_pid.c
+++ b/lib/erl_interface/src/encode/encode_pid.c
@@ -25,7 +25,6 @@
int ei_encode_pid(char *buf, int *index, const erlang_pid *p)
{
char* s = buf + *index;
- const char tag = (p->creation > 3) ? ERL_NEW_PID_EXT : ERL_PID_EXT;
++(*index); /* skip ERL_PID_EXT */
if (ei_encode_atom_len_as(buf, index, p->node, strlen(p->node),
@@ -33,21 +32,17 @@ int ei_encode_pid(char *buf, int *index, const erlang_pid *p)
return -1;
if (buf) {
- put8(s, tag);
+ put8(s, ERL_NEW_PID_EXT);
s = buf + *index;
/* now the integers */
put32be(s,p->num & 0x7fff); /* 15 bits */
put32be(s,p->serial & 0x1fff); /* 13 bits */
- if (tag == ERL_PID_EXT) {
- put8(s,(p->creation & 0x03)); /* 2 bits */
- } else {
- put32be(s, p->creation); /* 32 bits */
- }
+ put32be(s, p->creation); /* 32 bits */
}
- *index += 4 + 4 + (tag == ERL_PID_EXT ? 1 : 4);
+ *index += 4 + 4 + 4;
return 0;
}
diff --git a/lib/erl_interface/src/encode/encode_port.c b/lib/erl_interface/src/encode/encode_port.c
index eb464380c0..0fb4018db1 100644
--- a/lib/erl_interface/src/encode/encode_port.c
+++ b/lib/erl_interface/src/encode/encode_port.c
@@ -25,7 +25,6 @@
int ei_encode_port(char *buf, int *index, const erlang_port *p)
{
char *s = buf + *index;
- const char tag = p->creation > 3 ? ERL_NEW_PORT_EXT : ERL_PORT_EXT;
++(*index); /* skip ERL_PORT_EXT */
if (ei_encode_atom_len_as(buf, index, p->node, strlen(p->node), ERLANG_UTF8,
@@ -33,19 +32,15 @@ int ei_encode_port(char *buf, int *index, const erlang_port *p)
return -1;
}
if (buf) {
- put8(s, tag);
+ put8(s, ERL_NEW_PORT_EXT);
s = buf + *index;
/* now the integers */
put32be(s,p->id & 0x0fffffff /* 28 bits */);
- if (tag == ERL_PORT_EXT) {
- put8(s,(p->creation & 0x03));
- } else {
- put32be(s, p->creation);
- }
+ put32be(s, p->creation);
}
- *index += 4 + (tag == ERL_PORT_EXT ? 1 : 4);
+ *index += 4 + 4;
return 0;
}
diff --git a/lib/erl_interface/src/encode/encode_ref.c b/lib/erl_interface/src/encode/encode_ref.c
index 5ccfc32c6d..8c2e0a25f7 100644
--- a/lib/erl_interface/src/encode/encode_ref.c
+++ b/lib/erl_interface/src/encode/encode_ref.c
@@ -24,7 +24,6 @@
int ei_encode_ref(char *buf, int *index, const erlang_ref *p)
{
- const char tag = (p->creation > 3) ? ERL_NEWER_REFERENCE_EXT : ERL_NEW_REFERENCE_EXT;
char *s = buf + *index;
int i;
@@ -37,7 +36,7 @@ int ei_encode_ref(char *buf, int *index, const erlang_ref *p)
/* Always encode as an extended reference; all participating parties
are now expected to be able to decode extended references. */
if (buf) {
- put8(s, tag);
+ put8(s, ERL_NEWER_REFERENCE_EXT);
/* first, number of integers */
put16be(s, p->len);
@@ -46,15 +45,12 @@ int ei_encode_ref(char *buf, int *index, const erlang_ref *p)
s = buf + *index;
/* now the integers */
- if (tag == ERL_NEW_REFERENCE_EXT)
- put8(s,(p->creation & 0x03));
- else
- put32be(s, p->creation);
+ put32be(s, p->creation);
for (i = 0; i < p->len; i++)
put32be(s,p->n[i]);
}
- *index += p->len*4 + (tag == ERL_NEW_REFERENCE_EXT ? 1 : 4);
+ *index += p->len*4 + 4;
return 0;
}
diff --git a/lib/erl_interface/src/epmd/ei_epmd.h b/lib/erl_interface/src/epmd/ei_epmd.h
index ac153b6e66..e3cb041dc9 100644
--- a/lib/erl_interface/src/epmd/ei_epmd.h
+++ b/lib/erl_interface/src/epmd/ei_epmd.h
@@ -24,9 +24,12 @@
#define INADDR_LOOPBACK ((u_long) 0x7F000001)
#endif
+#define EI_DIST_5 5 /* OTP R4 - 22 */
+#define EI_DIST_6 6 /* OTP 23 and later */
+
#ifndef EI_DIST_HIGH
-#define EI_DIST_HIGH 5 /* R4 and later */
-#define EI_DIST_LOW 1 /* R3 and earlier */
+#define EI_DIST_HIGH EI_DIST_6
+#define EI_DIST_LOW EI_DIST_5
#endif
#ifndef EPMD_PORT
@@ -45,6 +48,7 @@
#ifndef EI_EPMD_ALIVE2_REQ
#define EI_EPMD_ALIVE2_REQ 120
#define EI_EPMD_ALIVE2_RESP 121
+#define EI_EPMD_ALIVE2_X_RESP 118
#define EI_EPMD_PORT2_REQ 122
#define EI_EPMD_PORT2_RESP 119
#define EI_EPMD_STOP_REQ 's'
diff --git a/lib/erl_interface/src/epmd/epmd_port.c b/lib/erl_interface/src/epmd/epmd_port.c
index 492c3fb3aa..1ea2f7b9df 100644
--- a/lib/erl_interface/src/epmd/epmd_port.c
+++ b/lib/erl_interface/src/epmd/epmd_port.c
@@ -25,16 +25,6 @@
#include <windows.h>
#include <winbase.h>
-#elif VXWORKS
-#include <vxWorks.h>
-#include <ifLib.h>
-#include <sockLib.h>
-#include <inetLib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-
#else
#include <unistd.h>
#include <sys/types.h>
@@ -114,9 +104,6 @@ static int ei_epmd_r4_port (struct in_addr *addr, const char *alive,
int err;
ssize_t dlen;
unsigned tmo = ms == 0 ? EI_SCLBK_INF_TMO : ms;
-#if defined(VXWORKS)
- char ntoabuf[32];
-#endif
if (len > sizeof(buf) - 3)
{
@@ -144,17 +131,8 @@ static int ei_epmd_r4_port (struct in_addr *addr, const char *alive,
return -1;
}
-#ifdef VXWORKS
- /* FIXME use union/macro for level. Correct level? */
- if (ei_tracelevel > 2) {
- inet_ntoa_b(*addr,ntoabuf);
- EI_TRACE_CONN2("ei_epmd_r4_port",
- "-> PORT2_REQ alive=%s ip=%s",alive,ntoabuf);
- }
-#else
EI_TRACE_CONN2("ei_epmd_r4_port",
"-> PORT2_REQ alive=%s ip=%s",alive,inet_ntoa(*addr));
-#endif
dlen = (ssize_t) 2;
err = ei_read_fill_t__(fd, buf, &dlen, tmo);
diff --git a/lib/erl_interface/src/epmd/epmd_publish.c b/lib/erl_interface/src/epmd/epmd_publish.c
index 20b8e867e8..f2c7abbd1a 100644
--- a/lib/erl_interface/src/epmd/epmd_publish.c
+++ b/lib/erl_interface/src/epmd/epmd_publish.c
@@ -25,16 +25,6 @@
#include <windows.h>
#include <winbase.h>
-#elif VXWORKS
-#include <vxWorks.h>
-#include <ifLib.h>
-#include <sockLib.h>
-#include <inetLib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-
#else
#include <unistd.h>
#include <sys/types.h>
@@ -68,7 +58,8 @@ static int ei_epmd_r4_publish (int port, const char *alive, unsigned ms)
int nlen = strlen(alive);
int len = elen + nlen + 13; /* hard coded: be careful! */
int n;
- int err, res, creation;
+ int err, response, res;
+ unsigned creation;
ssize_t dlen;
unsigned tmo = ms == 0 ? EI_SCLBK_INF_TMO : ms;
@@ -124,8 +115,10 @@ static int ei_epmd_r4_publish (int port, const char *alive, unsigned ms)
/* Don't close fd here! It keeps us registered with epmd */
s = buf;
- if (((res=get8(s)) != EI_EPMD_ALIVE2_RESP)) { /* response */
- EI_TRACE_ERR1("ei_epmd_r4_publish","<- unknown (%d)",res);
+ response = get8(s);
+ if (response != EI_EPMD_ALIVE2_RESP &&
+ response != EI_EPMD_ALIVE2_X_RESP) {
+ EI_TRACE_ERR1("ei_epmd_r4_publish","<- unknown (%d)",response);
EI_TRACE_ERR0("ei_epmd_r4_publish","-> CLOSE");
ei_close__(fd);
erl_errno = EIO;
@@ -141,18 +134,21 @@ static int ei_epmd_r4_publish (int port, const char *alive, unsigned ms)
return -1;
}
- creation = get16be(s);
+ if (response == EI_EPMD_ALIVE2_RESP)
+ creation = get16be(s);
+ else /* EI_EPMD_ALIVE2_X_RESP */
+ creation = get32be(s);
EI_TRACE_CONN2("ei_epmd_r4_publish",
- " result=%d (ok) creation=%d",res,creation);
-
- /* probably should save fd so we can close it later... */
- /* epmd_saveconn(OPEN,fd,alive); */
+ " result=%d (ok) creation=%u",res,creation);
- /* return the creation number, for no good reason */
- /* return creation;*/
+ /*
+ * Would be nice to somehow use the nice "unique" creation value
+ * received here from epmd instead of using the crappy one
+ * passed (already) to ei_connect_init.
+ */
- /* no - return the descriptor */
+ /* return the descriptor */
return fd;
}
diff --git a/lib/erl_interface/src/epmd/epmd_unpublish.c b/lib/erl_interface/src/epmd/epmd_unpublish.c
index c112f74147..592cc0371e 100644
--- a/lib/erl_interface/src/epmd/epmd_unpublish.c
+++ b/lib/erl_interface/src/epmd/epmd_unpublish.c
@@ -22,16 +22,6 @@
#include <windows.h>
#include <winbase.h>
-#elif VXWORKS
-#include <vxWorks.h>
-#include <ifLib.h>
-#include <sockLib.h>
-#include <inetLib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-
#else
#include <unistd.h>
#include <sys/types.h>
diff --git a/lib/erl_interface/src/legacy/global_names.c b/lib/erl_interface/src/global/global_names.c
index ee808620fb..bcbe740223 100644
--- a/lib/erl_interface/src/legacy/global_names.c
+++ b/lib/erl_interface/src/global/global_names.c
@@ -24,8 +24,8 @@
#include "eisend.h"
#include "eirecv.h"
#include "ei_connect_int.h"
-#include "erl_interface.h"
-#include "erl_connect.h"
+#include "ei.h"
+#include "ei_connect.h"
#define GLOBALNAMEBUF (16*1024) /* not very small actually */
@@ -36,14 +36,14 @@
* caller can make one call to free().
*/
/* global:registered_names() -> [name1,name2,...] */
-char **erl_global_names(int fd, int *count)
+char **ei_global_names(ei_cnode *ec, int fd, int *count)
{
char buf[GLOBALNAMEBUF];
char *bufp=buf;
char tmpbuf[64];
int size = 0;
int index = 0;
- erlang_pid *self = erl_self();
+ erlang_pid *self = ei_self(ec);
erlang_msg msg;
int i;
int version;
diff --git a/lib/erl_interface/src/legacy/global_register.c b/lib/erl_interface/src/global/global_register.c
index 4cb6d8071f..c260ce091c 100644
--- a/lib/erl_interface/src/legacy/global_register.c
+++ b/lib/erl_interface/src/global/global_register.c
@@ -22,15 +22,14 @@
#include "eiext.h"
#include "eisend.h"
#include "eirecv.h"
-#include "erl_interface.h"
+#include "ei.h"
-int erl_global_register(int fd, const char *name, ETERM *pid)
+int ei_global_register(int fd, const char *name, erlang_pid *self)
{
char buf[EISMALLBUF];
char *bufp=buf;
char tmpbuf[64];
int index = 0;
- erlang_pid self;
erlang_msg msg;
int needlink, needatom, needmonitor;
int arity;
@@ -38,24 +37,19 @@ int erl_global_register(int fd, const char *name, ETERM *pid)
int msglen;
int i;
- /* get that pid into a better format */
- if (!erl_encode(pid,(unsigned char*)buf)) return -1;
- if (ei_decode_version(buf,&index,&version)
- || ei_decode_pid(buf,&index,&self)) return -1;
-
/* set up rpc arguments */
/* { PidFrom, { call, Mod, Fun, Args, user }} */
index = 0;
ei_encode_version(buf,&index);
ei_encode_tuple_header(buf,&index,2);
- ei_encode_pid(buf,&index,&self); /* PidFrom */
+ ei_encode_pid(buf,&index,self); /* PidFrom */
ei_encode_tuple_header(buf,&index,5);
ei_encode_atom(buf,&index,"call"); /* call */
ei_encode_atom(buf,&index,"global"); /* Mod */
ei_encode_atom(buf,&index,"register_name_external"); /* Fun */
ei_encode_list_header(buf,&index,3); /* Args: [ name, self(), cnode ] */
ei_encode_atom(buf,&index,name);
- ei_encode_pid(buf,&index,&self);
+ ei_encode_pid(buf,&index,self);
ei_encode_tuple_header(buf,&index,2);
ei_encode_atom(buf,&index,"global"); /* special "resolve" treatment */
ei_encode_atom(buf,&index,"cnode"); /* i.e. we get a SEND when conflict */
@@ -63,7 +57,7 @@ int erl_global_register(int fd, const char *name, ETERM *pid)
ei_encode_atom(buf,&index,"user"); /* user */
/* make the rpc call */
- if (ei_send_reg_encoded(fd,&self,"rex",buf,index)) return -1;
+ if (ei_send_reg_encoded(fd,self,"rex",buf,index)) return -1;
/* get the reply: expect link and an atom, or just an atom */
needlink = needatom = needmonitor = 1;
diff --git a/lib/erl_interface/src/legacy/global_unregister.c b/lib/erl_interface/src/global/global_unregister.c
index 27f68670ca..ee785a2abd 100644
--- a/lib/erl_interface/src/legacy/global_unregister.c
+++ b/lib/erl_interface/src/global/global_unregister.c
@@ -23,18 +23,18 @@
#include "eisend.h"
#include "eirecv.h"
#include "ei_connect_int.h"
-#include "erl_interface.h"
-#include "erl_connect.h"
+#include "ei_connect.h"
+#include "ei.h"
/* remove the association between name and its pid */
/* global:unregister_name(name) -> ok */
-int erl_global_unregister(int fd, const char *name)
+int ei_global_unregister(ei_cnode *ec, int fd, const char *name)
{
char buf[EISMALLBUF];
char *bufp=buf;
char tmpbuf[64];
int index = 0;
- erlang_pid *self = erl_self();
+ erlang_pid *self = ei_self(ec);
erlang_msg msg;
int i;
int version,arity,msglen;
diff --git a/lib/erl_interface/src/legacy/global_whereis.c b/lib/erl_interface/src/global/global_whereis.c
index 13c4c93ca7..afedc98030 100644
--- a/lib/erl_interface/src/legacy/global_whereis.c
+++ b/lib/erl_interface/src/global/global_whereis.c
@@ -24,23 +24,22 @@
#include "eisend.h"
#include "eirecv.h"
#include "ei_connect_int.h"
-#include "erl_interface.h"
-#include "erl_connect.h"
+#include "ei.h"
+#include "ei_connect.h"
/* return the ETERM pid corresponding to name. If caller
* provides non-NULL node, nodename will be returned there
*/
/* global:whereis_name(name) -> pid */
-ETERM *erl_global_whereis(int fd, const char *name, char *node)
+int ei_global_whereis(ei_cnode *ec, int fd, const char *name, erlang_pid* pid, char *node)
{
char buf[EISMALLBUF];
char *bufp=buf;
char tmpbuf[64];
int index = 0;
- erlang_pid *self = erl_self();
+ erlang_pid *self = ei_self(ec);
erlang_pid epid;
- ETERM *opid;
erlang_msg msg;
int i;
int version,arity,msglen;
@@ -60,7 +59,7 @@ ETERM *erl_global_whereis(int fd, const char *name, char *node)
ei_encode_atom(buf,&index,"user"); /* user */
/* make the rpc call */
- if (ei_send_reg_encoded(fd,self,"rex",buf,index)) return NULL;
+ if (ei_send_reg_encoded(fd,self,"rex",buf,index)) return -1;
while (1) {
index = EISMALLBUF;
@@ -68,7 +67,7 @@ ETERM *erl_global_whereis(int fd, const char *name, char *node)
else break;
}
- if (i != ERL_SEND) return NULL;
+ if (i != ERL_SEND) return -1;
/* expecting { rex, pid } */
index = 0;
@@ -78,24 +77,18 @@ ETERM *erl_global_whereis(int fd, const char *name, char *node)
|| ei_decode_atom(buf,&index,tmpbuf)
|| strcmp(tmpbuf,"rex")
|| ei_decode_pid(buf,&index,&epid))
- return NULL; /* bad response from other side */
-
- /* put the pid into a format for the caller */
- index = 0;
- ei_encode_pid(buf,&index,&epid);
- opid = erl_decode((unsigned char*)buf);
+ return -1; /* bad response from other side */
/* extract the nodename for the caller */
if (node) {
- char* node_str = ERL_PID_NODE(opid);
+ char* node_str = epid.node;
if (node_str) {
strcpy(node, node_str);
}
else {
- erl_free_term(opid);
- return NULL;
+ return -1;
}
}
-
- return opid;
+ *pid = epid;
+ return 0;
}
diff --git a/lib/erl_interface/src/legacy/decode_term.c b/lib/erl_interface/src/legacy/decode_term.c
deleted file mode 100644
index 72bacc3123..0000000000
--- a/lib/erl_interface/src/legacy/decode_term.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 1998-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-#include "eidef.h"
-#include "eiext.h"
-#include "putget.h"
-#include "erl_interface.h"
-
-/*
- * This file is actually part of the erl_interface library,
- * not the newer 'ei' library. The header file is still in "ei.h"
- */
-
-/* FIXME: is this to be completed? */
-
-#if (0)
-int ei_decode_term(const char *buf, int *index, void *t)
-{
- const char *s = buf + *index;
- const char *s0 = s;
-
- if (t) {
- ETERM *tmp;
-
- /* this decodes and advances s */
- if (!(tmp = erl_decode_buf((unsigned char **)&s))) return -1;
-
- *(ETERM **)t = tmp;
- *index += s - s0;
-
- return 0;
- }
- else {
- int tmpindex = *index;
- long ttype;
- int arity;
- int i;
-
- /* these are all the external types */
- switch ((ttype = get8(s))) {
- case ERL_SMALL_INTEGER_EXT:
- case ERL_INTEGER_EXT:
- case ERL_SMALL_BIG_EXT:
- return ei_decode_long(buf,index,NULL);
-
- case ERL_FLOAT_EXT:
- case NEW_FLOAT_EXT:
- return ei_decode_double(buf,index,NULL);
-
- case ERL_ATOM_EXT:
- return ei_decode_atom(buf,index,NULL);
-
- case ERL_REFERENCE_EXT:
- case ERL_NEW_REFERENCE_EXT:
- return ei_decode_ref(buf,index,NULL);
-
- case ERL_PORT_EXT:
- return ei_decode_port(buf,index,NULL);
-
- case ERL_PID_EXT:
- return ei_decode_pid(buf,index,NULL);
-
- case ERL_SMALL_TUPLE_EXT:
- case ERL_LARGE_TUPLE_EXT:
- if (ei_decode_tuple_header(buf,index,&arity) < 0)
- return -1;
-
- for (i=0; i<arity; i++) {
- if (ei_decode_term(buf,index,NULL)) {
- /* restore possibly changed index before returning */
- *index = tmpindex;
- return -1;
- }
- }
- return 0;
-
- case ERL_STRING_EXT:
- return ei_decode_string(buf,index,NULL);
-
- case ERL_LIST_EXT:
- case ERL_NIL_EXT:
- if (ei_decode_list_header(buf,index,&arity) < 0)
- return -1;
-
- if (arity) {
- for (i=0; i<arity; i++) {
- if (ei_decode_term(buf,index,NULL) < 0) {
- /* restore possibly changed index before returning */
- *index = tmpindex;
- return -1;
- }
- }
- if (ei_decode_list_header(buf,index,&arity) < 0) {
- *index = tmpindex;
- return -1;
- }
- }
- return 0;
-
- case ERL_BINARY_EXT:
- return ei_decode_binary(buf,index,NULL,NULL);
-
- case ERL_LARGE_BIG_EXT:
- default:
- break;
- }
- }
-
- return -1;
-}
-#else
-int ei_decode_term(const char *buf, int *index, void *t)
-{
- const char *s = buf + *index;
- const char *s0 = s;
- ETERM *tmp;
-
- /* this decodes and advances s */
- if (!(tmp = erl_decode_buf((unsigned char **)&s))) return -1;
-
- if (t) *(ETERM **)t = tmp;
- else erl_free_term(tmp);
-
- *index += s - s0;
-
- return 0;
-}
-#endif
diff --git a/lib/erl_interface/src/legacy/encode_term.c b/lib/erl_interface/src/legacy/encode_term.c
deleted file mode 100644
index df740ab487..0000000000
--- a/lib/erl_interface/src/legacy/encode_term.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 1998-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-#include "eidef.h"
-#include "eiext.h"
-#include "putget.h"
-#include "ei_x_encode.h"
-#include "erl_interface.h"
-#include "erl_marshal.h"
-
-/* FIXME: depends on old erl_interface */
-
-int ei_x_encode_term(ei_x_buff* x, void* t)
-{
- int i = x->index;
- ei_encode_term(NULL, &i, t);
- if (!x_fix_buff(x, i))
- return -1;
- return ei_encode_term(x->buff, &x->index, t);
-}
-
-int ei_encode_term(char *buf, int *index, void *t)
-{
- char *s = buf + *index;
- char *s0 = s;
-
- if (!buf) s += erl_term_len(t) -1; /* -1 for version */
- else {
- /* this encodes all but the version at the start */
- /* and it will move s forward the right number of bytes */
- if (erl_encode_it(t,(unsigned char **)&s, 5)) return -1;
- }
-
- *index += s - s0;
-
- return 0;
-}
-
diff --git a/lib/erl_interface/src/legacy/erl_config.h b/lib/erl_interface/src/legacy/erl_config.h
deleted file mode 100644
index fb72169f23..0000000000
--- a/lib/erl_interface/src/legacy/erl_config.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 1998-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-#ifndef _ERL_CONFIG_H
-#define _ERL_CONFIG_H
-
-#endif /* _ERL_CONFIG_H */
diff --git a/lib/erl_interface/src/legacy/erl_connect.c b/lib/erl_interface/src/legacy/erl_connect.c
deleted file mode 100644
index e2fd4611c0..0000000000
--- a/lib/erl_interface/src/legacy/erl_connect.c
+++ /dev/null
@@ -1,467 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-/*
- * Purpose: Connect to any node at any host.
- */
-
-/***************************************************************************
- *
- * 'erl_interface' node connection handling is to use 'ei' for all
- * operations without access to the internal structure of saved data,
- * e.i. it should use the public interface functions. The connection
- * handling can be seen as a restricted node interface where only one
- * node can be used in one operating system process.
- *
- ***************************************************************************/
-
-#include "eidef.h"
-
-#include <stdlib.h>
-#include <sys/types.h>
-#include <fcntl.h>
-
-#ifdef __WIN32__
-#include <winsock2.h>
-#include <windows.h>
-#include <winbase.h>
-
-#elif VXWORKS
-#include <vxWorks.h>
-#include <hostLib.h>
-#include <selectLib.h>
-#include <ifLib.h>
-#include <sockLib.h>
-#include <taskLib.h>
-#include <inetLib.h>
-
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/times.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <timers.h>
-
-#include "erl_error.h"
-
-#else /* some other unix */
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/times.h>
-
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <sys/utsname.h> /* for gen_challenge (NEED FIX?) */
-#endif
-
-/* common includes */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-/* FIXME include less */
-#include "erl_interface.h"
-#include "erl_connect.h"
-#include "erl_eterm.h"
-#include "erl_malloc.h"
-#include "putget.h"
-#include "ei.h"
-#include "ei_connect_int.h"
-#include "ei_locking.h"
-#include "ei_epmd.h"
-#include "ei_internal.h"
-
-/* rpc_from() uses a buffer this size */
-#ifndef MAX_RECEIVE_BUF
-#define MAX_RECEIVE_BUF 32*1024
-#endif
-
-/* This is the global state of the old erl_* API */
-
-static ei_cnode erl_if_ec;
-
-/***************************************************************************
- *
- * API: erl_connect_init()
- * API: erl_connect_xinit()
- *
- * Returns 1 on success and 0 on failure.
- * Not documented to set erl_errno.
- *
- ***************************************************************************/
-
-int erl_connect_init(int this_node_number, char *cookie, short creation)
-{
- char nn[MAXATOMLEN];
-
- sprintf(nn, "c%d", this_node_number);
-
- return ei_connect_init(&erl_if_ec, nn, cookie, creation) == 0;
-}
-
-/* FIXME documented to use struct in_addr as addr */
-
-int erl_connect_xinit(char *thishostname,
- char *thisalivename,
- char *thisnodename,
- struct in_addr *thisipaddr,
- char *cookie,
- short creation)
-{
- return ei_connect_xinit(&erl_if_ec, thishostname, thisalivename,
- thisnodename, thisipaddr, cookie, creation) >= 0;
-}
-
-/***************************************************************************
- *
- * API: erl_connect()
- * API: erl_xconnect()
- *
- * Set up a connection to a given Node, and interchange hand shake
- * messages with it.
- *
- * Returns valid file descriptor on success and < 0 on failure.
- * Set erl_errno to EHOSTUNREACH, ENOMEM, EIO or errno from socket(2)
- * or connect(2).
- *
- ***************************************************************************/
-
-int erl_connect(char *nodename)
-{
- int res = ei_connect(&erl_if_ec, nodename);
- if (res < 0) erl_errno = EIO;
- return res;
-}
-
-/* FIXME documented to use struct in_addr as addr */
-
-int erl_xconnect(Erl_IpAddr addr, char *alivename)
-{
- return ei_xconnect(&erl_if_ec, addr, alivename);
-}
-
-
-/***************************************************************************
- *
- * API: erl_close_connection()
- *
- * Returns 0 on success and -1 on failure.
- *
- ***************************************************************************/
-
-int erl_close_connection(int fd)
-{
- return ei_close_connection(fd);
-}
-
-/*
- * Accept and initiate a connection from another
- * Erlang node. Return a file descriptor at success,
- * otherwise -1;
- */
-int erl_accept(int lfd, ErlConnect *conp)
-{
- return ei_accept(&erl_if_ec, lfd, conp);
-}
-
-
-/* Receives a message from an Erlang socket.
- * If the message was a TICK it is immediately
- * answered. Returns: ERL_ERROR, ERL_TICK or
- * the number of bytes read.
- */
-int erl_receive(int s, unsigned char *bufp, int bufsize)
-{
- return ei_receive(s, bufp, bufsize);
-}
-
-/*
- * Send an Erlang message to a registered process
- * at the Erlang node, connected with a socket.
- */
-int erl_reg_send(int fd, char *server_name, ETERM *msg)
-{
- ei_x_buff x;
- int r;
-
- if (ei_x_new_with_version(&x) < 0) {
- erl_errno = ENOMEM;
- return 0;
- }
- if (ei_x_encode_term(&x, msg) < 0) {
- erl_errno = EINVAL;
- r = 0;
- } else {
- r = ei_reg_send(&erl_if_ec, fd, server_name, x.buff, x.index);
- }
- ei_x_free(&x);
- return r == 0;
-}
-
-/*
- * Sends an Erlang message to a process at an Erlang node
- */
-int erl_send(int fd, ETERM *to ,ETERM *msg)
-{
- erlang_pid topid;
- ei_x_buff x;
- int r;
-
- ei_x_new_with_version(&x);
- ei_x_encode_term(&x, msg);
- /* make the to-pid */
- if (!ERL_IS_PID(to)) {
- ei_x_free(&x);
- erl_errno = EINVAL;
- return -1;
- }
-
- if (to->uval.pidval.node.latin1) {
- strcpy(topid.node, to->uval.pidval.node.latin1);
- }
- else {
- strcpy(topid.node, to->uval.pidval.node.utf8);
- }
- topid.num = ERL_PID_NUMBER(to);
- topid.serial = ERL_PID_SERIAL(to);
- topid.creation = ERL_PID_CREATION(to);
- r = ei_send(fd, &topid, x.buff, x.index);
- ei_x_free(&x);
- return r == 0;
-}
-
-static int erl_do_receive_msg(int fd, ei_x_buff* x, ErlMessage* emsg)
-{
- erlang_msg msg;
-
- int r;
- msg.from.node[0] = msg.to.node[0] = msg.toname[0] = '\0';
- r = ei_do_receive_msg(fd, 0, &msg, x, 0);
-
- if (r == ERL_MSG) {
- int index = 0;
- emsg->type = msg.msgtype;
-
- /*
- We can't call ei_decode_term for cases where there are no
- data following the type information. If there are other
- types added later where there are data this case has to be
- extended.
- */
-
- switch (msg.msgtype) {
- case ERL_SEND:
- case ERL_REG_SEND:
- case ERL_EXIT:
- case ERL_EXIT2:
- if (ei_decode_term(x->buff, &index, &emsg->msg) < 0)
- r = ERL_ERROR;
- break;
- default:
- emsg->msg = NULL; /* Not needed but may avoid problems for unsafe caller */
- break;
- }
- } else
- emsg->msg = NULL;
- if (msg.from.node[0] != '\0')
- emsg->from = erl_mk_pid(msg.from.node, msg.from.num, msg.from.serial, msg.from.creation);
- else
- emsg->from = NULL;
- if (msg.to.node[0] != '\0')
- emsg->to = erl_mk_pid(msg.to.node, msg.to.num, msg.to.serial, msg.to.creation);
- else
- emsg->to = NULL;
- strcpy(emsg->to_name, msg.toname);
- return r;
-}
-
-int erl_receive_msg(int fd, unsigned char *buf, int bufsize, ErlMessage *emsg)
-{
- ei_x_buff x;
- int r;
-
- ei_x_new(&x);
- r = erl_do_receive_msg(fd, &x, emsg);
- /* FIXME what is this about? */
- if (bufsize > x.index)
- bufsize = x.index;
- memcpy(buf, x.buff, bufsize);
- ei_x_free(&x);
- return r;
-}
-
-int erl_xreceive_msg(int fd, unsigned char **buf, int *bufsize,
- ErlMessage *emsg)
-{
- ei_x_buff x;
- int r;
-
- ei_x_new(&x);
- r = erl_do_receive_msg(fd, &x, emsg);
- if (*bufsize < x.index)
- *buf = erl_realloc(*buf, x.index);
- *bufsize = x.index;
- memcpy(*buf, x.buff, *bufsize);
- ei_x_free(&x);
- return r;
-}
-
-/*
- * The RPC consists of two parts, send and receive.
- * Here is the send part !
- * { PidFrom, { call, Mod, Fun, Args, user }}
- */
-/*
- * Now returns non-negative number for success, negative for failure.
- */
-int erl_rpc_to(int fd, char *mod, char *fun, ETERM *args)
-{
- int r;
- ei_x_buff x;
-
- ei_x_new(&x);
- ei_x_encode_term(&x, args);
- r = ei_rpc_to(&erl_if_ec, fd, mod, fun, x.buff, x.index);
- ei_x_free(&x);
- return r;
-} /* rpc_to */
-
- /*
- * And here is the rpc receiving part. A negative
- * timeout means 'infinity'. Returns either of: ERL_MSG,
- * ERL_TICK, ERL_ERROR or ERL_TIMEOUT.
-*/
-int erl_rpc_from(int fd, int timeout, ErlMessage *emsg)
-{
- fd_set readmask;
- struct timeval tv;
- struct timeval *t = NULL;
- unsigned char rbuf[MAX_RECEIVE_BUF];
-
- if (timeout >= 0) {
- tv.tv_sec = timeout / 1000;
- tv.tv_usec = (timeout % 1000) * 1000;
- t = &tv;
- }
-
- FD_ZERO(&readmask);
- FD_SET(fd,&readmask);
-
- switch (select(fd+1, &readmask, NULL, NULL, t)) {
- case -1:
- erl_errno = EIO;
- return ERL_ERROR;
- case 0:
- erl_errno = ETIMEDOUT;
- return ERL_TIMEOUT;
- default:
- if (FD_ISSET(fd, &readmask))
- return erl_receive_msg(fd, rbuf, MAX_RECEIVE_BUF, emsg);
- else {
- erl_errno = EIO;
- return ERL_ERROR;
- }
- }
-} /* rpc_from */
-
-/*
- * A true RPC. It return a NULL pointer
- * in case of failure, otherwise a valid
- * (ETERM *) pointer containing the reply
- */
-ETERM *erl_rpc(int fd, char *mod, char *fun, ETERM *args)
-{
- int i;
- ETERM *ep;
- ErlMessage emsg;
-
- if (erl_rpc_to(fd, mod, fun, args) < 0) {
- return NULL; }
- while ((i=erl_rpc_from(fd, ERL_NO_TIMEOUT, &emsg)) == ERL_TICK);
-
- if (i == ERL_ERROR) return NULL;
-
- ep = erl_element(2,emsg.msg); /* {RPC_Tag, RPC_Reply} */
- erl_free_term(emsg.msg);
- erl_free_term(emsg.to);
- return ep;
-} /* rpc */
-
-
-/*
- ** Handshake
- */
-
-int erl_publish(int port)
-{
- return ei_publish(&erl_if_ec, port);
-}
-
-int erl_unpublish(const char *alive)
-{
- return ei_unpublish_tmo(alive,0);
-}
-
-erlang_pid *erl_self(void)
-{
- return ei_self(&erl_if_ec);
-}
-
-const char *erl_thisnodename(void)
-{
- return ei_thisnodename(&erl_if_ec);
-}
-
-const char *erl_thishostname(void)
-{
- return ei_thishostname(&erl_if_ec);
-}
-
-const char *erl_thisalivename(void)
-{
- return ei_thisalivename(&erl_if_ec);
-}
-
-const char *erl_thiscookie(void)
-{
- return ei_thiscookie(&erl_if_ec);
-}
-
-short erl_thiscreation(void)
-{
- return ei_thiscreation(&erl_if_ec);
-}
diff --git a/lib/erl_interface/src/legacy/erl_error.c b/lib/erl_interface/src/legacy/erl_error.c
deleted file mode 100644
index a3bbfbc58f..0000000000
--- a/lib/erl_interface/src/legacy/erl_error.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-/*
- * Function: Some nice error routines taken from:
- * "Advanced Programming in the UNIX Environment",
- * by W.Richard Stevens
- *
- * void erl_err_sys(const char *fmt, ... ) fatal, sys-error
- * void erl_err_ret(const char *fmt, ... ) non-fatal, sys-error
- * void erl_err_quit(const char *fmt, ...) fatal, non-sys-error
- * void erl_err_msg(const char *fmt, ... ) non-fatal, non-sys-error
- */
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef VRTX /* What's VRIX? [sverkerw] */
-#define __READY_EXTENSIONS__
-#endif
-#include <errno.h>
-
-#if defined(VXWORKS)
-#include <taskLib.h>
-#include <taskVarLib.h>
-#endif
-
-#include "eidef.h"
-#include "erl_interface.h"
-#include "erl_error.h"
-
-/* Forward */
-static void err_doit(int, const char*, va_list);
-/* __attribute__ ((format (printf, 2, 0)))*/
-
-/*
- * Some thoughts on flushing stdout/stderr:
- *
- * The defaults are reasonable (linebuffered stdout, unbuffered
- * stderr). If they are in effect (the user neither knows nor cares),
- * there's no need to flush.
- *
- * If the user changes these defaults (and knows what he's doing, so
- * he knows and cares) we shouldn't surprise him by
- * second-guessing. So there's a need to not flush.
- *
- * If the user doesn't know what he's doing, he's hosed anyway.
- */
-
-/* Fatal error related to a system call.
- * Print a message and terminate.
- */
-void erl_err_sys(const char *fmt, ... )
-{
- va_list ap;
-
- va_start(ap, fmt);
- err_doit(1, fmt, ap);
- va_end(ap);
- exit(1);
-} /* erl_err_sys */
-
-/* Nonfatal error related to a system call.
- * Print a message and return
- */
-void erl_err_ret(const char *fmt, ... )
-{
- va_list ap;
-
- va_start(ap, fmt);
- err_doit(1, fmt, ap);
- va_end(ap);
- return;
-} /* erl_err_ret */
-
-/* Nonfatal error unrelated to a system call.
- * Print a message and return
- */
-void erl_err_msg(const char *fmt, ... )
-{
- va_list ap;
-
- va_start(ap, fmt);
- err_doit(0, fmt, ap);
- va_end(ap);
- return;
-} /* erl_err_msg */
-
-/* Fatal error unrelated to a system call.
- * Print a message and terminate
- */
-void erl_err_quit(const char *fmt, ... )
-{
- va_list ap;
-
- va_start(ap, fmt);
- err_doit(0, fmt, ap);
- va_end(ap);
- exit(1);
-} /* erl_err_quit */
-
-
-
-/*
- * For example on SunOS we don't have the ANSI C strerror.
- *
- * maybe move to a convenince lib [sverkerw]
- */
-#ifndef HAVE_STRERROR
-
-/* FIXME: move to configure */
-/* CONFIG: probe for sys_nerr/_sys_nerr */
-extern int sys_nerr;
-
-/* CONFIG: probe for sys_errlist/_sys_errlist and maybe for const-ness */
-#ifdef FREEBSD
-extern const char * const sys_errlist[];
-#else
-extern char * sys_errlist[];
-#endif
-
-/* Should be in string.h */
-/* Is supposed to return 'char *' (no const-ness in ANSI's prototype),
- but if you rewrite the returned string in place you deserve to
- lose. */
-static const char *strerror(int errnum)
-{
- if (errnum >= 0 && errnum < sys_nerr) {
- return sys_errlist[errnum];
- } else {
- /* Enough buffer for 64 bits of error. It should last a while. */
- /* FIXME problem for threaded ? */
- static char b[] = "(error -9223372036854775808)";
- sprintf(b, "(error %d)", errnum);
- buf[sizeof(b)-1] = '\0';
- return b;
- }
-}
-#endif /* !HAVE_STRERROR */
-
-
-/* Print a message and return to caller.
- * Caller specifies "errnoflag".
- */
-static void err_doit(int errnoflag, const char *fmt, va_list ap)
-{
-#ifndef NO_ERR_MSG
- int errno_save;
-
- errno_save = errno;
-
- vfprintf(stderr, fmt, ap);
- if (errnoflag)
- {
- fputs(": ", stderr);
- fputs(strerror(errno_save), stderr);
- }
- fputs("\n", stderr);
-#endif
-
- return;
-} /* err_doit */
-
diff --git a/lib/erl_interface/src/legacy/erl_error.h b/lib/erl_interface/src/legacy/erl_error.h
deleted file mode 100644
index 0cce083ae7..0000000000
--- a/lib/erl_interface/src/legacy/erl_error.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-#ifndef _ERL_ERROR_H
-#define _ERL_ERROR_H
-
-/* Initialize thread/task-safe erl_errno handling */
-void erl_init_errno(void);
-
-#endif /* _ERL_ERROR_H */
diff --git a/lib/erl_interface/src/legacy/erl_eterm.c b/lib/erl_interface/src/legacy/erl_eterm.c
deleted file mode 100644
index 7ecea83b1a..0000000000
--- a/lib/erl_interface/src/legacy/erl_eterm.c
+++ /dev/null
@@ -1,1413 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2017. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-/*
- * Purpose: Representation of Erlang terms.
- */
-
-#include "eidef.h"
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#if defined(HAVE_ISFINITE)
-#include <math.h>
-#endif
-
-#include "ei_locking.h"
-#include "ei_resolve.h"
-#include "erl_interface.h"
-#include "erl_eterm.h"
-#include "erl_malloc.h"
-#include "erl_marshal.h"
-#include "erl_error.h"
-#include "erl_internal.h"
-#include "ei_internal.h"
-#include "putget.h"
-
-#define ERL_IS_BYTE(x) (ERL_IS_INTEGER(x) && (ERL_INT_VALUE(x) & ~0xFF) == 0)
-
-/* FIXME use unsigned char, or uint8 for buffers, cast (int) really needed? */
-
-static void iolist_to_buf(const ETERM* term, char** bufp);
-static char* strsave(const char *src);
-
-/***************************************************************************
- *
- * API: erl_init()
- *
- * Not documented to set erl_errno.
- *
- ***************************************************************************/
-
-/* all initialisation of erl_interface modules should be called from here */
-/* order is important: erl_malloc and erl_resolve depend on ei_locking */
-/* NOTE: don't call this directly - please use erl_init() macro defined
- in ei_locking.h! */
-void erl_init(void *hp,long heap_size)
-{
- erl_init_malloc(hp, heap_size);
- erl_init_marshal();
- (void) ei_init();
-}
-
-void erl_set_compat_rel(unsigned rel)
-{
- ei_set_compat_rel(rel);
-}
-
-/*
- * Create an INTEGER. Depending on its value it
- * may end up as a BigNum.
- */
-ETERM *erl_mk_int (int i)
-{
- ETERM *ep;
-
- ep = erl_alloc_eterm(ERL_INTEGER);
- ERL_COUNT(ep) = 1;
- ERL_INT_VALUE(ep) = i;
- return ep;
-}
-
-ETERM *erl_mk_longlong (long long i)
-{
- ETERM *ep;
-
- ep = erl_alloc_eterm(ERL_LONGLONG);
- ERL_COUNT(ep) = 1;
- ERL_LL_VALUE(ep) = i;
- return ep;
-}
-
-/*
- * Create an UNSIGNED INTEGER. Depending on its
- * value it may end up as a BigNum.
- */
-
-ETERM *erl_mk_uint (unsigned int u)
-{
- ETERM *ep;
-
- ep = erl_alloc_eterm(ERL_U_INTEGER);
- ERL_COUNT(ep) = 1;
- ERL_INT_UVALUE(ep) = u;
- return ep;
-}
-
-ETERM *erl_mk_ulonglong (unsigned long long i)
-{
- ETERM *ep;
-
- ep = erl_alloc_eterm(ERL_U_LONGLONG);
- ERL_COUNT(ep) = 1;
- ERL_LL_UVALUE(ep) = i;
- return ep;
-}
-
-/*
- * Create a FLOAT.
- */
-ETERM *erl_mk_float (double d)
-{
- ETERM *ep;
-
-#if defined(HAVE_ISFINITE)
- /* Erlang does not handle Inf and NaN, so we return an error
- * rather than letting the Erlang VM complain about a bad external
- * term. */
- if(!isfinite(d)) {
- return NULL;
- }
-#endif
-
- ep = erl_alloc_eterm(ERL_FLOAT);
- ERL_COUNT(ep) = 1;
- ERL_FLOAT_VALUE(ep) = d;
- return ep;
-}
-
-/*
- * Create an ATOM
- */
-ETERM *erl_mk_atom (const char *s)
-{
- ETERM *ep;
-
- /* ASSERT(s != NULL); */
- if (!s) return NULL;
-
- ep = erl_alloc_eterm(ERL_ATOM);
- ERL_COUNT(ep) = 1;
- if (erl_atom_init_latin1(&ep->uval.aval.d, s) == NULL) {
- erl_free_term(ep);
- erl_errno = ENOMEM;
- return NULL;
- }
- return ep;
-}
-
-char* erl_atom_ptr_latin1(Erl_Atom_data* a)
-{
- if (a->latin1 == NULL) {
- erlang_char_encoding enc;
- a->lenL = utf8_to_latin1(NULL, a->utf8, a->lenU, a->lenU, &enc);
- if (a->lenL < 0) {
- a->lenL = 0;
- return NULL;
- }
- if (enc == ERLANG_ASCII) {
- a->latin1 = a->utf8;
- }
- else {
- a->latin1 = malloc(a->lenL+1);
- utf8_to_latin1(a->latin1, a->utf8, a->lenU, a->lenL, NULL);
- a->latin1[a->lenL] = '\0';
- }
- }
- return a->latin1;
-}
-
-char* erl_atom_ptr_utf8(Erl_Atom_data* a)
-{
- if (a->utf8 == NULL) {
- erlang_char_encoding enc;
- a->lenU = latin1_to_utf8(NULL, a->latin1, a->lenL, a->lenL*2, &enc);
- if (enc == ERLANG_ASCII) {
- a->utf8 = a->latin1;
- }
- else {
- a->utf8 = malloc(a->lenU + 1);
- latin1_to_utf8(a->utf8, a->latin1, a->lenL, a->lenU, NULL);
- a->utf8[a->lenU] = '\0';
- }
- }
- return a->utf8;
-}
-
-int erl_atom_size_latin1(Erl_Atom_data* a)
-{
- if (a->latin1 == NULL) {
- erl_atom_ptr_latin1(a);
- }
- return a->lenL;
-}
-int erl_atom_size_utf8(Erl_Atom_data* a)
-{
- if (a->utf8 == NULL) {
- erl_atom_ptr_utf8(a);
- }
- return a->lenU;
-}
-char* erl_atom_init_latin1(Erl_Atom_data* a, const char* s)
-{
- a->lenL = strlen(s);
- if ((a->latin1 = strsave(s)) == NULL)
- {
- return NULL;
- }
- a->utf8 = NULL;
- a->lenU = 0;
- return a->latin1;
-}
-
-
-/*
- * Given a string as input, creates a list.
- */
-ETERM *erl_mk_string(const char *s)
-{
- /* ASSERT(s != NULL); */
- if (!s) return NULL;
-
- return erl_mk_estring(s, strlen(s));
-}
-
-ETERM *erl_mk_estring(const char *s, int len)
-{
- ETERM *ep;
- int i;
-
- if ((!s) || (len < 0)) return NULL;
-
- /*
- * ASSERT(s != NULL);
- * ASSERT(len >= 0);
- */
-
- ep = erl_mk_empty_list();
- for (i = len-1; i >= 0; i--) {
- ETERM* integer;
- ETERM* cons;
-
- integer = erl_alloc_eterm(ERL_INTEGER);
- ERL_COUNT(integer) = 1;
- ERL_INT_VALUE(integer) = (unsigned char)s[i];
-
- cons = erl_alloc_eterm(ERL_LIST);
- ERL_COUNT(cons) = 1;
- HEAD(cons) = integer;
- TAIL(cons) = ep;
- ep = cons;
- }
- return ep;
-}
-
-/*
- * Create a PID.
- */
-ETERM *erl_mk_pid(const char *node,
- unsigned int number,
- unsigned int serial,
- unsigned char creation)
-{
- ETERM *ep;
-
- if (!node) return NULL;
- /* ASSERT(node != NULL); */
-
- ep = erl_alloc_eterm(ERL_PID);
- ERL_COUNT(ep) = 1;
- if (erl_atom_init_latin1(&ep->uval.pidval.node, node) == NULL)
- {
- erl_free_term(ep);
- erl_errno = ENOMEM;
- return NULL;
- }
- erl_mk_pid_helper(ep, number, serial, creation & 0x03);
- return ep;
-}
-
-void erl_mk_pid_helper(ETERM *ep, unsigned int number,
- unsigned int serial, unsigned int creation)
-{
- ERL_PID_NUMBER(ep) = number & 0x7fff; /* 15 bits */
- ERL_PID_SERIAL(ep) = serial & 0x1fff; /* 13 bits */
- ERL_PID_CREATION(ep) = creation; /* 32 bits */
-}
-
-/*
- * Create a PORT.
- */
-ETERM *erl_mk_port(const char *node,
- unsigned int number,
- unsigned char creation)
-{
- ETERM *ep;
-
- if (!node) return NULL;
- /* ASSERT(node != NULL); */
-
- ep = erl_alloc_eterm(ERL_PORT);
- ERL_COUNT(ep) = 1;
- if (erl_atom_init_latin1(&ep->uval.portval.node, node) == NULL)
- {
- erl_free_term(ep);
- erl_errno = ENOMEM;
- return NULL;
- }
- erl_mk_port_helper(ep, number, creation);
- return ep;
-}
-
-void erl_mk_port_helper(ETERM* ep, unsigned number, unsigned int creation)
-{
- ERL_PORT_NUMBER(ep) = number & 0x0fffffff; /* 18 bits */
- ERL_PORT_CREATION(ep) = creation; /* 32 bits */
-}
-
-/*
- * Create any kind of reference.
- */
-ETERM *__erl_mk_reference (ETERM* t,
- const char *node,
- size_t len,
- unsigned int n[],
- unsigned int creation)
-{
- if (t == NULL) {
- if (node == NULL) return NULL;
-
- t = erl_alloc_eterm(ERL_REF);
- ERL_COUNT(t) = 1;
-
- if (erl_atom_init_latin1(&t->uval.refval.node, node) == NULL)
- {
- erl_free_term(t);
- erl_errno = ENOMEM;
- return NULL;
- }
- }
- ERL_REF_LEN(t) = len;
- ERL_REF_NUMBERS(t)[0] = n[0] & 0x3ffff; /* 18 bits */
- ERL_REF_NUMBERS(t)[1] = n[1];
- ERL_REF_NUMBERS(t)[2] = n[2];
- ERL_REF_CREATION(t) = creation; /* 32 bits */
-
- return t;
-}
-
-/*
- * Create a REFERENCE.
- */
-ETERM *erl_mk_ref (const char *node,
- unsigned int number,
- unsigned char creation)
-{
- unsigned int n[3] = {0, 0, 0};
- n[0] = number;
- return __erl_mk_reference(NULL, node, 1, n, creation);
-}
-
-/*
- * Create a long REFERENCE.
- */
-ETERM *
-erl_mk_long_ref (const char *node,
- unsigned int n1, unsigned int n2, unsigned int n3,
- unsigned char creation)
-{
- unsigned int n[3] = {0, 0, 0};
- n[0] = n3; n[1] = n2; n[2] = n1;
- return __erl_mk_reference(NULL, node, 3, n, creation);
-}
-
-/*
- * Create a BINARY.
- */
-ETERM *erl_mk_binary (const char *b, int size)
-{
- ETERM *ep;
-
- if ((!b) || (size < 0)) return NULL;
- /* ASSERT(b != NULL); */
-
- ep = erl_alloc_eterm(ERL_BINARY);
- ERL_COUNT(ep) = 1;
- ERL_BIN_SIZE(ep) = size;
- ERL_BIN_PTR(ep) = (unsigned char *) erl_malloc(size);
- memcpy(ERL_BIN_PTR(ep), b, size);
- return ep;
-}
-
-/*
- * Create a TUPLE. For each element in the tuple
- * bump its reference counter.
- */
-ETERM *erl_mk_tuple (ETERM **arr,int size)
-{
- ETERM *ep;
- int i;
-
- if ((!arr) || (size < 0)) return NULL;
- for (i=0; i<size; i++) if (!arr[i]) return NULL;
- /* ASSERT(arr != NULL); */
-
- ep = erl_alloc_eterm(ERL_TUPLE);
- ERL_COUNT(ep) = 1;
- ERL_TUPLE_SIZE(ep) = size;
- ERL_TUPLE_ELEMS(ep) = (ETERM**) erl_malloc((size) * (sizeof(ETERM*)));
- for (i = 0; i < size; i++) {
- /* ASSERT(arr[i] != NULL); */
- ERL_COUNT(arr[i])++;
- ERL_TUPLE_ELEMENT(ep, i) = arr[i];
- }
- return ep;
-}
-
-/*
- * SET an ELEMENT in a TUPLE. Free the old element
- * and bump the reference counter of the new one.
- * Return 1 on success, otherwise 0.
- */
-#if 0
-int erl_setelement (int ix, ETERM *ep, ETERM *vp)
-{
- if ((!ep) || (!vp)) return 0;
- /* ASSERT(ep != NULL);
- * ASSERT(vp != NULL);
- */
-
- if ((ERL_TYPE(ep) == ERL_TUPLE) && (ix <= ERL_TUPLE_SIZE(ep))) {
- erl_free_term(ERL_TUPLE_ELEMENT(ep, ix-1));
- ERL_TUPLE_ELEMENT(ep, ix-1) = vp;
- ERL_COUNT(vp)++;
- return 1;
- }
- erl_err_msg("<ERROR> erl_setelement: Bad type to setelement or out of range \n");
- return 0;
-}
-#endif
-
-/*
- * Extract an ELEMENT from a TUPLE. Bump the
- * reference counter on the extracted object.
- */
-ETERM *erl_element (int ix, const ETERM *ep)
-{
- if ((!ep) || (ix < 0)) return NULL;
- /*
- * ASSERT(ep != NULL);
- * ASSERT(ix >= 0);
- */
-
- if ((ERL_TYPE(ep) == ERL_TUPLE) && (ix <= ERL_TUPLE_SIZE(ep))) {
- ERL_COUNT(ERL_TUPLE_ELEMENT(ep, ix-1))++;
- return ERL_TUPLE_ELEMENT(ep, ix-1);
- }
- else
- return NULL;
-} /* erl_element */
-
-ETERM *erl_mk_empty_list(void)
-{
- ETERM *ep;
-
- ep = erl_alloc_eterm(ERL_EMPTY_LIST);
- ERL_COUNT(ep) = 1;
- return ep;
-}
-
-/*
- * Construct a new list by CONS'ing a HEAD on
- * to the TAIL. Bump the reference counter on
- * the head and tail object. Note that we allow
- * non-well formed lists to be created.
- */
-ETERM *erl_cons(ETERM *hd, ETERM *tl)
-{
- ETERM *ep;
-
- if ((!hd) || (!tl)) return NULL;
-
- /*
- * ASSERT(hd != NULL);
- * ASSERT(tl != NULL);
- */
-
- ep = erl_alloc_eterm(ERL_LIST);
- ERL_COUNT(ep) = 1;
- HEAD(ep) = hd;
- TAIL(ep) = tl;
- ERL_COUNT(hd)++;
- ERL_COUNT(tl)++;
- return ep;
-}
-
-/*
- * Extract the HEAD of a LIST. Bump the reference
- * counter on the head object.
- */
-ETERM *erl_hd (const ETERM *ep)
-{
- if (!ep) return NULL;
- /* ASSERT(ep != NULL); */
-
- if (ERL_TYPE(ep) != ERL_LIST) {
- return (ETERM *) NULL;
- }
- ERL_COUNT(ERL_CONS_HEAD(ep))++;
- return ERL_CONS_HEAD(ep);
-}
-
-/*
- * Extract the TAIL of a LIST. Bump the reference
- * counter on the tail object.
- */
-ETERM *erl_tl (const ETERM *ep)
-{
- ETERM *tl;
-
- if (!ep) return NULL;
- /* ASSERT(ep != NULL); */
-
- if (ERL_TYPE(ep) != ERL_LIST) {
- return (ETERM *) NULL;
- }
-
- tl = TAIL(ep);
- ERL_COUNT(tl)++;
- return tl;
-}
-
-/*
- * Create a LIST from an array of elements. Note that
- * we create it from the last element in the array to
- * the first. Also, note that we decrement the reference
- * counter for each member in the list but the first one.
- * This is done because of the use of erl_cons.
- */
-
-ETERM *erl_mk_list (ETERM **arr, int size)
-{
- ETERM *ep;
- int i;
-
- if ((!arr) || (size < 0)) return NULL;
- for (i=0; i<size; i++) if (!arr[i]) return NULL;
-
- /* ASSERT(arr != NULL); */
- ep = erl_mk_empty_list();
- if (size > 0) {
- ERL_COUNT(ep)--;
- }
-
- for (i = size-1; i >= 0; i--) {
- /* ASSERT(arr[i] != NULL); */
- ep = erl_cons(arr[i], ep);
- if (i > 0)
- ERL_COUNT(ep)--; /* Internal reference */
- }
- return ep;
-}
-
-/*
- * Create an empty VARIABLE.
- */
-ETERM *erl_mk_var(const char *s)
-{
- ETERM *ep;
-
- if (!s) return NULL;
-
- /* ASSERT(s != NULL); */
-
- ep = erl_alloc_eterm(ERL_VARIABLE);
- ERL_COUNT(ep) = 1;
- ERL_VAR_LEN(ep) = strlen(s);
- if ((ERL_VAR_NAME(ep) = strsave(s)) == NULL)
- {
- erl_free_term(ep);
- erl_errno = ENOMEM;
- return NULL;
- }
- ERL_VAR_VALUE(ep) = (ETERM *) NULL;
- return ep;
-}
-
-/*
- * Return the CONTENT of a VARIABLE with NAME.
- * If the content is non-nil then bump its
- * reference counter.
- */
-ETERM *erl_var_content (const ETERM *ep, const char *name)
-{
- int i;
- ETERM *vp;
-
- if ((!ep) || (!name)) return NULL;
-
- /* ASSERT(ep != NULL); */
-
- switch(ERL_TYPE(ep))
- {
- case ERL_VARIABLE:
- if (strcmp(ERL_VAR_NAME(ep), name) == 0) {
- if ((vp = ERL_VAR_VALUE(ep)) != NULL) {
- ERL_COUNT(vp)++;
- return vp;
- }
- }
- break;
-
- case ERL_LIST:
- while (ep && (ERL_TYPE(ep) != ERL_EMPTY_LIST)) {
- if ((vp = erl_var_content(HEAD(ep), name))) return vp;
- ep = TAIL(ep);
- }
- break;
-
- case ERL_TUPLE:
- for (i=0; i < ERL_TUPLE_SIZE(ep); i++)
- if ((vp = erl_var_content(ERL_TUPLE_ELEMENT(ep, i), name)))
- {
- return vp;
- }
- break;
-
- default:
- /* variables can't occur in other types */
- break;
- }
-
- /* nothing found ! */
- return NULL;
-}
-
-/*
- * Return the SIZE of a TUPLE or a BINARY.
- * At failure -1 is returned.
- */
-int erl_size (const ETERM *ep)
-{
- if (!ep) return -1;
-
- /* ASSERT(ep != NULL); */
-
- switch (ERL_TYPE(ep)) {
- case ERL_TUPLE:
- return ERL_TUPLE_SIZE(ep);
-
- case ERL_BINARY:
- return ERL_BIN_SIZE(ep);
-
- default:
- return -1;
-
- }
-}
-
-/*
- * Return the LENGTH of a LIST.
- * At failure -1 is returned (this include non-proper lists like [a|b]).
- */
-int erl_length(const ETERM *ep)
-{
- int n = 0;
-
- if (!ep) return -1;
- /* ASSERT(ep != NULL); */
-
- while (ERL_TYPE(ep) == ERL_LIST) {
- n++;
- ep = TAIL(ep);
- }
-
- if (!ERL_IS_EMPTY_LIST(ep)) return -1;
-
- return n;
-}
-
-
-/***********************************************************************
- * I o l i s t f u n c t i o n s
- *
- * The following functions handles I/O lists.
- *
- * Informally, an I/O list is a deep list of characters and binaries,
- * which can be sent to an Erlang port.
- *
- * Formally, in BNF, an I/O list is defined as:
- *
- * iolist ::= []
- * | Binary
- * | [iohead | iolist]
- * ;
- *
- * iohead ::= Binary
- * | Byte (integer in the range [0..255])
- * | iolist
- * ;
- *
- * Note that versions of Erlang/OTP prior to R2 had a slightly more
- * restricted definition of I/O lists, in that the tail of a an I/O list
- * was not allowed to be a binary. The erl_interface functions
- * for I/O lists follows the more liberal rules described by the BNF
- * description above.
- ***********************************************************************/
-
-/*
- * This function converts an I/O list to a '\0' terminated C string.
- * The I/O list must not contain any occurrences of the integer 0.
- *
- * The string will be in memory allocated by erl_malloc(). It is the
- * responsibility of the caller to eventually call erl_free() to free
- * the memory.
- *
- * Returns: NULL if the list was not an I/O list or contained
- * the integer 0, otherwise a pointer to '\0' terminated string.
- */
-
-char* erl_iolist_to_string(const ETERM* term)
-{
- ETERM* bin;
-
- if ((bin = erl_iolist_to_binary(term)) == NULL) {
- return NULL;
- } else {
- char* result = NULL;
-
- if (memchr(ERL_BIN_PTR(bin), '\0', ERL_BIN_SIZE(bin)) == NULL) {
- result = (char *) erl_malloc(ERL_BIN_SIZE(bin)+1);
- memcpy(result, ERL_BIN_PTR(bin), ERL_BIN_SIZE(bin));
- result[ERL_BIN_SIZE(bin)] = '\0';
- }
- erl_free_term(bin);
- return result;
- }
-}
-
-/*
- * This function converts an I/O list to a binary term.
- *
- * Returns: NULL if the list was not an I/O list, otherwise
- * an ETERM pointer pointing to a binary term.
- */
-
-ETERM *erl_iolist_to_binary (const ETERM* term)
-{
- ETERM *dest;
- int size;
- char* ptr;
-
- if (!term) return NULL;
- /* ASSERT(term != NULL); */
-
- /*
- * Verify that the term is an I/O list and get its length.
- */
-
- size = erl_iolist_length(term);
- if (size == -1) {
- return NULL;
- }
-
- /*
- * Allocate the binary and copy the contents of the I/O list into it.
- */
-
- dest = erl_alloc_eterm(ERL_BINARY);
- ERL_COUNT(dest) = 1;
- ERL_BIN_SIZE(dest) = size;
- ptr = (char *)erl_malloc(size);
- ERL_BIN_PTR(dest) = (unsigned char *)ptr;
- iolist_to_buf(term, &ptr);
-
- /*
- * If ptr doesn't point exactly one byte beyond the end of the
- * binary, something must be seriously wrong.
- */
-
- if (ERL_BIN_PTR(dest) + size != (unsigned char *) ptr) return NULL;
- /* ASSERT(ERL_BIN_PTR(dest) + size == (unsigned char *) ptr); */
-
- return dest;
-}
-
-/*
- * Returns the length of an I/O list.
- *
- * Returns: -1 if the term if the given term is not a I/O list,
- * or the length otherwise.
- */
-
-int erl_iolist_length (const ETERM* term)
-{
- int len = 0;
-
- while (ERL_IS_CONS(term)) {
- ETERM* obj = HEAD(term);
-
- if (ERL_IS_BYTE(obj)) {
- len++;
- } else if (ERL_IS_CONS(obj)) {
- int i;
- if ((i = erl_iolist_length(obj)) < 0)
- return i;
- len += i;
- } else if (ERL_IS_BINARY(obj)) {
- len += ERL_BIN_SIZE(obj);
- } else if (!ERL_IS_EMPTY_LIST(obj)) {
- return(-1);
- }
- term = TAIL(term);
- }
- if (ERL_IS_EMPTY_LIST(term))
- return len;
- else if (ERL_IS_BINARY(term))
- return len + ERL_BIN_SIZE(term);
- else
- return -1;
-}
-
-static int erl_atom_copy(Erl_Atom_data* dst, const Erl_Atom_data* src)
-{
- if (src->latin1 == src->utf8) {
- dst->latin1 = dst->utf8 = strsave(src->latin1);
- dst->lenL = dst->lenU = strlen(src->latin1);
- }
- else if (src->latin1) {
- dst->latin1 = strsave(src->latin1);
- dst->lenL = strlen(src->latin1);
- dst->utf8 = NULL;
- dst->lenU = 0;
- }
- else {
- dst->utf8 = strsave(src->utf8);
- dst->lenU = strlen(src->utf8);
- dst->latin1 = NULL;
- dst->lenL = 0;
- }
- return (dst->latin1 != NULL || dst->utf8 == NULL);
-}
-
-
-/*
- * Return a brand NEW COPY of an ETERM.
- */
-/*
- * FIXME: Deep (the whole tree) or shallow (just the top term) copy?
- * The documentation never says, but the code as written below will
- * make a deep copy. This should be documented.
- */
-ETERM *erl_copy_term(const ETERM *ep)
-{
- int i;
- ETERM *cp;
-
- if (!ep) return NULL;
- /* ASSERT(ep != NULL); */
-
- cp = erl_alloc_eterm(ERL_TYPE(ep));
- ERL_COUNT(cp) = 1;
-
- switch(ERL_TYPE(cp)) {
- case ERL_INTEGER:
- case ERL_SMALL_BIG:
- ERL_INT_VALUE(cp) = ERL_INT_VALUE(ep);
- break;
- case ERL_U_INTEGER:
- case ERL_U_SMALL_BIG:
- ERL_INT_UVALUE(cp) = ERL_INT_UVALUE(ep);
- break;
- case ERL_LONGLONG:
- ERL_LL_VALUE(cp) = ERL_LL_VALUE(ep);
- break;
- case ERL_U_LONGLONG:
- ERL_LL_UVALUE(cp) = ERL_LL_UVALUE(ep);
- break;
- case ERL_FLOAT:
- ERL_FLOAT_VALUE(cp) = ERL_FLOAT_VALUE(ep);
- break;
- case ERL_ATOM:
- if (!erl_atom_copy(&cp->uval.aval.d, &ep->uval.aval.d))
- {
- erl_free_term(cp);
- erl_errno = ENOMEM;
- return NULL;
- }
- break;
- case ERL_PID:
- /* FIXME: First copy the bit pattern, then duplicate the node
- name and plug in. Somewhat ugly (also done with port and
- ref below). */
- memcpy(&cp->uval.pidval, &ep->uval.pidval, sizeof(Erl_Pid));
- erl_atom_copy(&cp->uval.pidval.node, &ep->uval.pidval.node);
- ERL_COUNT(cp) = 1;
- break;
- case ERL_PORT:
- memcpy(&cp->uval.portval, &ep->uval.portval, sizeof(Erl_Port));
- erl_atom_copy(&cp->uval.portval.node, &ep->uval.portval.node);
- ERL_COUNT(cp) = 1;
- break;
- case ERL_REF:
- memcpy(&cp->uval.refval, &ep->uval.refval, sizeof(Erl_Ref));
- erl_atom_copy(&cp->uval.refval.node, &ep->uval.refval.node);
- ERL_COUNT(cp) = 1;
- break;
- case ERL_LIST:
- HEAD(cp) = erl_copy_term(HEAD(ep));
- TAIL(cp) = erl_copy_term(TAIL(ep));
- break;
- case ERL_EMPTY_LIST:
- break;
- case ERL_TUPLE:
- i = ERL_TUPLE_SIZE(cp) = ERL_TUPLE_SIZE(ep);
- ERL_TUPLE_ELEMS(cp) = (ETERM**) erl_malloc(i * sizeof(ETERM*));
- for(i=0; i < ERL_TUPLE_SIZE(ep); i++)
- ERL_TUPLE_ELEMENT(cp,i) = erl_copy_term(ERL_TUPLE_ELEMENT(ep, i));
- break;
- case ERL_BINARY:
- ERL_BIN_SIZE(cp) = ERL_BIN_SIZE(ep);
- ERL_BIN_PTR(cp) = (unsigned char *) erl_malloc(ERL_BIN_SIZE(ep));
- memcpy(ERL_BIN_PTR(cp), ERL_BIN_PTR(ep), ERL_BIN_SIZE(ep));
- break;
- case ERL_FUNCTION:
- i = ERL_CLOSURE_SIZE(cp) = ERL_CLOSURE_SIZE(ep);
- ERL_FUN_ARITY(cp) = ERL_FUN_ARITY(ep);
- ERL_FUN_NEW_INDEX(cp) = ERL_FUN_NEW_INDEX(ep);
- ERL_FUN_INDEX(cp) = erl_copy_term(ERL_FUN_INDEX(ep));
- ERL_FUN_UNIQ(cp) = erl_copy_term(ERL_FUN_UNIQ(ep));
- ERL_FUN_CREATOR(cp) = erl_copy_term(ERL_FUN_CREATOR(ep));
- ERL_FUN_MODULE(cp) = erl_copy_term(ERL_FUN_MODULE(ep));
- memcpy(ERL_FUN_MD5(cp), ERL_FUN_MD5(ep), sizeof(ERL_FUN_MD5(ep)));
- ERL_CLOSURE(cp) = (ETERM**) erl_malloc(i * sizeof(ETERM*));
- for(i=0; i < ERL_CLOSURE_SIZE(ep); i++)
- ERL_CLOSURE_ELEMENT(cp,i) =
- erl_copy_term(ERL_CLOSURE_ELEMENT(ep, i));
- break;
- default:
- erl_err_msg("<ERROR> erl_copy_term: wrong type encountered !");
- erl_free_term(cp);
- return (ETERM *) NULL;
- }
-
- return cp;
-}
-
-#ifndef SILENT
-
-static int print_string(FILE* fp, const ETERM* ep);
-static int is_printable_list(const ETERM* term);
-
-/*
- * PRINT out an ETERM.
- */
-
-int erl_print_term(FILE *fp, const ETERM *ep)
-{
- int j,i,doquote;
- int ch_written = 0; /* counter of written chars */
-
- if ((!fp) || (!ep)) return 0;
- /* ASSERT(ep != NULL); */
-
- j = i = doquote = 0;
- switch(ERL_TYPE(ep))
- {
- case ERL_ATOM: {
- char* adata = ERL_ATOM_PTR(ep);
- /* FIXME: what if some weird locale is in use? */
- if (!islower(adata[0]))
- doquote = 1;
-
- for (i = 0; !doquote && i < ERL_ATOM_SIZE(ep); i++)
- {
- doquote = !(isalnum(adata[i]) || (adata[i] == '_'));
- }
-
- if (doquote) {
- putc('\'', fp);
- ch_written++;
- }
- fputs(adata, fp);
- ch_written += ERL_ATOM_SIZE(ep);
- if (doquote) {
- putc('\'', fp);
- ch_written++;
- }
- break;
- }
- case ERL_VARIABLE:
- if (!isupper((int)ERL_VAR_NAME(ep)[0])) {
- doquote = 1;
- putc('\'', fp);
- ch_written++;
- }
-
- fputs(ERL_VAR_NAME(ep), fp);
- ch_written += ERL_VAR_LEN(ep);
-
- if (doquote) {
- putc('\'', fp);
- ch_written++;
- }
- break;
-
- case ERL_PID:
- ch_written += fprintf(fp, "<%s.%d.%d>",
- ERL_PID_NODE(ep),
- ERL_PID_NUMBER(ep), ERL_PID_SERIAL(ep));
- break;
- case ERL_PORT:
- ch_written += fprintf(fp, "#Port");
- break;
- case ERL_REF:
- ch_written += fprintf(fp, "#Ref");
- break;
- case ERL_EMPTY_LIST:
- ch_written += fprintf(fp, "[]");
- break;
- case ERL_LIST:
- if (is_printable_list(ep)) {
- ch_written += print_string(fp, ep);
- } else {
- putc('[', fp);
- ch_written++;
- while (ERL_IS_CONS(ep)) {
- ch_written += erl_print_term(fp, HEAD(ep));
- ep = TAIL(ep);
- if (ERL_IS_CONS(ep)) {
- putc(',', fp);
- ch_written++;
- }
- }
- if (!ERL_IS_EMPTY_LIST(ep)) {
- putc('|', fp);
- ch_written++;
- ch_written += erl_print_term(fp, ep);
- }
- putc(']', fp);
- ch_written++;
- }
- break;
- case ERL_TUPLE:
- putc('{', fp);
- ch_written++;
- for (i=0; i < ERL_TUPLE_SIZE(ep); i++) {
- ch_written += erl_print_term(fp, ERL_TUPLE_ELEMENT(ep, j++) );
- if (i != ERL_TUPLE_SIZE(ep)-1) {
- putc(',', fp);
- ch_written++;
- }
- }
- putc('}', fp);
- ch_written++;
- break;
- case ERL_BINARY: {
- int sz = (ERL_BIN_SIZE(ep) > 20) ? 20 : ERL_BIN_SIZE(ep);
- unsigned char *ptr = ERL_BIN_PTR(ep);
- ch_written += fprintf(fp, "#Bin<");
- for (i = 0; i < sz; i++) {
- putc(ptr[i], fp); ch_written++;
- }
- if (sz == 20) ch_written += fprintf(fp, "(%d)....>", ERL_BIN_SIZE(ep)-20);
- else ch_written += fprintf(fp, ">");
- break;
- }
- case ERL_INTEGER:
- case ERL_SMALL_BIG:
- ch_written += fprintf(fp, "%d", ERL_INT_VALUE(ep));
- break;
- case ERL_U_INTEGER:
- case ERL_U_SMALL_BIG:
- ch_written += fprintf(fp, "%d", ERL_INT_UVALUE(ep));
- break;
- case ERL_LONGLONG:
- case ERL_U_LONGLONG:
- ch_written += fprintf(fp, "%lld", ERL_LL_UVALUE(ep));
- break;
- case ERL_FLOAT:
- ch_written += fprintf(fp, "%f", ERL_FLOAT_VALUE(ep));
- break;
- case ERL_FUNCTION:
- ch_written += fprintf(fp, "#Fun<");
- ch_written += erl_print_term(fp, ERL_FUN_MODULE(ep));
- putc('.', fp);
- ch_written++;
- ch_written += erl_print_term(fp, ERL_FUN_INDEX(ep));
- putc('.', fp);
- ch_written++;
- ch_written += erl_print_term(fp, ERL_FUN_UNIQ(ep));
- putc('>', fp);
- ch_written++;
- break;
- default:
- ch_written = -10000;
- erl_err_msg("<ERROR> erl_print_term: Bad type of term !");
- }
- return ch_written;
-}
-
-/*
- * FIXME not done yet....
- */
-
-#if 0
-
-int erl_sprint_term(char *buf, const ETERM *ep)
-{
- int j,i,doquote;
- int ch_written = 0; /* counter of written chars */
-
- if ((!buf) || (!ep)) return 0;
- /* ASSERT(ep != NULL); */
-
- j = i = doquote = 0;
- switch(ERL_TYPE(ep))
- {
- case ERL_ATOM:
- /* FIXME: what if some weird locale is in use? */
- if (!islower((int)ERL_ATOM_PTR(ep)[0]))
- doquote = 1;
-
- for (i = 0; !doquote && i < ERL_ATOM_SIZE(ep); i++)
- {
- doquote = !(isalnum((int)ERL_ATOM_PTR(ep)[i])
- || (ERL_ATOM_PTR(ep)[i] == '_'));
- }
-
- if (doquote) {
- *buf++ = '\'';
- ch_written++;
- }
- {
- int len = ERL_ATOM_SIZE(ep);
- strncpy(buf, ERL_ATOM_PTR(ep), len);
- buf += len;
- ch_written += len;
- }
- if (doquote) {
- *buf++ = '\'';
- ch_written++;
- }
- break;
-
- case ERL_VARIABLE:
- if (!isupper((int)ERL_VAR_NAME(ep)[0])) {
- doquote = 1;
- *buf++ = '\'';
- ch_written++;
- }
- len = ERL_VAR_LEN(ep);
- strncpy(buf, ERL_VAR_NAME(ep), len);
- buf += len;
- ch_written += len;
-
- if (doquote) {
- *buf++ = '\'';
- ch_written++;
- }
- break;
-
- case ERL_PID:
- len = sprintf(buf, "<%s.%d.%d>",
- ERL_PID_NODE(ep),
- ERL_PID_NUMBER(ep), ERL_PID_SERIAL(ep));
- buf += len;
- ch_written += len;
- break;
- case ERL_PORT:
- len = sprintf(buf , "#Port");
- buf += len;
- ch_written += len;
- break;
- case ERL_REF:
- len = sprintf(buf , "#Ref");
- buf += len;
- ch_written += len;
- break;
- case ERL_EMPTY_LIST:
- len = sprintf(buf , "[]");
- buf += len;
- ch_written += len;
- break;
- case ERL_LIST:
- if (is_printable_list(ep)) {
- ch_written += print_string(fp, ep);
- } else {
- putc('[', fp);
- ch_written++;
- while (ERL_IS_CONS(ep)) {
- ch_written += erl_sprint_term(fp, HEAD(ep));
- ep = TAIL(ep);
- if (ERL_IS_CONS(ep)) {
- putc(',', fp);
- ch_written++;
- }
- }
- if (!ERL_IS_EMPTY_LIST(ep)) {
- putc('|', fp);
- ch_written++;
- ch_written += erl_sprint_term(fp, ep);
- }
- putc(']', fp);
- ch_written++;
- }
- break;
- case ERL_TUPLE:
- putc('{', fp);
- ch_written++;
- for (i=0; i < ERL_TUPLE_SIZE(ep); i++) {
- ch_written += erl_sprint_term(fp, ERL_TUPLE_ELEMENT(ep, j++) );
- if (i != ERL_TUPLE_SIZE(ep)-1) {
- putc(',', fp);
- ch_written++;
- }
- }
- putc('}', fp);
- ch_written++;
- break;
- case ERL_BINARY:
- len = sprintf(buf , "#Bin");
- buf += len;
- ch_written += len;
- break;
- case ERL_INTEGER:
- case ERL_SMALL_BIG:
- len = sprintf(buf , "%d", ERL_INT_VALUE(ep));
- buf += len;
- ch_written += len;
- break;
- case ERL_U_INTEGER:
- case ERL_U_SMALL_BIG:
- len = sprintf(buf , "%d", ERL_INT_UVALUE(ep));
- buf += len;
- ch_written += len;
- break;
- case ERL_FLOAT:
- len = sprintf(buf , "%f", ERL_FLOAT_VALUE(ep));
- buf += len;
- ch_written += len;
- break;
- case ERL_FUNCTION:
- len = sprintf(buf , "#Fun<");
- buf += len;
- ch_written += len;
- ch_written += erl_sprint_term(fp, ERL_FUN_MODULE(ep));
- putc('.', fp);
- ch_written++;
- ch_written += erl_sprint_term(fp, ERL_FUN_INDEX(ep));
- putc('.', fp);
- ch_written++;
- ch_written += erl_sprint_term(fp, ERL_FUN_UNIQ(ep));
- putc('>', fp);
- ch_written++;
- break;
- default:
- ch_written = -10000;
- erl_err_msg("<ERROR> erl_sprint_term: Bad type of term !");
- }
- return ch_written;
-}
-#endif
-
-static int print_string(FILE* fp, const ETERM* ep)
-{
- int ch_written = 0; /* counter of written chars */
-
- putc('"', fp);
- ch_written++;
- while (ERL_IS_CONS(ep)) {
- int c = ERL_INT_VALUE(HEAD(ep));
-
- if (c >= ' ') {
- putc(c, fp);
- ch_written++;
- }
- else {
- switch (c) {
- case '\n': fputs("\\n", fp); ch_written += 2; break;
- case '\r': fputs("\\r", fp); ch_written += 2; break;
- case '\t': fputs("\\t", fp); ch_written += 2; break;
- case '\v': fputs("\\v", fp); ch_written += 2; break;
- case '\b': fputs("\\b", fp); ch_written += 2; break;
- case '\f': fputs("\\f", fp); ch_written += 2; break;
- break;
- default:
- ch_written += fprintf(fp, "\\%o", c);
- break;
- }
- }
- ep = TAIL(ep);
- }
- putc('"', fp);
- ch_written++;
- return ch_written;
-}
-
-/*
- * Returns 1 if term is a list of printable character, otherwise 0.
- */
-
-static int is_printable_list(const ETERM* term)
-{
- while (ERL_TYPE(term) == ERL_LIST) {
- ETERM* head = HEAD(term);
-
- if (!ERL_IS_BYTE(head)) {
- return 0;
- }
- if (ERL_INT_VALUE(head) < ' ') {
- switch (ERL_INT_VALUE(head)) {
- case '\n':
- case '\r':
- case '\t':
- case '\v':
- case '\b':
- case '\f':
- break;
- default:
- return 0;
- }
- }
- term = TAIL(term);
- }
-
- return ERL_IS_EMPTY_LIST(term);
-}
-
-#endif
-
-/*
- * Retrieves the bytes from an I/O list and copy into a buffer.
- *
- * NOTE! It is the responsibility of the caller to ensure that
- * that the buffer is big enough (typically by calling
- * erl_iolist_length()), and that the term is an I/O list.
- *
- * ETERM* term; Term to convert to bytes.
- * char** bufp; Pointer to pointer to buffer
- * where the bytes should be stored.
- * On return, the pointer will point beyond
- * the last byte stored.
- */
-
-static void iolist_to_buf(const ETERM* term, char** bufp)
-{
- char* dest = *bufp;
-
- while (ERL_IS_CONS(term)) {
- ETERM* obj = HEAD(term);
-
- if (ERL_IS_BYTE(obj)) {
- *dest++ = ERL_INT_VALUE(obj);
- } else if (ERL_IS_CONS(obj)) {
- iolist_to_buf(obj, &dest);
- } else if (ERL_IS_BINARY(obj)) {
- memcpy(dest, ERL_BIN_PTR(obj), ERL_BIN_SIZE(obj));
- dest += ERL_BIN_SIZE(obj);
- } else {
- /*
- * Types have been checked by caller.
- */
- if (!ERL_IS_EMPTY_LIST(obj)) return;
- /* ASSERT(ERL_IS_EMPTY_LIST(obj)); */
- }
- term = TAIL(term);
- }
- if (ERL_IS_BINARY(term)) {
- memcpy(dest, ERL_BIN_PTR(term), ERL_BIN_SIZE(term));
- dest += ERL_BIN_SIZE(term);
- } else {
- /*
- * Types have been checked by caller.
- */
- if (!ERL_IS_EMPTY_LIST(term)) return;
- /* ASSERT(ERL_IS_EMPTY_LIST(term));*/
- }
- *bufp = dest;
-}
-
-static char* strsave(const char *src)
-{
- char * dest = malloc(strlen(src)+1);
-
- if (dest != NULL)
- strcpy(dest, src);
- return dest;
-}
-
-
-/*
- * Local Variables:
- * compile-command: "cd ..; ERL_TOP=/clearcase/otp/erts make -k"
- * End:
- */
diff --git a/lib/erl_interface/src/legacy/erl_eterm.h b/lib/erl_interface/src/legacy/erl_eterm.h
deleted file mode 100644
index e2f3a90531..0000000000
--- a/lib/erl_interface/src/legacy/erl_eterm.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-#ifndef _ERL_ETERM_H
-#define _ERL_ETERM_H
-
-#ifndef SILENT
-#include <stdio.h>
-#endif
-
-#include "portability.h"
-
-#define ERL_MAX_COUNT 0xffffff
-#define ERL_MAX ((1 << 27)-1)
-#define ERL_MIN -(1 << 27)
-
-/* FIXME should this be documented and in erl_interface.h ??? */
-#define ERL_BIG_ARITY(x) ((x)->uval.bigval.arity)
-#define ERL_BIG_IS_NEG(x) ((x)->uval.bigval.is_neg)
-#define ERL_BIG_DIGITS(x) ((x)->uval.bigval.digits)
-#define ERL_BIG_DIGIT(x,i) (ERL_BIG_DIGITS(x)[(i)])
-
-/*
- * Typing checking macros.
- */
-
-/* FIXME should this be documented and in erl_interface.h ??? */
-#define ERL_IS_DEFINED(x) (ERL_TYPE(x) != 0)
-#define ERL_IS_COMPOUND(x) (ERL_TYPE(x) & ERL_COMPOUND)
-#define ERL_IS_FUNCTION(x) (ERL_TYPE(x) == ERL_FUNCTION)
-#define ERL_IS_BIG(x) (ERL_TYPE(x) == ERL_BIG)
-
-
-typedef struct _heapmark {
- unsigned long mark; /* id */
- int size; /* size of buffer */
- Erl_Heap *base; /* points to start of buffer */
- Erl_Heap *cur; /* points into buffer */
- struct _heapmark *prev; /* previous heapmark */
-} Erl_HeapMark;
-
-
-void erl_mk_port_helper(ETERM* ep, unsigned number, unsigned int creation);
-void erl_mk_pid_helper(ETERM*, unsigned,unsigned, unsigned int);
-ETERM * __erl_mk_reference(ETERM*, const char *, size_t, unsigned int n[], unsigned int);
-int erl_current_fix_desc(void);
-
-#endif /* _ERL_ETERM_H */
diff --git a/lib/erl_interface/src/legacy/erl_fix_alloc.c b/lib/erl_interface/src/legacy/erl_fix_alloc.c
deleted file mode 100644
index 890a9ce291..0000000000
--- a/lib/erl_interface/src/legacy/erl_fix_alloc.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-/*
- * Function: General purpose Memory allocator for fixed block
- * size objects. This allocater is at least an order of
- * magnitude faster than malloc().
- */
-#include "eidef.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "ei_locking.h"
-#include "erl_interface.h"
-#include "erl_error.h"
-#include "erl_malloc.h"
-#include "erl_fix_alloc.h"
-#include "erl_eterm.h"
-
-#define WIPE_CHAR ((char)0xaa) /* 10101010 */
-
-/* the freelist is a singly linked list of these */
-/* i.e. the user structure and a link pointer */
-struct fix_block {
- ETERM term;
- struct fix_block *next;
- int free;
-};
-
-/* this is a struct just to keep namespace pollution low on VxWorks */
-struct eterm_stateinfo {
- struct fix_block *freelist;
- unsigned long freed;
- unsigned long allocated;
-#ifdef _REENTRANT
- ei_mutex_t *lock;
-#endif /* _REENTRANT */
-};
-/* FIXME problem for threaded ? */
-static struct eterm_stateinfo *erl_eterm_state=NULL;
-
-
-int erl_init_eterm_alloc (void)
-{
-#if defined(PURIFY) && defined (DEBUG)
- fprintf(stderr,"erl_fix_alloc() compiled for Purify - using \"real\" malloc()");
-#endif
-
- erl_eterm_state = malloc(sizeof(*erl_eterm_state));
- if (erl_eterm_state == NULL) goto err1;
-
- erl_eterm_state->freelist = NULL;
- erl_eterm_state->freed = 0;
- erl_eterm_state->allocated = 0;
-#ifdef _REENTRANT
- erl_eterm_state->lock = ei_mutex_create();
- if (erl_eterm_state->lock == NULL) goto err2;
-#endif /* _REENTRANT */
-
- return 1;
-
- /* Error cleanup */
-#ifdef _REENTRANT
- err2:
- /* FIXME ENOMEM is not what went wrong... */
- free(erl_eterm_state);
-#endif /* _REENTRANT */
- err1:
- erl_errno = ENOMEM;
- return 0;
-}
-
-/* get an eterm, from the freelist if possible or from malloc() */
-void *erl_eterm_alloc (void)
-{
-#ifdef PURIFY
- ETERM *p;
-
- if ((p = malloc(sizeof(*p)))) {
- memset(p, WIPE_CHAR, sizeof(*p));
- }
- return p;
-#else
- struct fix_block *b;
-
-#ifdef _REENTRANT
- ei_mutex_lock(erl_eterm_state->lock, 0);
-#endif /* _REENTRANT */
-
- /* try to pop block from head of freelist */
- if ((b = erl_eterm_state->freelist) != NULL) {
- erl_eterm_state->freelist = b->next;
- erl_eterm_state->freed--;
- } else if ((b = malloc(sizeof(*b))) == NULL) {
- erl_errno = ENOMEM;
-#ifdef _REENTRANT
- ei_mutex_unlock(erl_eterm_state->lock);
-#endif /* _REENTRANT */
- return NULL;
- }
- erl_eterm_state->allocated++;
- b->free = 0;
- b->next = NULL;
-#ifdef _REENTRANT
- ei_mutex_unlock(erl_eterm_state->lock);
-#endif /* _REENTRANT */
- return (void *) &b->term;
-#endif /* !PURIFY */
-}
-
-/* free an eterm back to the freelist */
-void erl_eterm_free(void *p)
-{
-#ifdef PURIFY
- if (p) {
- memset(p, WIPE_CHAR, sizeof(ETERM));
- }
- free(p);
-#else
- struct fix_block *b = p;
-
- if (b) {
- if (b->free) {
-#ifdef DEBUG
- fprintf(stderr,"erl_eterm_free: attempt to free already freed block %p\n",b);
-#endif
- return;
- }
-
-#ifdef _REENTRANT
- ei_mutex_lock(erl_eterm_state->lock,0);
-#endif /* _REENTRANT */
- b->free = 1;
- b->next = erl_eterm_state->freelist;
- erl_eterm_state->freelist = b;
- erl_eterm_state->freed++;
- erl_eterm_state->allocated--;
-#ifdef _REENTRANT
- ei_mutex_unlock(erl_eterm_state->lock);
-#endif /* _REENTRANT */
- }
-#endif /* !PURIFY */
-}
-
-/* really free the freelist */
-void erl_eterm_release (void)
-{
-#if !defined(PURIFY)
- struct fix_block *b;
-
-#ifdef _REENTRANT
- ei_mutex_lock(erl_eterm_state->lock,0);
-#endif /* _REENTRANT */
- {
- while (erl_eterm_state->freelist != NULL) {
- b = erl_eterm_state->freelist;
- erl_eterm_state->freelist = b->next;
- free(b);
- erl_eterm_state->freed--;
- }
- }
-#ifdef _REENTRANT
- ei_mutex_unlock(erl_eterm_state->lock);
-#endif /* _REENTRANT */
-#endif /* !PURIFY */
-}
-
-void erl_eterm_statistics (unsigned long *allocd, unsigned long *freed)
-{
- if (allocd) *allocd = erl_eterm_state->allocated;
- if (freed) *freed = erl_eterm_state->freed;
-
- return;
-}
-
-
-/*
- * Local Variables:
- * compile-command: "cd ..; ERL_TOP=/clearcase/otp/erts make -k"
- * End:
- */
diff --git a/lib/erl_interface/src/legacy/erl_fix_alloc.h b/lib/erl_interface/src/legacy/erl_fix_alloc.h
deleted file mode 100644
index 50d1368e34..0000000000
--- a/lib/erl_interface/src/legacy/erl_fix_alloc.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-#ifndef _ERL_FIX_ALLOC_H
-#define _ERL_FIX_ALLOC_H
-
-int erl_init_eterm_alloc(void);
-void erl_eterm_free(void*);
-void *erl_eterm_alloc(void);
-
-#endif /* _ERL_FIX_ALLOC_H */
diff --git a/lib/erl_interface/src/legacy/erl_format.c b/lib/erl_interface/src/legacy/erl_format.c
deleted file mode 100644
index 45f5489e54..0000000000
--- a/lib/erl_interface/src/legacy/erl_format.c
+++ /dev/null
@@ -1,742 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-/*
- * Function: Provides two primitives: erl_format to build
- * Erlang terms in an easy way, and erl_match to perform
- * pattern match similar to what is done in Erlang.
- *
- */
-
-#include "eidef.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <ctype.h>
-
-#ifdef VRTX
-#define __READY_EXTENSIONS__
-#include <errno.h>
-#endif
-#include "erl_interface.h"
-#include "erl_eterm.h"
-#include "erl_malloc.h"
-#include "erl_error.h"
-#include "erl_internal.h"
-
-#define ERL_TRUE 1
-#define ERL_FALSE 0
-#define ERL_OK 0
-#define ERL_FORMAT_ERROR -1
-
-#define ERL_MAX_ENTRIES 255 /* Max entries in a tuple/list term */
-#define ERL_MAX_NAME_LENGTH 255 /* Max length of variable names */
-
-#define PRINT(t) \
-{ \
- print_term(stderr,t); \
- fprintf(stderr,"\n"); \
- }
-
-
-typedef struct lvar {
- ETERM *var;
- struct lvar *next;
-} lvar;
-
-
-/* Forward */
-static ETERM *eformat(char**, va_list*);
-static int ematch(ETERM*, ETERM*);
-
-/* FIXME not thread safe */
-struct _ef {
- lvar *chain; /* Chain of local variables */
- lvar *idle; /* Idle list of lvar's */
-} ef;
-
-/* Find local variable in term.
- */
-static ETERM *find_lvar(char *name)
-{
- lvar *tmp=ef.chain;
-
- while (tmp != NULL) {
- if (strcmp(tmp->var->uval.vval.name,name) == 0)
- return tmp->var->uval.vval.v;
- tmp = tmp->next;
- }
- return (ETERM *) NULL;
-
-} /* find_lvar */
-
-static void lvar_free(lvar *lv)
-{
- lvar *tmp=ef.chain;
-
- /* Link in the chain into the idle list */
- if (ef.idle == NULL)
- ef.idle = lv;
- else {
- tmp = ef.idle;
- while (tmp->next != NULL)
- tmp = tmp->next;
- tmp->next = lv;
- }
-
-
- /* Clear out the variable information */
- tmp = lv;
- while (tmp != NULL) {
- tmp->var = (ETERM *) NULL;
- tmp = tmp->next;
- }
-
-} /* lvar_free */
-
-static lvar *lvar_alloc(void)
-{
- lvar *tmp;
-
- if ((tmp = ef.idle) == NULL) {
- tmp = (lvar *) erl_malloc(sizeof(lvar));
- }
- else {
- tmp = ef.idle;
- ef.idle = tmp->next;
- }
- return tmp;
-
-} /* lvar_alloc */
-
-static void undo_bindings(void)
-{
- lvar *tmp=ef.chain;
-
- while (tmp != NULL) {
- erl_free_term(tmp->var->uval.vval.v);
- tmp->var->uval.vval.v = (ETERM *) NULL;
- tmp = tmp->next;
- }
-
-} /* undo_bindings */
-
-static void release_chain(void)
-{
-
- lvar_free(ef.chain);
- ef.chain = (lvar *) NULL;
-
-} /* release_chain */
-
-static void add_lvar(ETERM *t)
-{
- lvar *lv;
-
- lv = lvar_alloc();
- lv->var = t;
- lv->next = ef.chain;
- ef.chain = lv;
-
-} /* add_lvar */
-
-static char *pvariable(char **fmt, char *buf)
-{
- char *start=*fmt;
- char c;
- int len;
-
- while (1) {
- c = *(*fmt)++;
- if (isalnum((int) c) || (c == '_'))
- continue;
- else
- break;
- }
- (*fmt)--;
- len = *fmt - start;
- memcpy(buf, start, len);
- buf[len] = 0;
-
- return buf;
-
-} /* pvariable */
-
-static char *patom(char **fmt, char *buf)
-{
- char *start=*fmt;
- char c;
- int len;
-
- while (1) {
- c = *(*fmt)++;
- if (isalnum((int) c) || (c == '_') || (c == '@'))
- continue;
- else
- break;
- }
- (*fmt)--;
- len = *fmt - start;
- memcpy(buf, start, len);
- buf[len] = 0;
-
- return buf;
-
-} /* patom */
-
-/* Check if integer or float
- */
-static char *pdigit(char **fmt, char *buf)
-{
- char *start=*fmt;
- char c;
- int len,dotp=0;
-
- while (1) {
- c = *(*fmt)++;
- if (isdigit((int) c))
- continue;
- else if (!dotp && (c == '.')) {
- dotp = 1;
- continue;
- }
- else
- break;
- }
- (*fmt)--;
- len = *fmt - start;
- memcpy(buf, start, len);
- buf[len] = 0;
-
- return buf;
-
-} /* pdigit */
-
-static char *pstring(char **fmt, char *buf)
-{
- char *start=++(*fmt); /* skip first quote */
- char c;
- int len;
-
- while (1) {
- c = *(*fmt)++;
- if (c == '"') {
- if (*((*fmt)-1) == '\\')
- continue;
- else
- break;
- } else
- continue;
- }
- len = *fmt - 1 - start; /* skip last quote */
- memcpy(buf, start, len);
- buf[len] = 0;
-
- return buf;
-
-} /* pstring */
-
-static char *pquotedatom(char **fmt, char *buf)
-{
- char *start=++(*fmt); /* skip first quote */
- char c;
- int len;
-
- while (1) {
- c = *(*fmt)++;
- if (c == '\'') {
- if (*((*fmt)-1) == '\\')
- continue;
- else
- break;
- } else
- continue;
- }
- len = *fmt - 1 - start; /* skip last quote */
- memcpy(buf, start, len);
- buf[len] = 0;
-
- return buf;
-
-} /* pquotedatom */
-
-
-/*
- * The format letters are:
- * w - Any Erlang term
- * a - An Atom
- * b - A Binary
- * s - A String
- * i - An Integer
- * f - A Float (double)
- */
-static int pformat(char **fmt, va_list *pap, ETERM *v[], int size)
-{
- int rc=ERL_OK;
-
- /* this next section hacked to remove the va_arg calls */
- switch (*(*fmt)++) {
-
- case 'w':
- v[size] = va_arg(*pap, ETERM*);
- ERL_COUNT(v[size])++;
- break;
-
- case 'a':
- v[size] = erl_mk_atom(va_arg(*pap, char *));
- break;
-
- case 's':
- v[size] = erl_mk_string(va_arg(*pap, char *));
- break;
-
- case 'i':
- v[size] = erl_mk_int(va_arg(*pap, int));
- break;
-
- case 'f':
- v[size] = erl_mk_float(va_arg(*pap, double));
- break;
-
- case 'b': {
- char *sarg = va_arg(*pap, char *);
- v[size] = erl_mk_binary(sarg, strlen(sarg));
- break;
- }
-
- default:
- rc = ERL_FORMAT_ERROR;
- break;
- }
-
- return rc;
-
-} /* pformat */
-
-static int ptuple(char **fmt, va_list *pap, ETERM *v[], int size)
-{
- int res=ERL_FORMAT_ERROR;
-
- switch (*(*fmt)++) {
-
- case '}':
- res = size;
- break;
-
- case ',':
- res = ptuple(fmt, pap, v, size);
- break;
-
- case '~':
-
- if (pformat(fmt, pap, v, size) == ERL_OK)
- res = ptuple(fmt, pap, v, ++size);
- else
- erl_err_msg("ptuple(1): Wrong format sequence !");
- break;
-
- case ' ':
- return ptuple(fmt, pap, v, size);
- break;
-
- default: {
- (*fmt)--;
- if ((v[size++] = eformat(fmt, pap)) != (ETERM *) NULL)
- res = ptuple(fmt, pap, v, size);
- break;
-
- /*
- if (isupper(**fmt)) {
- v[size++] = erl_mk_var(pvariable(fmt, wbuf));
- res = ptuple(fmt, pap, v, size);
- }
- else if ((v[size++] = eformat(fmt, pap)) != (ETERM *) NULL)
- res = ptuple(fmt, pap, v, size);
- break;
- */
- }
-
- } /* switch */
-
- return res;
-
-} /* ptuple */
-
-
-static int plist(char **fmt, va_list *pap, ETERM *v[], int size)
-{
- int res=ERL_FORMAT_ERROR;
-
- switch (*(*fmt)++) {
-
- case ']':
- res = size;
- break;
-
- case ',':
- res = plist(fmt, pap, v, size);
- break;
-
- case '~':
-
- if (pformat(fmt, pap, v, size) == ERL_OK)
- res = plist(fmt, pap, v, ++size);
- else
- erl_err_msg("plist(1): Wrong format sequence !");
- break;
-
- case ' ':
- return plist(fmt, pap, v, size);
- break;
-
- default: {
- (*fmt)--;
- if ((v[size++] = eformat(fmt, pap)) != (ETERM *) NULL)
- res = plist(fmt, pap, v, size);
- break;
-
- /*
- if (isupper(**fmt)) {
- v[size++] = erl_mk_var(pvariable(fmt, wbuf));
- res = plist(fmt, pap, v, size);
- }
- else if ((v[size++] = eformat(fmt, pap)) != (ETERM *) NULL)
- res = plist(fmt, pap, v, size);
- break;
- */
- }
-
- } /* switch */
-
- return res;
-
-} /* plist */
-
-
-static ETERM *eformat(char **fmt, va_list *pap)
-{
- int size;
- ETERM *v[ERL_MAX_ENTRIES],*ep;
-
- switch (*(*fmt)++) {
- case '{':
- if ((size = ptuple(fmt, pap , v, 0)) != ERL_FORMAT_ERROR) {
- ep = erl_mk_tuple(v, size);
- erl_free_array(v, size);
- return ep;
- }
- else
- return (ETERM *) NULL;
- break;
-
- case '[':
- if (**fmt == ']') {
- (*fmt)++;
- return erl_mk_empty_list();
- } else if ((size = plist(fmt, pap , v, 0)) != ERL_FORMAT_ERROR) {
- ep = erl_mk_list(v, size);
- erl_free_array(v, size);
- return ep;
- } else
- return (ETERM *) NULL;
- break;
-
- case '$': /* char-value? */
- return erl_mk_int((int)(*(*fmt)++));
- break;
-
- case '~':
- if (pformat(fmt, pap, v, 0) == ERL_OK) {
- ep = erl_copy_term(v[0]);
- erl_free_term(v[0]);
- return ep;
- }
- break;
-
- case ' ':
- return eformat(fmt, pap);
- break;
-
- /* handle negative numbers too...
- * case '-':
- * {
- * ETERM *tmp;
- *
- * tmp = eformat(fmt,pap);
- * if (ERL_IS_INTEGER(tmp)) ERL_INT_VALUE(tmp) = -(ERL_INT_VALUE(tmp));
- * return tmp;
- * }
- *
- *
- * break;
- */
-
- default:
- {
- char wbuf[BUFSIZ]; /* now local to this function for reentrancy */
-
- (*fmt)--;
- if (islower((int)**fmt)) { /* atom ? */
- char *atom=patom(fmt, wbuf);
- return erl_mk_atom(atom);
- }
- else if (isupper((int)**fmt) || (**fmt == '_')) {
- char *var=pvariable(fmt, wbuf);
- return erl_mk_var(var);
- }
- else if (isdigit((int)**fmt)) { /* integer/float ? */
- char *digit=pdigit(fmt, wbuf);
- if (strchr(digit,(int) '.') == NULL)
- return erl_mk_int(atoi((const char *) digit));
- else
- return erl_mk_float(atof((const char *) digit));
- }
- else if (**fmt == '"') { /* string ? */
- char *string=pstring(fmt, wbuf);
- return erl_mk_string(string);
- }
- else if (**fmt == '\'') { /* quoted atom ? */
- char *qatom=pquotedatom(fmt, wbuf);
- return erl_mk_atom(qatom);
- }
- }
- break;
-
- }
-
- erl_err_msg("<ERROR> Syntax error in eformat, char was: %c !", **fmt);
- return (ETERM *) NULL;
-
-} /* eformat */
-
-
-ETERM *erl_format(char *fmt, ... )
-{
- ETERM *res=NULL;
- va_list ap;
-
- va_start(ap, fmt);
- res = eformat(&fmt, &ap);
- va_end(ap);
-
- return res;
-} /* erl_format */
-
-
-/*
- * Perform a pattern match between a pattern p and a term t.
- * As a side effect bind any unbound variables in p.
- * Return true or false.
- */
-static int ematch(ETERM *p, ETERM *t)
-{
- unsigned int type_p;
- unsigned int type_t;
- ETERM *tmp;
-
- /* two NULLs are equal, one is not... */
- if (!p && !t) return ERL_TRUE;
- if (!p || !t) return ERL_FALSE;
- /*
- * ASSERT(p != NULL);
- * ASSERT(t != NULL);
- */
-
- type_p = ERL_TYPE(p);
- type_t = ERL_TYPE(t);
-
- if (type_t == ERL_VARIABLE) {
- if (t->uval.vval.v == NULL)
- return ERL_FALSE; /* Can't have an unbound variable here ! */
- else
- t = t->uval.vval.v;
- }
-
- if (type_p != ERL_VARIABLE && type_p != type_t)
- return ERL_FALSE;
-
- switch (type_p) {
-
- case ERL_ATOM: {
- Erl_Atom_data* pa = &p->uval.aval.d;
- Erl_Atom_data* ta = &t->uval.aval.d;
- if (pa->utf8 && ta->utf8) {
- return pa->lenU == ta->lenU && memcmp(pa->utf8, ta->utf8, pa->lenU)==0;
- }
- else if (pa->latin1 && ta->latin1) {
- return pa->lenL == ta->lenL && memcmp(pa->latin1, ta->latin1, pa->lenL)==0;
- }
- else if (pa->latin1) {
- return cmp_latin1_vs_utf8(pa->latin1, pa->lenL, ta->utf8, ta->lenU)==0;
- }
- else {
- return cmp_latin1_vs_utf8(ta->latin1, ta->lenL, pa->utf8, pa->lenU)==0;
- }
- }
- case ERL_VARIABLE:
- if (strcmp(p->uval.vval.name, "_") == 0) /* anon. variable */
- return ERL_TRUE;
- else if ((tmp = find_lvar(p->uval.vval.name)) != (ETERM *) NULL) {
- /* v points to NULL in cases like erl_format("{X,X}") for the
- second variable */
- if (p->uval.vval.v == NULL)
- p->uval.vval.v = erl_copy_term(tmp);
- return ematch(p->uval.vval.v, t);
- }
- else {
- /* check if the variable is bound already */
- if (p->uval.vval.v != NULL) {
- if (ematch(p->uval.vval.v, t) == ERL_TRUE ){
- add_lvar(p);
- return ERL_TRUE;
- }
- else
- return ERL_FALSE;
- }
- else {
- p->uval.vval.v = erl_copy_term(t);
- add_lvar(p);
- return ERL_TRUE;
- }
- }
- break;
-
- case ERL_PID:
- if ((strcmp(ERL_PID_NODE(p), ERL_PID_NODE(t)) == 0) &&
- (ERL_PID_NUMBER(p) == ERL_PID_NUMBER(t)) &&
- (ERL_PID_SERIAL(p) == ERL_PID_SERIAL(t)) &&
- (ERL_PID_CREATION(p) == ERL_PID_CREATION(t)))
- return ERL_TRUE;
- else
- return ERL_FALSE;
- break;
-
- case ERL_PORT:
- if ((strcmp(ERL_PORT_NODE(p), ERL_PORT_NODE(t)) == 0) &&
- (ERL_PORT_NUMBER(p) == ERL_PORT_NUMBER(t)) &&
- (ERL_PORT_CREATION(p) == ERL_PORT_CREATION(t)))
- return ERL_TRUE;
- else
- return ERL_FALSE;
- break;
-
- case ERL_REF: {
- int i, len;
-
- if (strcmp(ERL_REF_NODE(p), ERL_REF_NODE(t)) != 0 ||
- ERL_REF_CREATION(p) != ERL_REF_CREATION(t))
- return ERL_FALSE;
-
- /* FIXME: {len=1, n={42}} and {len=3, n={42, 17, 13}} tests equal. */
- len = ERL_REF_LEN(p);
- if (len > ERL_REF_LEN(t))
- len = ERL_REF_LEN(t);
-
- for (i = 0; i < len; i++)
- if (ERL_REF_NUMBERS(p)[i] != ERL_REF_NUMBERS(t)[i])
- return ERL_FALSE;
-
- return ERL_TRUE;
- break;
- }
-
- case ERL_EMPTY_LIST:
- return ERL_TRUE;
-
- case ERL_LIST:
- while (ERL_IS_CONS(p) && ERL_IS_CONS(t)) {
- if (ematch(p->uval.lval.head, t->uval.lval.head) == ERL_FALSE)
- return ERL_FALSE;
- p = p->uval.lval.tail;
- t = t ->uval.lval.tail;
- }
- return ematch(p, t);
-
- case ERL_TUPLE:
- {
- int i;
- if (erl_size(p) != erl_size(t))
- return ERL_FALSE;
- else {
- for(i=0; i<erl_size(p); i++)
- if (ematch(p->uval.tval.elems[i],t->uval.tval.elems[i]) == ERL_FALSE)
- return ERL_FALSE;
- return ERL_TRUE;
- }
- }
- break;
-
- case ERL_BINARY:
- {
- int i;
- if ((i = p->uval.bval.size) != t->uval.bval.size)
- return ERL_FALSE;
- else
- return (memcmp(p->uval.bval.b,t->uval.bval.b,i)==0) ? ERL_TRUE : ERL_FALSE;
- }
- break;
-
- case ERL_INTEGER:
- return (p->uval.ival.i == t->uval.ival.i) ? ERL_TRUE : ERL_FALSE;
- break;
-
- case ERL_SMALL_BIG:
- case ERL_U_SMALL_BIG:
- /* This case can't happend since it is impossible
- * to create a bignum from the C code.
- */
- return ERL_FALSE;
- break;
-
- case ERL_FLOAT:
-#if defined(VXWORKS) && CPU == PPC860
- {
- return (erl_fp_compare((unsigned *)&(p->uval.fval.f),
- (unsigned *)&(t->uval.fval.f)) == 0)
- ? ERL_TRUE : ERL_FALSE;
- }
-#else
- return (p->uval.fval.f == t->uval.fval.f) ? ERL_TRUE : ERL_FALSE;
-#endif
- break;
- default:
- return ERL_FALSE;
- break;
- }
-
- /* erl_err_msg("ematch: Unknown type == %c\n", type_p); */
- return ERL_FALSE;
-
-} /* ematch */
-
-
-int erl_match(ETERM *p, ETERM *t)
-{
- int i;
-
- if ((i = ematch(p, t)) == ERL_FALSE)
- undo_bindings();
- release_chain();
- return i;
-
-} /* erl_match */
-
-
diff --git a/lib/erl_interface/src/legacy/erl_format.h b/lib/erl_interface/src/legacy/erl_format.h
deleted file mode 100644
index 92fa068206..0000000000
--- a/lib/erl_interface/src/legacy/erl_format.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-#ifndef _ERL_FORMAT_H
-#define _ERL_FORMAT_H
-
-#endif /* _ERL_FORMAT_H */
diff --git a/lib/erl_interface/src/legacy/erl_internal.h b/lib/erl_interface/src/legacy/erl_internal.h
deleted file mode 100644
index 25cf3e4f42..0000000000
--- a/lib/erl_interface/src/legacy/erl_internal.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-#ifndef _ERL_INTERNAL_H
-#define _ERL_INTERNAL_H
-
-/*
- * Function: Some useful stuff not to be exported to users.
- */
-
-#define HEAD(ep) ep->uval.lval.head
-#define TAIL(ep) ep->uval.lval.tail
-#define ERL_NO_REF(x) (ERL_COUNT(x) == 0)
-
-#ifdef DEBUG
-#define ASSERT(e) \
- if (e) { \
- ; \
- } else { \
- erl_assert_error(#e, __FILE__, __LINE__); \
- }
-
-extern void erl_assert_error(char* expr, char* file, int line)
- __attribute__ ((__noreturn__));
-
-#else
-
-#define ASSERT(e)
-
-#endif
-
-#endif /* _ERL_INTERNAL_H */
diff --git a/lib/erl_interface/src/legacy/erl_malloc.c b/lib/erl_interface/src/legacy/erl_malloc.c
deleted file mode 100644
index 27ef8c4b32..0000000000
--- a/lib/erl_interface/src/legacy/erl_malloc.c
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-
-#include "eidef.h"
-
-#include <stddef.h>
-#include <stdlib.h>
-
-#include "erl_interface.h"
-#include "erl_fix_alloc.h"
-#include "erl_malloc.h"
-#include "erl_internal.h"
-#include "erl_eterm.h"
-#include "ei_malloc.h"
-
-void erl_init_malloc(Erl_Heap *hp, long heap_size)
-{
- erl_init_eterm_alloc();
-} /* erl_init_malloc */
-
-ETERM *erl_alloc_eterm(unsigned char type)
-{
- ETERM *e;
-
- /* Use fix size allocator */
- if (!(e = (ETERM *) erl_eterm_alloc()))
- erl_err_sys("<ERROR> erl_alloc_eterm: Failed to allocate more memory\n");
-
- ERL_HEADER(e)->count = 0;
- ERL_HEADER(e)->type = type;
- return e;
-
-} /* erl_alloc_eterm */
-
-#define EXTERNAL 1
-#define INTERNAL 0
-#define COMPOUND 1
-#define NOT_COMPOUND 0
-
-static void _erl_free_term (ETERM *ep, int external, int compound);
-
-/*
- * Free a term, but don't deallocate it until
- * the reference counter triggers.
- */
-void erl_free_term(ETERM *ep)
-{
- _erl_free_term(ep, EXTERNAL, NOT_COMPOUND);
-} /* erl_free_term */
-
-/*
- * Free a term regardless of its reference
- * counter value. Use this when you have
- * built compound terms such as lists or tuples.
- */
-
-/*
- * FIXME is this true?!
- * Tearing down term structures no-matter-what is a horrible idea if
- * any term happens to be shared (with some other structure or even
- * with yourself).
- */
-
-void erl_free_compound (ETERM *ep)
-{
- _erl_free_term(ep, EXTERNAL, COMPOUND);
-} /* erl_free_compound */
-
-
-/*
-** The actual free'ing is done here in _erl_free_term.
-** It is by nature recursive, but does not recurse
-** on the CDR of a list, which makes it usable for large lists.
-*/
-
-/*
-** Convenience macro, called for variables and lists,
-** avoids deep recursions.
-*/
-#define RESTART(Eterm, External, Compound) \
-do { \
- ETERM *sep; \
- sep = (Eterm); \
- external = (External); \
- compound = (Compound); \
- /* Clear header info */ \
- ERL_TYPE(ep) = ERL_UNDEF; \
- erl_eterm_free((unsigned int *) ep); \
- ep = sep; \
- goto restart; \
-} while(0)
-
-#define FREE_AND_CLEAR(ptr) \
-do { \
- erl_free(ptr); \
- (ptr) = NULL; \
-} while (0)
-
-static void erl_atom_free(Erl_Atom_data* p)
-{
- erl_free(p->latin1);
- if (p->utf8 != p->latin1) {
- erl_free(p->utf8);
- }
- p->latin1 = NULL;
- p->utf8 = NULL;
- p->lenL = 0;
- p->lenU = 0;
-}
-
-static void _erl_free_term (ETERM *ep, int external, int compound)
-{
-restart:
- if (ep == NULL)
- return;
- if (compound || ERL_NO_REF(ep)) {
- /* Yes, it's time to *really* free this one ! */
- switch(ERL_TYPE(ep))
- {
- case ERL_ATOM:
- erl_atom_free(&ep->uval.aval.d);
- break;
- case ERL_VARIABLE:
- FREE_AND_CLEAR(ERL_VAR_NAME(ep));
- /* Note: It may be unbound ! */
- if (ERL_VAR_VALUE(ep) != NULL) {
- ERL_COUNT(ERL_VAR_VALUE(ep))--;
- /* Cleanup and Restart with the actual value */
- RESTART(ERL_VAR_VALUE(ep), INTERNAL, compound);
- }
- break;
- case ERL_LIST:
- if (HEAD(ep)) {
- ERL_COUNT(HEAD(ep))--;
- /* FIXME added cast, is this correct? */
- _erl_free_term((ETERM *)HEAD(ep), INTERNAL, compound);
- }
- if (TAIL(ep)) {
- ERL_COUNT(TAIL(ep))--;
- /* Clean up and walk on to CDR in list */
- RESTART(TAIL(ep), INTERNAL, compound);
- }
- break;
- case ERL_TUPLE:
- {
- int i;
- for (i=0; i < ERL_TUPLE_SIZE(ep); i++)
- if (ERL_TUPLE_ELEMENT(ep, i)) {
- ERL_COUNT(ERL_TUPLE_ELEMENT(ep, i))--;
- _erl_free_term(ERL_TUPLE_ELEMENT(ep, i),
- INTERNAL, compound);
- }
- FREE_AND_CLEAR(ERL_TUPLE_ELEMS(ep));
- }
- break;
- case ERL_BINARY:
- FREE_AND_CLEAR(ERL_BIN_PTR(ep));
- break;
- case ERL_PID:
- erl_atom_free(&ep->uval.pidval.node);
- break;
- case ERL_PORT:
- erl_atom_free(&ep->uval.portval.node);
- break;
- case ERL_REF:
- erl_atom_free(&ep->uval.refval.node);
- break;
- case ERL_EMPTY_LIST:
- case ERL_INTEGER:
- case ERL_SMALL_BIG:
- case ERL_U_SMALL_BIG:
- case ERL_FLOAT:
- break;
- case ERL_FUNCTION:
- {
- int i;
-
- _erl_free_term(ERL_FUN_INDEX(ep), INTERNAL, compound);
- _erl_free_term(ERL_FUN_UNIQ(ep), INTERNAL, compound);
- _erl_free_term(ERL_FUN_CREATOR(ep), INTERNAL, compound);
- _erl_free_term(ERL_FUN_MODULE(ep), INTERNAL, compound);
- if (ERL_CLOSURE(ep) != NULL) {
- for (i = 0; i < ERL_CLOSURE_SIZE(ep); i++)
- _erl_free_term(ERL_CLOSURE_ELEMENT(ep,i),
- INTERNAL, compound);
- }
- }
- break;
- } /* switch */
-
- /* Clear header info for those cases where we are done */
- ERL_TYPE(ep) = ERL_UNDEF;
- erl_eterm_free(ep);
- } else if (external) {
- ERL_COUNT(ep)--;
- external = INTERNAL;
- goto restart;
- }
-} /* _erl_free_term */
-#undef RESTART
-#undef FREE_AND_CLEAR
-
-void erl_free_array(ETERM **arr, int size)
-{
- int i;
-
- for (i=0; i<size; i++)
- erl_free_term(arr[i]);
-
-} /* erl_free_array */
-
-
-void* erl_malloc (long size)
-{
- void *res;
-
- if ((res = ei_malloc(size)) == NULL)
- erl_err_sys("<ERROR> erl_malloc: Failed to allocate more memory");
-
- return res;
-}
-
-void* erl_realloc(void* orig, long size)
-{
- void *res;
-
- if ((res = ei_realloc(orig, size)) == NULL)
- erl_err_sys("<ERROR> erl_realloc: Failed to allocate more memory");
- return res;
-}
-
-void erl_free (void *ptr)
-{
- ei_free(ptr);
-}
diff --git a/lib/erl_interface/src/legacy/erl_malloc.h b/lib/erl_interface/src/legacy/erl_malloc.h
deleted file mode 100644
index 6cbc01faba..0000000000
--- a/lib/erl_interface/src/legacy/erl_malloc.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-#ifndef _ERL_MALLOC_H
-#define _ERL_MALLOC_H
-
-/* FIXME: not documented */
-void *erl_realloc(void*, long);
-int erl_current_fix_desc(void);
-
-#endif /* _ERL_MALLOC_H */
diff --git a/lib/erl_interface/src/legacy/erl_marshal.c b/lib/erl_interface/src/legacy/erl_marshal.c
deleted file mode 100644
index 932bba43bf..0000000000
--- a/lib/erl_interface/src/legacy/erl_marshal.c
+++ /dev/null
@@ -1,2267 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2018. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-/*
- * Purpose: Decoding and encoding Erlang terms.
- */
-#include "eidef.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <string.h>
-#include <limits.h>
-
-#include "erl_interface.h"
-#include "erl_marshal.h"
-#include "erl_eterm.h"
-#include "erl_malloc.h"
-#include "erl_error.h"
-#include "erl_internal.h"
-
-#include "eiext.h" /* replaces external.h */
-#include "putget.h"
-
-static int is_string(ETERM* term);
-#if defined(VXWORKS) && CPU == PPC860
-int erl_fp_compare(unsigned *a, unsigned *b);
-static void erl_long_to_fp(long l, unsigned *d);
-#endif
-
-static int cmpbytes(unsigned char* s1,int l1,unsigned char* s2,int l2);
-static int cmpatoms(unsigned char* s1, int l1, unsigned char tag1, unsigned char* s2, int l2, unsigned char tag2);
-
-/* Used when comparing two encoded byte arrays */
-/* this global data is ok (from threading point of view) since it is
- * initialized once and never changed
- */
-
-#define CMP_ARRAY_SIZE 256
-/* FIXME problem for threaded ? */
-
-static enum
-{
- ERL_NUM_CMP=1, ERL_ATOM_CMP, ERL_REF_CMP, ERL_FUN_CMP, ERL_PORT_CMP,
- ERL_PID_CMP, ERL_TUPLE_CMP, ERL_NIL_CMP, ERL_LIST_CMP, ERL_BIN_CMP
-}cmp_array[CMP_ARRAY_SIZE];
-
-static int init_cmp_array_p=1; /* initialize array, the first time */
-
-#if defined(VXWORKS) && CPU == PPC860
-#include <limits.h>
-#endif
-
-#if defined(__GNUC__)
-# define INLINE __inline__
-#elif defined(__WIN32__)
-# define INLINE __inline
-#else
-# define INLINE
-#endif
-
-static int cmp_floats(double f1, double f2);
-static INLINE double to_float(long l);
-
-#define IS_ERL_NUM(t) (cmp_array[t]==ERL_NUM_CMP)
-#define IS_ERL_ATOM(t) (cmp_array[t]==ERL_ATOM_CMP)
-
-#define CMP_NUM_CLASS_SIZE 256
-static unsigned char cmp_num_class[CMP_NUM_CLASS_SIZE];
-static int init_cmp_num_class_p=1; /* initialize array, the first time */
-
-#define MK_CMP_NUM_CODE(x,y) (((x)<<2)|(y))
-#define CMP_NUM_CLASS(x) (cmp_num_class[x] & 0x03)
-#define CMP_NUM_CODE(x,y) (MK_CMP_NUM_CODE(CMP_NUM_CLASS(x),CMP_NUM_CLASS(y)))
-
-#define SMALL 1
-#define FLOAT 2
-#define BIG 3
-
-#define SMALL_SMALL MK_CMP_NUM_CODE(SMALL,SMALL)
-#define SMALL_FLOAT MK_CMP_NUM_CODE(SMALL,FLOAT)
-#define SMALL_BIG MK_CMP_NUM_CODE(SMALL,BIG)
-#define FLOAT_SMALL MK_CMP_NUM_CODE(FLOAT,SMALL)
-#define FLOAT_FLOAT MK_CMP_NUM_CODE(FLOAT,FLOAT)
-#define FLOAT_BIG MK_CMP_NUM_CODE(FLOAT,BIG)
-#define BIG_SMALL MK_CMP_NUM_CODE(BIG,SMALL)
-#define BIG_FLOAT MK_CMP_NUM_CODE(BIG,FLOAT)
-#define BIG_BIG MK_CMP_NUM_CODE(BIG,BIG)
-
-void erl_init_marshal(void)
-{
- if (init_cmp_array_p) {
- memset(cmp_array, 0, sizeof cmp_array);
- cmp_array[ERL_SMALL_INTEGER_EXT] = ERL_NUM_CMP;
- cmp_array[ERL_INTEGER_EXT] = ERL_NUM_CMP;
- cmp_array[ERL_FLOAT_EXT] = ERL_NUM_CMP;
- cmp_array[NEW_FLOAT_EXT] = ERL_NUM_CMP;
- cmp_array[ERL_SMALL_BIG_EXT] = ERL_NUM_CMP;
- cmp_array[ERL_LARGE_BIG_EXT] = ERL_NUM_CMP;
- cmp_array[ERL_ATOM_EXT] = ERL_ATOM_CMP;
- cmp_array[ERL_ATOM_UTF8_EXT] = ERL_ATOM_CMP;
- cmp_array[ERL_SMALL_ATOM_EXT] = ERL_ATOM_CMP;
- cmp_array[ERL_SMALL_ATOM_UTF8_EXT] = ERL_ATOM_CMP;
- cmp_array[ERL_REFERENCE_EXT] = ERL_REF_CMP;
- cmp_array[ERL_NEW_REFERENCE_EXT] = ERL_REF_CMP;
- cmp_array[ERL_NEWER_REFERENCE_EXT]=ERL_REF_CMP;
- cmp_array[ERL_FUN_EXT] = ERL_FUN_CMP;
- cmp_array[ERL_NEW_FUN_EXT] = ERL_FUN_CMP;
- cmp_array[ERL_PORT_EXT] = ERL_PORT_CMP;
- cmp_array[ERL_NEW_PORT_EXT] = ERL_PORT_CMP;
- cmp_array[ERL_PID_EXT] = ERL_PID_CMP;
- cmp_array[ERL_NEW_PID_EXT] = ERL_PID_CMP;
- cmp_array[ERL_SMALL_TUPLE_EXT] = ERL_TUPLE_CMP;
- cmp_array[ERL_LARGE_TUPLE_EXT] = ERL_TUPLE_CMP;
- cmp_array[ERL_NIL_EXT] = ERL_NIL_CMP;
- cmp_array[ERL_STRING_EXT] = ERL_LIST_CMP;
- cmp_array[ERL_LIST_EXT] = ERL_LIST_CMP;
- cmp_array[ERL_BINARY_EXT] = ERL_BIN_CMP;
- init_cmp_array_p = 0;
- }
- if (init_cmp_num_class_p) {
- memset(cmp_num_class, 0, CMP_NUM_CLASS_SIZE);
- cmp_num_class[ERL_SMALL_INTEGER_EXT] = SMALL;
- cmp_num_class[ERL_INTEGER_EXT] = SMALL;
- cmp_num_class[ERL_FLOAT_EXT] = FLOAT;
- cmp_num_class[NEW_FLOAT_EXT] = FLOAT;
- cmp_num_class[ERL_SMALL_BIG_EXT] = BIG;
- cmp_num_class[ERL_LARGE_BIG_EXT] = BIG;
- init_cmp_num_class_p = 0;
- }
-}
-
-/* The encoder calls length, if erl_length() should return */
-/* -1 for dotted pairs (why !!!!) we can't use erl_length() */
-/* from the encoder in erl_marshal.c */
-
-static int erl_length_x(const ETERM *ep) {
- int n = 0;
-
- if (!ep) return -1;
-
- while (ERL_TYPE(ep) == ERL_LIST) {
- n++;
- ep = TAIL(ep);
- }
-
- return n;
-}
-
-
-/*==============================================================
- * Marshalling routines.
- *==============================================================
- */
-
-static void encode_atom(Erl_Atom_data* a, unsigned char **ext)
-{
- int ix = 0;
- if (a->latin1) {
- ei_encode_atom_len_as((char*)*ext, &ix, a->latin1, a->lenL,
- ERLANG_LATIN1, ERLANG_UTF8);
- }
- else {
- ei_encode_atom_len_as((char*)*ext, &ix, a->utf8, a->lenU,
- ERLANG_UTF8, ERLANG_UTF8);
- }
- *ext += ix;
-}
-
-/*
- * The actual ENCODE engine.
- * Returns 0 on success, otherwise 1.
- */
-int erl_encode_it(ETERM *ep, unsigned char **ext, int dist)
-{
- int i;
- unsigned int u;
- long long l;
- unsigned long long ul;
-
- switch(ERL_TYPE(ep))
- {
- case ERL_ATOM:
- encode_atom(&ep->uval.aval.d, ext);
- return 0;
-
- case ERL_INTEGER:
- i = ep->uval.ival.i;
- /* SMALL_INTEGER */
- if ((i < 256) && (i >= 0)) {
- *(*ext)++ = ERL_SMALL_INTEGER_EXT;
- *(*ext)++ = i & 0xff;
- return 0;
- }
- /* R14B: Use all 32 bits of INTEGER_EXT */
- *(*ext)++ = ERL_INTEGER_EXT;
- *(*ext)++ = (i >> 24) & 0xff;
- *(*ext)++ = (i >> 16) & 0xff;
- *(*ext)++ = (i >> 8) & 0xff;
- *(*ext)++ = i & 0xff;
- return 0;
-
- case ERL_U_INTEGER:
- u = ep->uval.uival.u;
- /* ERL_U_SMALL_BIG */
- if ((int)u < 0) {
- *(*ext)++ = ERL_SMALL_BIG_EXT;
- *(*ext)++ = 4; /* four bytes */
- *(*ext)++ = 0; /* sign byte */
- *(*ext)++ = u & 0xff; /* LSB first */
- *(*ext)++ = (u >> 8) & 0xff;
- *(*ext)++ = (u >> 16) & 0xff;
- *(*ext)++ = (u >> 24) & 0xff;
- return 0;
- }
- /* SMALL_INTEGER */
- if (u < 256) {
- *(*ext)++ = ERL_SMALL_INTEGER_EXT;
- *(*ext)++ = u & 0xff;
- return 0;
- }
- /* R14B: Use all 32 bits of INTEGER_EXT */
- *(*ext)++ = ERL_INTEGER_EXT;
- *(*ext)++ = (u >> 24) & 0xff;
- *(*ext)++ = (u >> 16) & 0xff;
- *(*ext)++ = (u >> 8) & 0xff;
- *(*ext)++ = u & 0xff;
- return 0;
- case ERL_LONGLONG:
- l = ep->uval.llval.i;
- /* ERL_SMALL_BIG */
- if (l > ((long long) INT_MAX) || l < ((long long) INT_MIN)) {
- *(*ext)++ = ERL_SMALL_BIG_EXT;
- *(*ext)++ = 8;
- if ((*(*ext)++ = (l<0))) /* sign byte */
- l = -l;
- *(*ext)++ = l & 0xff; /* LSB first */
- *(*ext)++ = (l >> 8) & 0xff;
- *(*ext)++ = (l >> 16) & 0xff;
- *(*ext)++ = (l >> 24) & 0xff;
- *(*ext)++ = (l >> 32) & 0xff;
- *(*ext)++ = (l >> 40) & 0xff;
- *(*ext)++ = (l >> 48) & 0xff;
- *(*ext)++ = (l >> 56) & 0xff;
- return 0;
- }
- /* SMALL_INTEGER */
- if ((l < 256) && (l >= 0)) {
- *(*ext)++ = ERL_SMALL_INTEGER_EXT;
- *(*ext)++ = l & 0xff;
- return 0;
- }
- /* R14B: Use all 32 bits of INTEGER_EXT */
- *(*ext)++ = ERL_INTEGER_EXT;
- *(*ext)++ = (l >> 24) & 0xff;
- *(*ext)++ = (l >> 16) & 0xff;
- *(*ext)++ = (l >> 8) & 0xff;
- *(*ext)++ = l & 0xff;
- return 0;
-
- case ERL_U_LONGLONG:
- ul = ep->uval.ullval.u;
- /* ERL_U_SMALL_BIG */
- if (ul > ((unsigned long long) INT_MAX)) {
- *(*ext)++ = ERL_SMALL_BIG_EXT;
- *(*ext)++ = 8; /* eight bytes */
- *(*ext)++ = 0; /* sign byte */
- *(*ext)++ = ul & 0xff; /* LSB first */
- *(*ext)++ = (ul >> 8) & 0xff;
- *(*ext)++ = (ul >> 16) & 0xff;
- *(*ext)++ = (ul >> 24) & 0xff;
- *(*ext)++ = (ul >> 32) & 0xff;
- *(*ext)++ = (ul >> 40) & 0xff;
- *(*ext)++ = (ul >> 48) & 0xff;
- *(*ext)++ = (ul >> 56) & 0xff;
- return 0;
- }
- /* SMALL_INTEGER */
- if (ul < 256) {
- *(*ext)++ = ERL_SMALL_INTEGER_EXT;
- *(*ext)++ = ul & 0xff;
- return 0;
- }
- /* R14B: Use all 32 bits of INTEGER_EXT */
- *(*ext)++ = ERL_INTEGER_EXT;
- *(*ext)++ = (ul >> 24) & 0xff;
- *(*ext)++ = (ul >> 16) & 0xff;
- *(*ext)++ = (ul >> 8) & 0xff;
- *(*ext)++ = ul & 0xff;
- return 0;
-
- case ERL_PID: {
- unsigned char* tagp = (*ext)++;
- /* First poke in node as an atom */
- encode_atom(&ep->uval.pidval.node, ext);
- /* And then fill in the integer fields */
- i = ERL_PID_NUMBER(ep);
- *(*ext)++ = (i >> 24) &0xff;
- *(*ext)++ = (i >> 16) &0xff;
- *(*ext)++ = (i >> 8) &0xff;
- *(*ext)++ = i &0xff;
- i = ERL_PID_SERIAL(ep);
- *(*ext)++ = (i >> 24) &0xff;
- *(*ext)++ = (i >> 16) &0xff;
- *(*ext)++ = (i >> 8) &0xff;
- *(*ext)++ = i &0xff;
-
- i = ERL_PID_CREATION(ep);
- if ((unsigned int)i <= 3) {
- *tagp = ERL_PID_EXT;
- *(*ext)++ = i;
- } else {
- *tagp = ERL_NEW_PID_EXT;
- *(*ext)++ = (i >> 24) &0xff;
- *(*ext)++ = (i >> 16) &0xff;
- *(*ext)++ = (i >> 8) &0xff;
- *(*ext)++ = i &0xff;
- }
- return 0;
- }
- case ERL_REF: {
- unsigned char* tagp = (*ext)++;
-
- int len, j;
-
- /* Always encode as an extended reference; all
- participating parties are now expected to be
- able to decode extended references. */
-
- i = strlen((char *)ERL_REF_NODE(ep));
- len = ERL_REF_LEN(ep);
- *(*ext)++ = (len >> 8) &0xff;
- *(*ext)++ = len &0xff;
-
- encode_atom(&ep->uval.refval.node, ext);
-
- i = ERL_REF_CREATION(ep);
- if ((unsigned int)i <= 3) {
- *tagp = ERL_NEW_REFERENCE_EXT;
- *(*ext)++ = i;
- } else {
- *tagp = ERL_NEWER_REFERENCE_EXT;
- *(*ext)++ = (i >> 24) &0xff;
- *(*ext)++ = (i >> 16) &0xff;
- *(*ext)++ = (i >> 8) &0xff;
- *(*ext)++ = i &0xff;
- }
-
- /* Then the integer fields */
- for (j = 0; j < ERL_REF_LEN(ep); j++) {
- i = ERL_REF_NUMBERS(ep)[j];
- *(*ext)++ = (i >> 24) &0xff;
- *(*ext)++ = (i >> 16) &0xff;
- *(*ext)++ = (i >> 8) &0xff;
- *(*ext)++ = i &0xff;
- }
- }
- return 0;
- case ERL_PORT: {
- unsigned char* tagp = (*ext)++;
- /* First poke in node as an atom */
- encode_atom(&ep->uval.portval.node, ext);
- /* Then the integer fields */
- i = ERL_PORT_NUMBER(ep);
- *(*ext)++ = (i >> 24) &0xff;
- *(*ext)++ = (i >> 16) &0xff;
- *(*ext)++ = (i >> 8) &0xff;
- *(*ext)++ = i &0xff;
-
- i = ERL_PORT_CREATION(ep);
- if ((unsigned int)i <= 3) {
- *tagp = ERL_PORT_EXT;
- *(*ext)++ = i;
- } else {
- *tagp = ERL_NEW_PORT_EXT;
- *(*ext)++ = (i >> 24) &0xff;
- *(*ext)++ = (i >> 16) &0xff;
- *(*ext)++ = (i >> 8) &0xff;
- *(*ext)++ = i &0xff;
- }
- return 0;
- }
- case ERL_EMPTY_LIST:
- *(*ext)++ = ERL_NIL_EXT;
- break;
- case ERL_LIST:
- i = is_string(ep);
- if (0 < i && i < 0x10000) { /* String. */
- *(*ext)++ = ERL_STRING_EXT;
- *(*ext)++ = (i >>8) &0xff;
- *(*ext)++ = i &0xff;
- while (ERL_TYPE(ep) == ERL_LIST) {
- *(*ext)++ = HEAD(ep)->uval.ival.i;
- ep = TAIL(ep);
- }
- break;
- } else { /* List. */
- i = erl_length_x(ep);
- *(*ext)++ = ERL_LIST_EXT;
- *(*ext)++ = (i >> 24) &0xff;
- *(*ext)++ = (i >> 16) &0xff;
- *(*ext)++ = (i >> 8) &0xff;
- *(*ext)++ = i &0xff;
- while (ERL_TYPE(ep) == ERL_LIST) {
- if (erl_encode_it(HEAD(ep), ext, dist))
- return 1;
- ep = TAIL(ep);
- }
- i = erl_encode_it(ep, ext, dist);
- return i;
- }
- case ERL_TUPLE:
- i = ep->uval.tval.size;
- if (i <= 0xff) {
- *(*ext)++ = ERL_SMALL_TUPLE_EXT;
- *(*ext)++ = i & 0xff;
- }
- else {
- *(*ext)++ = ERL_LARGE_TUPLE_EXT;
- *(*ext)++ = (i >> 24) & 0xff;
- *(*ext)++ = (i >> 16) & 0xff;
- *(*ext)++ = (i >> 8) & 0xff;
- *(*ext)++ = i & 0xff;
- }
- for (i=0; i<ep->uval.tval.size; i++)
- if (erl_encode_it(ep->uval.tval.elems[i], ext, dist))
- return 1;
- break;
- case ERL_FLOAT:
- *(*ext)++ = ERL_FLOAT_EXT;
- memset(*ext, 0, 31);
- sprintf((char *) *ext, "%.20e", ep->uval.fval.f);
- *ext += 31;
- break;
- case ERL_BINARY:
- *(*ext)++ = ERL_BINARY_EXT;
- i = ep->uval.bval.size;
- *(*ext)++ = (i >> 24) & 0xff;
- *(*ext)++ = (i >> 16) & 0xff;
- *(*ext)++ = (i >> 8) & 0xff;
- *(*ext)++ = i & 0xff;
- memcpy((char *) *ext, (char*) ep->uval.bval.b, i);
- *ext += i;
- break;
- case ERL_FUNCTION:
- if (ERL_FUN_ARITY(ep) != -1) {
- unsigned char *size_p = *ext + 1;
- *(*ext)++ = ERL_NEW_FUN_EXT;
- *ext += 4;
- i = ERL_FUN_ARITY(ep);
- put8(*ext, i);
- memcpy(*ext, ERL_FUN_MD5(ep), 16);
- *ext += 16;
- i = ERL_FUN_NEW_INDEX(ep);
- put32be(*ext, i);
- i = ERL_CLOSURE_SIZE(ep);
- put32be(*ext, i);
- erl_encode_it(ERL_FUN_MODULE(ep), ext, dist);
- erl_encode_it(ERL_FUN_INDEX(ep), ext, dist);
- erl_encode_it(ERL_FUN_UNIQ(ep), ext, dist);
- erl_encode_it(ERL_FUN_CREATOR(ep), ext, dist);
- for (i = 0; i < ERL_CLOSURE_SIZE(ep); i++)
- erl_encode_it(ep->uval.funcval.closure[i], ext, dist);
- if (size_p != NULL) {
- i = *ext - size_p;
- put32be(size_p, i);
- }
- } else {
- *(*ext)++ = ERL_FUN_EXT;
- i = ERL_CLOSURE_SIZE(ep);
- *(*ext)++ = (i >> 24) & 0xff;
- *(*ext)++ = (i >> 16) & 0xff;
- *(*ext)++ = (i >> 8) & 0xff;
- *(*ext)++ = i & 0xff;
- erl_encode_it(ERL_FUN_CREATOR(ep), ext, dist);
- erl_encode_it(ERL_FUN_MODULE(ep), ext, dist);
- erl_encode_it(ERL_FUN_INDEX(ep), ext, dist);
- erl_encode_it(ERL_FUN_UNIQ(ep), ext, dist);
- for (i = 0; i < ERL_CLOSURE_SIZE(ep); i++)
- erl_encode_it(ep->uval.funcval.closure[i], ext, dist);
- }
- break;
- default:
- return 1;
- }
- return 0;
-}
-
-/*
- * ENCODE an ETERM into a BUFFER, assuming BUFFER is of
- * enough size. At success return number of bytes written
- * into it, otherwise return 0.
- */
-static int erl_encode3(ETERM *ep, unsigned char *t, int dist)
-{
- unsigned char *x = t;
-
- *x++ = ERL_VERSION_MAGIC;
- if (erl_encode_it(ep, &x, dist)) {
-#ifdef DEBUG
- erl_err_msg("<ERROR> erl_encode: Error while encoding");
-#endif
- return 0;
- }
- return (x - t);
-
-}
-
-/* API */
-
-int erl_encode(ETERM *ep, unsigned char *t)
-{
- return erl_encode3(ep, t, 4);
-}
-
-/* determine the buffer size that will be required for the eterm */
-static int erl_term_len_helper(ETERM *ep, int dist);
-
-/* FIXME hard coded dist version */
-int erl_term_len(ETERM *ep)
-{
- return 1+erl_term_len_helper(ep, 4);
-}
-
-static int atom_len_helper(Erl_Atom_data* a)
-{
- (void) erl_atom_ptr_utf8(a);
- return 1 + 1 + (a->lenU > 255) + a->lenU;
-}
-
-static int erl_term_len_helper(ETERM *ep, int dist)
-{
- int len = 0;
- int i;
- unsigned int u;
- long long l;
- unsigned long long ul;
-
- if (ep) {
- switch (ERL_TYPE(ep)) {
- case ERL_ATOM:
- len = atom_len_helper(&ep->uval.aval.d);
- break;
-
- case ERL_INTEGER:
- i = ep->uval.ival.i;
- if ((i < 256) && (i >= 0)) len = 2;
- else len = 5;
- break;
-
- case ERL_U_INTEGER:
- u = ep->uval.uival.u;
- if ((int)u < 0) len = 7;
- else if (u < 256) len = 2;
- else len = 5;
- break;
-
- case ERL_LONGLONG:
- l = ep->uval.llval.i;
- if ((l > ((long long) INT_MAX)) ||
- (l < ((long long) INT_MIN))) len = 11;
- else if ((l < 256) && (l >= 0)) len = 2;
- else len = 5;
- break;
-
- case ERL_U_LONGLONG:
- ul = ep->uval.ullval.u;
- if (ul > ((unsigned long long) INT_MAX)) len = 11;
- else if (ul < 256) len = 2;
- else len = 5;
- break;
-
- case ERL_PID:
- len = 1 + atom_len_helper(&ep->uval.pidval.node) + 4 + 4 + 1;
- break;
-
- case ERL_REF:
- len = 1 + 2 + atom_len_helper(&ep->uval.refval.node) + 1 + ERL_REF_LEN(ep) * 4;
- break;
-
- case ERL_PORT:
- len = 1 + atom_len_helper(&ep->uval.portval.node) + 4 + 1;
- break;
-
- case ERL_EMPTY_LIST:
- len = 1;
- break;
-
- case ERL_LIST:
- i = is_string(ep);
- if ((i > 0) && (i < 0x10000)) { /* string: 3 + strlen */
- for (len = 3; ERL_TYPE(ep) == ERL_LIST; ep = TAIL(ep)) {
- len++;
- }
- }
- else { /* list: 5 + len(elem1) + len(elem2) ... */
- for (len = 5; ERL_TYPE(ep) == ERL_LIST; ep = TAIL(ep)) {
- len += erl_term_len_helper(HEAD(ep), dist);
- }
- len += erl_term_len_helper(ep, dist); /* last element */
- }
- break;
-
- case ERL_TUPLE:
- /* (2 or 5) + len(elem1) + len(elem2) ... */
- i = ep->uval.tval.size;
- if (i <= 0xff) len = 2;
- else len = 5;
-
- for (i=0; i<ep->uval.tval.size; i++) {
- len += erl_term_len_helper(ep->uval.tval.elems[i], dist);
- }
- break;
-
- case ERL_FLOAT:
- len = 32;
- break;
-
- case ERL_BINARY:
- i = ep->uval.bval.size;
- len = 5 + i;
- break;
-
- case ERL_FUNCTION:
- if (ERL_FUN_ARITY(ep) == -1) {
- len = 1 + 4;
- len += erl_term_len_helper(ERL_FUN_CREATOR(ep),dist);
- len += erl_term_len_helper(ERL_FUN_MODULE(ep),dist);
- len += erl_term_len_helper(ERL_FUN_INDEX(ep),dist);
- len += erl_term_len_helper(ERL_FUN_UNIQ(ep),dist);
- for (i = 0; i < ERL_CLOSURE_SIZE(ep); i++)
- len += erl_term_len_helper(ERL_CLOSURE_ELEMENT(ep,i), dist);
- } else {
- len = 1 + 4 + 16 + 4 + 4;
- len += erl_term_len_helper(ERL_FUN_MODULE(ep),dist);
- len += erl_term_len_helper(ERL_FUN_INDEX(ep),dist);
- len += erl_term_len_helper(ERL_FUN_UNIQ(ep),dist);
- len += erl_term_len_helper(ERL_FUN_CREATOR(ep),dist);
- for (i = 0; i < ERL_CLOSURE_SIZE(ep); i++)
- len += erl_term_len_helper(ERL_CLOSURE_ELEMENT(ep,i), dist);
- }
- break;
-
- default:
-#ifdef DEBUG
- fprintf(stderr, "Shouldn't happen: erl_term_len, unknown term type: '%c'\n",ERL_TYPE(ep));
-#endif
- erl_errno = EINVAL;
- exit(1);
- }
- }
-
- return len;
-}
-
-/*
- * This one makes it easy to ENCODE several CONSECUTIVE
- * ETERM's into the same buffer.
- */
-int erl_encode_buf(ETERM *ep, unsigned char **ext)
-{
- unsigned char *start=*ext;
-
- *(*ext)++ = ERL_VERSION_MAGIC;
- if (erl_encode_it(ep, ext, 0)) {
-#ifdef DEBUG
- erl_err_msg("<ERROR> erl_encode_buf: Error while encoding\n");
-#endif
- return 0;
- }
- return (*ext - start);
-
-} /* erl_encode_buf */
-
-
-static int read_atom(unsigned char** ext, Erl_Atom_data* a)
-{
- char buf[MAXATOMLEN_UTF8];
- int offs = 0;
- erlang_char_encoding enc;
- int ret = ei_decode_atom_as((char*)*ext, &offs, buf, MAXATOMLEN_UTF8,
- ERLANG_LATIN1|ERLANG_UTF8, NULL, &enc);
- *ext += offs;
-
- if (ret == 0) {
- int i = strlen(buf);
- char* clone = erl_malloc(i+1);
- memcpy(clone, buf, i+1);
-
- a->latin1 = NULL;
- a->lenL = 0;
- a->utf8 = NULL;
- a->lenU = 0;
- if (enc & (ERLANG_LATIN1 | ERLANG_ASCII)) {
- a->latin1 = clone;
- a->lenL = i;
- }
- if (enc & (ERLANG_UTF8 | ERLANG_ASCII)) {
- a->utf8 = clone;
- a->lenU = i;
- }
- }
- return ret;
-}
-
-/*
- * The actual DECODE engine.
- * Returns NULL in case of failure.
- */
-static ETERM *erl_decode_it(unsigned char **ext)
-{
- char *cp;
- ETERM *ep,*tp,*np;
- unsigned int u,sign;
- int i,j,arity;
- double ff;
- unsigned char tag;
-
- /* Assume we are going to decode an integer */
- ep = erl_alloc_eterm(ERL_INTEGER);
- ERL_COUNT(ep) = 1;
-
- tag = *(*ext)++;
- switch (tag)
- {
- case ERL_INTEGER_EXT:
- i = (int) (**ext << 24) | ((*ext)[1] << 16) |
- ((*ext)[2] << 8) | (*ext)[3];
- *ext += 4;
- ep->uval.ival.i = i;
- return ep;
-
- case ERL_SMALL_INTEGER_EXT:
- i = *(*ext)++;
- ep->uval.ival.i = i;
- return ep;
-
- /* NOTE: The arity below for bigs is not really the arity (= number of digits) */
- /* It is the byte count and this might cause problems in other parts... */
- case ERL_SMALL_BIG_EXT:
- arity = *(*ext)++;
- goto big_cont;
- case ERL_LARGE_BIG_EXT:
- arity = (**ext << 24) | ((*ext)[1])<< 16 |
- ((*ext)[2]) << 8 |((*ext)[3]);
- *ext += 4;
- big_cont:
-
-#ifdef _MSC_VER
-#define MAX_TO_NEGATE 0x8000000000000000Ui64
-#else
-#define MAX_TO_NEGATE 0x8000000000000000ULL
-#endif
-
- sign = *(*ext)++;
- if (arity > 8)
- goto big_truncate;
-
- if (arity == 4 && ((*ext)[3] & 0x80) && !sign) {
- /* It will fit into an unsigned int !! */
- u = (((*ext)[3] << 24)|((*ext)[2])<< 16|((*ext)[1]) << 8 |(**ext));
- ERL_TYPE(ep) = ERL_U_INTEGER;
- ep->uval.uival.u = u;
- /* *ext += i; */
- *ext += arity;
- return ep;
- } else if (arity == 4 && !((*ext)[3] & 0x80)) {
- /* It will fit into an int !!
- */
- i = (int) (((*ext)[3] << 24) | ((*ext)[2])<< 16 |
- ((*ext)[1]) << 8 | (**ext));
- if (sign) i = -i;
- ERL_TYPE(ep) = ERL_INTEGER;
- ep->uval.ival.i = i;
- *ext += arity;
- return ep;
- } else if (arity == 8 && ((*ext)[7] & 0x80) && !sign) {
- /* Fits in an unsigned long long */
- int x;
- unsigned long long ul = 0LL;
-
- for(x = 0 ; x < arity ; x++) {
- ul |= ((unsigned long long)(*ext)[x]) << ((unsigned long long)(8*x));
- }
-
- ERL_TYPE(ep) = ERL_U_LONGLONG;
- ep->uval.ullval.u = ul;
- *ext += arity;
- return ep;
- } else {
- /* Fits in a signed long long */
- int x;
- unsigned long long l = 0LL;
- long long sl;
-
- for(x = 0 ; x < arity ; x++) {
- l |= ((unsigned long long)(*ext)[x]) << ((unsigned long long)(8*x));
- }
-
- sl = (long long)l;
-
- if (sign && l != MAX_TO_NEGATE) {
- sl = -sl;
- if (sl > 0) goto big_truncate;
- }
-
- ERL_TYPE(ep) = ERL_LONGLONG;
- ep->uval.llval.i = sl;
- *ext += arity;
- return ep;
- }
-#undef MAX_TO_NEGATE
- big_truncate:
- /* truncate to: (+/-) 1 */
-#ifdef DEBUG
- erl_err_msg("<WARNING> erl_decode_it: Integer truncated...");
-#endif
- ERL_TYPE(ep) = ERL_INTEGER;
- ep->uval.ival.i = sign?-1:1;
- *ext += arity;
- return ep;
-
- case ERL_ATOM_EXT:
- case ERL_SMALL_ATOM_EXT:
- case ERL_ATOM_UTF8_EXT:
- case ERL_SMALL_ATOM_UTF8_EXT:
-
- ERL_TYPE(ep) = ERL_ATOM;
- --(*ext);
- if (read_atom(ext, &ep->uval.aval.d) < 0) return NULL;
- return ep;
-
- case ERL_PID_EXT:
- case ERL_NEW_PID_EXT:
- {
- unsigned int number, serial;
- unsigned int creation;
-
- ERL_TYPE(ep) = ERL_PID;
- if (read_atom(ext, &ep->uval.pidval.node) < 0) return NULL;
-
- /* get the integers */
- number = ((*ext)[0] << 24) | ((*ext)[1]) << 16 |
- ((*ext)[2]) << 8 | ((*ext)[3]);
- *ext += 4;
- serial = ((*ext)[0] << 24) | ((*ext)[1]) << 16 |
- ((*ext)[2]) << 8 | ((*ext)[3]);
- *ext += 4;
- if (tag == ERL_PID_EXT)
- creation = *(*ext)++;
- else {
- creation = ((*ext)[0] << 24) | ((*ext)[1]) << 16 |
- ((*ext)[2]) << 8 | ((*ext)[3]);
- *ext += 4;
- }
- erl_mk_pid_helper(ep, number, serial, creation);
- return ep;
- }
- case ERL_REFERENCE_EXT:
- {
- unsigned int n[3] = {0, 0, 0};
- unsigned char creation;
-
- ERL_TYPE(ep) = ERL_REF;
- if (read_atom(ext, &ep->uval.refval.node) < 0) return NULL;
-
- /* get the integers */
- n[0] = ((*ext)[0] << 24) | ((*ext)[1]) << 16 |
- ((*ext)[2]) << 8 | ((*ext)[3]);
- *ext += 4;
- creation = *(*ext)++;
- __erl_mk_reference(ep, NULL, 1, n, creation);
- return ep;
- }
-
- case ERL_NEW_REFERENCE_EXT:
- case ERL_NEWER_REFERENCE_EXT:
- {
- size_t cnt, i;
- unsigned int n[3];
- unsigned int creation;
-
- ERL_TYPE(ep) = ERL_REF;
- cnt = ((*ext)[0] << 8) | (*ext)[1];
- *ext += 2;
-
- if (read_atom(ext, &ep->uval.refval.node) < 0) return NULL;
-
- /* get the integers */
- if (tag == ERL_NEW_REFERENCE_EXT)
- creation = *(*ext)++;
- else {
- creation = ((*ext)[0] << 24) | ((*ext)[1]) << 16 |
- ((*ext)[2]) << 8 | ((*ext)[3]);
- *ext += 4;
- }
- for(i = 0; i < cnt; i++)
- {
- n[i] = ((*ext)[0] << 24) | ((*ext)[1]) << 16 |
- ((*ext)[2]) << 8 | ((*ext)[3]);
- *ext += 4;
- }
- __erl_mk_reference(ep, NULL, cnt, n, creation);
- return ep;
- }
-
- case ERL_PORT_EXT:
- case ERL_NEW_PORT_EXT:
- {
- unsigned int number;
- unsigned int creation;
-
- ERL_TYPE(ep) = ERL_PORT;
- if (read_atom(ext, &ep->uval.portval.node) < 0) return NULL;
-
- /* get the integers */
- number = ((*ext)[0] << 24) | ((*ext)[1]) << 16 |
- ((*ext)[2]) << 8 | ((*ext)[3]);
- *ext += 4;
- if (tag == ERL_PORT_EXT)
- creation = *(*ext)++;
- else {
- creation = (((*ext)[0] << 24) | ((*ext)[1]) << 16 |
- ((*ext)[2]) << 8 | ((*ext)[3]));
- *ext += 4;
- }
- erl_mk_port_helper(ep, number, creation);
- return ep;
- }
-
- case ERL_NIL_EXT:
- ERL_TYPE(ep) = ERL_EMPTY_LIST;
- return ep;
-
- case ERL_LIST_EXT:
- ERL_TYPE(ep) = ERL_LIST;
- i = (**ext << 24) | ((*ext)[1] << 16) |((*ext)[2] << 8) | (*ext)[3];
- *ext += 4;
- /* ASSERT(i != 0); */ /* Should be represented by ERL_NIL_EXT. */
- tp = ep;
- for (j = 0; j < i; j++)
- if ((HEAD(tp) = erl_decode_it(ext)) == NULL)
- goto failure;
- else if (j + 1 < i) {
- /* We have to watch out for how we allocates the
- * last tail element since we may encounter non-
- * well formed lists.
- */
- np = erl_alloc_eterm(ERL_LIST);
- ERL_COUNT(np) = 1;
- TAIL(np) = NULL; /* in case of failure */
- TAIL(tp) = np;
- tp = np;
- }
- if ((TAIL(tp) = erl_decode_it(ext)) == NULL)
- goto failure;
- return ep;
-
- case ERL_STRING_EXT:
- {
- unsigned char* s;
-
- ERL_TYPE(ep) = ERL_EMPTY_LIST;
- i = (**ext << 8) | ((*ext)[1]);
- *ext += 2;
- s = *ext+i;
-
- while (*ext < s) {
- ETERM* integer;
- ETERM* cons;
-
- integer = erl_alloc_eterm(ERL_INTEGER);
- ERL_COUNT(integer) = 1;
- integer->uval.ival.i = *--s;
-
- cons = erl_alloc_eterm(ERL_LIST);
- ERL_COUNT(cons) = 1;
- HEAD(cons) = integer;
- TAIL(cons) = ep;
- ep = cons;
- }
- *ext += i;
- return ep;
- }
-
- case ERL_SMALL_TUPLE_EXT:
- ERL_TYPE(ep) = ERL_TUPLE;
- i = *(*ext)++;
- goto decode_tuple;
-
- case ERL_LARGE_TUPLE_EXT:
- i = (**ext << 24) | ((*ext)[1]) << 16 |
- ((*ext)[2]) << 8 | ((*ext)[3]) ;
- *ext += 4;
- decode_tuple:
- ep->uval.tval.size = i;
- j = (i + 1) * sizeof(ETERM*);
- ep->uval.tval.elems = (ETERM**) erl_malloc(j);
- memset(ep->uval.tval.elems, 0, j); /* in case of failure below... */
- for (i=0; i<ep->uval.tval.size; i++)
- if ((tp = erl_decode_it(ext)) == NULL)
- goto failure;
- else
- ep->uval.tval.elems[i] = tp;
- return ep;
-
- case ERL_FLOAT_EXT:
- case NEW_FLOAT_EXT:
- ERL_TYPE(ep) = ERL_FLOAT;
- cp = (char *) *ext;
- i = -1;
- if (ei_decode_double(cp, &i, &ff) == -1)
- goto failure;
- *ext += i;
- ep->uval.fval.f = ff;
- return ep;
-
- case ERL_BINARY_EXT:
- ERL_TYPE(ep) = ERL_BINARY;
- i = (**ext << 24) | ((*ext)[1] << 16) |
- ((*ext)[2] << 8) | (*ext)[3];
- *ext += 4;
- ep->uval.bval.size = i;
- ep->uval.bval.b = (unsigned char *) erl_malloc(i);
- memcpy(ep->uval.bval.b, *ext, i);
- *ext += i;
- return ep;
-
- case ERL_FUN_EXT: /* FIXME: error checking */
- ERL_TYPE(ep) = ERL_FUNCTION;
- i = get32be(*ext);
- /*i = *(**ext << 24) | ((*ext)[1] << 16) | ((*ext)[2] << 8) | (*ext)[3];
- *ext += 4; */
- ERL_FUN_ARITY(ep) = -1;
- ERL_CLOSURE_SIZE(ep) = i;
- ERL_FUN_CREATOR(ep) = erl_decode_it(ext);
- ERL_FUN_MODULE(ep) = erl_decode_it(ext);
- ERL_FUN_INDEX(ep) = erl_decode_it(ext);
- ERL_FUN_UNIQ(ep) = erl_decode_it(ext);
- j = i * sizeof(ETERM*);
- ERL_CLOSURE(ep) = (ETERM**) erl_malloc(j);
- memset(ERL_CLOSURE(ep), 0, j);
- for (i = 0; i < ERL_CLOSURE_SIZE(ep); i++)
- ERL_CLOSURE_ELEMENT(ep,i) = erl_decode_it(ext);
- return ep;
-
- case ERL_NEW_FUN_EXT: /* FIXME: error checking */
- ERL_TYPE(ep) = ERL_FUNCTION;
- i = get32be(*ext); /* size, we don't use it here */
- ERL_FUN_ARITY(ep) = get8(*ext);
- memcpy(ERL_FUN_MD5(ep), *ext, 16);
- *ext += 16;
- ERL_FUN_NEW_INDEX(ep) = get32be(*ext);
- i = get32be(*ext);
- ERL_CLOSURE_SIZE(ep) = i;
- ERL_FUN_MODULE(ep) = erl_decode_it(ext);
- ERL_FUN_INDEX(ep) = erl_decode_it(ext);
- ERL_FUN_UNIQ(ep) = erl_decode_it(ext);
- ERL_FUN_CREATOR(ep) = erl_decode_it(ext);
- j = i * sizeof(ETERM*);
- ERL_CLOSURE(ep) = (ETERM**) erl_malloc(j);
- memset(ERL_CLOSURE(ep), 0, j);
- for (i = 0; i < ERL_CLOSURE_SIZE(ep); i++)
- ERL_CLOSURE_ELEMENT(ep,i) = erl_decode_it(ext);
- return ep;
-
- } /* switch */
-
- failure:
- erl_free_term(ep);
- return (ETERM *) NULL;
-
-} /* erl_decode_it */
-
-/*
- * DECODE a buffer of BYTES into an ETERM.
- * Returns NULL in case of failure.
- */
-ETERM *erl_decode(unsigned char *t)
-{
- ETERM *ep;
- unsigned char *ext;
-
- ext = t;
-
- /* We ignore the version magic since it might be
- * possible that the buffer has been manipulated
- * with erl_peek_ext.
- */
- if (*ext == ERL_VERSION_MAGIC)
- ext++;
-
- ep = NULL;
- ep = erl_decode_it(&ext);
-#ifdef DEBUG
- if (!ep) erl_err_msg("<ERROR> erl_decode: Error while decoding");
-#endif
- return ep;
-
-} /* erl_decode */
-
-/*
- * This one makes it possible to DECODE two CONSECUTIVE
- * ETERM's in the same buffer.
- */
-ETERM *erl_decode_buf(unsigned char **ext)
-{
- ETERM *ep;
-
- /* We ignore the version magic since it might be
- * possible that the buffer has been manipulated
- * with erl_peek_ext.
- */
- if (**ext == ERL_VERSION_MAGIC)
- (*ext)++;
-
- ep = NULL;
- ep = erl_decode_it(ext);
-#ifdef DEBUG
- if (!ep) erl_err_msg("<ERROR> erl_decode_buf: Error while decoding");
-#endif
- return ep;
-
-} /* erl_decode_buf */
-
-
-/*==============================================================
- * Ok, here comes routines for inspecting/manipulating
- * an encoded buffer of bytes.
- *==============================================================
- */
-
-/*
- * Return 1 if the VERSION MAGIC in the BUFFER is the
- * same as the this library version.
- */
-int erl_verify_magic(unsigned char *ext)
-{
-
- if (*ext == ERL_VERSION_MAGIC)
- return 1;
- else
- return 0;
-
-} /* erl_verify_magic */
-
-/*
- * Return the TYPE of an ENCODED ETERM.
- * At failure, return 0.
- */
-unsigned char erl_ext_type(unsigned char *ext)
-{
- /* FIXME old code could skip multiple magic */
-
- /* Move over magic number if any */
- if (*ext == ERL_VERSION_MAGIC) ext++;
-
- switch (*ext) {
- case ERL_SMALL_INTEGER_EXT:
- case ERL_INTEGER_EXT:
- return ERL_INTEGER;
- case ERL_ATOM_EXT:
- case ERL_ATOM_UTF8_EXT:
- case ERL_SMALL_ATOM_EXT:
- case ERL_SMALL_ATOM_UTF8_EXT:
- return ERL_ATOM;
- case ERL_PID_EXT:
- case ERL_NEW_PID_EXT:
- return ERL_PID;
- case ERL_PORT_EXT:
- case ERL_NEW_PORT_EXT:
- return ERL_PORT;
- case ERL_REFERENCE_EXT:
- case ERL_NEW_REFERENCE_EXT:
- case ERL_NEWER_REFERENCE_EXT:
- return ERL_REF;
- case ERL_NIL_EXT:
- return ERL_EMPTY_LIST;
- case ERL_LIST_EXT:
- return ERL_LIST;
- case ERL_SMALL_TUPLE_EXT:
- case ERL_LARGE_TUPLE_EXT:
- return ERL_TUPLE;
- case ERL_FLOAT_EXT:
- case NEW_FLOAT_EXT:
- return ERL_FLOAT;
- case ERL_BINARY_EXT:
- return ERL_BINARY;
- case ERL_FUN_EXT:
- case ERL_NEW_FUN_EXT:
- return ERL_FUNCTION;
- case ERL_SMALL_BIG_EXT:
- case ERL_LARGE_BIG_EXT:
- return ERL_BIG;
- default:
- return 0;
-
- } /* switch */
-
-} /* erl_ext_type */
-
-/*
- * Returns the number of elements in compund
- * terms. For other kind of terms zero is returned.
- * At failure -1 is returned.
- */
-int erl_ext_size(unsigned char *t)
-{
- int i;
- unsigned char *v;
-
- if (*t == ERL_VERSION_MAGIC)
- return erl_ext_size(t+1);
-
- v = t+1;
- switch(*t) {
- case ERL_SMALL_INTEGER_EXT:
- case ERL_INTEGER_EXT:
- case ERL_ATOM_EXT:
- case ERL_ATOM_UTF8_EXT:
- case ERL_SMALL_ATOM_EXT:
- case ERL_SMALL_ATOM_UTF8_EXT:
- case ERL_PID_EXT:
- case ERL_NEW_PID_EXT:
- case ERL_PORT_EXT:
- case ERL_NEW_PORT_EXT:
- case ERL_REFERENCE_EXT:
- case ERL_NEW_REFERENCE_EXT:
- case ERL_NEWER_REFERENCE_EXT:
- case ERL_NIL_EXT:
- case ERL_BINARY_EXT:
- case ERL_STRING_EXT:
- case ERL_FLOAT_EXT:
- case NEW_FLOAT_EXT:
- case ERL_SMALL_BIG_EXT:
- case ERL_LARGE_BIG_EXT:
- return 0;
- break;
- case ERL_SMALL_TUPLE_EXT:
- i = v[0];
- return i;
- break;
- case ERL_LIST_EXT:
- case ERL_LARGE_TUPLE_EXT:
- i = (v[0] << 24) | (v[1] << 16) | (v[2] << 8) | v[3];
- return i;
- break;
- case ERL_FUN_EXT:
- i = (v[0] << 24) | (v[1] << 16) | (v[2] << 8) | v[3];
- return i+4;
- break;
- case ERL_NEW_FUN_EXT:
- v += 4 + 1 + 16 + 4;
- i = get32be(v);
- return i + 4;
- break;
- default:
- return -1;
- break;
- } /* switch */
-
-} /* ext_size */
-
-
-static int jump_atom(unsigned char** ext)
-{
- unsigned char* e = *ext;
- int len;
-
- switch (*e++) {
- case ERL_ATOM_EXT:
- case ERL_ATOM_UTF8_EXT:
- len = (e[0] << 8) | e[1];
- e += (len + 2);
- break;
-
- case ERL_SMALL_ATOM_EXT:
- case ERL_SMALL_ATOM_UTF8_EXT:
- len = e[0];
- e += (len + 1);
- break;
-
- default:
- return 0;
- }
- *ext = e;
- return 1;
-}
-
-
-/*
- * MOVE the POINTER PAST the ENCODED ETERM we
- * are currently pointing at. Returns 1 at
- * success, otherwise 0.
- */
-static int jump(unsigned char **ext)
-{
- int j,k,i=0;
- int n;
- const int tag = *(*ext)++;
-
- switch (tag) {
- case ERL_VERSION_MAGIC:
- return jump(ext);
- case ERL_INTEGER_EXT:
- *ext += 4;
- break;
- case ERL_SMALL_INTEGER_EXT:
- *ext += 1;
- break;
- case ERL_ATOM_EXT:
- case ERL_ATOM_UTF8_EXT:
- case ERL_SMALL_ATOM_EXT:
- case ERL_SMALL_ATOM_UTF8_EXT:
- jump_atom(ext);
- break;
- case ERL_PID_EXT:
- if (!jump_atom(ext)) return 0;
- *ext += 4 + 4 + 1;
- break;
- case ERL_NEW_PID_EXT:
- if (!jump_atom(ext)) return 0;
- *ext += 4 + 4 + 4;
- break;
- case ERL_REFERENCE_EXT:
- case ERL_PORT_EXT:
- if (!jump_atom(ext)) return 0;
- *ext += 4 + 1;
- break;
- case ERL_NEW_PORT_EXT:
- if (!jump_atom(ext)) return 0;
- *ext += 4 + 4;
- break;
- case ERL_NEW_REFERENCE_EXT:
- case ERL_NEWER_REFERENCE_EXT:
- n = (**ext << 8) | (*ext)[1];
- *ext += 2;
- /* first field is an atom */
- if (!jump_atom(ext)) return 0;
- *ext += 4*n + (tag == ERL_NEW_REFERENCE_EXT ? 1 : 4);
- break;
- case ERL_NIL_EXT:
- /* We just passed it... */
- break;
- case ERL_LIST_EXT:
- i = j = 0;
- j = (**ext << 24) | ((*ext)[1] << 16) |((*ext)[2] << 8) | (*ext)[3];
- *ext += 4;
- for(k=0; k<j; k++)
- if ((i = jump(ext)) == 0)
- return(0);
- if (**ext == ERL_NIL_EXT) {
- *ext += 1;
- break;
- }
- if (jump(ext) == 0) return 0;
- break;
- case ERL_STRING_EXT:
- i = **ext << 8 | (*ext)[1];
- *ext += 2 + i;
- break;
- case ERL_SMALL_TUPLE_EXT:
- i = *(*ext)++;
- goto jump_tuple;
- case ERL_LARGE_TUPLE_EXT:
- i = (**ext << 24) | ((*ext)[1] << 16) |((*ext)[2] << 8) | (*ext)[3];
- *ext += 4;
- jump_tuple:
- for (j = 0; j < i; j++)
- if ((k = jump(ext)) == 0)
- return(0);
- break;
- case ERL_FLOAT_EXT:
- *ext += 31;
- break;
- case NEW_FLOAT_EXT:
- *ext += 8;
- break;
- case ERL_BINARY_EXT:
- i = (**ext << 24) | ((*ext)[1] << 16) |((*ext)[2] << 8) | (*ext)[3];
- *ext += 4+i;
- break;
- case ERL_FUN_EXT:
- i = (**ext << 24) | ((*ext)[1] << 16) |((*ext)[2] << 8) | (*ext)[3];
- *ext += 4;
- i += 4;
- for (j = 0; j < i; j++)
- if ((k = jump(ext)) == 0)
- return(0);
- break;
- case ERL_NEW_FUN_EXT:
- i = get32be(*ext);
- *ext += i + 4;
- break;
- case ERL_SMALL_BIG_EXT:
- i = *(*ext);
- *ext += i + 1;
- break;
- case ERL_LARGE_BIG_EXT:
- i = get32be(*ext);
- *ext += i + 4;
- break;
- default:
- return 0;
- } /* switch */
-
- return 1;
-
-} /* jump */
-
-/*
- * The actual PEEK engine.
- */
-static unsigned char *peek_ext(unsigned char **ext, int jumps)
-{
- int i;
-
- switch (*(*ext)++)
- {
- case ERL_VERSION_MAGIC:
- return peek_ext(ext, jumps);
- case ERL_SMALL_TUPLE_EXT:
- i = *(*ext)++;
- goto do_the_peek_stuff;
- case ERL_LARGE_TUPLE_EXT:
- case ERL_LIST_EXT:
- i = (**ext << 24) | ((*ext)[1]) << 16| ((*ext)[2]) << 8| ((*ext)[3]) ;
- *ext += 4;
- do_the_peek_stuff:
- if (i <= jumps) {
-#ifdef DEBUG
- erl_err_msg("<ERROR> peek_ext: Out of range");
-#endif
- return NULL;
- }
- for(i=0; i<jumps; i++)
- if (!jump(ext)) {
-#ifdef DEBUG
- erl_err_msg("<ERROR> peek_ext: Bad data");
-#endif
- return NULL;
- }
- return *ext;
- default:
-#ifdef DEBUG
- erl_err_msg("<ERROR> peek_ext: Can't peek in non list/tuple type");
-#endif
- return NULL;
- } /* switch */
-
-} /* peek_ext */
-
-/*
- * Return a POINTER TO the N:TH ELEMENT in a
- * COMPUND ENCODED ETERM.
- */
-unsigned char *erl_peek_ext(unsigned char *ext, int jumps)
-{
- unsigned char *x=ext;
-
- return peek_ext(&x, jumps);
-
-} /* erl_peek_ext */
-
-/*
- * Lexically compare two strings of bytes,
- * (string s1 length l1 and s2 l2).
- * Return: -1 if s1 < s2
- * 0 if s1 = s2
- * 1 if s1 > s2
- */
-static int cmpbytes(unsigned char* s1,int l1,unsigned char* s2,int l2)
-{
- int i;
- i = 0;
- while((i < l1) && (i < l2)) {
- if (s1[i] < s2[i]) return(-1);
- if (s1[i] > s2[i]) return(1);
- i++;
- }
- if (l1 < l2) return(-1);
- if (l1 > l2) return(1);
- return(0);
-
-} /* cmpbytes */
-
-#define tag2enc(T) ((T)==ERL_ATOM_EXT || (T)==ERL_SMALL_ATOM_EXT ? ERLANG_LATIN1 : ERLANG_UTF8)
-
-static int cmpatoms(unsigned char* s1, int l1, unsigned char tag1,
- unsigned char* s2, int l2, unsigned char tag2)
-{
- erlang_char_encoding enc1 = tag2enc(tag1);
- erlang_char_encoding enc2 = tag2enc(tag2);
-
- if (enc1 == enc2) {
- return cmpbytes(s1, l1,s2,l2);
- }
-
- if (enc1 == ERLANG_LATIN1) {
- return cmp_latin1_vs_utf8((char*)s1, l1, (char*)s2, l2);
- }
- else {
- return -cmp_latin1_vs_utf8((char*)s2, l2, (char*)s1, l1);
- }
-}
-
-int cmp_latin1_vs_utf8(const char* strL, int lenL, const char* strU, int lenU)
-{
- unsigned char* sL = (unsigned char*)strL;
- unsigned char* sU = (unsigned char*)strU;
- unsigned char* sL_end = sL + lenL;
- unsigned char* sU_end = sU + lenU;
-
- while(sL < sL_end && sU < sU_end) {
- unsigned char UasL;
- if (*sL >= 0x80) {
- if (*sU < 0xC4 && (sU+1) < sU_end) {
- UasL = ((sU[0] & 0x3) << 6) | (sU[1] & 0x3F);
- }
- else return -1;
- }
- else {
- UasL = *sU;
- }
- if (*sL < UasL) return -1;
- if (*sL > UasL) return 1;
-
- sL++;
- if (*sU < 0x80) sU++;
- else if (*sU < 0xE0) sU += 2;
- else if (*sU < 0xF0) sU += 3;
- else /*if (*sU < 0xF8)*/ sU += 4;
- }
-
- return (sU >= sU_end) - (sL >= sL_end); /* -1, 0 or 1 */
-}
-
-
-#define CMP_EXT_ERROR_CODE 4711
-
-#define CMP_EXT_INT32_BE(AP, BP) \
-do { \
- if ((AP)[0] != (BP)[0]) return (AP)[0] < (BP)[0] ? -1 : 1; \
- if ((AP)[1] != (BP)[1]) return (AP)[1] < (BP)[1] ? -1 : 1; \
- if ((AP)[2] != (BP)[2]) return (AP)[2] < (BP)[2] ? -1 : 1; \
- if ((AP)[3] != (BP)[3]) return (AP)[3] < (BP)[3] ? -1 : 1; \
-} while (0)
-
-#define CMP_EXT_SKIP_ATOM(EP) \
-do { \
- if (!jump_atom(&(EP))) \
- return CMP_EXT_ERROR_CODE; \
-} while (0)
-
-/*
- * We now know that both byte arrays are of the same type.
- */
-static int compare_top_ext(unsigned char**, unsigned char **); /* forward */
-static int cmp_exe2(unsigned char **e1, unsigned char **e2);
-
-static int cmp_refs(unsigned char **e1, unsigned char **e2)
-{
- int tmp, n1, n2;
- unsigned char *node1, *node2, *id1, *id2, cre1, cre2;
-
- if (*((*e1)++) == ERL_REFERENCE_EXT) {
- node1 = *e1;
- CMP_EXT_SKIP_ATOM(*e1);
- n1 = 1;
- id1 = *e1;
- cre1 = (*e1)[4];
- *e1 += 5;
- } else {
- n1 = get16be(*e1);
- node1 = *e1;
- CMP_EXT_SKIP_ATOM(*e1);
- cre1 = **e1;
- id1 = (*e1) + 1 + (n1 - 1)*4;
- *e1 = id1 + 4;
- }
-
- if (*((*e2)++) == ERL_REFERENCE_EXT) {
- node2 = *e2;
- CMP_EXT_SKIP_ATOM(*e2);
- n2 = 1;
- id2 = *e2;
- cre2 = (*e2)[4];
- *e2 += 5;
- } else {
- n2 = get16be(*e2);
- node2 = *e2;
- CMP_EXT_SKIP_ATOM(*e2);
- cre2 = **e2;
- id2 = (*e2) + 1 + (n2 - 1)*4;
- *e2 = id2 + 4;
- }
-
- /* First compare node names... */
- tmp = cmp_exe2(&node1, &node2);
- if (tmp != 0)
- return tmp;
-
- /* ... then creations ... */
- if (cre1 != cre2)
- return cre1 < cre2 ? -1 : 1;
-
- /* ... and then finally ids. */
- if (n1 != n2) {
- unsigned char zero[] = {0, 0, 0, 0};
- if (n1 > n2)
- do {
- CMP_EXT_INT32_BE(id1, zero);
- id1 -= 4;
- n1--;
- } while (n1 > n2);
- else
- do {
- CMP_EXT_INT32_BE(zero, id2);
- id2 -= 4;
- n2--;
- } while (n2 > n1);
- }
-
- for (; n1 > 0; n1--, id1 -= 4, id2 -= 4)
- CMP_EXT_INT32_BE(id1, id2);
-
- return 0;
-}
-
-static int cmp_string_list(unsigned char **e1, unsigned char **e2) {
-
- /* we need to compare a string in **e1 and a list in **e2 */
- /* convert the string to list representation and convert that with e2 */
- /* we need a temporary buffer of: */
- /* 5 (list tag + length) + 2*string length + 1 (end of list tag) */
- /* for short lists we use a stack allocated buffer, otherwise we malloc */
-
- unsigned char *bp;
- unsigned char buf[5+2*255+1]; /* used for short lists */
- int i,e1_len;
- int res;
-
- e1_len = ((*e1)[1] << 8) | ((*e1)[2]);
- if ( e1_len < 256 ) {
- bp = buf;
- } else {
- bp = erl_malloc(5+(2*e1_len)+1);
- }
-
- bp[0] = ERL_LIST_EXT;
- bp[1] = bp[2] = 0;
- bp[3] = (*e1)[1];
- bp[4] = (*e1)[2];
-
- for(i=0;i<e1_len;i++) {
- bp[5+2*i] = ERL_SMALL_INTEGER_EXT;
- bp[5+2*i+1] = (*e1)[3+i];
- }
-
- bp[5+2*e1_len] = ERL_NIL_EXT;
-
- res = cmp_exe2(&bp, e2);
-
- if ( e1_len >= 256 ) free(bp);
-
- return res;
-}
-
-static int cmp_exe2(unsigned char **e1, unsigned char **e2)
-{
- int min, ret,i,j,k;
- double ff1, ff2;
- unsigned char tag1, tag2;
-
- if ( ((*e1)[0] == ERL_STRING_EXT) && ((*e2)[0] == ERL_LIST_EXT) ) {
- return cmp_string_list(e1, e2);
- } else if ( ((*e1)[0] == ERL_LIST_EXT) && ((*e2)[0] == ERL_STRING_EXT) ) {
- return -cmp_string_list(e2, e1);
- }
-
- tag1 = *(*e1)++;
- tag2 = *(*e2)++;
- i = j = 0;
- switch (tag1)
- {
- case ERL_SMALL_INTEGER_EXT:
- if (**e1 < **e2) ret = -1;
- else if (**e1 > **e2) ret = 1;
- else ret = 0;
- *e1 += 1; *e2 += 1;
- return ret;
- case ERL_INTEGER_EXT:
- i = (int) (**e1 << 24) | ((*e1)[1] << 16) |((*e1)[2] << 8) | (*e1)[3];
- j = (int) (**e2 << 24) | ((*e2)[1] << 16) |((*e2)[2] << 8) | (*e2)[3];
- if ( i < j)
- ret = -1;
- else if ( i > j)
- ret = 1;
- else
- ret = 0;
- *e1 += 4; *e2 += 4;
- return ret;
- case ERL_ATOM_EXT:
- case ERL_ATOM_UTF8_EXT:
- i = (**e1) << 8; (*e1)++;
- j = (**e2) << 8; (*e2)++;
- /*fall through*/
- case ERL_SMALL_ATOM_EXT:
- case ERL_SMALL_ATOM_UTF8_EXT:
- i |= (**e1); (*e1)++;
- j |= (**e2); (*e2)++;
- ret = cmpatoms(*e1, i, tag1, *e2, j, tag2);
- *e1 += i;
- *e2 += j;
- return ret;
- case ERL_PID_EXT:
- case ERL_NEW_PID_EXT: {
- erlang_pid pid1, pid2;
- unsigned char* buf1 = *e1 - 1;
- unsigned char* buf2 = *e2 - 1;
- int ix1 = 0, ix2 = 0;
-
- if (ei_decode_pid((char*)buf1, &ix1, &pid1) ||
- ei_decode_pid((char*)buf2, &ix2, &pid2))
- return CMP_EXT_ERROR_CODE;
-
- *e1 = buf1 + ix1;
- *e2 = buf2 + ix2;
-
- /* First compare serials ... */
- if (pid1.serial < pid2.serial) return -1;
- else if (pid1.serial > pid2.serial) return 1;
-
- /* ... then ids ... */
- if (pid1.num < pid2.num) return -1;
- else if (pid1.num > pid2.num) return 1;
-
- /* ... then node names ... */
- j = strcmp(pid1.node, pid2.node);
- if (j < 0) return -1;
- else if (j > 0) return 1;
-
- /* ... and then finaly creations. */
- if (pid1.creation < pid2.creation) return -1;
- else if (pid1.creation > pid2.creation) return 1;
-
- return 0;
- }
- case ERL_PORT_EXT:
- case ERL_NEW_PORT_EXT: {
- erlang_port port1, port2;
- unsigned char* buf1 = *e1 - 1;
- unsigned char* buf2 = *e2 - 1;
- int ix1 = 0, ix2 = 0;
-
- if (ei_decode_port((char*)buf1, &ix1, &port1) ||
- ei_decode_port((char*)buf2, &ix2, &port2))
- return CMP_EXT_ERROR_CODE;
-
- *e1 = buf1 + ix1;
- *e2 = buf2 + ix2;
-
- /* First compare node names ... */
- j = strcmp(port1.node, port2.node);
- if (j < 0) return -1;
- else if (j > 0) return 1;
-
- /* ... then creations ... */
- if (port1.creation < port2.creation) return -1;
- else if (port1.creation > port2.creation) return 1;
-
- /* ... and then finally ids. */
- if (port1.id < port2.id) return -1;
- else if (port1.id > port2.id) return 1;
-
- return 0;
- }
- case ERL_NIL_EXT: return 0;
- case ERL_LIST_EXT:
- i = (**e1 << 24) | ((*e1)[1] << 16) |((*e1)[2] << 8) | (*e1)[3];
- *e1 += 4;
- j = (**e2 << 24) | ((*e2)[1] << 16) |((*e2)[2] << 8) | (*e2)[3];
- *e2 += 4;
- if ( i == j && j == 0 ) return 0;
- min = (i < j) ? i : j;
- k = 0;
- while (1) {
- if (k++ == min){
- if (i == j) return compare_top_ext(e1 , e2);
- if (i < j) return -1;
- return 1;
- }
- if ((ret = compare_top_ext(e1 , e2)) == 0)
- continue;
- return ret;
- }
- case ERL_STRING_EXT:
- i = (**e1 << 8) | ((*e1)[1]);
- *e1 += 2;
- j = (**e2 << 8) | ((*e2)[1]);
- *e2 += 2;
- ret = cmpbytes(*e1, i, *e2, j);
- *e1 += i;
- *e2 += j;
- return ret;
- case ERL_SMALL_TUPLE_EXT:
- i = *(*e1)++; j = *(*e2)++;
- if (i < j) return -1;
- if (i > j ) return 1;
- while (i--) {
- if ((j = compare_top_ext(e1, e2))) return j;
- }
- return 0;
- case ERL_LARGE_TUPLE_EXT:
- i = (**e1 << 24) | ((*e1)[1]) << 16| ((*e1)[2]) << 8| ((*e1)[3]) ;
- *e1 += 4;
- j = (**e2 << 24) | ((*e2)[1]) << 16| ((*e2)[2]) << 8| ((*e2)[3]) ;
- *e2 += 4;
- if (i < j) return -1;
- if (i > j ) return 1;
- while (i--) {
- if ((j = compare_top_ext(e1, e2))) return j;
- }
- return 0;
- case ERL_FLOAT_EXT:
- case NEW_FLOAT_EXT:
- i = -1;
- if (ei_decode_double((char *) *e1, &i, &ff1) != 0)
- return -1;
- *e1 += i;
- j = -1;
- if (ei_decode_double((char *) *e2, &j, &ff2) != 0)
- return -1;
- *e2 += j;
- return cmp_floats(ff1,ff2);
-
- case ERL_BINARY_EXT:
- i = (**e1 << 24) | ((*e1)[1] << 16) |((*e1)[2] << 8) | (*e1)[3];
- *e1 += 4;
- j = (**e2 << 24) | ((*e2)[1] << 16) |((*e2)[2] << 8) | (*e2)[3];
- *e2 += 4;
- ret = cmpbytes(*e1, i , *e2 , j);
- *e1 += i; *e2 += j;
- return ret;
-
- case ERL_FUN_EXT: /* FIXME: */
- case ERL_NEW_FUN_EXT: /* FIXME: */
- return -1;
-
- default:
- return cmpbytes(*e1, 1, *e2, 1);
-
- } /* switch */
-
-} /* cmp_exe2 */
-
-/* Number compare */
-
-static int cmp_floats(double f1, double f2)
-{
-#if defined(VXWORKS) && CPU == PPC860
- return erl_fp_compare((unsigned *) &f1, (unsigned *) &f2);
-#else
- if (f1<f2) return -1;
- else if (f1>f2) return 1;
- else return 0;
-#endif
-}
-
-static INLINE double to_float(long l)
-{
- double f;
-#if defined(VXWORKS) && CPU == PPC860
- erl_long_to_fp(l, (unsigned *) &f);
-#else
- f = l;
-#endif
- return f;
-}
-
-
-static int cmp_small_big(unsigned char**e1, unsigned char **e2)
-{
- int i1,i2;
- int t2;
- int n2;
- long l1;
- int res;
-
- erlang_big *b1,*b2;
-
- i1 = i2 = 0;
- if ( ei_decode_long((char *)*e1,&i1,&l1) < 0 ) return -1;
-
- ei_get_type((char *)*e2,&i2,&t2,&n2);
-
- /* any small will fit in two digits */
- if ( (b1 = ei_alloc_big(2)) == NULL ) return -1;
- if ( ei_small_to_big(l1,b1) < 0 ) {
- ei_free_big(b1);
- return -1;
- }
-
- if ( (b2 = ei_alloc_big(n2)) == NULL ) {
- ei_free_big(b1);
- return 1;
- }
-
- if ( ei_decode_big((char *)*e2,&i2,b2) < 0 ) {
- ei_free_big(b1);
- ei_free_big(b2);
- return 1;
- }
-
- res = ei_big_comp(b1,b2);
-
- ei_free_big(b1);
- ei_free_big(b2);
-
- *e1 += i1;
- *e2 += i2;
-
- return res;
-}
-
-static int cmp_small_float(unsigned char**e1, unsigned char **e2)
-{
- int i1,i2;
- long l1;
- double f1,f2;
-
- /* small -> float -> float_comp */
-
- i1 = i2 = 0;
- if ( ei_decode_long((char *)*e1,&i1,&l1) < 0 ) return -1;
- if ( ei_decode_double((char *)*e2,&i2,&f2) < 0 ) return 1;
-
- f1 = to_float(l1);
-
- *e1 += i1;
- *e2 += i2;
-
- return cmp_floats(f1,f2);
-}
-
-static int cmp_float_big(unsigned char**e1, unsigned char **e2)
-{
- int res;
- int i1,i2;
- int t2,n2;
- double f1,f2;
- erlang_big *b2;
-
- /* big -> float if overflow return big sign else float_comp */
-
- i1 = i2 = 0;
- if ( ei_decode_double((char *)*e1,&i1,&f1) < 0 ) return -1;
-
- if (ei_get_type((char *)*e2,&i2,&t2,&n2) < 0) return 1;
- if ((b2 = ei_alloc_big(n2)) == NULL) return 1;
- if (ei_decode_big((char *)*e2,&i2,b2) < 0) return 1;
-
- /* convert the big to float */
- if ( ei_big_to_double(b2,&f2) < 0 ) {
- /* exception look at the sign */
- res = b2->is_neg ? 1 : -1;
- ei_free_big(b2);
- return res;
- }
-
- ei_free_big(b2);
-
- *e1 += i1;
- *e2 += i2;
-
- return cmp_floats(f1,f2);
-}
-
-static int cmp_small_small(unsigned char**e1, unsigned char **e2)
-{
- int i1,i2;
- long l1,l2;
-
- i1 = i2 = 0;
- if ( ei_decode_long((char *)*e1,&i1,&l1) < 0 ) {
- fprintf(stderr,"Failed to decode 1\r\n");
- return -1;
- }
- if ( ei_decode_long((char *)*e2,&i2,&l2) < 0 ) {
- fprintf(stderr,"Failed to decode 2\r\n");
- return 1;
- }
-
- *e1 += i1;
- *e2 += i2;
-
- if ( l1 < l2 ) return -1;
- else if ( l1 > l2 ) return 1;
- else return 0;
-}
-
-static int cmp_float_float(unsigned char**e1, unsigned char **e2)
-{
- int i1,i2;
- double f1,f2;
-
- i1 = i2 = 0;
- if ( ei_decode_double((char *)*e1,&i1,&f1) < 0 ) return -1;
- if ( ei_decode_double((char *)*e2,&i2,&f2) < 0 ) return 1;
-
- *e1 += i1;
- *e2 += i2;
-
- return cmp_floats(f1,f2);
-}
-
-static int cmp_big_big(unsigned char**e1, unsigned char **e2)
-{
- int res;
- int i1,i2;
- int t1,t2;
- int n1,n2;
- erlang_big *b1,*b2;
-
- i1 = i2 = 0;
- ei_get_type((char *)*e1,&i1,&t1,&n1);
- ei_get_type((char *)*e2,&i2,&t2,&n2);
-
- if ( (b1 = ei_alloc_big(n1)) == NULL) return -1;
- if ( (b2 = ei_alloc_big(n2)) == NULL) {
- ei_free_big(b1);
- return 1;
- }
-
- ei_decode_big((char *)*e1,&i1,b1);
- ei_decode_big((char *)*e2,&i2,b2);
-
- res = ei_big_comp(b1,b2);
-
- ei_free_big(b1);
- ei_free_big(b2);
-
- *e1 += i1;
- *e2 += i2;
-
- return res;
-}
-
-static int cmp_number(unsigned char**e1, unsigned char **e2)
-{
- switch (CMP_NUM_CODE(**e1,**e2)) {
-
- case SMALL_BIG:
- /* fprintf(stderr,"compare small_big\r\n"); */
- return cmp_small_big(e1,e2);
-
- case BIG_SMALL:
- /* fprintf(stderr,"compare sbig_small\r\n"); */
- return -cmp_small_big(e2,e1);
-
- case SMALL_FLOAT:
- /* fprintf(stderr,"compare small_float\r\n"); */
- return cmp_small_float(e1,e2);
-
- case FLOAT_SMALL:
- /* fprintf(stderr,"compare float_small\r\n"); */
- return -cmp_small_float(e2,e1);
-
- case FLOAT_BIG:
- /* fprintf(stderr,"compare float_big\r\n"); */
- return cmp_float_big(e1,e2);
-
- case BIG_FLOAT:
- /* fprintf(stderr,"compare big_float\r\n"); */
- return -cmp_float_big(e2,e1);
-
- case SMALL_SMALL:
- /* fprintf(stderr,"compare small_small\r\n"); */
- return cmp_small_small(e1,e2);
-
- case FLOAT_FLOAT:
- /* fprintf(stderr,"compare float_float\r\n"); */
- return cmp_float_float(e1,e2);
-
- case BIG_BIG:
- /* fprintf(stderr,"compare big_big\r\n"); */
- return cmp_big_big(e1,e2);
-
- default:
- /* should never get here ... */
- /* fprintf(stderr,"compare standard\r\n"); */
- return cmp_exe2(e1,e2);
- }
-
-}
-
-/*
- * If the arrays are of the same type, then we
- * have to do a real compare.
- */
-/*
- * COMPARE TWO encoded BYTE ARRAYS e1 and e2.
- * Return: -1 if e1 < e2
- * 0 if e1 == e2
- * 1 if e2 > e1
- */
-static int compare_top_ext(unsigned char**e1, unsigned char **e2)
-{
- if (**e1 == ERL_VERSION_MAGIC) (*e1)++;
- if (**e2 == ERL_VERSION_MAGIC) (*e2)++;
-
- if (cmp_array[**e1] < cmp_array[**e2]) return -1;
- if (cmp_array[**e1] > cmp_array[**e2]) return 1;
-
- if (IS_ERL_NUM(**e1))
- return cmp_number(e1,e2);
-
- if (cmp_array[**e1] == ERL_REF_CMP)
- return cmp_refs(e1, e2);
-
- return cmp_exe2(e1, e2);
-}
-
-int erl_compare_ext(unsigned char *e1, unsigned char *e2)
-{
- return compare_top_ext(&e1, &e2);
-} /* erl_compare_ext */
-
-#if defined(VXWORKS) && CPU == PPC860
-/* FIXME we have no floating point but don't we have emulation?! */
-int erl_fp_compare(unsigned *a, unsigned *b)
-{
- /* Big endian mode of powerPC, IEEE floating point. */
- unsigned a_split[4] = {a[0] >> 31, /* Sign bit */
- (a[0] >> 20) & 0x7FFU, /* Exponent */
- a[0] & 0xFFFFFU, /* Mantissa MS bits */
- a[1]}; /* Mantissa LS bits */
- unsigned b_split[4] = {b[0] >> 31,
- (b[0] >> 20) & 0x7FFU,
- b[0] & 0xFFFFFU,
- b[1]};
- int a_is_infinite, b_is_infinite;
- int res;
-
-
- /* Make -0 be +0 */
- if (a_split[1] == 0 && a_split[2] == 0 && a_split[3] == 0)
- a_split[0] = 0;
- if (b_split[1] == 0 && b_split[2] == 0 && b_split[3] == 0)
- b_split[0] = 0;
- /* Check for infinity */
- a_is_infinite = (a_split[1] == 0x7FFU && a_split[2] == 0 &&
- a_split[3] == 0);
- b_is_infinite = (b_split[1] == 0x7FFU && b_split[2] == 0 &&
- b_split[3] == 0);
-
- if (a_is_infinite && !b_is_infinite)
- return (a_split[0]) ? -1 : 1;
- if (b_is_infinite && !a_is_infinite)
- return (b_split[0]) ? 1 : -1;
- if (a_is_infinite && b_is_infinite)
- return b[0] - a[0];
- /* Check for indeterminate or nan, infinite is already handled,
- so we only check the exponent. */
- if((a_split[1] == 0x7FFU) || (b_split[1] == 0x7FFU))
- return INT_MAX; /* Well, they are not equal anyway,
- abort() could be an alternative... */
-
- if (a_split[0] && !b_split[0])
- return -1;
- if (b_split[0] && !a_split[0])
- return 1;
- /* Compare */
- res = memcmp(a_split + 1, b_split + 1, 3 * sizeof(unsigned));
- /* Make -1, 0 or 1 */
- res = (!!res) * ((res < 0) ? -1 : 1);
- /* Turn sign if negative values */
- if (a_split[0]) /* Both are negative */
- res = -1 * res;
- return res;
-}
-
-static void join(unsigned d_split[4], unsigned *d)
-{
- d[0] = (d_split[0] << 31) | /* Sign bit */
- ((d_split[1] & 0x7FFU) << 20) | /* Exponent */
- (d_split[2] & 0xFFFFFU); /* Mantissa MS bits */
- d[1] = d_split[3]; /* Mantissa LS bits */
-}
-
-static int blength(unsigned long l)
-{
- int i;
- for(i = 0; l; ++i)
- l >>= 1;
- return i;
-}
-
-static void erl_long_to_fp(long l, unsigned *d)
-{
- unsigned d_split[4];
- unsigned x;
- if (l < 0) {
- d_split[0] = 1;
- x = -l;
- } else {
- d_split[0] = 0;
- x = l;
- }
-
- if (!l) {
- memset(d_split,0,sizeof(d_split));
- } else {
- int len = blength(x);
- x <<= (33 - len);
- d_split[2] = (x >> 12);
- d_split[3] = (x << 20);
- d_split[1] = 1023 + len - 1;
- }
- join(d_split,d);
-}
-
-#endif
-
-
-/*
- * Checks if a term is a "string": a flat list of byte-sized integers.
- *
- * Returns: 0 if the term is not a string, otherwise the length is returned.
- */
-
-static int is_string(ETERM* term)
-{
- int len = 0;
-
- while (ERL_TYPE(term) == ERL_LIST) {
- ETERM* head = HEAD(term);
-
- if (!ERL_IS_INTEGER(head) || ((unsigned)head->uval.ival.i) > 255) {
- return 0;
- }
- len++;
- term = TAIL(term);
- }
-
- if (ERL_IS_EMPTY_LIST(term)) {
- return len;
- }
- return 0;
-}
diff --git a/lib/erl_interface/src/legacy/erl_marshal.h b/lib/erl_interface/src/legacy/erl_marshal.h
deleted file mode 100644
index c1963b832d..0000000000
--- a/lib/erl_interface/src/legacy/erl_marshal.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-#ifndef _ERL_MARSHALL_H
-#define _ERL_MARSHALL_H
-
-#include "erl_eterm.h" /* FIXME don't want to include this here */
-
-/* FIXME: not documented, may be internal */
-int erl_verify_magic(unsigned char*);
-void erl_init_marshal(void);
-int erl_encode_it(ETERM *ep, unsigned char **ext, int dist);
-
-#endif /* _ERL_MARSHALL_H */
diff --git a/lib/erl_interface/src/legacy/erl_resolve.c b/lib/erl_interface/src/legacy/erl_resolve.c
deleted file mode 100644
index bb09caec85..0000000000
--- a/lib/erl_interface/src/legacy/erl_resolve.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 2003-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-
-/***************************************************************************
- *
- * Compatibility with the old erl_interface library that had some
- * undocumented functions.
- *
- ***************************************************************************/
-
-#include "eidef.h"
-
-#include "erl_interface.h"
-#include "ei_resolve.h"
-#include "ei_connect_int.h"
-#include "ei_epmd.h"
-
-struct hostent *erl_gethostbyname(const char *name)
-{
- return ei_gethostbyname(name);
-}
-
-
-void erl_init_resolve(void)
-{
- ei_init_resolve();
-}
-
-
-struct hostent *erl_gethostbyaddr(const char *addr, int len, int type)
-{
- return ei_gethostbyaddr(addr, len, type);
-}
-
-
-struct hostent *erl_gethostbyname_r(const char *name,
- struct hostent *hostp,
- char *buffer,
- int buflen,
- int *h_errnop)
-{
- return ei_gethostbyname_r(name,hostp,buffer,buflen,h_errnop);
-}
-
-
-struct hostent *erl_gethostbyaddr_r(const char *addr,
- int length,
- int type,
- struct hostent *hostp,
- char *buffer,
- int buflen,
- int *h_errnop)
-{
- return ei_gethostbyaddr_r(addr,length,type,hostp,buffer,buflen,h_errnop);
-}
-
-
-int erl_distversion(int fd)
-{
- return ei_distversion(fd);
-}
-
-int erl_epmd_connect(struct in_addr *inaddr)
-{
- return ei_epmd_connect_tmo(inaddr,0);
-}
-
-int erl_epmd_port(struct in_addr *inaddr, const char *alive, int *dist)
-{
- return ei_epmd_port(inaddr, alive, dist);
-}
-
-
-
-/* FIXME !!!!!
-erl_epmd_port ei_epmd_port
-erl_mutex_lock ei_mutex_lock
-erl_malloc erl_free ????
-erl_publish erl_unpublish
-< extern int erl_epmd_connect(struct in_addr *inaddr);
-< extern int erl_epmd_publish(int port, const char *alive);
-< extern int erl_epmd_port(struct in_addr *inaddr, const char *alive, int *dist);
-
-< int erl_unpublish(const char *alive)
----
-> int ei_unpublish_alive(const char *alive)
-
-erl_self
-erl_getfdcookie
-*/
diff --git a/lib/erl_interface/src/legacy/erl_timeout.c b/lib/erl_interface/src/legacy/erl_timeout.c
deleted file mode 100644
index e36ea0e250..0000000000
--- a/lib/erl_interface/src/legacy/erl_timeout.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 1997-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-/* timeout.c
- *
- * todo: use posix timers (timer_create etc) instead of setitimer.
- *
- */
-#if !defined(__WIN32__) && !defined(VXWORKS)
-
-/* FIXME: well, at least I can compile now... */
-
-#include "eidef.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <setjmp.h>
-#include <signal.h>
-
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-
-#include "erl_interface.h"
-#include "erl_timeout.h"
-
-typedef struct jmp_s {
- jmp_buf jmpbuf;
- struct itimerval timerinfo;
- void *siginfo;
- struct jmp_s *next;
-} *jmp_t;
-
-static jmp_t push(jmp_t j);
-static jmp_t pop(void);
-static void timeout_handler(int dummy);
-
-jmp_buf *timeout_setup(int ms)
-{
- struct itimerval t;
- jmp_t j;
- void *s;
-
-#ifdef DEBUG
- fprintf(stderr,"timeout setup\n");
-#endif
- s=signal(SIGALRM,timeout_handler);
-
- /* set the timer */
- t.it_interval.tv_sec = 0;
- t.it_interval.tv_usec = 0;
- t.it_value.tv_sec = ms / 1000;
- t.it_value.tv_usec = (ms % 1000) * 1000;
-
- /* get a jump buffer and save it */
- j = erl_malloc(sizeof(*j));
- j->siginfo = s;
- push(j);
-
- setitimer(ITIMER_REAL,&t,&(j->timerinfo));
-
- return &(j->jmpbuf);
-}
-
-
-int timeout_cancel(void)
-{
- jmp_t j;
-
-#ifdef DEBUG
- fprintf(stderr,"timeout cancel\n");
-#endif
- /* retrieve the jump buffer */
- j=pop();
- /* restore the timer and signal disposition */
- setitimer(ITIMER_REAL,&(j->timerinfo),NULL);
- signal(SIGALRM,j->siginfo);
-
- free(j);
-
- return 0;
-}
-
-void timeout_handler(int dummy)
-{
- jmp_t j;
-
-#ifdef DEBUG
- fprintf(stderr,"timeout handler\n");
-#endif
-
- /* retrieve the jump buffer */
- j=pop();
-
- /* restore the timer and signal disposition */
- setitimer(ITIMER_REAL,&(j->timerinfo),NULL);
- signal(SIGALRM,j->siginfo);
-
- free(j);
- longjmp(j->jmpbuf,JMPVAL);
- return; /* not reached */
-}
-
-
-/* a simple stack for saving the jump buffer allows us to pass a
- * variable between functions that don't call each other, in a way
- * that will survive the longjmp().
- */
-
-/* FIXME problem for threaded ? */
-static jmp_t jmp_head=NULL;
-#ifdef DEBUG
-static int depth = 0;
-static int maxdepth = 0;
-#endif
-
-static jmp_t push(jmp_t j)
-{
- j->next = jmp_head;
- jmp_head = j;
-
-#ifdef DEBUG
- depth++;
- if (depth > maxdepth) maxdepth = depth;
-#endif
-
- return j;
-}
-
-static jmp_t pop(void)
-{
- jmp_t j = jmp_head;
- if (j) jmp_head = j->next;
-#ifdef DEBUG
- depth--;
-#endif
- return j;
-}
-
-#endif /* platform */
diff --git a/lib/erl_interface/src/legacy/erl_timeout.h b/lib/erl_interface/src/legacy/erl_timeout.h
deleted file mode 100644
index 6bcfa5ecbb..0000000000
--- a/lib/erl_interface/src/legacy/erl_timeout.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 1997-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-#ifndef _ERL_TIMEOUT_H
-#define _ERL_TIMEOUT_H
-
-#if !defined (__WIN32__) && !defined (VXWORKS)
-
-#include <setjmp.h>
-
-/*
- use timeout like this (delay in ms):
-
- if (timeout(delay,fun(a,b,c))) {
- printf("timeout occurred\n");
- }
- else {
- ...
- }
-
-If the call to fun() has not returned before 'delay' ms, it will be
-interrupted and and timeout() will return a non-zero value.
-
-If fun() finishes before 'delay' ms, then timeout will return 0.
-
-If you need the return value from fun then assign it like this:
-
- if (timeout(delay,(x = fun(...)))) {
- }
-
-These functions work by setting and catching SIGALRM, and although it
-saves and restores the signal handler, it may not work in situations
-where you are already using SIGALRM (this includes calls to sleep(3)).
-
-Note that although recursive calls to timeout will not fail, they may
-not give the expected results. All invocations of timeout use the same
-timer, which is set on entrance to timeout and restored on exit from
-timeout. So although an inner call to timeout will restart the timer
-for any pending outer call when it exits, any time that has already
-elapsed against the outer timeout is forgotten. In addition, the alarm
-signal will always go to the innermost (last called) timeout, which
-may or may not be the intention in recursive cases.
-
-*/
-
-#define JMPVAL 997 /* magic */
-
-#define timeout(ms,funcall) \
- (setjmp(*timeout_setup(ms)) == JMPVAL ? -1: \
- ((void)(funcall), timeout_cancel()))
-
-
-/* don't call any of these directly - use the macro! see above! */
-jmp_buf *timeout_setup(int ms);
-int timeout_cancel(void);
-
-#endif /* WIN32 && VXWORKS */
-
-#endif /* _ERL_TIMEOUT_H */
diff --git a/lib/erl_interface/src/legacy/portability.h b/lib/erl_interface/src/legacy/portability.h
deleted file mode 100644
index 42a78662d5..0000000000
--- a/lib/erl_interface/src/legacy/portability.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 2000-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-
-#ifndef _PORTABILITY_H
-#define _PORTABILITY_H
-
-#if !defined(__GNUC__) || __GNUC__ < 2
-
-/*
- * GCC's attributes are too useful to not use. Other compilers
- * just lose opportunities to optimize and warn.
- */
-# define __attribute__(foo) /* nothing */
-
-#endif
-
-#endif /* _PORTABILITY_H */
diff --git a/lib/erl_interface/src/misc/ei_format.c b/lib/erl_interface/src/misc/ei_format.c
index a188171f40..695c3404f7 100644
--- a/lib/erl_interface/src/misc/ei_format.c
+++ b/lib/erl_interface/src/misc/ei_format.c
@@ -24,10 +24,6 @@
* ei_format to build binary format terms a bit like printf
*/
-#ifdef VXWORKS
-#include <vxWorks.h>
-#endif
-
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
diff --git a/lib/erl_interface/src/misc/ei_locking.c b/lib/erl_interface/src/misc/ei_locking.c
index a5ddbb85f2..20464869ad 100644
--- a/lib/erl_interface/src/misc/ei_locking.c
+++ b/lib/erl_interface/src/misc/ei_locking.c
@@ -26,7 +26,7 @@
/* Note that these locks are NOT recursive on Win32 or Solaris,
* i.e. self-deadlock will occur if a thread tries to obtain a lock it
- * is already holding. The primitives used on VxWorks are recursive however.
+ * is already holding.
*/
#include "eidef.h"
@@ -36,10 +36,6 @@
#include <windows.h>
#include <winbase.h>
-#elif VXWORKS
-#include <vxWorks.h>
-#include <semLib.h>
-
#else /* unix */
#include <stdlib.h>
#include <unistd.h>
@@ -63,12 +59,6 @@ ei_mutex_t *ei_mutex_create(void)
#ifdef __WIN32__
l->lock = CreateMutex(NULL,FALSE,NULL);
-
-#elif VXWORKS
- if (!(l->lock = semMCreate(SEM_DELETE_SAFE))) {
- ei_free(l);
- return NULL;
- }
#else /* unix */
l->lock = ei_m_create();
#endif
@@ -97,10 +87,6 @@ int ei_mutex_free(ei_mutex_t *l, int nblock)
/* we are now holding the lock */
#ifdef __WIN32__
CloseHandle(l->lock);
-
-#elif VXWORKS
- if (semDelete(l->lock) == ERROR) return -1;
-
#else /* unix */
ei_m_destroy(l->lock);
#endif
@@ -131,11 +117,6 @@ int ei_mutex_lock(ei_mutex_t *l, int nblock)
/* check valid values for timeout: is 0 ok? */
if (WaitForSingleObject(l->lock,(nblock? 0 : INFINITE)) != WAIT_OBJECT_0)
return -1;
-
-#elif VXWORKS
- if (semTake(l->lock,(nblock? NO_WAIT : WAIT_FOREVER)) == ERROR)
- return -1;
-
#else /* unix */
if (nblock) {
if (ei_m_trylock(l->lock) < 0) return -1;
@@ -151,10 +132,6 @@ int ei_mutex_unlock(ei_mutex_t *l)
{
#ifdef __WIN32__
ReleaseMutex(l->lock);
-
-#elif VXWORKS
- semGive(l->lock);
-
#else /* unix */
ei_m_unlock(l->lock);
#endif
diff --git a/lib/erl_interface/src/misc/ei_locking.h b/lib/erl_interface/src/misc/ei_locking.h
index 1bbee2d499..93aade6b2d 100644
--- a/lib/erl_interface/src/misc/ei_locking.h
+++ b/lib/erl_interface/src/misc/ei_locking.h
@@ -24,11 +24,6 @@
#include "config.h"
-#if defined(VXWORKS)
-#include <taskLib.h>
-#include <taskVarLib.h>
-#endif
-
#ifdef __WIN32__
#include <winsock2.h>
#include <windows.h>
@@ -45,8 +40,6 @@
typedef struct ei_mutex_s {
#ifdef __WIN32__
HANDLE lock;
-#elif VXWORKS
- SEM_ID lock;
#else /* unix */
#if defined(HAVE_MIT_PTHREAD_H) || defined(HAVE_PTHREAD_H)
pthread_mutex_t *lock;
@@ -64,7 +57,7 @@ int ei_mutex_lock(ei_mutex_t *l, int nblock);
int ei_mutex_unlock(ei_mutex_t *l);
-#if defined(_REENTRANT) && !defined(VXWORKS) && !defined(__WIN32__)
+#if defined(_REENTRANT) && !defined(__WIN32__)
void *ei_m_create(void);
int ei_m_destroy(void *l);
@@ -72,6 +65,6 @@ int ei_m_lock(void *l);
int ei_m_trylock(void *l);
int ei_m_unlock(void *l);
-#endif /* _REENTRANT && !VXWORKS && !__WIN32__ */
+#endif /* _REENTRANT && !__WIN32__ */
#endif /* _EI_LOCKING_H */
diff --git a/lib/erl_interface/src/misc/ei_portio.c b/lib/erl_interface/src/misc/ei_portio.c
index bccc86c1b1..afa766a776 100644
--- a/lib/erl_interface/src/misc/ei_portio.c
+++ b/lib/erl_interface/src/misc/ei_portio.c
@@ -42,29 +42,7 @@ static unsigned long param_one = 1;
#define MEANS_SOCKET_ERROR(Ret) ((Ret == SOCKET_ERROR))
#define IS_INVALID_SOCKET(Sock) ((Sock) == INVALID_SOCKET)
-#elif VXWORKS
-#include <vxWorks.h>
-#include <hostLib.h>
-#include <ifLib.h>
-#include <sockLib.h>
-#include <taskLib.h>
-#include <inetLib.h>
-#include <selectLib.h>
-#include <ioLib.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <timers.h>
-
-static unsigned long param_zero = 0;
-static unsigned long param_one = 1;
-#define SET_BLOCKING(Sock) ioctl((Sock),FIONBIO,(int)&param_zero)
-#define SET_NONBLOCKING(Sock) ioctl((Sock),FIONBIO,(int)&param_one)
-#define MEANS_SOCKET_ERROR(Ret) ((Ret) == ERROR)
-#define IS_INVALID_SOCKET(Sock) ((Sock) < 0)
-
-#else /* other unix */
+#else /* unix */
#include <stdlib.h>
#include <sys/socket.h>
#include <unistd.h>
@@ -622,7 +600,7 @@ int ei_accept_ctx_t__(ei_socket_callbacks *cbs, void **ctx,
} while (error == EINTR);
}
do {
- error = cbs->accept(ctx, addr, len, ms);
+ error = cbs->EI_ACCEPT_NAME(ctx, addr, len, ms);
} while (error == EINTR);
return error;
}
diff --git a/lib/erl_interface/src/misc/ei_portio.h b/lib/erl_interface/src/misc/ei_portio.h
index 5172d085b4..b47b220d51 100644
--- a/lib/erl_interface/src/misc/ei_portio.h
+++ b/lib/erl_interface/src/misc/ei_portio.h
@@ -23,7 +23,7 @@
#define _EI_PORTIO_H
#undef EI_HAVE_STRUCT_IOVEC__
-#if !defined(__WIN32__) && !defined(VXWORKS) && defined(HAVE_SYS_UIO_H)
+#if !defined(__WIN32__) && defined(HAVE_SYS_UIO_H)
/* Declaration of struct iovec *iov should be visible in this scope. */
# include <sys/uio.h>
# define EI_HAVE_STRUCT_IOVEC__
diff --git a/lib/erl_interface/src/misc/ei_printterm.c b/lib/erl_interface/src/misc/ei_printterm.c
index aee7f7eeb0..0dfecb6d4b 100644
--- a/lib/erl_interface/src/misc/ei_printterm.c
+++ b/lib/erl_interface/src/misc/ei_printterm.c
@@ -24,10 +24,6 @@
* ei_print_term to print out a binary coded term
*/
-#ifdef VXWORKS
-#include <vxWorks.h>
-#endif
-
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
diff --git a/lib/erl_interface/src/misc/ei_pthreads.c b/lib/erl_interface/src/misc/ei_pthreads.c
index c6d07a9a0a..df7a7fbb8f 100644
--- a/lib/erl_interface/src/misc/ei_pthreads.c
+++ b/lib/erl_interface/src/misc/ei_pthreads.c
@@ -38,25 +38,6 @@ static LONG volatile tls_init_mutex = 0;
#endif
#endif
-#if defined(VXWORKS)
-
-/*
- Moved to each of the erl_*threads.c files, as they seem to know how
- to get thread-safety.
-*/
-static volatile int __erl_errno;
-volatile int *__erl_errno_place(void)
-{
- /* This check is somewhat insufficient, double task var entries will occur
- if __erl_errno is actually -1, which on the other hand is an invalid
- error code. */
- if (taskVarGet(taskIdSelf(), &__erl_errno) == ERROR) {
- taskVarAdd(taskIdSelf(), &__erl_errno);
- }
- return &__erl_errno;
-}
-#endif /* VXWORKS */
-
#if defined(__WIN32__)
#ifdef USE_DECLSPEC_THREAD
@@ -106,7 +87,7 @@ volatile int *__erl_errno_place(void)
#endif /* __WIN32__ */
-#if defined(_REENTRANT) && !defined(VXWORKS) && !defined(__WIN32__)
+#if defined(_REENTRANT) && !defined(__WIN32__)
#if defined(HAVE_PTHREAD_H) || defined(HAVE_MIT_PTHREAD_H)
@@ -219,9 +200,9 @@ volatile int *__erl_errno_place(void)
#endif /* HAVE_PTHREAD_H || HAVE_MIT_PTHREAD_H */
-#endif /* _REENTRANT && !VXWORKS && !__WIN32__ */
+#endif /* _REENTRANT && !__WIN32__ */
-#if !defined(_REENTRANT) && !defined(VXWORKS) && !defined(__WIN32__)
+#if !defined(_REENTRANT) && !defined(__WIN32__)
volatile int __erl_errno;
diff --git a/lib/erl_interface/src/misc/ei_x_encode.c b/lib/erl_interface/src/misc/ei_x_encode.c
index 8e77679d2a..fe3c20faff 100644
--- a/lib/erl_interface/src/misc/ei_x_encode.c
+++ b/lib/erl_interface/src/misc/ei_x_encode.c
@@ -23,10 +23,6 @@
* ei_x_encode to encode in a self-expanding buffer
*/
-#ifdef VXWORKS
-#include <vxWorks.h>
-#endif
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
diff --git a/lib/erl_interface/src/misc/eidef.h b/lib/erl_interface/src/misc/eidef.h
index f38824d826..f1fdafaa08 100644
--- a/lib/erl_interface/src/misc/eidef.h
+++ b/lib/erl_interface/src/misc/eidef.h
@@ -27,11 +27,6 @@
#include "config.h" /* Central include of config.h */
-/* vxWorks.h needs to be before stddef.h */
-#ifdef VXWORKS
-#include <vxWorks.h>
-#endif
-
#include <stddef.h> /* We want to get definition of NULL */
#include "ei.h" /* Want the API function declarations */
diff --git a/lib/erl_interface/src/not_used/ei_send.c b/lib/erl_interface/src/not_used/ei_send.c
deleted file mode 100644
index 8071876677..0000000000
--- a/lib/erl_interface/src/not_used/ei_send.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 2001-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- *
-
- */
-#ifdef __WIN32__
-#include <winsock2.h>
-#include <windows.h>
-#include <winbase.h>
-
-#elif VXWORKS
-#include <sys/types.h>
-#include <unistd.h>
-
-#else /* unix */
-#include <sys/types.h>
-#include <unistd.h>
-#include <sys/uio.h>
-#endif
-
-#include "eidef.h"
-#include "eiext.h"
-#include "ei_connect.h"
-#include "ei_internal.h"
-#include "putget.h"
-#include "ei_trace.h"
-#include "show_msg.h"
-
-/* FIXME this is not useed !!!!! */
-
-/* length (4), PASS_THROUGH (1), header, message */
-int ei_ei_send_encoded(ei_cnode* ec, int fd, const erlang_pid *to,
- const char *msg, int msglen)
-{
- char *s, header[1200]; /* see size calculation below */
- erlang_trace *token = NULL;
- int index = 5; /* reserve 5 bytes for control message */
-#ifdef HAVE_WRITEV
- struct iovec v[2];
-#endif
-
- /* are we tracing? */
- /* check that he can receive trace tokens first */
- if (ei_distversion(fd) > 0)
- token = ei_trace(0,(erlang_trace *)NULL);
-
- /* header = SEND, cookie, to max sizes: */
- ei_encode_version(header,&index); /* 1 */
- if (token) {
- ei_encode_tuple_header(header,&index,4); /* 2 */
- ei_encode_long(header,&index,ERL_SEND_TT); /* 2 */
- } else {
- ei_encode_tuple_header(header,&index,3);
- ei_encode_long(header,&index,ERL_SEND);
- }
- ei_encode_atom(header,&index, "" /*ei_getfdcookie(ec, fd)*/); /* 258 */
- ei_encode_pid(header,&index,to); /* 268 */
-
- if (token) ei_encode_trace(header,&index,token); /* 534 */
-
- /* control message (precedes header actually) */
- /* length = 1 ('p') + header len + message len */
- s = header;
- put32be(s, index + msglen - 4); /* 4 */
- put8(s, ERL_PASS_THROUGH); /* 1 */
- /*** sum: 1070 */
-
-#ifdef DEBUG_DIST
- if (ei_trace_distribution > 0) ei_show_sendmsg(stderr,header,msg);
-#endif
-
-#ifdef HAVE_WRITEV
-
- v[0].iov_base = (char *)header;
- v[0].iov_len = index;
- v[1].iov_base = (char *)msg;
- v[1].iov_len = msglen;
-
- if (writev(fd,v,2) != index+msglen) return -1;
-
-#else /* !HAVE_WRITEV */
-
- if (writesocket(fd,header,index) != index) return -1;
- if (writesocket(fd,msg,msglen) != msglen) return -1;
-
-#endif /* !HAVE_WRITEV */
-
- return 0;
-}
diff --git a/lib/erl_interface/src/not_used/ei_send_reg.c b/lib/erl_interface/src/not_used/ei_send_reg.c
deleted file mode 100644
index ba9c7348f9..0000000000
--- a/lib/erl_interface/src/not_used/ei_send_reg.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 2001-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- *
-
- */
-#ifdef __WIN32__
-#include <winsock2.h>
-#include <windows.h>
-#include <winbase.h>
-
-#elif VXWORKS
-#include <sys/types.h>
-#include <unistd.h>
-
-#else /* unix */
-#include <sys/types.h>
-#include <unistd.h>
-#include <sys/uio.h>
-#endif
-
-#include "eidef.h"
-#include "eiext.h"
-#include "ei_connect.h"
-#include "ei_internal.h"
-#include "putget.h"
-#include "ei_trace.h"
-#include "show_msg.h"
-
-/* FIXME this is not useed !!!!! */
-/* FIXME merge with ei_send.c */
-
-/* length (4), PASS_THROUGH (1), header, message */
-int ei_ei_send_reg_encoded(ei_cnode* ec, int fd, const erlang_pid *from,
- const char *to, const char *msg, int msglen)
-{
- char *s, header[1400]; /* see size calculation below */
- erlang_trace *token = NULL;
- int index = 5; /* reserve 5 bytes for control message */
-#ifdef HAVE_WRITEV
- struct iovec v[2];
-#endif
-
- /* are we tracing? */
- /* check that he can receive trace tokens first */
- if (ei_distversion(fd) > 0)
- token = ei_trace(0,(erlang_trace *)NULL);
-
- /* header = REG_SEND, from, cookie, toname max sizes: */
- ei_encode_version(header,&index); /* 1 */
- if (token) {
- ei_encode_tuple_header(header,&index,5); /* 2 */
- ei_encode_long(header,&index,ERL_REG_SEND_TT); /* 2 */
- } else {
- ei_encode_tuple_header(header,&index,4);
- ei_encode_long(header,&index,ERL_REG_SEND);
- }
- ei_encode_pid(header,&index,from); /* 268 */
- ei_encode_atom(header,&index,"" /*ei_getfdcookie(ec, fd)*/ ); /* 258 */
- ei_encode_atom(header,&index,to); /* 268 */
-
- if (token) ei_encode_trace(header,&index,token); /* 534 */
-
- /* control message (precedes header actually) */
- /* length = 1 ('p') + header len + message len */
- s = header;
- put32be(s, index + msglen - 4); /* 4 */
- put8(s, ERL_PASS_THROUGH); /* 1 */
- /*** sum: 1336 */
-
-#ifdef DEBUG_DIST
- if (ei_trace_distribution > 0) ei_show_sendmsg(stderr,header,msg);
-#endif
-
-#ifdef HAVE_WRITEV
-
- v[0].iov_base = (char *)header;
- v[0].iov_len = index;
- v[1].iov_base = (char *)msg;
- v[1].iov_len = msglen;
-
- if (writev(fd,v,2) != index+msglen) return -1;
-
-#else
-
- /* no writev() */
- if (writesocket(fd,header,index) != index) return -1;
- if (writesocket(fd,msg,msglen) != msglen) return -1;
-
-#endif
-
- return 0;
-}
diff --git a/lib/erl_interface/src/not_used/send_link.c b/lib/erl_interface/src/not_used/send_link.c
deleted file mode 100644
index 38fae27df4..0000000000
--- a/lib/erl_interface/src/not_used/send_link.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 1998-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- *
-
- */
-#ifdef __WIN32__
-#include <winsock2.h>
-#include <windows.h>
-#include <winbase.h>
-
-#elif VXWORKS
-#include <unistd.h>
-
-#else /* unix */
-#include <unistd.h>
-
-#endif
-
-#include <string.h>
-#include <stdlib.h>
-#include "eidef.h"
-#include "eiext.h"
-#include "eisend.h"
-#include "ei_internal.h"
-#include "putget.h"
-#include "erl_rport.h"
-
-
-/* this sends either link or unlink ('which' decides) */
-static int link_unlink(int fd, const erlang_pid *from, const erlang_pid *to,
- int which, unsigned ms)
-{
- char msgbuf[EISMALLBUF];
- char *s;
- int index = 0;
- int n;
- unsigned tmo = ms == 0 ? EI_SCLBK_INF_TMO : ms;
-
- index = 5; /* max sizes: */
- ei_encode_version(msgbuf,&index); /* 1 */
- ei_encode_tuple_header(msgbuf,&index,3);
- ei_encode_long(msgbuf,&index,which);
- ei_encode_pid(msgbuf,&index,from); /* 268 */
- ei_encode_pid(msgbuf,&index,to); /* 268 */
-
- /* 5 byte header missing */
- s = msgbuf;
- put32be(s, index - 4); /* 4 */
- put8(s, ERL_PASS_THROUGH); /* 1 */
- /* sum: 542 */
-
-
-#ifdef DEBUG_DIST
- if (ei_trace_distribution > 1) ei_show_sendmsg(stderr,msgbuf,NULL);
-#endif
-
- n = ei_write_fill_t__(fd,msgbuf,index,tmo);
-
- return (n==index ? 0 : -1);
-}
-
-/* FIXME not used? */
-#if 0
-/* use this to send a link */
-int ei_send_unlink(int fd, const erlang_pid *from, const erlang_pid *to)
-{
- return link_unlink(fd, from, to, ERL_UNLINK,0);
-}
-
-/* use this to send an unlink */
-int ei_send_link(int fd, const erlang_pid *from, const erlang_pid *to)
-{
- return link_unlink(fd, from, to, ERL_LINK,0);
-}
-/* use this to send a link */
-int ei_send_unlink_tmo(int fd, const erlang_pid *from, const erlang_pid *to,
- unsigned ms)
-{
- return link_unlink(fd, from, to, ERL_UNLINK,ms);
-}
-
-/* use this to send an unlink */
-int ei_send_link_tmo(int fd, const erlang_pid *from, const erlang_pid *to,
- unsigned ms)
-{
- return link_unlink(fd, from, to, ERL_LINK,ms);
-}
-#endif
diff --git a/lib/erl_interface/src/not_used/whereis.c b/lib/erl_interface/src/not_used/whereis.c
deleted file mode 100644
index 4072fa7b33..0000000000
--- a/lib/erl_interface/src/not_used/whereis.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 1998-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- *
-
- */
-#ifdef __WIN32__
-#include <winsock2.h>
-#include <windows.h>
-#include <winbase.h>
-
-#elif VXWORKS
-#include <unistd.h>
-
-#else /* unix */
-#include <unistd.h>
-
-#endif
-
-#include <string.h>
-#include <stdlib.h>
-#include "erl_interface.h"
-#include "erl_connect.h"
-#include "erl_format.h"
-#include "erl_eterm.h"
-#include "erl_malloc.h"
-
-/* FIXME rewrite to ei functions */
-/* FIXME not used */
-
-erlang_pid *erl_whereis(int fd, const char *name)
-{
- ETERM *reply;
- ETERM *n;
- /* FIXME problem for threaded ? */
- static erlang_pid pid;
-
- n = erl_format("[~a]",name);
- reply = erl_rpc(fd,"erlang","whereis",n);
- erl_free_term(n);
-
- if (reply && (ERL_IS_PID(reply))) {
- char *node;
- node = ERL_PID_NODE(reply);
- strcpy(pid.node,node);
- pid.num = ERL_PID_NUMBER(reply);
- pid.serial = ERL_PID_SERIAL(reply);
- pid.creation = ERL_PID_CREATION(reply);
- erl_free_term(reply);
- return &pid;
- }
-
- if (reply) erl_free_term(reply);
- return NULL;
-}
-
diff --git a/lib/erl_interface/src/prog/ei_fake_prog.c b/lib/erl_interface/src/prog/ei_fake_prog.c
index 6f58c9833d..c483859c8b 100644
--- a/lib/erl_interface/src/prog/ei_fake_prog.c
+++ b/lib/erl_interface/src/prog/ei_fake_prog.c
@@ -54,11 +54,7 @@
/* #include <netdb.h> now included by ei.h */
#include "ei.h"
-#ifdef VXWORKS
-int ei_fake_prog_main(void)
-#else
int main(void)
-#endif
{
ErlConnect conp;
Erl_IpAddr thisipaddr = (Erl_IpAddr)0;
@@ -91,12 +87,10 @@ int main(void)
unsigned long *ulongp = NULL;
unsigned long ulongx = 0;
void *voidp = NULL;
-#ifndef VXWORKS
EI_LONGLONG *longlongp = (EI_LONGLONG*)NULL;
EI_LONGLONG longlongx = 0;
EI_ULONGLONG *ulonglongp = (EI_ULONGLONG*)NULL;
EI_ULONGLONG ulonglongx = 0;
-#endif
erlang_char_encoding enc;
ei_socket_callbacks cbs;
@@ -260,8 +254,6 @@ int main(void)
}
#endif /* HAVE_GMP_H && HAVE_LIBGMP */
-#ifndef VXWORKS
-
ei_decode_longlong(charp, intp, longlongp);
ei_decode_ulonglong(charp, intp, ulonglongp);
ei_encode_longlong(charp, intp, longlongx);
@@ -269,8 +261,6 @@ int main(void)
ei_x_encode_longlong(&eix, longlongx);
ei_x_encode_ulonglong(&eix, ulonglongx);
-#endif
-
#ifdef USE_EI_UNDOCUMENTED
ei_decode_intlist(charp, intp, longp, intp);
diff --git a/lib/erl_interface/src/prog/erl_call.c b/lib/erl_interface/src/prog/erl_call.c
index ab91157035..f3d025d30f 100644
--- a/lib/erl_interface/src/prog/erl_call.c
+++ b/lib/erl_interface/src/prog/erl_call.c
@@ -33,23 +33,6 @@
#include <windows.h>
#include <winbase.h>
-#elif VXWORKS
-
-#include <stdio.h>
-#include <string.h>
-#include <vxWorks.h>
-#include <hostLib.h>
-#include <selectLib.h>
-#include <ifLib.h>
-#include <sockLib.h>
-#include <taskLib.h>
-#include <inetLib.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <time.h>
-
#else /* unix */
#include <sys/types.h>
@@ -104,6 +87,8 @@ struct call_flags {
int debugp;
int verbosep;
int haltp;
+ long port;
+ char *hostname;
char *cookie;
char *node;
char *hidden;
@@ -131,13 +116,7 @@ static char* ei_chk_strdup(char *s);
*
***************************************************************************/
-/* FIXME isn't VxWorks to handle arguments differently? */
-
-#if !defined(VXWORKS)
int main(int argc, char *argv[])
-#else
-int erl_call(int argc, char **argv)
-#endif
{
int i = 1,fd,creation;
struct hostent *hp;
@@ -152,6 +131,8 @@ int erl_call(int argc, char **argv)
struct call_flags flags = {0}; /* Default 0 and NULL in all fields */
char* progname = argv[0];
ei_cnode ec;
+ flags.port = -1;
+ flags.hostname = NULL;
ei_init();
@@ -177,6 +158,29 @@ int erl_call(int argc, char **argv)
flags.node = ei_chk_strdup(argv[i+1]);
i++;
flags.use_long_name = 1;
+ } else if (strcmp(argv[i], "-address") == 0) { /* -address [HOST:]PORT */
+ if (i+1 >= argc) {
+ usage_arg(progname, "-address ");
+ }
+ {
+ char* hostname_port_arg = ei_chk_strdup(argv[i+1]);
+ char* address_string_end = strchr(hostname_port_arg, ':');
+ if (address_string_end == NULL) {
+ flags.port = strtol(hostname_port_arg, NULL, 10);
+ } else {
+ flags.port = strtol(address_string_end + 1, NULL, 10);
+ /* Remove port part from hostname_port_arg*/
+ *address_string_end = '\0';
+ if (strlen(hostname_port_arg) > 0) {
+ flags.hostname = hostname_port_arg;
+ }
+ }
+
+ if (flags.port < 1 || flags.port > 65535) {
+ usage_error(progname, "-address");
+ }
+ i++;
+ }
} else {
if (strlen(argv[i]) != 2) {
usage_error(progname, argv[i]);
@@ -251,11 +255,12 @@ int erl_call(int argc, char **argv)
} /* while */
-
/*
* Can't have them both !
*/
- if (flags.modp && flags.evalp) {
+ if ((flags.modp && flags.evalp) ||
+ (flags.port != -1 && flags.startp) ||
+ (flags.port != -1 && flags.node)) {
usage(progname);
}
@@ -284,7 +289,7 @@ int erl_call(int argc, char **argv)
/*
* What we, at least, requires !
*/
- if (flags.node == NULL) {
+ if (flags.node == NULL && flags.port == -1) {
usage(progname);
}
@@ -292,20 +297,14 @@ int erl_call(int argc, char **argv)
flags.cookie = NULL;
}
- /* FIXME decide how many bits etc or leave to connect_xinit? */
- creation = (time(NULL) % 3) + 1; /* "random" */
+ creation = time(NULL) + 1; /* "random" */
if (flags.hidden == NULL) {
/* As default we are c17@gethostname */
i = flags.randomp ? (time(NULL) % 997) : 17;
flags.hidden = (char *) ei_chk_malloc(10 + 2 ); /* c17 or cXYZ */
-#if defined(VXWORKS)
- sprintf(flags.hidden, "c%d",
- i < 0 ? (int) taskIdSelf() : i);
-#else
sprintf(flags.hidden, "c%d",
i < 0 ? (int) getpid() : i);
-#endif
}
{
/* A name for our hidden node was specified */
@@ -346,10 +345,15 @@ int erl_call(int argc, char **argv)
}
}
- if ((p = strchr((const char *)flags.node, (int) '@')) == 0) {
+ if (flags.port != -1 && flags.hostname != NULL) {
+ host = flags.hostname;
+ strcpy(host_name, flags.hostname);
+ } else if ((flags.port != -1 && flags.hostname == NULL) ||
+ (strchr((const char *)flags.node, (int) '@') == 0)) {
strcpy(host_name, ei_thishostname(&ec));
host = host_name;
} else {
+ p = strchr((const char *)flags.node, (int) '@');
*p = 0;
host = p+1;
}
@@ -368,28 +372,45 @@ int erl_call(int argc, char **argv)
}
strncpy(host_name, hp->h_name, EI_MAXHOSTNAMELEN);
host_name[EI_MAXHOSTNAMELEN] = '\0';
- if (strlen(flags.node) + strlen(host_name) + 2 > sizeof(nodename)) {
- fprintf(stderr,"erl_call: nodename too long: %s\n", flags.node);
- exit(1);
+ if (flags.port == -1) {
+ if (strlen(flags.node) + strlen(host_name) + 2 > sizeof(nodename)) {
+ fprintf(stderr,"erl_call: nodename too long: %s\n", flags.node);
+ exit(1);
+ }
+ sprintf(nodename, "%s@%s", flags.node, host_name);
}
- sprintf(nodename, "%s@%s", flags.node, host_name);
-
/*
* Try to connect. Start an Erlang system if the
* start option is on and no system is running.
*/
if (flags.startp && !flags.haltp) {
fd = do_connect(&ec, nodename, &flags);
- } else if ((fd = ei_connect(&ec, nodename)) < 0) {
- /* We failed to connect ourself */
- /* FIXME do we really know we failed because of node not up? */
- if (flags.haltp) {
- exit(0);
- } else {
- fprintf(stderr,"erl_call: failed to connect to node %s\n",
- nodename);
- exit(1);
- }
+ } else if (flags.port == -1) {
+ if ((fd = ei_connect(&ec, nodename)) < 0) {
+ /* We failed to connect ourself */
+ /* FIXME do we really know we failed because of node not up? */
+ if (flags.haltp) {
+ exit(0);
+ } else {
+ fprintf(stderr,"erl_call: failed to connect to node %s\n",
+ nodename);
+ exit(1);
+ }
+ }
+ } else {
+ /* Connect using address:port */
+ if ((fd = ei_connect_host_port(&ec, host, (int)flags.port)) < 0) {
+ /* We failed to connect ourself */
+ /* FIXME do we really know we failed because of node not up? */
+ if (flags.haltp) {
+ exit(0);
+ } else {
+ fprintf(stderr,"erl_call: failed to connect to node with address \"%s:%ld\"\n",
+ flags.hostname == NULL ? "" : flags.hostname,
+ flags.port);
+ exit(1);
+ }
+ }
}
/* If we are connected and the halt switch is set */
@@ -415,8 +436,14 @@ int erl_call(int argc, char **argv)
}
if (flags.verbosep) {
- fprintf(stderr,"erl_call: we are now connected to node \"%s\"\n",
- nodename);
+ if (flags.port == -1) {
+ fprintf(stderr,"erl_call: we are now connected to node \"%s\"\n",
+ nodename);
+ } else {
+ fprintf(stderr,"erl_call: we are now connected to node with address \"%s:%ld\"\n",
+ flags.hostname == NULL ? "": flags.hostname,
+ flags.port);
+ }
}
/*
@@ -809,7 +836,7 @@ static int get_module(char **mbuf, char **mname)
static void usage_noexit(const char *progname) {
fprintf(stderr,"\nUsage: %s [-[demqrsv]] [-c Cookie] [-h HiddenName] \n", progname);
fprintf(stderr," [-x ErlScript] [-a [Mod [Fun [Args]]]]\n");
- fprintf(stderr," (-n Node | -sname Node | -name Node)\n\n");
+ fprintf(stderr," (-n Node | -sname Node | -name Node | -address [HOSTNAME:]PORT)\n\n");
#ifdef __WIN32__
fprintf(stderr," where: -a apply(Mod,Fun,Args) (e.g -a \"erlang length [[a,b,c]]\"\n");
#else
@@ -817,12 +844,18 @@ static void usage_noexit(const char *progname) {
#endif
fprintf(stderr," -c cookie string; by default read from ~/.erlang.cookie\n");
fprintf(stderr," -d direct Erlang output to ~/.erl_call.out.<Nodename>\n");
- fprintf(stderr," -e evaluate contents of standard input (e.g echo \"X=1,Y=2,{X,Y}.\"|erl_call -e ...)\n");
+ fprintf(stderr," -e evaluate contents of standard input (e.g., echo \"X=1,Y=2,{X,Y}.\"|%s -e ...)\n",
+ progname);
fprintf(stderr," -h specify a name for the erl_call client node\n");
fprintf(stderr," -m read and compile Erlang module from stdin\n");
fprintf(stderr," -n name of Erlang node, same as -name\n");
fprintf(stderr," -name name of Erlang node, expanded to a fully qualified\n");
fprintf(stderr," -sname name of Erlang node, short form will be used\n");
+ fprintf(stderr," -address [HOSTNAME:]PORT of Erlang node\n"
+ " (the default hostname is the hostname of the local manchine)\n"
+ " (e.g., %s -address my_host:36303 ...)\n"
+ " (cannot be combinated with -s, -n, -name and -sname)\n",
+ progname);
fprintf(stderr," -q halt the Erlang node (overrides the -s switch)\n");
fprintf(stderr," -r use a random name for the erl_call client node\n");
fprintf(stderr," -s start a new Erlang node if necessary\n");
diff --git a/lib/erl_interface/src/prog/erl_fake_prog.c b/lib/erl_interface/src/prog/erl_fake_prog.c
deleted file mode 100644
index 093bad8d7c..0000000000
--- a/lib/erl_interface/src/prog/erl_fake_prog.c
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 2002-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-
-/***************************************************************************
- *
- * This is a fake program that contains all functions, variables and
- * defined symbols mentioned in the manual. We compile this file to see
- * that the header files and created library is complete.
- *
- * You can't run this program, it is for compiling and linking only.
- *
- ***************************************************************************/
-
-/* Use most of
- * CFLAGS="-I../include -g -O2
- * -ansi -pedantic
- * -Wall
- * -Wshadow
- * -Wstrict-prototypes
- * -Wmissing-prototypes
- * -Wmissing-declarations
- * -Wnested-externs
- * -Winline
- * -Werror"
- */
-
-/* #include <netdb.h> now included by ei.h */
-#include "erl_interface.h"
-
-#ifdef VXWORKS
-int erl_fake_prog_main(void)
-#else
-int main(void)
-#endif
-{
- ei_x_buff eix;
- int index = 0;
- ETERM **etermpp = NULL, *etermp = NULL;
- char *charp = NULL;
- unsigned char uchar, **ucharpp = NULL, *ucharp = NULL;
- void *voidp = NULL;
- Erl_Heap *erl_heapp = NULL;
- int intx = 0;
- int *intp = NULL;
- unsigned int uintx, *uintp;
- unsigned long *ulongp = NULL;
- long longx = 0;
- double doublex = 0.0;
- short shortx = 42;
- FILE *filep = NULL;
- Erl_IpAddr erl_ipaddr = NULL;
- ErlMessage *erlmessagep = NULL;
- ErlConnect *erlconnectp = NULL;
- struct hostent *hostp = NULL;
- struct in_addr *inaddrp = NULL;
-
- /* Converion to erl_interface format is in liberl_interface */
-
- intx = erl_errno;
-
- ei_encode_term(charp, &index, voidp);
- ei_x_encode_term(&eix, voidp);
- ei_decode_term(charp, &index, voidp);
-
- erl_init(voidp, longx);
- erl_connect_init(intx, charp,shortx);
- erl_connect_xinit(charp,charp,charp,erl_ipaddr,charp,shortx);
- erl_connect(charp);
- erl_xconnect(erl_ipaddr,charp);
- erl_close_connection(intx);
- erl_receive(intx, ucharp, intx);
- erl_receive_msg(intx, ucharp, intx, erlmessagep);
- erl_xreceive_msg(intx, ucharpp, intp, erlmessagep);
- erl_send(intx, etermp, etermp);
- erl_reg_send(intx, charp, etermp);
- erl_rpc(intx,charp,charp,etermp);
- erl_rpc_to(intx,charp,charp,etermp);
- erl_rpc_from(intx,intx,erlmessagep);
-
- erl_publish(intx);
- erl_accept(intx,erlconnectp);
-
- erl_thiscookie();
- erl_thisnodename();
- erl_thishostname();
- erl_thisalivename();
- erl_thiscreation();
- erl_unpublish(charp);
- erl_err_msg(charp);
- erl_err_quit(charp);
- erl_err_ret(charp);
- erl_err_sys(charp);
-
- erl_cons(etermp,etermp);
- erl_copy_term(etermp);
- erl_element(intx,etermp);
-
- erl_hd(etermp);
- erl_iolist_to_binary(etermp);
- erl_iolist_to_string(etermp);
- erl_iolist_length(etermp);
- erl_length(etermp);
- erl_mk_atom(charp);
- erl_mk_binary(charp,intx);
- erl_mk_empty_list();
- erl_mk_estring(charp, intx);
- erl_mk_float(doublex);
- erl_mk_int(intx);
- erl_mk_list(etermpp,intx);
- erl_mk_pid(charp,uintx,uintx,uchar);
- erl_mk_port(charp,uintx,uchar);
- erl_mk_ref(charp,uintx,uchar);
- erl_mk_long_ref(charp,uintx,uintx,uintx,uchar);
- erl_mk_string(charp);
- erl_mk_tuple(etermpp,intx);
- erl_mk_uint(uintx);
- erl_mk_var(charp);
- erl_print_term(filep,etermp);
- /* erl_sprint_term(charp,etermp); */
- erl_size(etermp);
- erl_tl(etermp);
- erl_var_content(etermp, charp);
-
- erl_format(charp);
- erl_match(etermp, etermp);
-
- erl_global_names(intx, intp);
- erl_global_register(intx, charp, etermp);
- erl_global_unregister(intx, charp);
- erl_global_whereis(intx, charp, charp);
-
- erl_init_malloc(erl_heapp,longx);
- erl_alloc_eterm(uchar);
- erl_eterm_release();
- erl_eterm_statistics(ulongp,ulongp);
- erl_free_array(etermpp,intx);
- erl_free_term(etermp);
- erl_free_compound(etermp);
- erl_malloc(longx);
- erl_free(voidp);
-
- erl_compare_ext(ucharp, ucharp);
- erl_decode(ucharp);
- erl_decode_buf(ucharpp);
- erl_encode(etermp,ucharp);
- erl_encode_buf(etermp,ucharpp);
- erl_ext_size(ucharp);
- erl_ext_type(ucharp);
- erl_peek_ext(ucharp,intx);
- erl_term_len(etermp);
-
- erl_gethostbyname(charp);
- erl_gethostbyaddr(charp, intx, intx);
- erl_gethostbyname_r(charp, hostp, charp, intx, intp);
- erl_gethostbyaddr_r(charp, intx, intx, hostp, charp, intx, intp);
-
- erl_init_resolve();
- erl_distversion(intx);
-
- erl_epmd_connect(inaddrp);
- erl_epmd_port(inaddrp, charp, intp);
-
- charp = ERL_ATOM_PTR(etermp);
- intx = ERL_ATOM_SIZE(etermp);
- ucharp = ERL_BIN_PTR(etermp);
- intx = ERL_BIN_SIZE(etermp);
- etermp = ERL_CONS_HEAD(etermp);
- etermp = ERL_CONS_TAIL(etermp);
- intx = ERL_COUNT(etermp);
- doublex= ERL_FLOAT_VALUE(etermp);
- uintx = ERL_INT_UVALUE(etermp);
- intx = ERL_INT_VALUE(etermp);
- intx = ERL_IS_ATOM(etermp);
- intx = ERL_IS_BINARY(etermp);
- intx = ERL_IS_CONS(etermp);
- intx = ERL_IS_EMPTY_LIST(etermp);
- intx = ERL_IS_FLOAT(etermp);
- intx = ERL_IS_INTEGER(etermp);
- intx = ERL_IS_LIST(etermp);
- intx = ERL_IS_PID(etermp);
- intx = ERL_IS_PORT(etermp);
- intx = ERL_IS_REF(etermp);
- intx = ERL_IS_TUPLE(etermp);
- intx = ERL_IS_UNSIGNED_INTEGER(etermp);
- uchar = ERL_PID_CREATION(etermp);
- charp = ERL_PID_NODE(etermp);
- uintx = ERL_PID_NUMBER(etermp);
- uintx = ERL_PID_SERIAL(etermp);
- uchar = ERL_PORT_CREATION(etermp);
- charp = ERL_PORT_NODE(etermp);
- uintx = ERL_PORT_NUMBER(etermp);
- uchar = ERL_REF_CREATION(etermp);
- intx = ERL_REF_LEN(etermp);
- charp = ERL_REF_NODE(etermp);
- uintx = ERL_REF_NUMBER(etermp);
- uintp = ERL_REF_NUMBERS(etermp);
- etermp = ERL_TUPLE_ELEMENT(etermp,intx);
- intx = ERL_TUPLE_SIZE(etermp);
-
- return
- BUFSIZ +
- EAGAIN +
- EHOSTUNREACH +
- EINVAL +
- EIO +
- EMSGSIZE +
- ENOMEM +
- ERL_ATOM +
- ERL_BINARY +
- ERL_ERROR +
- ERL_EXIT +
- ERL_FLOAT +
- ERL_INTEGER +
- ERL_LINK +
- ERL_LIST +
- ERL_MSG +
- ERL_NO_TIMEOUT +
- ERL_PID +
- ERL_PORT +
- ERL_REF +
- ERL_REG_SEND +
- ERL_SEND +
- ERL_SMALL_BIG +
- ERL_TICK +
- ERL_TIMEOUT +
- ERL_TUPLE +
- ERL_UNLINK +
- ERL_U_INTEGER +
- ERL_U_SMALL_BIG +
- ERL_VARIABLE +
- ETIMEDOUT +
- MAXNODELEN +
- MAXREGLEN;
-}
diff --git a/lib/erl_interface/src/prog/erl_start.c b/lib/erl_interface/src/prog/erl_start.c
index b7aa451946..a4930443d4 100644
--- a/lib/erl_interface/src/prog/erl_start.c
+++ b/lib/erl_interface/src/prog/erl_start.c
@@ -31,40 +31,7 @@
#include <windows.h>
#include <winbase.h>
-#elif VXWORKS
-#include <stdio.h>
-#include <string.h>
-#include <vxWorks.h>
-#include <hostLib.h>
-#include <selectLib.h>
-#include <ifLib.h>
-#include <sockLib.h>
-#include <taskLib.h>
-#include <inetLib.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <symLib.h>
-#include <sysSymTbl.h>
-#include <sysLib.h>
-#include <tickLib.h>
-
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-
-#include <a_out.h>
-
-/* #include "netdb.h" */
-#else /* other unix */
+#else /* unix */
#include <errno.h>
#include <netdb.h>
#include <netinet/in.h>
@@ -111,7 +78,7 @@ typedef socklen_t SocklenType;
static struct in_addr *get_addr(const char *hostname, struct in_addr *oaddr);
static int wait_for_erlang(int sockd, int magic, struct timeval *timeout);
-#if defined(VXWORKS) || defined(__WIN32__)
+#if defined(__WIN32__)
static int unique_id(void);
static unsigned long spawn_erlang_epmd(ei_cnode *ec,
char *alive,
@@ -148,7 +115,7 @@ int erl_start_sys(ei_cnode *ec, char *alive, Erl_IpAddr adr, int flags,
int port;
int sockd = 0;
int one = 1;
-#if defined(VXWORKS) || defined(__WIN32__)
+#if defined(__WIN32__)
unsigned long pid = 0;
#else
int pid = 0;
@@ -177,7 +144,7 @@ int erl_start_sys(ei_cnode *ec, char *alive, Erl_IpAddr adr, int flags,
listen(sockd,5);
-#if defined(VXWORKS) || defined(__WIN32__)
+#if defined(__WIN32__)
if((pid = spawn_erlang_epmd(ec,alive,adr,flags,erl,args,port,1))
== 0)
return ERL_SYS_ERROR;
@@ -185,15 +152,9 @@ int erl_start_sys(ei_cnode *ec, char *alive, Erl_IpAddr adr, int flags,
timeout.tv_sec = 10; /* ignoring ERL_START_TIME */
if((r = wait_for_erlang(sockd,unique_id(),&timeout))
== ERL_TIMEOUT) {
-#if defined(VXWORKS)
- taskDelete((int) pid);
- if(taskIdVerify((int) pid) != ERROR)
- taskDeleteForce((int) pid);
-#else /* Windows */
/* Well, this is not a nice way to do it, and it does not
always kill the emulator, but the alternatives are few.*/
TerminateProcess((HANDLE) pid,1);
-#endif /* defined(VXWORKS) */
}
#else /* Unix */
switch ((pid = fork())) {
@@ -229,7 +190,7 @@ int erl_start_sys(ei_cnode *ec, char *alive, Erl_IpAddr adr, int flags,
}
}
-#endif /* defined(VXWORKS) || defined(__WIN32__) */
+#endif /* defined(__WIN32__) */
done:
#if defined(__WIN32__)
@@ -240,18 +201,10 @@ done:
return r;
} /* erl_start_sys() */
-#if defined(VXWORKS) || defined(__WIN32__)
-#if defined(VXWORKS)
-#define DEF_ERL_COMMAND ""
-#define DEF_EPMD_COMMAND ""
-#define ERLANG_SYM "start_erl"
-#define EPMD_SYM "start_epmd"
-#define ERL_REPLY_FMT "-s erl_reply reply %s %d %d"
-#else
+#if defined(__WIN32__)
#define DEF_ERL_COMMAND "erl"
#define DEF_EPMD_COMMAND "epmd"
#define ERL_REPLY_FMT "-s erl_reply reply \"%s\" \"%d\" \"%d\""
-#endif
#define ERL_NAME_FMT "-noinput -name %s"
#define ERL_SNAME_FMT "-noinput -sname %s"
@@ -259,11 +212,7 @@ done:
#define FORMATTED_INT_LEN 10
static int unique_id(void){
-#if defined(VXWORKS)
- return taskIdSelf();
-#else
return (int) GetCurrentThreadId();
-#endif
}
static int enquote_args(char **oargs, char ***qargs){
@@ -317,20 +266,7 @@ static void free_args(char **args){
free(args);
}
-#if defined(VXWORKS)
-static FUNCPTR lookup_function(char *symname){
- char *value;
- SYM_TYPE type;
- if(symFindByName(sysSymTbl,
- symname,
- &value,
- &type) == ERROR /*|| type != N_TEXT*/)
- return NULL;
- return (FUNCPTR) value;
-}
-#endif /* defined(VXWORKS) */
-
-/* In NT and VxWorks, we cannot fork(), Erlang and Epmd gets
+/* In NT we cannot fork(), Erlang and Epmd gets
spawned by this function instead. */
static unsigned long spawn_erlang_epmd(ei_cnode *ec,
@@ -342,13 +278,9 @@ static unsigned long spawn_erlang_epmd(ei_cnode *ec,
int port,
int is_erlang)
{
-#if defined(VXWORKS)
- FUNCPTR erlfunc;
-#else /* Windows */
STARTUPINFO sinfo;
SECURITY_ATTRIBUTES sa;
PROCESS_INFORMATION pinfo;
-#endif
char *cmdbuf;
int cmdlen;
char *ptr;
@@ -362,14 +294,10 @@ static unsigned long spawn_erlang_epmd(ei_cnode *ec,
if(is_erlang){
get_addr(ei_thishostname(ec), &myaddr);
-#if defined(VXWORKS)
- inet_ntoa_b(myaddr, iaddrbuf);
-#else /* Windows */
if((ptr = inet_ntoa(myaddr)) == NULL)
return 0;
else
strcpy(iaddrbuf,ptr);
-#endif
}
if ((flags & ERL_START_REMOTE) ||
(is_erlang && (hisaddr->s_addr != myaddr.s_addr))) {
@@ -378,11 +306,7 @@ static unsigned long spawn_erlang_epmd(ei_cnode *ec,
num_args = enquote_args(args, &args);
for(cmdlen = i = 0; args[i] != NULL; ++i)
cmdlen += strlen(args[i]) + 1;
-#if !defined(VXWORKS)
- /* On VxWorks, we dont actually run a command,
- we call start_erl() */
if(!erl_or_epmd)
-#endif
erl_or_epmd = (is_erlang) ? DEF_ERL_COMMAND :
DEF_EPMD_COMMAND;
if(is_erlang){
@@ -417,23 +341,6 @@ static unsigned long spawn_erlang_epmd(ei_cnode *ec,
fprintf(stderr,"erl_call: commands are %s\n",cmdbuf);
}
/* OK, one single command line... */
-#if defined(VXWORKS)
- erlfunc = lookup_function((is_erlang) ? ERLANG_SYM :
- EPMD_SYM);
- if(erlfunc == NULL){
- if (flags & ERL_START_VERBOSE) {
- fprintf(stderr,"erl_call: failed to find symbol %s\n",
- (is_erlang) ? ERLANG_SYM : EPMD_SYM);
- }
- ret = 0;
- } else {
- /* Just call it, it spawns itself... */
- ret = (unsigned long)
- (*erlfunc)((int) cmdbuf,0,0,0,0,0,0,0,0,0);
- if(ret == (unsigned long) ERROR)
- ret = 0;
- }
-#else /* Windows */
/* Hmmm, hidden or unhidden window??? */
memset(&sinfo,0,sizeof(sinfo));
sinfo.cb = sizeof(STARTUPINFO);
@@ -460,7 +367,6 @@ static unsigned long spawn_erlang_epmd(ei_cnode *ec,
ret = 0;
else
ret = (unsigned long) pinfo.hProcess;
-#endif
free(cmdbuf);
return ret;
}
@@ -488,7 +394,7 @@ static int exec_erlang(ei_cnode *ec,
char *args[],
int port)
{
-#if !defined(__WIN32__) && !defined(VXWORKS)
+#if !defined(__WIN32__)
int fd,len,l,i;
char **s;
char *argv[4];
@@ -587,7 +493,7 @@ static int exec_erlang(ei_cnode *ec,
return ERL_SYS_ERROR;
} /* exec_erlang() */
-#endif /* defined(VXWORKS) || defined(WINDOWS) */
+#endif /* defined(WINDOWS) */
#if defined(__WIN32__)
static void gettimeofday(struct timeval *now,void *dummy){
@@ -601,13 +507,6 @@ static void gettimeofday(struct timeval *now,void *dummy){
now->tv_usec = x % 1000000;
}
-#elif defined(VXWORKS)
-static void gettimeofday(struct timeval *now, void *dummy){
- int rate = sysClkRateGet(); /* Ticks per second */
- unsigned long ctick = tickGet();
- now->tv_sec = ctick / rate; /* secs since reboot */
- now->tv_usec = ((ctick - (now->tv_sec * rate))*1000000)/rate;
-}
#endif
diff --git a/lib/erl_interface/src/registry/reg_get.c b/lib/erl_interface/src/registry/reg_get.c
index 67d99e231e..73975f6a91 100644
--- a/lib/erl_interface/src/registry/reg_get.c
+++ b/lib/erl_interface/src/registry/reg_get.c
@@ -19,10 +19,6 @@
*
*/
-#ifdef VXWORKS
-#include <vxWorks.h>
-#endif
-
#include <stdarg.h>
#include "reg.h"
diff --git a/lib/erl_interface/src/registry/reg_set.c b/lib/erl_interface/src/registry/reg_set.c
index 95b90adb87..3846df1cb5 100644
--- a/lib/erl_interface/src/registry/reg_set.c
+++ b/lib/erl_interface/src/registry/reg_set.c
@@ -19,10 +19,6 @@
*
*/
-#ifdef VXWORKS
-#include <vxWorks.h>
-#endif
-
#include <stdarg.h>
#include "reg.h"
diff --git a/lib/erl_interface/test/Makefile b/lib/erl_interface/test/Makefile
index f8f2ef0156..3e3213d3e1 100644
--- a/lib/erl_interface/test/Makefile
+++ b/lib/erl_interface/test/Makefile
@@ -34,12 +34,7 @@ MODULES= \
ei_print_SUITE \
ei_tmo_SUITE \
erl_call_SUITE \
- erl_connect_SUITE \
- erl_global_SUITE \
- erl_eterm_SUITE \
- erl_ext_SUITE \
- erl_format_SUITE \
- erl_match_SUITE \
+ ei_global_SUITE \
port_call_SUITE \
runner
diff --git a/lib/erl_interface/test/all_SUITE_data/Makefile.src b/lib/erl_interface/test/all_SUITE_data/Makefile.src
index 4f27b097c8..0d242663ea 100644
--- a/lib/erl_interface/test/all_SUITE_data/Makefile.src
+++ b/lib/erl_interface/test/all_SUITE_data/Makefile.src
@@ -23,7 +23,7 @@ CC0 = @CC@
CC = .@DS@gccifier@exe@ -CC"$(CC0)"
CFLAGS0 = @CFLAGS@ -I@erl_interface_include@
CFLAGS = @EI_CFLAGS@ $(THR_DEFS) -I@erl_interface_include@
-EI_COMMON_OBJS = runner@obj@ ei_runner@obj@
+EI_COMMON_OBJS = runner@obj@ ei_runner@obj@ my_ussi@obj@
ALL_OBJS = gccifier@exe@ $(EI_COMMON_OBJS)
CP=cp
diff --git a/lib/erl_interface/test/all_SUITE_data/init_tc.erl b/lib/erl_interface/test/all_SUITE_data/init_tc.erl
index d9ad291f3d..da3d8053a0 100644
--- a/lib/erl_interface/test/all_SUITE_data/init_tc.erl
+++ b/lib/erl_interface/test/all_SUITE_data/init_tc.erl
@@ -77,11 +77,7 @@ generate_c(Cases, File, TcName) ->
lists:foreach(fun(Case) -> io:format(File, " ~s,~n", [Case]) end, Cases),
io:format(File, "~s",
[["};\n\n",
- "#ifdef VXWORKS\n",
- "int ", TcName, "(int argc, char* argv[])\n",
- "#else\n",
"int main(int argc, char* argv[])\n",
- "#endif\n",
"{\n",
" run_tests(argv[0], test_cases, ",
"sizeof(test_cases)/sizeof(test_cases[0]));\n",
diff --git a/lib/erl_interface/test/all_SUITE_data/my_ussi.c b/lib/erl_interface/test/all_SUITE_data/my_ussi.c
new file mode 100644
index 0000000000..5f8c79b7cf
--- /dev/null
+++ b/lib/erl_interface/test/all_SUITE_data/my_ussi.c
@@ -0,0 +1,198 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2019. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+/*
+ * User Supplied Socket Implementation (ussi)
+ * for test purpose.
+ */
+#include <stdlib.h>
+#include <string.h>
+#include "ei.h"
+
+struct my_ctx
+{
+ void* ctx;
+};
+
+/*
+ * To minimize effort but still test a different context format
+ * we cheat and wrap the existing TCP default callbacks.
+ */
+extern ei_socket_callbacks ei_default_socket_callbacks;
+
+static int my_socket(void **ctx, void *setup_ctx)
+{
+ struct my_ctx *myctx = malloc(sizeof(struct my_ctx));
+ int ret;
+ ret = ei_default_socket_callbacks.socket(&myctx->ctx, NULL);
+ *ctx = myctx;
+ return ret;
+}
+
+static int my_close(void *ctx)
+{
+ struct my_ctx *myctx = ctx;
+ int ret = ei_default_socket_callbacks.close(myctx->ctx);
+ free(myctx);
+ return ret;
+}
+
+static int my_get_fd(void *ctx, int *fd)
+{
+ struct my_ctx *myctx = ctx;
+ return ei_default_socket_callbacks.get_fd(myctx->ctx, fd);
+}
+
+static int my_hs_packet_header_size(void *ctx, int *sz)
+{
+ struct my_ctx *myctx = ctx;
+ return ei_default_socket_callbacks.handshake_packet_header_size(myctx->ctx, sz);
+}
+
+static int my_connect_handshake_complete(void *ctx)
+{
+ struct my_ctx *myctx = ctx;
+ return ei_default_socket_callbacks.connect_handshake_complete(myctx->ctx);
+}
+
+static int my_accept_handshake_complete(void *ctx)
+{
+ struct my_ctx *myctx = ctx;
+ return ei_default_socket_callbacks.accept_handshake_complete(myctx->ctx);
+}
+
+static int my_listen(void *ctx, void *addr, int *len, int backlog)
+{
+ struct my_ctx *myctx = ctx;
+ return ei_default_socket_callbacks.listen(myctx->ctx, addr, len, backlog);
+}
+
+static int my_accept(void **ctx, void *addr, int *len, unsigned tmo)
+{
+ struct my_ctx *listen_ctx = *ctx;
+ struct my_ctx *conn_ctx = malloc(sizeof(struct my_ctx));
+ int ret;
+ *conn_ctx = *listen_ctx;
+ ret = ei_default_socket_callbacks.accept(&conn_ctx->ctx, addr, len, tmo);
+ if (ret == 0)
+ *ctx = conn_ctx;
+ else
+ free(conn_ctx);
+ return ret;
+}
+
+static int my_connect(void *ctx, void *addr, int len, unsigned tmo)
+{
+ struct my_ctx *myctx = ctx;
+ return ei_default_socket_callbacks.connect(myctx->ctx, addr, len, tmo);
+}
+
+static void* memdup(const void* mem, int nbytes)
+{
+ void *p = malloc(nbytes);
+ memcpy(p, mem, nbytes);
+ return p;
+}
+
+static void scramble(void* bytes, int nbytes)
+{
+/* Would be nice to really test that only our callbacks are used
+ and the default ones are not.
+ Need corresponding Erlang distribution impl to work.
+
+ unsigned char *p = bytes;
+ int i;
+ for (i=0; i < nbytes; ++i)
+ p[i] = ~p[i];
+*/
+}
+
+/* our own iovec struct to avoid config dependency HAVE_WRITEV */
+struct my_iovec {
+ void *iov_base; /* Starting address */
+ size_t iov_len; /* Number of bytes to transfer */
+};
+
+static int my_writev(void *ctx, const void *viov, int iovcnt, ssize_t *len, unsigned tmo)
+{
+ struct my_ctx *myctx = ctx;
+ struct my_iovec *iov;
+ int i, ret;
+
+ /* create mutable copy of both iovec and data */
+ iov = memdup(viov, sizeof(struct my_iovec) * iovcnt);
+ for (i=0; i < iovcnt; ++i) {
+ iov[i].iov_base = memdup(iov[i].iov_base, iov[i].iov_len);
+ scramble(iov[i].iov_base, iov[i].iov_len);
+ }
+
+ ret = ei_default_socket_callbacks.writev(myctx->ctx, viov, iovcnt, len, tmo);
+
+ for (i=0; i < iovcnt; ++i)
+ free(iov[i].iov_base);
+ free(iov);
+ return ret;
+}
+
+static int my_write(void *ctx, const char* buf, ssize_t *len, unsigned tmo)
+{
+ struct my_ctx *myctx = ctx;
+ unsigned char* copy = memdup(buf, *len);
+ int i, ret;
+
+ scramble(copy, *len);
+ ret = ei_default_socket_callbacks.write(myctx->ctx, copy, len, tmo);
+ free(copy);
+ return ret;
+}
+
+static int my_read(void *ctx, char* buf, ssize_t *len, unsigned tmo)
+{
+ struct my_ctx *myctx = ctx;
+ int ret, i;
+
+ ret = ei_default_socket_callbacks.read(myctx->ctx, buf, len, tmo);
+ if (ret == 0)
+ scramble(buf, *len);
+ return ret;
+}
+
+ei_socket_callbacks my_ussi = {
+ 0, /* flags */
+ my_socket,
+ my_close,
+ my_listen,
+ my_accept,
+ my_connect,
+ my_writev,
+ my_write,
+ my_read,
+ my_hs_packet_header_size,
+ my_connect_handshake_complete,
+ my_accept_handshake_complete,
+ my_get_fd
+};
+
+void my_ussi_init(void)
+{
+ my_ussi.flags = ei_default_socket_callbacks.flags;
+ if (!ei_default_socket_callbacks.writev)
+ my_ussi.writev = NULL;
+}
diff --git a/lib/erl_interface/src/legacy/erl_connect.h b/lib/erl_interface/test/all_SUITE_data/my_ussi.h
index 6cb5d5cd1b..0db07c990e 100644
--- a/lib/erl_interface/src/legacy/erl_connect.h
+++ b/lib/erl_interface/test/all_SUITE_data/my_ussi.h
@@ -1,8 +1,8 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2016. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2019. All Rights Reserved.
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -14,12 +14,15 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
+ *
* %CopyrightEnd%
*/
-#ifndef _ERL_CONNECT_H
-#define _ERL_CONNECT_H
-erlang_pid *erl_self(void);
+/*
+ * User Supplied Socket Implementation (ussi)
+ * for test purpose.
+ */
+
+extern ei_socket_callbacks my_ussi;
-#endif /* _ERL_CONNECT_H */
+extern void my_ussi_init(void);
diff --git a/lib/erl_interface/test/all_SUITE_data/runner.c b/lib/erl_interface/test/all_SUITE_data/runner.c
deleted file mode 100644
index 42e8bb03e5..0000000000
--- a/lib/erl_interface/test/all_SUITE_data/runner.c
+++ /dev/null
@@ -1,459 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 1997-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#ifndef __WIN32__
-#include <unistd.h>
-#endif
-#include <stdarg.h>
-
-#include "runner.h"
-
-#ifndef __WIN32__
-#define _O_BINARY 0
-#define _setmode(fd, mode)
-#endif
-
-#define HEADER_SIZE 4
-
-static char* progname; /* Name of this program (from argv[0]). */
-static int fd_from_erl; /* File descriptor from Erlang. */
-static int fd_to_erl; /* File descriptor to Erlang. */
-
-static int packet_loop();
-static void ensure_buf_big_enough();
-static int readn();
-static void reply(char* buf, unsigned size);
-static void dump();
-
-void
-run_tests(char* argv0, TestCase test_cases[], unsigned number)
-{
- int i;
- int n;
- char* packet;
-
- progname = argv0;
- _setmode(0, _O_BINARY);
- _setmode(1, _O_BINARY);
- fd_from_erl = 0;
- fd_to_erl = 1;
-
- packet = read_packet(&n);
-
- /*
- * Dispatch to the appropriate test function.
- */
-
- i = packet[0] * 256 + packet[1];
- if (i >= number) {
- fprintf(stderr, "%s: bad test case number %d",
- progname, i);
- free(packet);
- exit(1);
- } else {
- (*test_cases[i])();
- free(packet);
- }
-}
-
-
-/***********************************************************************
- *
- * R e a d i n g p a c k e t s
- *
- ************************************************************************/
-
-/*
- * Reads an Erlang term.
- *
- * Returns: A pointer to a term (an ETERM structure) if there was
- * at term available, or a NULL pointer if there was an 'eot' (end-of-test)
- * packet. Aborts if anything else received.
- */
-
-ETERM*
-get_term(void)
-{
- char* encoded;
- ETERM* term;
- int n;
-
- encoded = read_packet(&n);
-
- switch (encoded[0]) {
- case 'e':
- free(encoded);
- return NULL;
- case 't':
- term = erl_decode(encoded+1);
- free(encoded);
- if (term == NULL) {
- fail("Failed to decode term");
- exit(0);
- }
- return term;
- default:
- fprintf(stderr, "Garbage received: ");
- dump(encoded, n, 16);
- putc('\n', stderr);
- fail("C program received garbage");
- free(encoded);
- exit(1);
- }
-}
-
-
-/*
- * Reads a packet from Erlang. The packet must be a standard {packet, 2}
- * packet. This function aborts if any error is detected (including EOF).
- *
- * Returns: The number of bytes in the packet.
- */
-
-char *read_packet(int *len)
-{
-
- unsigned char* io_buf = NULL; /* Buffer for file i/o. */
- int i;
- unsigned char header[HEADER_SIZE];
- unsigned packet_length; /* Length of current packet. */
- int bytes_read;
-
- /*
- * Read the packet header.
- */
-
- bytes_read = readn(fd_from_erl, header, HEADER_SIZE);
-
- if (bytes_read == 0) {
- fprintf(stderr, "%s: Unexpected end of file\n", progname);
- exit(1);
- }
- if (bytes_read != HEADER_SIZE) {
- fprintf(stderr, "%s: Failed to read packet header\n", progname);
- exit(1);
- }
-
- /*
- * Get the length of this packet.
- */
-
- packet_length = 0;
-
- for (i = 0; i < HEADER_SIZE; i++)
- packet_length = (packet_length << 8) | header[i];
-
- if (len) *len=packet_length; /* report length only if caller requested it */
-
- if ((io_buf = (char *) malloc(packet_length)) == NULL) {
- fprintf(stderr, "%s: insufficient memory for i/o buffer of size %d\n",
- progname, packet_length);
- exit(1);
- }
-
- /*
- * Read the packet itself.
- */
-
- bytes_read = readn(fd_from_erl, io_buf, packet_length);
- if (bytes_read != packet_length) {
- fprintf(stderr, "%s: couldn't read packet of length %d\r\n",
- progname, packet_length);
- free(io_buf);
- exit(1);
- }
-
- return io_buf;
-}
-
-
-/***********************************************************************
- * S e n d i n g r e p l i e s
- *
- * The functions below send various types of replies back to Erlang.
- * Each reply start with a letter indicating the type of reply.
- *
- * Reply Translated to on Erlang side
- * ----- ----------------------------
- * [$b|Bytes] {bytes, Bytes}
- * [$e] eot
- * [$f] ct:fail()
- * [$f|Reason] ct:fail(Reason)
- * [$t|EncodedTerm] {term, Term}
- * [$N] 'NULL'
- * [$m|Message] io:format("~s", [Message]) (otherwise ignored)
- *
- ***********************************************************************/
-
-/*
- * This function reports the outcome of a test fail. It is useful if
- * you implement a test case entirely in C code.
- *
- * If the ok argument is zero, a [$f] reply will be sent to the
- * Erlang side (causing ct:fail() to be called); otherwise,
- * the atom 'eot' will be sent to Erlang.
- *
- * If you need to provide more details on a failure, use the fail() function.
- */
-
-void
-do_report(file, line, ok)
- char* file;
- int line;
- int ok; /* Zero if failed; non-zero otherwise. */
-{
- char reason;
- unsigned long ab;
- unsigned long fb;
-
- reason = ok ? 'e' : 'f';
-
- if (!ok) {
- do_fail(file, line, "Generic failure");
- } else {
- /* release all unallocated blocks */
- erl_eterm_release();
- /* check mem usage stats */
- erl_eterm_statistics(&ab, &fb);
- if ((ab == 0) && (fb == 0) ) {
- reply(&reason, 1);
- }
- else {
- char sbuf[128];
-
- sprintf(sbuf, "still %lu terms allocated,"
- " %lu on freelist at end of test", ab, fb);
- do_fail(file, line, sbuf);
- }
- }
-}
-
-
-/*
- * This function causes a call to ct:fail(Reason) on the
- * Erlang side.
- */
-
-void
-do_fail(char* file, int line, char* reason)
-{
- char sbuf[2048];
-
- sbuf[0] = 'f';
- sprintf(sbuf+1, "%s, line %d: %s", file, line, reason);
- reply(sbuf, 1+strlen(sbuf+1));
-}
-
-/*
- * This function sends a message to the Erlang side.
- * The message will be written to the test servers log file,
- * but will otherwise be completly ignored.
- */
-
-void
-message(char* format, ...)
-{
- va_list ap;
- char sbuf[1024];
-
- sbuf[0] = 'm';
- va_start(ap, format);
- vsprintf(sbuf+1, format, ap);
- va_end(ap);
-
- reply(sbuf, 1+strlen(sbuf+1));
-}
-
-/*
- * This function sends the given term to the Erlang side,
- * where it will be received as {term, Term}.
- *
- * If the given pointer is NULL (indicating an invalid term),
- * the result on the Erlang side will be the atom 'NULL'.
- *
- * After sending the term, this function frees the term by
- * calling erl_free_term().
- */
-
-void
-send_term(term)
- ETERM* term; /* Term to be sent to Erlang side. */
-{
- char encoded[64*1024];
- int n;
-
- if (term == NULL) {
- encoded[0] = 'N';
- n = 1;
- } else {
- encoded[0] = 't';
- n = 1 + erl_encode(term, encoded+1);
- erl_free_term(term);
- }
- reply(encoded, n);
-}
-
-#if 0
-
-/* Seriously broken!!! */
-
-void
-send_bin_term(x_ei_buff* x)
-{
- x_ei_buff x2;
- x_ei_new(&x2);
- x2.buff[x2.index++] = 't';
- x_ei_append(&x2, x);
- reply(x2.buff, x2.index);
- free(x2.buff);
-}
-#endif
-
-/*
- * This function sends a raw buffer of data to the
- * Erlang side, where it will be received as {bytes, Bytes}.
- */
-
-void
-send_buffer(buf, size)
- char* buf; /* Buffer with bytes to send to Erlang. */
- int size; /* Size of data to send to Erlang. */
-{
- char* send_buf;
-
- send_buf = (char *) malloc(size+1);
- send_buf[0] = 'b';
- memcpy(send_buf+1, buf, size);
- reply(send_buf, size+1);
- free(send_buf);
-}
-
-/***********************************************************************
- *
- * P r i v a t e h e l p e r s
- *
- ***********************************************************************/
-
-/*
- * Sends a packet back to Erlang.
- */
-
-static void
-reply(reply_buf, size)
- char* reply_buf; /* Buffer with reply. */
- unsigned size; /* Size of reply. */
-{
- int n; /* Temporary to hold size. */
- int i; /* Loop counter. */
- char* buf;
-
-
- buf = (char *) malloc(size+HEADER_SIZE);
- memcpy(buf+HEADER_SIZE, reply_buf, size);
-
- /*
- * Fill the header starting with the least significant byte.
- */
-
- n = size;
- for (i = HEADER_SIZE-1; i >= 0; i--) {
- buf[i] = (char) n; /* Store least significant byte. */
- n = n >> 8;
- }
-
- size += HEADER_SIZE;
-/*
- fprintf(stderr, "\r\nReply size: %u\r\n",
- (unsigned)buf[0] << 8 + (unsigned)buf[1]);
-
- for (i = 0; i < size; i++) {
- fprintf(stderr,"%u %c\r\n",buf[i],buf[i]);
- }
-
- fprintf(stderr, "\r\n");
-*/
- write(fd_to_erl, buf, size);
- free(buf);
-}
-
-
-/*
- * Reads len number of bytes.
- */
-
-static int
-readn(fd, buf, len)
- int fd; /* File descriptor to read from. */
- unsigned char *buf; /* Store in this buffer. */
- int len; /* Number of bytes to read. */
-{
- int n; /* Byte count in last read call. */
- int sofar = 0; /* Bytes read so far. */
-
- do {
- if ((n = read(fd, buf+sofar, len-sofar)) <= 0)
- /* error or EOF in read */
- return(n);
- sofar += n;
- } while (sofar < len);
- return sofar;
-}
-
-void
-dump(buf, sz, max)
- unsigned char* buf;
- int sz;
- int max;
-{
- int i, imax;
- char comma[5] = ",";
-
- if (!sz)
- return;
- if (sz > max)
- imax = max;
- else
- imax = sz;
-
- for (i=0; i<imax; i++) {
- if (i == imax-1) {
- if (sz > max)
- strcpy(comma, ",...");
- else
- comma[0] = 0;
- }
- if (isdigit(buf[i]))
- fprintf(stderr, "%u%s", (int)(buf[i]), comma);
- else {
- if (isalpha(buf[i])) {
- fprintf(stderr, "%c%s", buf[i], comma);
- }
- else
- fprintf(stderr, "%u%s", (int)(buf[i]), comma);
- }
- }
-}
-
diff --git a/lib/erl_interface/test/all_SUITE_data/runner.h b/lib/erl_interface/test/all_SUITE_data/runner.h
deleted file mode 100644
index 493602869f..0000000000
--- a/lib/erl_interface/test/all_SUITE_data/runner.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 1997-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-
-#include "erl_interface.h"
-
-typedef void (*TestCase)(void);
-
-#define TESTCASE(name) void name(void)
-#define ASIZE(a) (sizeof(a)/sizeof(a[0]))
-
-void run_tests(char* argv0, TestCase cases[], unsigned number);
-
-/*
- * Reading.
- */
-
-ETERM* get_term(void);
-char *read_packet(int *len);
-
-/*
- * Sending replies.
- */
-
-#define fail(reason) do_fail(__FILE__, __LINE__, reason)
-#define report(ok) do_report(__FILE__, __LINE__, ok)
-
-void do_report(char* file, int line, int ok);
-void do_fail(char* file, int line, char* reason);
-void send_term(ETERM* term);
-void send_buffer(char* buf, int size);
-void message(char* format, ...);
-
-void send_bin_term(ei_x_buff* x);
-
diff --git a/lib/erl_interface/test/ei_accept_SUITE.erl b/lib/erl_interface/test/ei_accept_SUITE.erl
index f40c67375b..c49b8a358a 100644
--- a/lib/erl_interface/test/ei_accept_SUITE.erl
+++ b/lib/erl_interface/test/ei_accept_SUITE.erl
@@ -43,12 +43,15 @@ init_per_testcase(Case, Config) ->
runner:init_per_testcase(?MODULE, Case, Config).
ei_accept(Config) when is_list(Config) ->
- ei_accept_do(Config, 0), % default
- ei_accept_do(Config, 21). % ei_set_compat_rel
+ [ei_accept_do(Config, CR, SI)
+ || CR <- [0,21],
+ SI <- [default, ussi]],
+ ok.
-ei_accept_do(Config, CompatRel) ->
+ei_accept_do(Config, CompatRel, SockImpl) ->
+ io:format("CompatRel=~p, SockImpl=~p\n", [CompatRel, SockImpl]),
P = runner:start(Config, ?interpret),
- 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0, CompatRel),
+ 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0, CompatRel, SockImpl),
Myname = hd(tl(string:tokens(atom_to_list(node()), "@"))),
io:format("Myname ~p ~n", [Myname]),
@@ -72,7 +75,8 @@ ei_accept_do(Config, CompatRel) ->
{ok, ListenFd} = ei_publish(P, Port),
{any, EINode} ! TermToSend,
- {ok, Fd, _Node} = ei_accept(P, ListenFd),
+ {ok, Fd, Node} = ei_accept(P, ListenFd),
+ Node = node(),
Got1 = ei_receive(P, Fd),
%% Send again, now without auto-connect
@@ -88,9 +92,13 @@ ei_accept_do(Config, CompatRel) ->
ei_threaded_accept(Config) when is_list(Config) ->
Einode = filename:join(proplists:get_value(data_dir, Config), "eiaccnode"),
+ ei_threaded_accept_do(Einode, default),
+ ei_threaded_accept_do(Einode, ussi),
+ ok.
+
+ei_threaded_accept_do(Einode, SockImpl) ->
N = 3,
- Host = atom_to_list(node()),
- start_einode(Einode, N, Host),
+ start_einode(Einode, N, SockImpl),
io:format("started eiaccnode"),
TestServerPid = self(),
[spawn_link(fun() -> send_rec_einode(I, TestServerPid) end) || I <- lists:seq(0, N-1)],
@@ -101,7 +109,7 @@ ei_threaded_accept(Config) when is_list(Config) ->
%% Test erlang:monitor toward erl_interface "processes"
monitor_ei_process(Config) when is_list(Config) ->
P = runner:start(Config, ?interpret),
- 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0, 0),
+ 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0, 0, default),
Myname = hd(tl(string:tokens(atom_to_list(node()), "@"))),
io:format("Myname ~p ~n", [Myname]),
@@ -125,10 +133,19 @@ monitor_ei_process(Config) when is_list(Config) ->
runner:finish(P),
- [{'DOWN', MRef1, process, {any, EINode}, noconnection},
- {'DOWN', MRef2, process, {any, EINode}, noconnection}
- ] = lists:sort(flush(2, 1000)),
-
+ ok =receive
+ {'DOWN', MRef1, process, {any, EINode}, noconnection} ->
+ ok
+ after 1000 ->
+ timeout
+ end,
+ ok = receive
+ {'DOWN', MRef2, process, {any, EINode}, noconnection} ->
+ ok
+ after 1000 ->
+ timeout
+ end,
+ [] = flush(0, 1000),
ok.
waitfornode(String,0) ->
@@ -164,9 +181,10 @@ send_rec_einode(N, TestServerPid) ->
ct:fail(EINode)
end.
-start_einode(Einode, N, Host) ->
+start_einode(Einode, N, SockImpl) ->
Einodecmd = Einode ++ " " ++ atom_to_list(erlang:get_cookie())
- ++ " " ++ integer_to_list(N) ++ " " ++ Host,
+ ++ " " ++ integer_to_list(N)
+ ++ " " ++ atom_to_list(SockImpl),
io:format("Einodecmd ~p ~n", [Einodecmd]),
open_port({spawn, Einodecmd}, []),
ok.
@@ -174,8 +192,8 @@ start_einode(Einode, N, Host) ->
%%% Interface functions for ei (erl_interface) functions.
-ei_connect_init(P, Num, Cookie, Creation, Compat) ->
- send_command(P, ei_connect_init, [Num,Cookie,Creation,Compat]),
+ei_connect_init(P, Num, Cookie, Creation, Compat, SockImpl) ->
+ send_command(P, ei_connect_init, [Num,Cookie,Creation,Compat,SockImpl]),
case get_term(P) of
{term,Int} when is_integer(Int) -> Int
end.
diff --git a/lib/erl_interface/test/ei_accept_SUITE_data/Makefile.src b/lib/erl_interface/test/ei_accept_SUITE_data/Makefile.src
index 10ef437f8b..7fd0a123b4 100644
--- a/lib/erl_interface/test/ei_accept_SUITE_data/Makefile.src
+++ b/lib/erl_interface/test/ei_accept_SUITE_data/Makefile.src
@@ -25,6 +25,7 @@ CC = ..@DS@all_SUITE_data@DS@gccifier@exe@ -CC"$(CC0)"
LD = @LD@
LIBEI = @erl_interface_eilib@
LIBFLAGS = ../all_SUITE_data/ei_runner@obj@ \
+ ../all_SUITE_data/my_ussi@obj@ \
$(LIBEI) @LIBS@ @erl_interface_sock_libs@ \
@erl_interface_threadlib@
CFLAGS = @EI_CFLAGS@ $(THR_DEFS) -I@erl_interface_include@ -I../all_SUITE_data
diff --git a/lib/erl_interface/test/ei_accept_SUITE_data/ei_accept_test.c b/lib/erl_interface/test/ei_accept_SUITE_data/ei_accept_test.c
index 09b0b5440b..64cb2dc447 100644
--- a/lib/erl_interface/test/ei_accept_SUITE_data/ei_accept_test.c
+++ b/lib/erl_interface/test/ei_accept_SUITE_data/ei_accept_test.c
@@ -27,9 +27,6 @@
#include <stdio.h>
#include <string.h>
-#ifdef VXWORKS
-#include "reclaim.h"
-#endif
#ifdef __WIN32__
#include <winsock2.h>
@@ -41,6 +38,7 @@
#endif
#include "ei_runner.h"
+#include "my_ussi.h"
static void cmd_ei_connect_init(char* buf, int len);
static void cmd_ei_publish(char* buf, int len);
@@ -58,7 +56,7 @@ static struct {
int num_args; /* Number of arguments. */
void (*func)(char* buf, int len);
} commands[] = {
- "ei_connect_init", 4, cmd_ei_connect_init,
+ "ei_connect_init", 5, cmd_ei_connect_init,
"ei_publish", 1, cmd_ei_publish,
"ei_accept", 1, cmd_ei_accept,
"ei_receive", 1, cmd_ei_receive,
@@ -110,10 +108,11 @@ static void cmd_ei_connect_init(char* buf, int len)
unsigned long compat;
char node_name[100];
char cookie[MAXATOMLEN], * cp = cookie;
+ char socket_impl[10];
ei_x_buff res;
if (ei_decode_long(buf, &index, &num) < 0)
fail("expected int");
- sprintf(node_name, "c%d", num);
+ sprintf(node_name, "c%ld", num);
if (ei_decode_atom(buf, &index, cookie) < 0)
fail("expected atom (cookie)");
if (cookie[0] == '\0')
@@ -124,7 +123,18 @@ static void cmd_ei_connect_init(char* buf, int len)
fail("expected uint");
if (compat)
ei_set_compat_rel(compat);
- r = ei_connect_init(&ec, node_name, cp, creation);
+ if (ei_decode_atom_as(buf, &index, socket_impl, sizeof(socket_impl),
+ ERLANG_ASCII, NULL, NULL) < 0)
+ fail("expected atom (socket_impl)");
+ if (strcmp(socket_impl,"default") == 0)
+ r = ei_connect_init(&ec, node_name, cp, creation);
+ else if (strcmp(socket_impl,"ussi") == 0)
+ r = ei_connect_init_ussi(&ec, node_name, cp, creation,
+ &my_ussi, sizeof(my_ussi), NULL);
+ else
+ fail1("unknown socket_impl atom '%s'", socket_impl);
+
+
ei_x_new_with_version(&res);
ei_x_encode_long(&res, r);
send_bin_term(&res);
@@ -152,9 +162,6 @@ static void cmd_ei_publish(char* buf, int len)
if ((i = ei_publish(&ec, lport)) == -1)
fail("ei_publish");
-#ifdef VXWORKS
- save_fd(i);
-#endif
/* send listen-fd, result and errno */
ei_x_new_with_version(&x);
ei_x_encode_tuple_header(&x, 3);
@@ -179,9 +186,6 @@ static void cmd_ei_accept(char* buf, int len)
fail("expected int (listen fd)");
r = ei_accept(&ec, listen, &conn);
-#ifdef VXWORKS
- save_fd(r);
-#endif
/* send result, errno and nodename */
ei_x_new_with_version(&x);
ei_x_encode_tuple_header(&x, 3);
diff --git a/lib/erl_interface/test/ei_accept_SUITE_data/eiaccnode.c b/lib/erl_interface/test/ei_accept_SUITE_data/eiaccnode.c
index 90c7a2259f..4ce55cacef 100644
--- a/lib/erl_interface/test/ei_accept_SUITE_data/eiaccnode.c
+++ b/lib/erl_interface/test/ei_accept_SUITE_data/eiaccnode.c
@@ -22,35 +22,28 @@
#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
#ifdef __WIN32__
#include <winsock2.h>
#include <windows.h>
#include <process.h>
#else
-#ifndef VXWORKS
#include <pthread.h>
-#endif
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#endif
#include "ei.h"
+#include "my_ussi.h"
-#ifdef VXWORKS
-#include <vxWorks.h>
-#include <sockLib.h>
-#include <inetLib.h>
-#define MAIN cnode
-#else
#define MAIN main
-#endif
/*
A small einode.
To be called from the test case ei_accept_SUITE:multi_thread
- usage: eiaccnode <cookie> <n>
+ usage: eiaccnode <cookie> <n> <default|ussi>
- start threads 0..n-1
- in each thread
@@ -61,7 +54,8 @@
- shutdown gracefully
*/
-static const char* cookie, * desthost;
+static const char* cookie;
+static int use_ussi;
#ifndef SD_SEND
#ifdef SHUTWR
@@ -78,7 +72,7 @@ static void*
#endif
einode_thread(void* num)
{
- int n = (int)num;
+ int n = (int)(long)num;
int port;
ei_cnode ec;
char myname[100], destname[100], filename[100];
@@ -88,10 +82,15 @@ static void*
FILE* file;
sprintf(filename, "eiacc%d_trace.txt", n);
- file = fopen(filename, "w");
+ file = fopen(filename, "a");
sprintf(myname, "eiacc%d", n); fflush(file);
- r = ei_connect_init(&ec, myname, cookie, 0);
+ fprintf(file, "---- use_ussi = %d ----\n", use_ussi); fflush(file);
+ if (use_ussi)
+ r = ei_connect_init_ussi(&ec, myname, cookie, 0,
+ &my_ussi, sizeof(my_ussi), NULL);
+ else
+ r = ei_connect_init(&ec, myname, cookie, 0);
port = 0;
listen = ei_listen(&ec, &port, 5);
if (listen <= 0) {
@@ -151,54 +150,52 @@ static void*
return 0;
}
+int
MAIN(int argc, char *argv[])
{
int i, n, no_threads;
-#ifndef VXWORKS
#ifdef __WIN32__
HANDLE threads[100];
#else
pthread_t threads[100];
#endif
-#endif
- if (argc < 3)
+ if (argc < 4)
exit(1);
cookie = argv[1];
n = atoi(argv[2]);
if (n > 100)
exit(2);
- desthost = argv[3];
- if (argc == 3)
+
+ if (strcmp(argv[3], "default") == 0)
+ use_ussi = 0;
+ else if (strcmp(argv[3], "ussi") == 0)
+ use_ussi = 1;
+ else
+ printf("bad argv[3] '%s'", argv[3]);
+
+ if (argc == 4)
no_threads = 0;
else
no_threads = argv[4] != NULL && strcmp(argv[4], "nothreads") == 0;
-#ifdef VXWORKS
- no_threads = 1;
-#endif
ei_init();
for (i = 0; i < n; ++i) {
if (!no_threads) {
-#ifndef VXWORKS
#ifdef __WIN32__
unsigned tid;
threads[i] = (HANDLE)_beginthreadex(NULL, 0, einode_thread,
- (void*)i, 0, &tid);
-#else
- pthread_create(&threads[i], NULL, einode_thread, (void*)i);
-#endif
+ (void*)(size_t)i, 0, &tid);
#else
- ;
+ pthread_create(&threads[i], NULL, einode_thread, (void*)(size_t)i);
#endif
} else
- einode_thread((void*)i);
+ einode_thread((void*)(size_t)i);
}
if (!no_threads)
-#ifndef VXWORKS
for (i = 0; i < n; ++i) {
#ifdef __WIN32__
if (WaitForSingleObject(threads[i], INFINITE) != WAIT_OBJECT_0)
@@ -207,9 +204,6 @@ MAIN(int argc, char *argv[])
#endif
printf("bad wait thread %d\n", i);
}
-#else
- ;
-#endif
printf("ok\n");
return 0;
}
diff --git a/lib/erl_interface/test/ei_connect_SUITE.erl b/lib/erl_interface/test/ei_connect_SUITE.erl
index 6184ce801b..2ec1237e8e 100644
--- a/lib/erl_interface/test/ei_connect_SUITE.erl
+++ b/lib/erl_interface/test/ei_connect_SUITE.erl
@@ -24,7 +24,7 @@
-include_lib("common_test/include/ct.hrl").
-include("ei_connect_SUITE_data/ei_connect_test_cases.hrl").
--export([all/0, suite/0,
+-export([all/0, suite/0, groups/0,
init_per_testcase/2,
ei_send/1,
ei_reg_send/1,
@@ -33,7 +33,8 @@
rpc_test/1,
ei_send_funs/1,
ei_threaded_send/1,
- ei_set_get_tracelevel/1]).
+ ei_set_get_tracelevel/1,
+ ei_connect_host_port_test/1]).
-import(runner, [get_term/1,send_term/2]).
@@ -42,15 +43,30 @@ suite() ->
{timetrap, {seconds, 30}}].
all() ->
- [ei_send, ei_reg_send, ei_rpc, ei_format_pid, ei_send_funs,
- ei_threaded_send, ei_set_get_tracelevel].
+ [ei_threaded_send,
+ ei_connect_host_port_test,
+ {group, default},
+ {group, ussi}].
+
+groups() ->
+ Members = [ei_send,
+ ei_format_pid,
+ ei_send_funs,
+ ei_set_get_tracelevel,
+ ei_reg_send,
+ ei_rpc],
+ [{default, [], Members},
+ {ussi, [], Members}].
+
+get_group(Config) ->
+ proplists:get_value(name, proplists:get_value(tc_group_properties,Config)).
init_per_testcase(Case, Config) ->
runner:init_per_testcase(?MODULE, Case, Config).
ei_send(Config) when is_list(Config) ->
P = runner:start(Config, ?interpret),
- 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0),
+ 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0, get_group(Config)),
{ok,Fd} = ei_connect(P, node()),
ok = ei_send(P, Fd, self(), AMsg={a,message}),
@@ -63,7 +79,7 @@ ei_send(Config) when is_list(Config) ->
ei_format_pid(Config) when is_list(Config) ->
S = self(),
P = runner:start(Config, ?interpret),
- 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0),
+ 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0, get_group(Config)),
{ok,Fd} = ei_connect(P, node()),
ok = ei_format_pid(P, Fd, S),
@@ -75,7 +91,7 @@ ei_format_pid(Config) when is_list(Config) ->
ei_send_funs(Config) when is_list(Config) ->
P = runner:start(Config, ?interpret),
- 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0),
+ 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0, get_group(Config)),
{ok,Fd} = ei_connect(P, node()),
Fun1 = fun ei_send/1,
@@ -94,7 +110,7 @@ ei_send_funs(Config) when is_list(Config) ->
ei_reg_send(Config) when is_list(Config) ->
P = runner:start(Config, ?interpret),
- 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0),
+ 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0, get_group(Config)),
{ok,Fd} = ei_connect(P, node()),
ARegName = a_strange_registred_name,
@@ -143,7 +159,7 @@ start_einode(Einode, N, Host) ->
ei_rpc(Config) when is_list(Config) ->
P = runner:start(Config, ?interpret),
- 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0),
+ 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0, get_group(Config)),
{ok,Fd} = ei_connect(P, node()),
S= "Hej du glade!", SRev = lists:reverse(S),
@@ -157,7 +173,7 @@ ei_rpc(Config) when is_list(Config) ->
ei_set_get_tracelevel(Config) when is_list(Config) ->
P = runner:start(Config, ?interpret),
5 = ei_set_get_tracelevel(P, 5),
- 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0),
+ 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0, get_group(Config)),
{ok,Fd} = ei_connect(P, node()),
S= "Hej du glade!", SRev = lists:reverse(S),
@@ -171,10 +187,31 @@ ei_set_get_tracelevel(Config) when is_list(Config) ->
ok.
+ei_connect_host_port_test(Config) when is_list(Config) ->
+ P = runner:start(Config, ?interpret),
+ 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0, default),
+ [NodeName, Hostname] = string:lexemes(atom_to_list(node()), "@"),
+ {ok, NamePortList} = net_adm:names(),
+ {value, {_, Port}}
+ = lists:search(fun({N, _}) ->
+ string:equal(N, NodeName)
+ end,
+ NamePortList),
+ {ok,Fd} = ei_connect_host_port(P,
+ erlang:list_to_atom(Hostname),
+ Port),
+ ok = ei_send(P, Fd, self(), AMsg={a,message}),
+ receive AMsg -> ok end,
+
+ runner:send_eot(P),
+ runner:recv_eot(P),
+ ok.
+
+
%%% Interface functions for ei (erl_interface) functions.
-ei_connect_init(P, Num, Cookie, Creation) ->
- send_command(P, ei_connect_init, [Num,Cookie,Creation]),
+ei_connect_init(P, Num, Cookie, Creation, SockImpl) ->
+ send_command(P, ei_connect_init, [Num,Cookie,Creation,SockImpl]),
case get_term(P) of
{term,Int} when is_integer(Int) -> Int
end.
@@ -186,6 +223,13 @@ ei_connect(P, Node) ->
{term,{-1,Errno}} -> {error,Errno}
end.
+ei_connect_host_port(P, Hostname, Port) ->
+ send_command(P, ei_connect_host_port, [Hostname, Port]),
+ case get_term(P) of
+ {term,{Fd,_}} when Fd >= 0 -> {ok,Fd};
+ {term,{-1,Errno}} -> {error,Errno}
+ end.
+
ei_set_get_tracelevel(P, Tracelevel) ->
send_command(P, ei_set_get_tracelevel, [Tracelevel]),
case get_term(P) of
diff --git a/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.src b/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.src
index c2d8261dd8..bbea076ebd 100644
--- a/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.src
+++ b/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.src
@@ -23,10 +23,9 @@ include @erl_interface_mk_include@
CC0 = @CC@
CC = ..@DS@all_SUITE_data@DS@gccifier@exe@ -CC"$(CC0)"
LD = @LD@
-LIBERL = @erl_interface_lib@
LIBEI = @erl_interface_eilib@
LIBFLAGS = ../all_SUITE_data/ei_runner@obj@ \
- $(LIBERL) $(LIBEI) @LIBS@ @erl_interface_sock_libs@ \
+ $(LIBEI) @LIBS@ @erl_interface_sock_libs@ \
@erl_interface_threadlib@
CFLAGS = @EI_CFLAGS@ $(THR_DEFS) -I@erl_interface_include@ -I../all_SUITE_data
EI_CONNECT_OBJS = ei_connect_test@obj@ ei_connect_test_decl@obj@
@@ -39,7 +38,8 @@ clean:
$(RM) ei_connect_test@exe@ einode@exe@
ei_connect_test@exe@: $(EI_CONNECT_OBJS) $(LIBEI)
- $(LD) @CROSSLDFLAGS@ -o $@ $(EI_CONNECT_OBJS) $(LIBFLAGS)
+ $(LD) @CROSSLDFLAGS@ -o $@ $(EI_CONNECT_OBJS) \
+ ../all_SUITE_data/my_ussi@obj@ $(LIBFLAGS)
einode@exe@: $(EINODE_OBJS) $(LIBEI)
diff --git a/lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c b/lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c
index 385bcdd422..54e78253a0 100644
--- a/lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c
+++ b/lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c
@@ -27,14 +27,13 @@
#include <stdio.h>
#include <string.h>
-#ifdef VXWORKS
-#include "reclaim.h"
-#endif
#include "ei_runner.h"
+#include "my_ussi.h"
static void cmd_ei_connect_init(char* buf, int len);
static void cmd_ei_connect(char* buf, int len);
+static void cmd_ei_connect_host_port(char* buf, int len);
static void cmd_ei_send(char* buf, int len);
static void cmd_ei_format_pid(char* buf, int len);
static void cmd_ei_send_funs(char* buf, int len);
@@ -52,8 +51,9 @@ static struct {
int num_args; /* Number of arguments. */
void (*func)(char* buf, int len);
} commands[] = {
- "ei_connect_init", 3, cmd_ei_connect_init,
+ "ei_connect_init", 4, cmd_ei_connect_init,
"ei_connect", 1, cmd_ei_connect,
+ "ei_connect_host_port", 2, cmd_ei_connect_host_port,
"ei_send", 3, cmd_ei_send,
"ei_send_funs", 3, cmd_ei_send_funs,
"ei_reg_send", 3, cmd_ei_reg_send,
@@ -107,9 +107,11 @@ TESTCASE(interpret)
static void cmd_ei_connect_init(char* buf, int len)
{
int index = 0, r = 0;
- long l;
+ long l, creation;
char b[100];
char cookie[MAXATOMLEN], * cp = cookie;
+ char socket_impl[10];
+ int use_ussi;
ei_x_buff res;
if (ei_decode_long(buf, &index, &l) < 0)
fail("expected int");
@@ -118,7 +120,23 @@ static void cmd_ei_connect_init(char* buf, int len)
fail("expected atom (cookie)");
if (cookie[0] == '\0')
cp = NULL;
- r = ei_connect_init(&ec, b, cp, 0);
+ if (ei_decode_long(buf, &index, &creation) < 0)
+ fail("expected int (creation)");
+ if (ei_decode_atom_as(buf, &index, socket_impl,
+ sizeof(socket_impl), ERLANG_ASCII, NULL, NULL) < 0)
+ fail("expected atom (socket_impl)");
+ if (strcmp(socket_impl, "default") == 0)
+ use_ussi = 0;
+ else if (strcmp(socket_impl, "ussi") == 0)
+ use_ussi = 1;
+ else
+ fail1("expected atom 'default' or 'ussi', got '%s'", socket_impl);
+
+ if (use_ussi)
+ r = ei_connect_init_ussi(&ec, b, cp, (short)creation,
+ &my_ussi, sizeof(my_ussi), NULL);
+ else
+ r = ei_connect_init(&ec, b, cp, (short)creation);
ei_x_new_with_version(&res);
ei_x_encode_long(&res, r);
send_bin_term(&res);
@@ -133,11 +151,20 @@ static void cmd_ei_connect(char* buf, int len)
if (ei_decode_atom(buf, &index, node) < 0)
fail("expected atom");
i=ei_connect(&ec, node);
-#ifdef VXWORKS
- if(i >= 0) {
- save_fd(i);
- }
-#endif
+ send_errno_result(i);
+}
+
+static void cmd_ei_connect_host_port(char* buf, int len)
+{
+ int index = 0;
+ char hostname[256];
+ int i;
+ long port;
+ if (ei_decode_atom(buf, &index, hostname) < 0)
+ fail("expected atom");
+ if (ei_decode_long(buf, &index, &port) < 0)
+ fail("expected int");
+ i = ei_connect_host_port(&ec, hostname, (int)port);
send_errno_result(i);
}
@@ -225,7 +252,7 @@ static void cmd_ei_send_funs(char* buf, int len)
fail("expected Fun1");
if (ei_decode_fun(buf, &index, &fun2) < 0)
fail("expected Fun2");
- if (ei_decode_bitstring(buf, &index, &bitstring, &bitoffs, &bits) < 0)
+ if (ei_decode_bitstring(buf, &index, (const char**)&bitstring, &bitoffs, &bits) < 0)
fail("expected bitstring");
if (ei_x_new_with_version(&x) < 0)
fail("ei_x_new_with_version");
diff --git a/lib/erl_interface/test/ei_connect_SUITE_data/einode.c b/lib/erl_interface/test/ei_connect_SUITE_data/einode.c
index bb71575740..083ca1d372 100644
--- a/lib/erl_interface/test/ei_connect_SUITE_data/einode.c
+++ b/lib/erl_interface/test/ei_connect_SUITE_data/einode.c
@@ -28,20 +28,13 @@
#include <windows.h>
#include <process.h>
#else
-#ifndef VXWORKS
#include <pthread.h>
-#endif
#include <sys/socket.h>
#endif
#include "ei.h"
-#include "erl_interface.h"
-#ifdef VXWORKS
-#define MAIN cnode
-#else
#define MAIN main
-#endif
/*
A small einode.
@@ -105,32 +98,25 @@ static void*
MAIN(int argc, char *argv[])
{
int i, n, no_threads;
-#ifndef VXWORKS
#ifdef __WIN32__
HANDLE threads[100];
#else
pthread_t threads[100];
#endif
-#endif
if (argc < 3)
exit(1);
- erl_init(NULL, 0);
+ ei_init();
cookie = argv[1];
n = atoi(argv[2]);
if (n > 100)
exit(2);
desthost = argv[3];
-#ifndef VXWORKS
no_threads = argv[4] != NULL && strcmp(argv[4], "nothreads") == 0;
-#else
- no_threads = 1;
-#endif
for (i = 0; i < n; ++i) {
if (!no_threads) {
-#ifndef VXWORKS
#ifdef __WIN32__
unsigned tid;
threads[i] = (HANDLE)_beginthreadex(NULL, 0, einode_thread,
@@ -138,14 +124,10 @@ MAIN(int argc, char *argv[])
#else
pthread_create(&threads[i], NULL, einode_thread, (void*)i);
#endif
-#else
- ;
-#endif
} else
einode_thread((void*)i);
}
if (!no_threads)
-#ifndef VXWORKS
for (i = 0; i < n; ++i) {
#ifdef __WIN32__
if (WaitForSingleObject(threads[i], INFINITE) != WAIT_OBJECT_0)
@@ -154,9 +136,6 @@ MAIN(int argc, char *argv[])
#endif
printf("bad wait thread %d\n", i);
}
-#else
- ;
-#endif
printf("ok\n");
return 0;
}
diff --git a/lib/erl_interface/test/ei_decode_SUITE.erl b/lib/erl_interface/test/ei_decode_SUITE.erl
index e005ec89c7..35feeea42c 100644
--- a/lib/erl_interface/test/ei_decode_SUITE.erl
+++ b/lib/erl_interface/test/ei_decode_SUITE.erl
@@ -77,29 +77,19 @@ test_ei_decode_ulong(Config) when is_list(Config) ->
%% ######################################################################## %%
test_ei_decode_longlong(Config) when is_list(Config) ->
- case os:type() of
- vxworks ->
- {skip,"Skipped on VxWorks"};
- _ ->
- P = runner:start(Config, ?test_ei_decode_longlong),
- send_integers2(P),
- runner:recv_eot(P),
- ok
- end.
+ P = runner:start(Config, ?test_ei_decode_longlong),
+ send_integers2(P),
+ runner:recv_eot(P),
+ ok.
%% ######################################################################## %%
test_ei_decode_ulonglong(Config) when is_list(Config) ->
- case os:type() of
- vxworks ->
- {skip,"Skipped on VxWorks"};
- _ ->
- P = runner:start(Config, ?test_ei_decode_ulonglong),
- send_integers2(P),
- runner:recv_eot(P),
- ok
- end.
+ P = runner:start(Config, ?test_ei_decode_ulonglong),
+ send_integers2(P),
+ runner:recv_eot(P),
+ ok.
%% ######################################################################## %%
@@ -128,13 +118,8 @@ test_ei_decode_nonoptimal(Config) when is_list(Config) ->
send_non_optimal_pos(P), % decode_char
send_non_optimal(P), % decode_long
send_non_optimal_pos(P), % decode_ulong
- case os:type() of
- vxworks ->
- ok;
- _ ->
- send_non_optimal(P), % decode_longlong
- send_non_optimal_pos(P) % decode_ulonglong
- end,
+ send_non_optimal(P), % decode_longlong
+ send_non_optimal_pos(P), % decode_ulonglong
runner:recv_eot(P),
ok.
diff --git a/lib/erl_interface/test/ei_decode_SUITE_data/ei_decode_test.c b/lib/erl_interface/test/ei_decode_SUITE_data/ei_decode_test.c
index 46d6b8f2af..b27c3c589c 100644
--- a/lib/erl_interface/test/ei_decode_SUITE_data/ei_decode_test.c
+++ b/lib/erl_interface/test/ei_decode_SUITE_data/ei_decode_test.c
@@ -20,10 +20,6 @@
#include <string.h>
-#ifdef VXWORKS
-#include "reclaim.h"
-#endif
-
#include "ei_runner.h"
/*
@@ -31,15 +27,9 @@
* Author: Kent
*/
-#ifdef VXWORKS
-#define MESSAGE_BACK(SIZE) \
- message("err = %d, size2 = %d, expected size = %d", \
- err, size1, SIZE);
-#else
#define MESSAGE_BACK(SIZE) \
message("err = %d, size2 = %d, expected size = %d, long long val = %lld", \
err, size1, SIZE, (EI_LONGLONG)p);
-#endif
#define ERLANG_ANY (ERLANG_ASCII|ERLANG_LATIN1|ERLANG_UTF8)
@@ -483,7 +473,6 @@ TESTCASE(test_ei_decode_longlong)
{
ei_init();
-#ifndef VXWORKS
EI_DECODE_2 (decode_longlong, 2, EI_LONGLONG, 0);
EI_DECODE_2 (decode_longlong, 2, EI_LONGLONG, 255);
EI_DECODE_2 (decode_longlong, 5, EI_LONGLONG, 256);
@@ -509,7 +498,6 @@ TESTCASE(test_ei_decode_longlong)
EI_DECODE_2_FAIL(decode_longlong, 11, EI_LONGLONG, ll(0xffffffffffffffff));
EI_DECODE_2_FAIL(decode_longlong, 1, EI_LONGLONG, 0); /* Illegal type */
-#endif
report(1);
}
@@ -519,7 +507,6 @@ TESTCASE(test_ei_decode_ulonglong)
{
ei_init();
-#ifndef VXWORKS
EI_DECODE_2 (decode_ulonglong, 2, EI_ULONGLONG, 0);
EI_DECODE_2 (decode_ulonglong, 2, EI_ULONGLONG, 255);
EI_DECODE_2 (decode_ulonglong, 5, EI_ULONGLONG, 256);
@@ -545,7 +532,6 @@ TESTCASE(test_ei_decode_ulonglong)
EI_DECODE_2 (decode_ulonglong,11, EI_ULONGLONG, ll(0xffffffffffffffff));
EI_DECODE_2_FAIL(decode_ulonglong, 1, EI_ULONGLONG, 0); /* Illegal type */
-#endif
report(1);
}
@@ -637,8 +623,6 @@ TESTCASE(test_ei_decode_nonoptimal)
/* ---------------------------------------------------------------- */
-#ifndef VXWORKS
-
EI_DECODE_2(decode_longlong, 2, EI_LONGLONG, 42);
EI_DECODE_2(decode_longlong, 5, EI_LONGLONG, 42);
EI_DECODE_2(decode_longlong, 4, EI_LONGLONG, 42);
@@ -681,8 +665,6 @@ TESTCASE(test_ei_decode_nonoptimal)
/* EI_DECODE_2(decode_ulonglong, EI_ULONGLONG, -42); */
/* EI_DECODE_2(decode_ulonglong, EI_ULONGLONG, -42); */
-#endif /* !VXWORKS */
-
/* ---------------------------------------------------------------- */
report(1);
diff --git a/lib/erl_interface/test/ei_decode_encode_SUITE_data/ei_decode_encode_test.c b/lib/erl_interface/test/ei_decode_encode_SUITE_data/ei_decode_encode_test.c
index 512f9ed0c7..5594bec757 100644
--- a/lib/erl_interface/test/ei_decode_encode_SUITE_data/ei_decode_encode_test.c
+++ b/lib/erl_interface/test/ei_decode_encode_SUITE_data/ei_decode_encode_test.c
@@ -18,10 +18,6 @@
* %CopyrightEnd%
*/
-#ifdef VXWORKS
-#include "reclaim.h"
-#endif
-
#include "ei_runner.h"
/*
diff --git a/lib/erl_interface/test/ei_encode_SUITE.erl b/lib/erl_interface/test/ei_encode_SUITE.erl
index 0267a5126f..10fcd6b871 100644
--- a/lib/erl_interface/test/ei_encode_SUITE.erl
+++ b/lib/erl_interface/test/ei_encode_SUITE.erl
@@ -101,59 +101,49 @@ test_ei_encode_ulong(Config) when is_list(Config) ->
%% ######################################################################## %%
test_ei_encode_longlong(Config) when is_list(Config) ->
- case os:type() of
- vxworks ->
- {skip,"Skipped on VxWorks"};
- _ ->
- P = runner:start(Config, ?test_ei_encode_longlong),
-
- {<<97,0>> ,0} = get_buf_and_term(P),
- {<<97,255>> ,255} = get_buf_and_term(P),
- {<<98,256:32/big-signed-integer>>,256} = get_buf_and_term(P),
- {<<98,-1:32/big-signed-integer>> ,-1} = get_buf_and_term(P),
-
- {<<98, 16#07ffffff:32/big-signed-integer>>, 16#07ffffff} = get_buf_and_term(P),
- {<<98,-16#08000000:32/big-signed-integer>>,-16#08000000} = get_buf_and_term(P),
- {<<110,4,0, 0,0,0,8>> , 16#08000000} = get_buf_and_term(P),
- {<<110,4,1, 1,0,0,8>> ,-16#08000001} = get_buf_and_term(P),
-
- {<<110,4,0, 255,255,255,127>> , 16#7fffffff} = get_buf_and_term(P),
- {<<110,4,1, 0,0,0,128>> ,-16#80000000} = get_buf_and_term(P),
- {<<110,6,0, 255,255,255,255,255,127>> , 16#7fffffffffff} = get_buf_and_term(P),
- {<<110,6,1, 0,0,0,0,0,128>> ,-16#800000000000} = get_buf_and_term(P),
- {<<110,8,0, 255,255,255,255,255,255,255,127>>,16#7fffffffffffffff} = get_buf_and_term(P),
- {<<110,8,1, 0,0,0,0,0,0,0,128>> ,-16#8000000000000000} = get_buf_and_term(P),
-
- runner:recv_eot(P),
- ok
- end.
+ P = runner:start(Config, ?test_ei_encode_longlong),
+
+ {<<97,0>> ,0} = get_buf_and_term(P),
+ {<<97,255>> ,255} = get_buf_and_term(P),
+ {<<98,256:32/big-signed-integer>>,256} = get_buf_and_term(P),
+ {<<98,-1:32/big-signed-integer>> ,-1} = get_buf_and_term(P),
+
+ {<<98, 16#07ffffff:32/big-signed-integer>>, 16#07ffffff} = get_buf_and_term(P),
+ {<<98,-16#08000000:32/big-signed-integer>>,-16#08000000} = get_buf_and_term(P),
+ {<<110,4,0, 0,0,0,8>> , 16#08000000} = get_buf_and_term(P),
+ {<<110,4,1, 1,0,0,8>> ,-16#08000001} = get_buf_and_term(P),
+
+ {<<110,4,0, 255,255,255,127>> , 16#7fffffff} = get_buf_and_term(P),
+ {<<110,4,1, 0,0,0,128>> ,-16#80000000} = get_buf_and_term(P),
+ {<<110,6,0, 255,255,255,255,255,127>> , 16#7fffffffffff} = get_buf_and_term(P),
+ {<<110,6,1, 0,0,0,0,0,128>> ,-16#800000000000} = get_buf_and_term(P),
+ {<<110,8,0, 255,255,255,255,255,255,255,127>>,16#7fffffffffffffff} = get_buf_and_term(P),
+ {<<110,8,1, 0,0,0,0,0,0,0,128>> ,-16#8000000000000000} = get_buf_and_term(P),
+
+ runner:recv_eot(P),
+ ok.
%% ######################################################################## %%
test_ei_encode_ulonglong(Config) when is_list(Config) ->
- case os:type() of
- vxworks ->
- {skip,"Skipped on VxWorks"};
- _ ->
- P = runner:start(Config, ?test_ei_encode_ulonglong),
-
- {<<97,0>> ,0} = get_buf_and_term(P),
- {<<97,255>> ,255} = get_buf_and_term(P),
- {<<98,256:32/big-unsigned-integer>>,256} = get_buf_and_term(P),
-
- {<<98, 16#07ffffff:32/big-signed-integer>>,16#07ffffff} = get_buf_and_term(P),
- {<<110,4,0, 0,0,0,8>> ,16#08000000} = get_buf_and_term(P),
-
- {<<110,4,0, 255,255,255,127>> ,16#7fffffff} = get_buf_and_term(P),
- {<<110,4,0, 0,0,0,128>> ,16#80000000} = get_buf_and_term(P),
- {<<110,4,0, 255,255,255,255>> ,16#ffffffff} = get_buf_and_term(P),
- {<<110,6,0, 255,255,255,255,255,255>>,16#ffffffffffff} = get_buf_and_term(P),
- {<<110,8,0, 255,255,255,255,255,255,255,255>>,16#ffffffffffffffff} = get_buf_and_term(P),
+ P = runner:start(Config, ?test_ei_encode_ulonglong),
- runner:recv_eot(P),
- ok
- end.
+ {<<97,0>> ,0} = get_buf_and_term(P),
+ {<<97,255>> ,255} = get_buf_and_term(P),
+ {<<98,256:32/big-unsigned-integer>>,256} = get_buf_and_term(P),
+
+ {<<98, 16#07ffffff:32/big-signed-integer>>,16#07ffffff} = get_buf_and_term(P),
+ {<<110,4,0, 0,0,0,8>> ,16#08000000} = get_buf_and_term(P),
+
+ {<<110,4,0, 255,255,255,127>> ,16#7fffffff} = get_buf_and_term(P),
+ {<<110,4,0, 0,0,0,128>> ,16#80000000} = get_buf_and_term(P),
+ {<<110,4,0, 255,255,255,255>> ,16#ffffffff} = get_buf_and_term(P),
+ {<<110,6,0, 255,255,255,255,255,255>>,16#ffffffffffff} = get_buf_and_term(P),
+ {<<110,8,0, 255,255,255,255,255,255,255,255>>,16#ffffffffffffffff} = get_buf_and_term(P),
+
+ runner:recv_eot(P),
+ ok.
%% ######################################################################## %%
diff --git a/lib/erl_interface/test/ei_encode_SUITE_data/ei_encode_test.c b/lib/erl_interface/test/ei_encode_SUITE_data/ei_encode_test.c
index 6f63cc5d7e..6f1276e016 100644
--- a/lib/erl_interface/test/ei_encode_SUITE_data/ei_encode_test.c
+++ b/lib/erl_interface/test/ei_encode_SUITE_data/ei_encode_test.c
@@ -18,10 +18,6 @@
* %CopyrightEnd%
*/
-#ifdef VXWORKS
-#include "reclaim.h"
-#endif
-
#include "ei_runner.h"
/*
@@ -460,8 +456,6 @@ TESTCASE(test_ei_encode_longlong)
{
ei_init();
-#ifndef VXWORKS
-
EI_ENCODE_1(encode_longlong, 0);
EI_ENCODE_1(encode_longlong, 255);
@@ -490,8 +484,6 @@ TESTCASE(test_ei_encode_longlong)
EI_ENCODE_1(encode_longlong, -ll(0x8000000000000000));
-#endif /* !VXWORKS */
-
report(1);
}
@@ -501,8 +493,6 @@ TESTCASE(test_ei_encode_ulonglong)
{
ei_init();
-#ifndef VXWORKS
-
EI_ENCODE_1(encode_ulonglong, 0);
EI_ENCODE_1(encode_ulonglong, 255);
@@ -523,8 +513,6 @@ TESTCASE(test_ei_encode_ulonglong)
EI_ENCODE_1(encode_ulonglong, ll(0xffffffffffffffff));
-#endif /* !VXWORKS */
-
report(1);
}
diff --git a/lib/erl_interface/test/ei_format_SUITE_data/ei_format_test.c b/lib/erl_interface/test/ei_format_SUITE_data/ei_format_test.c
index 1c0443c0f4..19d2cc1510 100644
--- a/lib/erl_interface/test/ei_format_SUITE_data/ei_format_test.c
+++ b/lib/erl_interface/test/ei_format_SUITE_data/ei_format_test.c
@@ -18,10 +18,6 @@
* %CopyrightEnd%
*/
-#ifdef VXWORKS
-#include "reclaim.h"
-#endif
-
#include "ei_runner.h"
#include <string.h>
diff --git a/lib/erl_interface/test/erl_global_SUITE.erl b/lib/erl_interface/test/ei_global_SUITE.erl
index 6d3a75c8d7..da80ab24cd 100644
--- a/lib/erl_interface/test/erl_global_SUITE.erl
+++ b/lib/erl_interface/test/ei_global_SUITE.erl
@@ -19,22 +19,27 @@
%%
%%
--module(erl_global_SUITE).
+-module(ei_global_SUITE).
-include_lib("common_test/include/ct.hrl").
--include("erl_global_SUITE_data/erl_global_test_cases.hrl").
+-include("ei_global_SUITE_data/ei_global_test_cases.hrl").
-export([all/0,suite/0,
init_per_testcase/2,
- erl_global_registration/1,
- erl_global_whereis/1, erl_global_names/1]).
+ ei_global_registration/1,
+ ei_global_whereis/1,
+ ei_global_names/1
+ ]).
-import(runner, [get_term/1,send_term/2]).
-define(GLOBAL_NAME, global_register_node_test).
all() ->
- [erl_global_registration, erl_global_whereis, erl_global_names].
+ [ei_global_registration, ei_global_whereis, ei_global_names].
+
+get_group(Config) ->
+ proplists:get_value(name, proplists:get_value(tc_group_properties,Config)).
suite() ->
[{ct_hooks,[ts_install_cth]},
@@ -43,82 +48,76 @@ suite() ->
init_per_testcase(Case, Config) ->
runner:init_per_testcase(?MODULE, Case, Config).
-erl_global_registration(Config) when is_list(Config) ->
+ei_global_registration(Config) when is_list(Config) ->
P = runner:start(Config, ?interpret),
- {ok, Fd} = erl_connect(P, node(), 42, erlang:get_cookie(), 0),
+ 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0, ussi),
+ {ok,Fd} = ei_connect(P, node()),
- ok = erl_global_register(P, Fd, ?GLOBAL_NAME),
- ok = erl_global_unregister(P, Fd, ?GLOBAL_NAME),
+ ok = ei_global_register(P, Fd, ?GLOBAL_NAME),
+ ok = ei_global_unregister(P, Fd, ?GLOBAL_NAME),
- 0 = erl_close_connection(P,Fd),
runner:send_eot(P),
runner:recv_eot(P),
ok.
-erl_global_whereis(Config) when is_list(Config) ->
+ei_global_whereis(Config) when is_list(Config) ->
P = runner:start(Config, ?interpret),
- {ok, Fd} = erl_connect(P, node(), 42, erlang:get_cookie(), 0),
+ 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0, ussi),
+ {ok,Fd} = ei_connect(P, node()),
Self = self(),
yes = global:register_name(?GLOBAL_NAME, Self),
- Self = erl_global_whereis(P, Fd, ?GLOBAL_NAME),
+ Self = ei_global_whereis(P, Fd, ?GLOBAL_NAME),
global:unregister_name(?GLOBAL_NAME),
- 0 = erl_close_connection(P, Fd),
runner:send_eot(P),
runner:recv_eot(P),
ok.
-erl_global_names(Config) when is_list(Config) ->
+ei_global_names(Config) when is_list(Config) ->
P = runner:start(Config, ?interpret),
- {ok, Fd} = erl_connect(P, node(), 42, erlang:get_cookie(), 0),
+ 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0, ussi),
+ {ok,Fd} = ei_connect(P, node()),
Self = self(),
global:register_name(?GLOBAL_NAME, Self),
- {Names1, _N1} = erl_global_names(P, Fd),
+ {Names1, _N1} = ei_global_names(P, Fd),
true = lists:member(atom_to_list(?GLOBAL_NAME), Names1),
global:unregister_name(?GLOBAL_NAME),
- {Names2, _N2} = erl_global_names(P, Fd),
+ {Names2, _N2} = ei_global_names(P, Fd),
false = lists:member(atom_to_list(?GLOBAL_NAME), Names2),
- 0 = erl_close_connection(P, Fd),
runner:send_eot(P),
runner:recv_eot(P),
ok.
-%%% Interface functions for erl_interface functions.
-
-erl_connect(P, Node, Num, Cookie, Creation) ->
- send_command(P, erl_connect, [Num, Node, Cookie, Creation]),
- case get_term(P) of
- {term,{Fd,_}} when Fd >= 0 -> {ok,Fd};
- {term,{-1,Errno}} -> {error,Errno}
- end.
+%% %%% Interface functions for erl_interface functions.
-erl_close_connection(P, FD) ->
- send_command(P, erl_close_connection, [FD]),
- case get_term(P) of
- {term,Int} when is_integer(Int) -> Int
- end.
+%% erl_connect(P, Node, Num, Cookie, Creation) ->
+%% send_command(P, erl_connect, [Num, Node, Cookie, Creation]),
+%% case get_term(P) of
+%% {term,{Fd,_}} when Fd >= 0 -> {ok,Fd};
+%% {term,{-1,Errno}} -> {error,Errno}
+%% end.
-erl_global_register(P, Fd, Name) ->
- send_command(P, erl_global_register, [Fd,Name]),
+ei_global_register(P, Fd, Name) ->
+ send_command(P, ei_global_register, [Fd,Name]),
get_send_result(P).
-erl_global_whereis(P, Fd, Name) ->
- send_command(P, erl_global_whereis, [Fd,Name]),
+ei_global_whereis(P, Fd, Name) ->
+ send_command(P, ei_global_whereis, [Fd,Name]),
case get_term(P) of
{term, What} ->
What
end.
-erl_global_names(P, Fd) ->
- send_command(P, erl_global_names, [Fd]),
+ei_global_names(P, Fd) ->
+ send_command(P, ei_global_names, [Fd]),
case get_term(P) of
{term, What} ->
What
end.
-erl_global_unregister(P, Fd, Name) ->
- send_command(P, erl_global_unregister, [Fd,Name]),
+ei_global_unregister(P, Fd, Name) ->
+ send_command(P, ei_global_unregister, [Fd,Name]),
get_send_result(P).
get_send_result(P) ->
@@ -132,3 +131,17 @@ get_send_result(P) ->
send_command(P, Name, Args) ->
runner:send_term(P, {Name,list_to_tuple(Args)}).
+
+
+ei_connect_init(P, Num, Cookie, Creation, SockImpl) ->
+ send_command(P, ei_connect_init, [Num,Cookie,Creation,SockImpl]),
+ case get_term(P) of
+ {term,Int} when is_integer(Int) -> Int
+ end.
+
+ei_connect(P, Node) ->
+ send_command(P, ei_connect, [Node]),
+ case get_term(P) of
+ {term,{Fd,_}} when Fd >= 0 -> {ok,Fd};
+ {term,{-1,Errno}} -> {error,Errno}
+ end.
diff --git a/lib/erl_interface/test/erl_global_SUITE_data/Makefile.first b/lib/erl_interface/test/ei_global_SUITE_data/Makefile.first
index b2c62be1f2..5ec0c06af8 100644
--- a/lib/erl_interface/test/erl_global_SUITE_data/Makefile.first
+++ b/lib/erl_interface/test/ei_global_SUITE_data/Makefile.first
@@ -18,5 +18,5 @@
# %CopyrightEnd%
#
-erl_global_test_decl.c: erl_global_test.c
- erl -noinput -pa ../all_SUITE_data -s init_tc run erl_global_test -s erlang halt
+erl_global_test_decl.c: ei_global_test.c
+ erl -noinput -pa ../all_SUITE_data -s init_tc run ei_global_test -s erlang halt
diff --git a/lib/erl_interface/test/erl_global_SUITE_data/Makefile.src b/lib/erl_interface/test/ei_global_SUITE_data/Makefile.src
index 1c1530d1b6..43c9095ab4 100644
--- a/lib/erl_interface/test/erl_global_SUITE_data/Makefile.src
+++ b/lib/erl_interface/test/ei_global_SUITE_data/Makefile.src
@@ -25,17 +25,18 @@ CC = ..@DS@all_SUITE_data@DS@gccifier@exe@ -CC"$(CC0)"
LD = @LD@
LIBERL = @erl_interface_lib@
LIBEI = @erl_interface_eilib@
-LIBFLAGS = ../all_SUITE_data/runner@obj@ \
- $(LIBERL) $(LIBEI) @LIBS@ @erl_interface_sock_libs@ \
+LIBFLAGS = ../all_SUITE_data/ei_runner@obj@ \
+ $(LIBEI) @LIBS@ @erl_interface_sock_libs@ \
@erl_interface_threadlib@
CFLAGS = @EI_CFLAGS@ $(THR_DEFS) -I@erl_interface_include@ -I../all_SUITE_data
-OBJS = erl_global_test@obj@ erl_global_test_decl@obj@
+EI_GLOBAL_OBJS = ei_global_test@obj@ ei_global_test_decl@obj@
-all: erl_global_test@exe@
-
-erl_global_test@exe@: $(OBJS) $(LIBERL) $(LIBEI)
- $(LD) @CROSSLDFLAGS@ -o $@ $(OBJS) $(LIBFLAGS)
+all: ei_global_test@exe@
clean:
- $(RM) $(OBJS)
- $(RM) erl_global_test@exe@
+ $(RM) $(EI_GLOBAL_OBJS)
+ $(RM) ei_global_test@exe@
+
+ei_global_test@exe@: $(EI_GLOBAL_OBJS) $(LIBEI)
+ $(LD) @CROSSLDFLAGS@ -o $@ $(EI_GLOBAL_OBJS) \
+ ../all_SUITE_data/my_ussi@obj@ $(LIBFLAGS)
diff --git a/lib/erl_interface/test/ei_global_SUITE_data/ei_global_test.c b/lib/erl_interface/test/ei_global_SUITE_data/ei_global_test.c
new file mode 100644
index 0000000000..4c018667fe
--- /dev/null
+++ b/lib/erl_interface/test/ei_global_SUITE_data/ei_global_test.c
@@ -0,0 +1,239 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2000-2016. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+/*
+ * Purpose: Tests the functions in erl_global.c.
+ *
+ * See the ei_global_SUITE.erl file for a "table of contents".
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "ei_runner.h"
+#include "my_ussi.h"
+#include "ei_connect.h"
+
+static void cmd_ei_connect_init(char* buf, int len);
+static void cmd_ei_connect(char* buf, int len);
+static void cmd_ei_global_register(char* buf, int len);
+static void cmd_ei_global_whereis(char* buf, int len);
+static void cmd_ei_global_names(char* buf, int len);
+static void cmd_ei_global_unregister(char* buf, int len);
+static void cmd_ei_close_connection(char* buf, int len);
+
+static void send_errno_result(int value);
+
+ei_cnode ec;
+
+static struct {
+ char* name;
+ int num_args; /* Number of arguments. */
+ void (*func)(char* buf, int len);
+} commands[] = {
+ "ei_connect_init", 4, cmd_ei_connect_init,
+ "ei_connect", 1, cmd_ei_connect,
+ "ei_global_register", 2, cmd_ei_global_register,
+ "ei_global_whereis", 2, cmd_ei_global_whereis,
+ "ei_global_names", 1, cmd_ei_global_names,
+ "ei_global_unregister", 2, cmd_ei_global_unregister
+};
+
+
+/*
+ * Sends a list contaning all data types to the Erlang side.
+ */
+
+TESTCASE(interpret)
+{
+ ei_x_buff x;
+ int i;
+ ei_term term;
+
+ ei_init();
+
+ ei_x_new(&x);
+ while (get_bin_term(&x, &term) == 0) {
+ char* buf = x.buff, func[MAXATOMLEN];
+ int index = x.index, arity;
+ if (term.ei_type != ERL_SMALL_TUPLE_EXT || term.arity != 2)
+ fail("term should be a tuple of size 2");
+ if (ei_decode_atom(buf, &index, func) < 0)
+ fail("function name should be an atom");
+ if (ei_decode_tuple_header(buf, &index, &arity) != 0)
+ fail("function arguments should be a tuple");
+ for (i = 0; i < sizeof(commands)/sizeof(commands[0]); i++) {
+ if (strcmp(func, commands[i].name) == 0) {
+ if (arity != commands[i].num_args)
+ fail("wrong number of arguments");
+ commands[i].func(buf + index, x.buffsz - index);
+ break;
+ }
+ }
+ if (i >= sizeof(commands)/sizeof(commands[0])) {
+ message("\"%d\" \n", func);
+ fail("bad command");
+ }
+ }
+ report(1);
+ ei_x_free(&x);
+ return;
+}
+
+static void cmd_ei_connect_init(char* buf, int len)
+{
+ int index = 0, r = 0;
+ long l, creation;
+ char b[100];
+ char cookie[MAXATOMLEN], * cp = cookie;
+ char socket_impl[10];
+ int use_ussi;
+ ei_x_buff res;
+ if (ei_decode_long(buf, &index, &l) < 0)
+ fail("expected int");
+ sprintf(b, "c%ld", l);
+ if (ei_decode_atom(buf, &index, cookie) < 0)
+ fail("expected atom (cookie)");
+ if (cookie[0] == '\0')
+ cp = NULL;
+ if (ei_decode_long(buf, &index, &creation) < 0)
+ fail("expected int (creation)");
+ if (ei_decode_atom_as(buf, &index, socket_impl,
+ sizeof(socket_impl), ERLANG_ASCII, NULL, NULL) < 0)
+ fail("expected atom (socket_impl)");
+ if (strcmp(socket_impl, "default") == 0)
+ use_ussi = 0;
+ else if (strcmp(socket_impl, "ussi") == 0)
+ use_ussi = 1;
+ else
+ fail1("expected atom 'default' or 'ussi', got '%s'", socket_impl);
+
+ if (use_ussi)
+ r = ei_connect_init_ussi(&ec, b, cp, (short)creation,
+ &my_ussi, sizeof(my_ussi), NULL);
+ else
+ r = ei_connect_init(&ec, b, cp, (short)creation);
+ ei_x_new_with_version(&res);
+ ei_x_encode_long(&res, r);
+ send_bin_term(&res);
+ ei_x_free(&res);
+}
+
+static void cmd_ei_connect(char* buf, int len)
+{
+ int index = 0;
+ char node[256];
+ int i;
+ if (ei_decode_atom(buf, &index, node) < 0)
+ fail("expected atom");
+ i=ei_connect(&ec, node);
+ send_errno_result(i);
+}
+
+static void
+cmd_ei_global_register(char* buf, int len)
+{
+ int index = 0;
+ long fd;
+ char name[256];
+ if (ei_decode_long(buf, &index, &fd) < 0)
+ fail("expected long");
+ if (ei_decode_atom(buf, &index, name) < 0)
+ fail("expected atom");
+ send_errno_result(ei_global_register((int)fd, name, ei_self(&ec)));
+}
+
+static void
+cmd_ei_global_whereis(char* buf, int len)
+{
+ int index = 0;
+ long fd;
+ char name[512];
+ char node_name[512];
+ erlang_pid pid;
+ if (ei_decode_long(buf, &index, &fd) < 0)
+ fail("expected long");
+ if (ei_decode_atom(buf, &index, name) < 0)
+ fail("expected atom");
+
+ if (ei_global_whereis(&ec, fd, name, &pid, node_name) < 0)
+ fail("ei_global_whereis error code");
+
+ {
+ ei_x_buff x;
+ ei_x_new_with_version(&x);
+ ei_x_encode_pid(&x, &pid);
+ send_bin_term(&x);
+ ei_x_free(&x);
+ }
+}
+
+static void
+cmd_ei_global_names(char* buf, int len)
+{
+ int index = 0;
+ long fd;
+ char** names = NULL;
+ int count = 0, i;
+ if (ei_decode_long(buf, &index, &fd) < 0)
+ fail("expected long");
+
+ names = ei_global_names(&ec, (int)fd, &count);
+
+ {
+ ei_x_buff x;
+ ei_x_new_with_version(&x);
+ ei_x_encode_tuple_header(&x, 2);
+ ei_x_encode_list_header(&x, count);
+ for(i=0; i<count; i++) {
+ ei_x_encode_string(&x, names[i]);
+ }
+ ei_x_encode_empty_list(&x);
+ ei_x_encode_long(&x, count);
+ send_bin_term(&x);
+ ei_x_free(&x);
+ }
+}
+
+static void
+cmd_ei_global_unregister(char* buf, int len)
+{
+ int index = 0;
+ long fd;
+ char name[256];
+ if (ei_decode_long(buf, &index, &fd) < 0)
+ fail("expected long");
+ if (ei_decode_atom(buf, &index, name) < 0)
+ fail("expected atom");
+
+ send_errno_result(ei_global_unregister(&ec, (int)fd, name));
+}
+
+static void send_errno_result(int value)
+{
+ ei_x_buff x;
+ ei_x_new_with_version(&x);
+ ei_x_encode_tuple_header(&x, 2);
+ ei_x_encode_long(&x, value);
+ ei_x_encode_long(&x, erl_errno);
+ send_bin_term(&x);
+ ei_x_free(&x);
+}
diff --git a/lib/erl_interface/test/ei_print_SUITE_data/ei_print_test.c b/lib/erl_interface/test/ei_print_SUITE_data/ei_print_test.c
index 27d4153250..2d332c8b0c 100644
--- a/lib/erl_interface/test/ei_print_SUITE_data/ei_print_test.c
+++ b/lib/erl_interface/test/ei_print_SUITE_data/ei_print_test.c
@@ -37,13 +37,9 @@ send_printed_buf(ei_x_buff* x)
FILE* f;
int n, index = 0, ver;
-#ifdef VXWORKS
- tmp = ".";
-#else
if (tmp == NULL) {
tmp = "/tmp";
}
-#endif
strcpy(fn, tmp);
strcat(fn, "/ei_print_test.txt");
f = fopen(fn, "w+");
diff --git a/lib/erl_interface/test/ei_tmo_SUITE.erl b/lib/erl_interface/test/ei_tmo_SUITE.erl
index 5b9de80128..8d8776949c 100644
--- a/lib/erl_interface/test/ei_tmo_SUITE.erl
+++ b/lib/erl_interface/test/ei_tmo_SUITE.erl
@@ -25,10 +25,12 @@
-include_lib("kernel/include/inet.hrl").
-include("ei_tmo_SUITE_data/ei_tmo_test_cases.hrl").
--export([all/0, suite/0,
+-export([all/0, groups/0, suite/0,
init_per_testcase/2, end_per_testcase/2,
- framework_check/1, ei_accept_tmo/1, ei_connect_tmo/1, ei_send_tmo/1,
- ei_connect_tmo/0,
+ framework_check/1, ei_accept_tmo/1, ei_connect_tmo/1,
+ ei_send_tmo/1,
+ ei_send_failure_tmo/1,
+ ei_connect_unreachable_tmo/0, ei_connect_unreachable_tmo/1,
ei_recv_tmo/1]).
suite() ->
@@ -36,19 +38,25 @@ suite() ->
{timetrap, {minutes, 1}}].
all() ->
- [framework_check, ei_accept_tmo, ei_connect_tmo,
- ei_send_tmo, ei_recv_tmo].
+ [framework_check,
+ ei_connect_unreachable_tmo,
+ ei_send_failure_tmo,
+ {group, default},
+ {group, ussi}].
+
+groups() ->
+ Members = [ei_recv_tmo,
+ ei_accept_tmo,
+ ei_connect_tmo,
+ ei_send_tmo],
+ [{default, [], Members},
+ {ussi, [], Members}].
+
+get_group(Config) ->
+ proplists:get_value(name, proplists:get_value(tc_group_properties,Config)).
init_per_testcase(Case, Config) ->
- Config1 = runner:init_per_testcase(?MODULE, Case, Config),
-
- % test if platform is vxworks_simso
- {_,Host} = split(node()),
- Bool = case atom_to_list(Host) of
- [$v,$x,$s,$i,$m | _] -> true;
- _ -> false
- end,
- [{vxsim,Bool} | Config1].
+ runner:init_per_testcase(?MODULE, Case, Config).
end_per_testcase(_Case, _Config) ->
ok.
@@ -76,7 +84,8 @@ do_one_recv(Config,CNode) ->
P1 = runner:start(Config, ?recv_tmo),
runner:send_term(P1,{CNode,
erlang:get_cookie(),
- node()}),
+ node(),
+ get_group(Config)}),
{term, X} = runner:get_term(P1, 10000),
true = is_integer(X),
CNode1 = join(CNode,Host),
@@ -89,24 +98,22 @@ do_one_recv_failure(Config,CNode) ->
P1 = runner:start(Config, ?recv_tmo),
runner:send_term(P1,{CNode,
erlang:get_cookie(),
- node()}),
+ node(),
+ get_group(Config)}),
{term, X} = runner:get_term(P1, 10000),
true = is_integer(X),
{term, {Ret,ETimedout,ETimedout}} = runner:get_term(P1, 10000),
true = (Ret < 0),
runner:recv_eot(P1).
+-define(EI_DIST_LOW, 5).
+-define(EI_DIST_HIGH, 6).
%% Check send with timeouts.
ei_send_tmo(Config) when is_list(Config) ->
- %dbg:tracer(),
- %dbg:p(self()),
- VxSim = proplists:get_value(vxsim, Config),
register(ei_send_tmo_1,self()),
do_one_send(Config,self(),c_node_send_tmo_1),
do_one_send(Config,ei_send_tmo_1,c_node_send_tmo_2),
- do_one_send_failure(Config,self(),cccc1,c_nod_send_tmo_3,VxSim),
- do_one_send_failure(Config,ei_send_tmo_1,cccc2,c_nod_send_tmo_4,VxSim),
ok.
@@ -115,7 +122,8 @@ do_one_send(Config,From,CNode) ->
P1 = runner:start(Config, ?send_tmo),
runner:send_term(P1,{CNode,
erlang:get_cookie(),
- node()}),
+ node(),
+ get_group(Config)}),
{term, X} = runner:get_term(P1, 10000),
true = is_integer(X),
CNode1 = join(CNode,Host),
@@ -130,7 +138,17 @@ do_one_send(Config,From,CNode) ->
{term, 0} = runner:get_term(P1, 10000),
runner:recv_eot(P1).
-do_one_send_failure(Config,From,FakeName,CName,VxSim) ->
+ei_send_failure_tmo(Config) when is_list(Config) ->
+ register(ei_send_tmo_1,self()),
+ [begin
+ io:format("Test dist version ~p\n", [Ver]),
+ do_one_send_failure(Config,self(),cccc1,c_nod_send_tmo_3, Ver),
+ do_one_send_failure(Config,ei_send_tmo_1,cccc2,c_nod_send_tmo_4, Ver)
+ end
+ || Ver <- lists:seq(?EI_DIST_LOW, ?EI_DIST_HIGH)],
+ ok.
+
+do_one_send_failure(Config,From,FakeName,CName, OurVer) ->
{_,Host} = split(node()),
OurName = join(FakeName,Host),
Node = join(CName,Host),
@@ -140,22 +158,23 @@ do_one_send_failure(Config,From,FakeName,CName,VxSim) ->
Else ->
exit(Else)
end,
- EpmdSocket = register(OurName, LSocket, 1, 5),
+ EpmdSocket = epmd_register(OurName, LSocket, OurVer),
P3 = runner:start(Config, ?send_tmo),
Cookie = kaksmula_som_ingen_bryr_sig_om,
runner:send_term(P3,{CName,
Cookie,
- OurName}),
+ OurName,
+ default}),
SocketB = case gen_tcp:accept(LSocket) of
{ok, Socket1} ->
Socket1;
Else2 ->
exit(Else2)
end,
- {hidden,Node,5} = recv_name(SocketB), % See 1)
+ {hidden,Node} = recv_name(SocketB, OurVer), % See 1)
send_status(SocketB, ok),
MyChallengeB = gen_challenge(),
- send_challenge(SocketB, OurName, MyChallengeB, 5),
+ send_challenge(SocketB, OurName, MyChallengeB, OurVer),
HisChallengeB = recv_challenge_reply(SocketB,
MyChallengeB,
Cookie),
@@ -178,53 +197,43 @@ do_one_send_failure(Config,From,FakeName,CName,VxSim) ->
%% must be large enough so there's time for the select() to time out and
%% the test program to return the error tuple (below).
- Res0 = if VxSim == false ->
- {term,{Res,ETO,Iters,ETO}} = runner:get_term(P3, 20000),
- Res;
- true -> % relax the test for vxsim
- case runner:get_term(P3, 20000) of
- {term,{Res,ETO,Iters,ETO}} ->
- Res;
- {term,{Res,_,Iters,_ETO}} -> % EIO?
- Res
- end
- end,
+ {term,{Res,ETO,Iters,ETO}} = runner:get_term(P3, 20000),
runner:recv_eot(P3),
- true = ((Res0 < 0) and (Iters > 0)),
+ true = ((Res < 0) and (Iters > 0)),
gen_tcp:close(SocketB),
gen_tcp:close(EpmdSocket),
ok.
%% Check accept with timeouts.
-ei_connect_tmo() -> [{require, test_host_not_reachable}].
+ei_connect_unreachable_tmo() -> [{require, test_host_not_reachable}].
-ei_connect_tmo(Config) when is_list(Config) ->
- %dbg:tracer(),
- %dbg:p(self()),
- VxSim = proplists:get_value(vxsim, Config),
+ei_connect_unreachable_tmo(Config) when is_list(Config) ->
DummyNode = make_and_check_dummy(),
P = runner:start(Config, ?connect_tmo),
runner:send_term(P,{c_nod_connect_tmo_1,
kaksmula_som_ingen_bryr_sig_om,
- DummyNode}),
- ETimedout =
- if VxSim == false ->
- {term,{-3,ETO,ETO}} = runner:get_term(P, 10000),
- ETO;
- true -> % relax the test for vxsim
- case runner:get_term(P, 10000) of
- {term,{-3,ETO,ETO}} ->
- ETO;
- {term,{-1,_,ETO}} -> % EHOSTUNREACH = ok
- ETO
- end
- end,
+ DummyNode,
+ default}),
+ {term,{-3,ETimedout,ETimedout}} = runner:get_term(P, 10000),
runner:recv_eot(P),
+ ok.
+
+ei_connect_tmo(Config) when is_list(Config) ->
+ [begin
+ io:format("Test dist version ~p published as ~p\n", [OurVer,OurEpmdVer]),
+ do_ei_connect_tmo(Config, OurVer, OurEpmdVer)
+ end
+ || OurVer <- lists:seq(?EI_DIST_LOW, ?EI_DIST_HIGH),
+ OurEpmdVer <- lists:seq(?EI_DIST_LOW, ?EI_DIST_HIGH),
+ OurVer >= OurEpmdVer].
+
+do_ei_connect_tmo(Config, OurVer, OurEpmdVer) ->
P2 = runner:start(Config, ?connect_tmo),
runner:send_term(P2,{c_nod_connect_tmo_2,
erlang:get_cookie(),
- node()}),
+ node(),
+ get_group(Config)}),
{term, X} = runner:get_term(P2, 10000),
runner:recv_eot(P2),
true = is_integer(X),
@@ -238,22 +247,24 @@ ei_connect_tmo(Config) when is_list(Config) ->
Else ->
exit(Else)
end,
- EpmdSocket = register(OurName, LSocket, 1, 5),
+ EpmdSocket = epmd_register(OurName, LSocket, OurEpmdVer),
P3 = runner:start(Config, ?connect_tmo),
Cookie = kaksmula_som_ingen_bryr_sig_om,
runner:send_term(P3,{c_nod_connect_tmo_3,
Cookie,
- OurName}),
+ OurName,
+ get_group(Config)}),
SocketB = case gen_tcp:accept(LSocket) of
{ok, Socket1} ->
Socket1;
Else2 ->
exit(Else2)
end,
- {hidden,Node,5} = recv_name(SocketB), % See 1)
+ {hidden,Node} = recv_name(SocketB, OurEpmdVer), % See 1)
send_status(SocketB, ok),
MyChallengeB = gen_challenge(),
- send_challenge(SocketB, OurName, MyChallengeB, 5),
+ send_challenge(SocketB, OurName, MyChallengeB, OurVer),
+ recv_complement(SocketB, OurVer, OurEpmdVer),
_HisChallengeB = recv_challenge_reply(SocketB,
MyChallengeB,
Cookie),
@@ -266,16 +277,27 @@ ei_connect_tmo(Config) when is_list(Config) ->
%% Check accept with timeouts.
ei_accept_tmo(Config) when is_list(Config) ->
- %%dbg:tracer(),
- %%dbg:p(self()),
+ [begin
+ io:format("Test our dist ver=~p and assumed ver=~p\n",
+ [OurVer, AssumedVer]),
+ do_ei_accept_tmo(Config, OurVer, AssumedVer)
+ end
+ || OurVer <- lists:seq(?EI_DIST_LOW, ?EI_DIST_HIGH),
+ AssumedVer <- lists:seq(?EI_DIST_LOW, ?EI_DIST_HIGH),
+ OurVer >= AssumedVer],
+ ok.
+
+do_ei_accept_tmo(Config, OurVer, AssumedVer) ->
P = runner:start(Config, ?accept_tmo),
runner:send_term(P,{c_nod_som_ingen_kontaktar_1,
- kaksmula_som_ingen_bryr_sig_om}),
+ kaksmula_som_ingen_bryr_sig_om,
+ get_group(Config)}),
{term,{-1,ETimedout,ETimedout}} = runner:get_term(P, 10000),
runner:recv_eot(P),
P2 = runner:start(Config, ?accept_tmo),
runner:send_term(P2,{c_nod_som_vi_kontaktar_1,
- erlang:get_cookie()}),
+ erlang:get_cookie(),
+ get_group(Config)}),
receive after 1000 -> ok end,
CNode1 = make_node(c_nod_som_vi_kontaktar_1),
{ignored,CNode1} ! tjenare,
@@ -284,19 +306,20 @@ ei_accept_tmo(Config) when is_list(Config) ->
true = is_integer(X),
P3 = runner:start(Config, ?accept_tmo),
runner:send_term(P3,{c_nod_som_vi_kontaktar_2,
- erlang:get_cookie()}),
+ erlang:get_cookie(),
+ get_group(Config)}),
receive after 1000 -> ok end,
CNode2 = make_node(c_nod_som_vi_kontaktar_2),
{NA,NB} = split(CNode2),
{_,Host} = split(node()),
OurName = join(ccc,Host),
- {port,PortNo,_} = erl_epmd:port_please(NA,NB),
+ {port,PortNo,?EI_DIST_HIGH} = erl_epmd:port_please(NA,NB),
{ok, SocketA} = gen_tcp:connect(atom_to_list(NB),PortNo,
[{active,false},
{packet,2}]),
- send_name(SocketA,OurName,5),
+ send_name(SocketA,OurName,OurVer,AssumedVer),
ok = recv_status(SocketA),
- {hidden,_Node,5,HisChallengeA} = recv_challenge(SocketA), % See 1)
+ {hidden,_Node,HisChallengeA} = recv_challenge(SocketA,OurVer), % See 1)
_OurChallengeA = gen_challenge(),
_OurDigestA = gen_digest(HisChallengeA, erlang:get_cookie()),
%% Dont do the last two steps of the connection setup...
@@ -342,6 +365,7 @@ make_and_check_dummy() ->
-define(DFLAG_EXTENDED_PIDS_PORTS,16#100).
-define(DFLAG_NEW_FLOATS,16#800).
-define(DFLAG_DIST_MONITOR,8).
+-define(DFLAG_HANDSHAKE_23,16#1000000).
%% From R9 and forward extended references is compulsory
%% From 14 and forward new float is compulsory
@@ -405,31 +429,61 @@ recv_status(Socket) ->
exit(Bad)
end.
-send_challenge(Socket, Node, Challenge, Version) ->
- send_challenge(Socket, Node, Challenge, Version, ?COMPULSORY_DFLAGS).
-send_challenge(Socket, Node, Challenge, Version, Flags) ->
- {ok, {{_Ip1,_Ip2,_Ip3,_Ip4}, _}} = inet:sockname(Socket),
- ?to_port(Socket, [$n,?int16(Version),?int32(Flags),
- ?int32(Challenge), atom_to_list(Node)]).
-
-recv_challenge(Socket) ->
+send_challenge(Socket, Node, Challenge, OurVer) ->
+ send_challenge(Socket, Node, Challenge, OurVer, ?COMPULSORY_DFLAGS).
+
+send_challenge(Socket, Node, Challenge, OurVer, Flags) ->
+ if OurVer =:= 5 ->
+ ?to_port(Socket, [$n, ?int16(OurVer), ?int32(Flags),
+ ?int32(Challenge), atom_to_list(Node)]);
+ OurVer >= 6 ->
+ NodeName = atom_to_binary(Node, latin1),
+ NameLen = byte_size(NodeName),
+ Creation = erts_internal:get_creation(),
+ ?to_port(Socket, [$N,
+ <<(Flags bor ?DFLAG_HANDSHAKE_23):64,
+ Challenge:32,
+ Creation:32,
+ NameLen:16>>,
+ NodeName])
+ end.
+
+recv_challenge(Socket, OurVer) ->
case gen_tcp:recv(Socket, 0) of
{ok,[$n,V1,V0,Fl1,Fl2,Fl3,Fl4,CA3,CA2,CA1,CA0 | Ns]} ->
+ 5 = OurVer,
Flags = ?u32(Fl1,Fl2,Fl3,Fl4),
- Type = case Flags band ?DFLAG_PUBLISHED of
- 0 ->
- hidden;
- _ ->
- normal
- end,
+ Type = flags_to_type(Flags),
Node =list_to_atom(Ns),
- Version = ?u16(V1,V0),
+ OurVer = ?u16(V1,V0), % echoed back
+ Challenge = ?u32(CA3,CA2,CA1,CA0),
+ {Type,Node,Challenge};
+
+ {ok,[$N, F7,F6,F5,F4,F3,F2,F1,F0, CA3,CA2,CA1,CA0,
+ _Cr3,_Cr2,_Cr1,_Cr0, NL1,NL0 | Rest]} ->
+ true = (OurVer >= 6),
+ <<Flags:64>> = <<F7,F6,F5,F4,F3,F2,F1,F0>>,
+ Type = flags_to_type(Flags),
+ NameLen = ?u16(NL1,NL0),
+ {NodeName,_} = lists:split(NameLen, Rest),
+ Node = list_to_atom(NodeName),
Challenge = ?u32(CA3,CA2,CA1,CA0),
- {Type,Node,Version,Challenge};
+ %%Creation = ?u32(Cr3,Cr2,Cr1,Cr0),
+ %%true = (Creation =/= 0),
+ {Type,Node,Challenge};
+
_ ->
?shutdown(no_node)
end.
+flags_to_type(Flags) ->
+ case Flags band ?DFLAG_PUBLISHED of
+ 0 ->
+ hidden;
+ _ ->
+ normal
+ end.
+
%send_challenge_reply(Socket, Challenge, Digest) ->
% ?to_port(Socket, [$r,?int32(Challenge),Digest]).
@@ -443,8 +497,8 @@ recv_challenge_reply(Socket, ChallengeA, Cookie) ->
true ->
?shutdown(bad_challenge_reply)
end;
- _ ->
- ?shutdown(no_node)
+ Other ->
+ ?shutdown({recv_challenge_reply,Other})
end.
send_challenge_ack(Socket, Digest) ->
@@ -463,37 +517,53 @@ send_challenge_ack(Socket, Digest) ->
% ?shutdown(bad_challenge_ack)
% end.
-send_name(Socket, MyNode0, Version) ->
- send_name(Socket, MyNode0, Version, ?COMPULSORY_DFLAGS).
-send_name(Socket, MyNode0, Version, Flags) ->
- MyNode = atom_to_list(MyNode0),
- ?to_port(Socket, [$n,?int16(Version),?int32(Flags)] ++
- MyNode).
+send_name(Socket, MyNode, OurVer, AssumedVer) ->
+ Flags = ?COMPULSORY_DFLAGS bor (case OurVer of
+ 5 -> 0;
+ 6 -> ?DFLAG_HANDSHAKE_23
+ end),
+ send_name(Socket, MyNode, OurVer, AssumedVer, Flags).
+
+send_name(Socket, MyNode, OurVer, AssumedVer, Flags) ->
+ NodeName = atom_to_binary(MyNode, latin1),
+ if AssumedVer =:= 5 ->
+ ?to_port(Socket, [$n,?int16(OurVer),?int32(Flags),NodeName]);
+ AssumedVer >= 6 ->
+ Creation = erts_internal:get_creation(),
+ ?to_port(Socket, [$N,
+ <<Flags:64,
+ Creation:32,
+ (byte_size(NodeName)):16>>,
+ NodeName])
+ end.
-%%
-%% recv_name is common for both old and new handshake.
-%%
-recv_name(Socket) ->
+recv_name(Socket, OurEpmdVer) ->
case gen_tcp:recv(Socket, 0) of
- {ok,Data} ->
- get_name(Data);
+ {ok,[$n, V1,V0, F3,F2,F1,F0 | OtherNode]} ->
+ 5 = OurEpmdVer,
+ 5 = ?u16(V1,V0),
+ Type = flags_to_type(?u32(F3,F2,F1,F0)),
+ {Type, list_to_atom(OtherNode)};
+ {ok,[$N, F7,F6,F5,F4,F3,F2,F1,F0, _Cr3,_Cr2,_Cr1,_Cr0, NL1, NL0 | Rest]} ->
+ true = (OurEpmdVer >= 6),
+ {OtherNode, _Residue} = lists:split(?u16(NL1,NL0), Rest),
+ <<Flags:64>> = <<F7,F6,F5,F4,F3,F2,F1,F0>>,
+ Type = flags_to_type(Flags),
+ {Type, list_to_atom(OtherNode)};
Res ->
?shutdown({no_node,Res})
end.
-get_name([$m,VersionA,VersionB,_Ip1,_Ip2,_Ip3,_Ip4|OtherNode]) ->
- {normal, list_to_atom(OtherNode), ?u16(VersionA,VersionB)};
-get_name([$h,VersionA,VersionB,_Ip1,_Ip2,_Ip3,_Ip4|OtherNode]) ->
- {hidden, list_to_atom(OtherNode), ?u16(VersionA,VersionB)};
-get_name([$n,VersionA, VersionB, Flag1, Flag2, Flag3, Flag4 | OtherNode]) ->
- Type = case ?u32(Flag1, Flag2, Flag3, Flag4) band ?DFLAG_PUBLISHED of
- 0 -> hidden;
- _ -> normal
- end,
- {Type, list_to_atom(OtherNode),
- ?u16(VersionA,VersionB)};
-get_name(Data) ->
- ?shutdown(Data).
+recv_complement(Socket, OurVer, 5) when OurVer > 5 ->
+ case gen_tcp:recv(Socket, 0) of
+ {ok,[$c, _F7,_F6,_F5,_F4, _Cr3,_Cr2,_Cr1,_Cr0]} ->
+ ok;
+ Res ->
+ ?shutdown({no_node,Res})
+ end;
+recv_complement(_, _OurVer, _OurEpmdVer) ->
+ ok.
+
%%
%% tell_name is for old handshake
@@ -538,13 +608,10 @@ wait_for_reg_reply(Socket, SoFar) ->
receive
{tcp, Socket, Data0} ->
case SoFar ++ Data0 of
- [$y, Result, A, B] ->
- case Result of
- 0 ->
- {alive, Socket, ?u16(A, B)};
- _ ->
- {error, duplicate_name}
- end;
+ [$y, 0, Cr1,Cr0] ->
+ {alive, Socket, ?u16(Cr1,Cr0)};
+ [$v, 0, Cr3,Cr2,Cr1,Cr0] ->
+ {alive, Socket, ?u32(Cr3,Cr2,Cr1,Cr0)};
Data when length(Data) < 4 ->
wait_for_reg_reply(Socket, Data);
Garbage ->
@@ -558,9 +625,9 @@ wait_for_reg_reply(Socket, SoFar) ->
end.
-register(NodeName, ListenSocket, VLow, VHigh) ->
+epmd_register(NodeName, ListenSocket, OurVer) ->
{ok,{_,TcpPort}} = inet:sockname(ListenSocket),
- case do_register_node(NodeName, TcpPort, VLow, VHigh) of
+ case do_register_node(NodeName, TcpPort, ?EI_DIST_LOW, OurVer) of
{alive, Socket, _Creation} ->
Socket;
Other ->
diff --git a/lib/erl_interface/test/ei_tmo_SUITE_data/Makefile.src b/lib/erl_interface/test/ei_tmo_SUITE_data/Makefile.src
index b4ee361939..378e276524 100644
--- a/lib/erl_interface/test/ei_tmo_SUITE_data/Makefile.src
+++ b/lib/erl_interface/test/ei_tmo_SUITE_data/Makefile.src
@@ -25,7 +25,8 @@ CC = ..@DS@all_SUITE_data@DS@gccifier@exe@ -CC"$(CC0)"
LD = @LD@
LIBEI = @erl_interface_eilib@
LIBFLAGS = ../all_SUITE_data/ei_runner@obj@ \
- $(LIBEI) @LIBS@ @erl_interface_sock_libs@ \
+ ../all_SUITE_data/my_ussi@obj@ \
+ $(LIBEI) @LIBS@ @erl_interface_sock_libs@ \
@erl_interface_threadlib@
CFLAGS = @EI_CFLAGS@ $(THR_DEFS) -I@erl_interface_include@ -I../all_SUITE_data
EI_TMO_OBJS = ei_tmo_test@obj@ ei_tmo_test_decl@obj@
diff --git a/lib/erl_interface/test/ei_tmo_SUITE_data/ei_tmo_test.c b/lib/erl_interface/test/ei_tmo_SUITE_data/ei_tmo_test.c
index 693e405f75..3c20e94c02 100644
--- a/lib/erl_interface/test/ei_tmo_SUITE_data/ei_tmo_test.c
+++ b/lib/erl_interface/test/ei_tmo_SUITE_data/ei_tmo_test.c
@@ -21,9 +21,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#ifdef VXWORKS
-#include "reclaim.h"
-#endif
#ifdef __WIN32__
#include <winsock2.h>
@@ -35,6 +32,7 @@
#endif
#include "ei_runner.h"
+#include "my_ussi.h"
#ifndef __WIN32__
#define closesocket(X) close(X)
@@ -67,7 +65,7 @@ static void debugf_open(int number)
{
char filename[1024];
sprintf(filename,"ei_tmo_test%d.debug",number);
-#if !defined(VXWORKS) && !defined(__WIN32__)
+#if !defined(__WIN32__)
close(2);
#endif
debugfile = fopen(filename,"a");
@@ -86,6 +84,7 @@ static void debugf_close(void)
#define DEBUGF(X) /* noop */
#endif
+
TESTCASE(framework_check)
{
char *ptr = NULL;
@@ -128,19 +127,26 @@ TESTCASE(framework_check)
report(1);
}
-int decode_request(char **nodename_p, char **cookie_p, char **peername_p)
+int decode_request(char **nodename_p, char **cookie_p, char **peername_p,
+ int *use_ussi_p)
{
char *nodename = NULL;
char *cookie = NULL;
char *peername = NULL;
+ char socket_impl[10];
char *ptr = NULL;
ei_x_buff x;
int len;
int version;
int type;
int size;
- int expected_size = (peername_p == NULL) ? 2 : 3;
+ int expected_size = 2;
int ret = -1;
+
+ if (peername_p)
+ ++expected_size;
+ if (use_ussi_p)
+ ++expected_size;
ptr = read_packet(&len);
ei_x_new(&x);
@@ -180,7 +186,6 @@ int decode_request(char **nodename_p, char **cookie_p, char **peername_p)
}
nodename = malloc(size+1);
ei_decode_atom(x.buff,&len,nodename);
- nodename[size] = '\0'; /* needed????? */
if (ei_get_type(x.buff,&len,&type,&size) != 0) {
DEBUGF(("Failure at line %d\n",__LINE__));
goto cleanup;
@@ -191,8 +196,7 @@ int decode_request(char **nodename_p, char **cookie_p, char **peername_p)
}
cookie = malloc(size + 1);
ei_decode_atom(x.buff,&len,cookie);
- cookie[size] = '\0'; /* needed????? */
- if (expected_size > 2) {
+ if (peername_p) {
if (ei_get_type(x.buff,&len,&type,&size) != 0) {
DEBUGF(("Failure at line %d\n",__LINE__));
goto cleanup;
@@ -212,6 +216,22 @@ int decode_request(char **nodename_p, char **cookie_p, char **peername_p)
DEBUGF(("nodename = %s, cookie = %s\n",
nodename, cookie));
}
+
+ if (use_ussi_p) {
+ if (ei_decode_atom_as(x.buff,&len,socket_impl,sizeof(socket_impl),
+ ERLANG_ASCII, NULL, NULL)) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+ if (strcmp(socket_impl,"default") == 0)
+ *use_ussi_p = 0;
+ else if (strcmp(socket_impl,"ussi") == 0)
+ *use_ussi_p = 1;
+ else {
+ DEBUGF(("Unkown socket_impl '%s' at %d\n",socket_impl,__LINE__));
+ goto cleanup;
+ }
+ }
*nodename_p = nodename;
nodename = NULL;
*cookie_p = cookie;
@@ -339,6 +359,7 @@ TESTCASE(recv_tmo)
char *nodename = NULL;
char *cookie = NULL;
char *peername = NULL;
+ int use_ussi;
int com_sock = -1;
ei_cnode nodeinfo;
@@ -346,12 +367,22 @@ TESTCASE(recv_tmo)
OPEN_DEBUGFILE(5);
- if (decode_request(&nodename,&cookie,&peername) != 0) {
+ if (decode_request(&nodename,&cookie,&peername,&use_ussi) != 0) {
goto cleanup;
}
- if (ei_connect_init(&nodeinfo, nodename, cookie, 0) < 0) {
- DEBUGF(("Failure at line %d\n",__LINE__));
- goto cleanup;
+ if (use_ussi) {
+ my_ussi_init();
+ if (ei_connect_init_ussi(&nodeinfo, nodename, cookie, 0,
+ &my_ussi, sizeof(my_ussi), NULL) < 0) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+ }
+ else {
+ if (ei_connect_init(&nodeinfo, nodename, cookie, 0) < 0) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
}
if ((com_sock = ei_connect_tmo(&nodeinfo, peername, 5000)) < 0) {
@@ -451,18 +482,29 @@ TESTCASE(send_tmo)
char *cookie = NULL;
char *peername = NULL;
int com_sock = -1;
+ int use_ussi;
ei_cnode nodeinfo;
ei_init();
OPEN_DEBUGFILE(4);
- if (decode_request(&nodename,&cookie,&peername) != 0) {
+ if (decode_request(&nodename,&cookie,&peername,&use_ussi) != 0) {
goto cleanup;
}
- if (ei_connect_init(&nodeinfo, nodename, cookie, 0) < 0) {
- DEBUGF(("Failure at line %d\n",__LINE__));
- goto cleanup;
+ if (use_ussi) {
+ my_ussi_init();
+ if (ei_connect_init_ussi(&nodeinfo, nodename, cookie, 0,
+ &my_ussi, sizeof(my_ussi), NULL) < 0) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+ }
+ else {
+ if (ei_connect_init(&nodeinfo, nodename, cookie, 0) < 0) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
}
if ((com_sock = ei_connect_tmo(&nodeinfo, peername, 5000)) < 0) {
@@ -593,18 +635,29 @@ TESTCASE(connect_tmo)
char *cookie = NULL;
char *peername = NULL;
int com_sock = -1;
+ int use_ussi;
ei_cnode nodeinfo;
ei_init();
OPEN_DEBUGFILE(3);
- if (decode_request(&nodename,&cookie,&peername) != 0) {
+ if (decode_request(&nodename,&cookie,&peername,&use_ussi) != 0) {
goto cleanup;
}
- if (ei_connect_init(&nodeinfo, nodename, cookie, 0) < 0) {
- DEBUGF(("Failure at line %d\n",__LINE__));
- goto cleanup;
+ if (use_ussi) {
+ my_ussi_init();
+ if (ei_connect_init_ussi(&nodeinfo, nodename, cookie, 0,
+ &my_ussi, sizeof(my_ussi), NULL) < 0) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+ }
+ else {
+ if (ei_connect_init(&nodeinfo, nodename, cookie, 0) < 0) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
}
if ((com_sock = ei_connect_tmo(&nodeinfo, peername, 5000)) < 0) {
@@ -679,10 +732,12 @@ TESTCASE(accept_tmo)
int listen_sock = -1;
int epmd_sock = -1;
int com_sock = -1;
+ int use_ussi;
struct sockaddr_in sin;
int sin_siz = sizeof(sin);
ErlConnect peer;
ei_cnode nodeinfo;
+ int port_no;
ei_init();
@@ -690,38 +745,55 @@ TESTCASE(accept_tmo)
putenv("EI_TRACELEVEL=10");
- if (decode_request(&nodename,&cookie,NULL) != 0) {
- goto cleanup;
- }
- if (ei_connect_init(&nodeinfo, nodename, cookie, 0) < 0) {
- DEBUGF(("Failure at line %d\n",__LINE__));
+ if (decode_request(&nodename,&cookie,NULL,&use_ussi) != 0) {
goto cleanup;
}
+ if (use_ussi) {
+ my_ussi_init();
+ if (ei_connect_init_ussi(&nodeinfo, nodename, cookie, 0,
+ &my_ussi, sizeof(my_ussi), NULL) < 0) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+ port_no = 0;
+ listen_sock = ei_listen(&nodeinfo, &port_no, 5);
+ if (listen_sock == ERL_ERROR) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+ }
+ else {
+ if (ei_connect_init(&nodeinfo, nodename, cookie, 0) < 0) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
- if ((listen_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- DEBUGF(("Failure at line %d\n",__LINE__));
- goto cleanup;
- }
- memset(&sin, 0, sizeof(sin));
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = INADDR_ANY;
-
- if (bind(listen_sock,(struct sockaddr *) &sin, sizeof(sin)) != 0) {
- DEBUGF(("Failure at line %d\n",__LINE__));
- goto cleanup;
- }
- if (getsockname(listen_sock,
- (struct sockaddr *) &sin, &sin_siz) != 0) {
- DEBUGF(("Failure at line %d\n",__LINE__));
- goto cleanup;
- }
- if (listen(listen_sock, 5) != 0) {
- DEBUGF(("Failure at line %d\n",__LINE__));
- goto cleanup;
- }
-
- if ((epmd_sock = ei_publish(&nodeinfo, ntohs(sin.sin_port))) < 0) {
- DEBUGF(("Failure at line %d[%d,%d]\n",__LINE__,sin.sin_port,erl_errno));
+ if ((listen_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = INADDR_ANY;
+
+ if (bind(listen_sock,(struct sockaddr *) &sin, sizeof(sin)) != 0) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+ if (getsockname(listen_sock,
+ (struct sockaddr *) &sin, &sin_siz) != 0) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+ if (listen(listen_sock, 5) != 0) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+ port_no = ntohs(sin.sin_port);
+ }
+
+ if ((epmd_sock = ei_publish(&nodeinfo, port_no)) < 0) {
+ DEBUGF(("Failure at line %d[%d,%d]\n",__LINE__,port_no,erl_errno));
goto cleanup;
}
diff --git a/lib/erl_interface/test/erl_call_SUITE.erl b/lib/erl_interface/test/erl_call_SUITE.erl
index 9e2b2e4251..0d95a1361b 100644
--- a/lib/erl_interface/test/erl_call_SUITE.erl
+++ b/lib/erl_interface/test/erl_call_SUITE.erl
@@ -23,42 +23,88 @@
-include_lib("common_test/include/ct.hrl").
--export([all/0, smoke/1]).
+-export([all/0, smoke/1, test_connect_to_host_port/1]).
-all() ->
- [smoke].
+all() ->
+ [smoke,
+ test_connect_to_host_port].
smoke(Config) when is_list(Config) ->
- ErlCall = find_erl_call(),
- NameSwitch = case net_kernel:longnames() of
- true ->
- "-name";
- false ->
- "-sname"
- end,
Name = atom_to_list(?MODULE)
++ "-"
++ integer_to_list(erlang:system_time(microsecond)),
- ArgsList = ["-s", "-a", "erlang node", NameSwitch, Name],
- io:format("erl_call: \"~ts\"\n~nargs list: ~p~n", [ErlCall, ArgsList]),
- CmdRes = get_smoke_port_res(open_port({spawn_executable, ErlCall},
- [{args, ArgsList}, eof]), []),
- io:format("CmdRes: ~p~n", [CmdRes]),
+ RetNodeName = start_node_and_get_node_name(Name),
+
+ halt_node(Name),
[_, Hostname] = string:lexemes(atom_to_list(node()), "@"),
NodeName = list_to_atom(Name ++ "@" ++ Hostname),
- io:format("NodeName: ~p~n~n", [NodeName]),
+ NodeName = list_to_atom(RetNodeName),
+ ok.
- pong = net_adm:ping(NodeName),
- rpc:cast(NodeName, erlang, halt, []),
- NodeName = list_to_atom(string:trim(CmdRes, both, "'")),
+
+test_connect_to_host_port(Config) when is_list(Config) ->
+ Name = atom_to_list(?MODULE)
+ ++ "-"
+ ++ integer_to_list(erlang:system_time(microsecond)),
+ Port = start_node_and_get_port(Name),
+ AddressCaller =
+ fun(Address) ->
+ get_erl_call_result(["-address",
+ Address,
+ "-a",
+ "erlang length [[1,2,3,4,5,6,7,8,9]]"])
+ end,
+ "9" = AddressCaller(erlang:integer_to_list(Port)),
+ "9" = AddressCaller(":" ++ erlang:integer_to_list(Port)),
+ [_, Hostname] = string:lexemes(atom_to_list(node()), "@"),
+ "9" = AddressCaller(Hostname ++ ":" ++ erlang:integer_to_list(Port)),
+ FailedRes = AddressCaller("80"),
+ case string:find(FailedRes, "80") of
+ nomatch -> ct:fail("Incorrect error message");
+ _ -> ok
+ end,
+ halt_node(Name),
ok.
%
% Utility functions...
%
+
+halt_node(Name) ->
+ [_, Hostname] = string:lexemes(atom_to_list(node()), "@"),
+ NodeName = list_to_atom(Name ++ "@" ++ Hostname),
+ io:format("NodeName: ~p~n~n", [NodeName]),
+
+ pong = net_adm:ping(NodeName),
+ rpc:cast(NodeName, erlang, halt, []).
+
+start_node_and_get_node_name(Name) ->
+ NameSwitch = case net_kernel:longnames() of
+ true ->
+ "-name";
+ false ->
+ "-sname"
+ end,
+ string:trim(get_erl_call_result(["-s",
+ NameSwitch,
+ Name, "-a",
+ "erlang node"]),
+ both,
+ "'").
+
+start_node_and_get_port(Name) ->
+ start_node_and_get_node_name(Name),
+ {ok, NamePortList} = net_adm:names(),
+ {value, {_, Port}}
+ = lists:search(fun({N, _}) ->
+ string:equal(N, Name)
+ end,
+ NamePortList),
+ Port.
+
find_erl_call() ->
ErlCallName = case os:type() of
{win32, _} -> "erl_call.exe";
@@ -86,10 +132,19 @@ find_erl_call() ->
ErlCall
end.
-get_smoke_port_res(Port, Acc) when is_port(Port) ->
+
+get_erl_call_result(ArgsList) ->
+ ErlCall = find_erl_call(),
+ io:format("erl_call: \"~ts\"\n~nargs list: ~p~n", [ErlCall, ArgsList]),
+ CmdRes = get_port_res(open_port({spawn_executable, ErlCall},
+ [{args, ArgsList}, eof, stderr_to_stdout]), []),
+ io:format("CmdRes: ~p~n", [CmdRes]),
+ CmdRes.
+
+get_port_res(Port, Acc) when is_port(Port) ->
receive
{Port, {data, Data}} ->
- get_smoke_port_res(Port, [Acc|Data]);
+ get_port_res(Port, [Acc|Data]);
{Port, eof} ->
lists:flatten(Acc)
end.
diff --git a/lib/erl_interface/test/erl_connect_SUITE.erl b/lib/erl_interface/test/erl_connect_SUITE.erl
deleted file mode 100644
index 782691b8fb..0000000000
--- a/lib/erl_interface/test/erl_connect_SUITE.erl
+++ /dev/null
@@ -1,131 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2000-2018. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
--module(erl_connect_SUITE).
-
--include_lib("common_test/include/ct.hrl").
--include("erl_connect_SUITE_data/erl_connect_test_cases.hrl").
-
--export([all/0, suite/0,
- init_per_testcase/2,
- erl_send/1, erl_reg_send/1,
- erl_send_cookie_file/1]).
-
--import(runner, [get_term/1,send_term/2]).
-
-suite() ->
- [{ct_hooks,[ts_install_cth]},
- {timetrap, {seconds, 30}}].
-
-all() ->
- [erl_send, erl_reg_send, erl_send_cookie_file].
-
-
-init_per_testcase(Case, Config) ->
- runner:init_per_testcase(?MODULE, Case, Config).
-
-erl_send(Config) when is_list(Config) ->
- P = runner:start(Config, ?interpret),
- 1 = erl_connect_init(P, 42, erlang:get_cookie(), 0),
- {ok,Fd} = erl_connect(P, node()),
-
- ok = erl_send(P, Fd, self(), AMsg={a,message}),
- receive AMsg -> ok end,
-
- 0 = erl_close_connection(P,Fd),
- runner:send_eot(P),
- runner:recv_eot(P),
- ok.
-
-erl_send_cookie_file(Config) when is_list(Config) ->
- case os:type() of
- vxworks ->
- {skip,"Skipped on VxWorks"};
- _ ->
- P = runner:start(Config, ?interpret),
- 1 = erl_connect_init(P, 42, '', 0),
- {ok,Fd} = erl_connect(P, node()),
-
- ok = erl_send(P, Fd, self(), AMsg={a,message}),
- receive AMsg -> ok end,
-
- 0 = erl_close_connection(P,Fd),
- runner:send_eot(P),
- runner:recv_eot(P),
- ok
- end.
-
-erl_reg_send(Config) when is_list(Config) ->
- P = runner:start(Config, ?interpret),
- 1 = erl_connect_init(P, 42, erlang:get_cookie(), 0),
- {ok,Fd} = erl_connect(P, node()),
-
- ARegName = a_strange_registred_name,
- register(ARegName, self()),
- ok = erl_reg_send(P, Fd, ARegName, AMsg={another,[strange],message}),
- receive AMsg -> ok end,
-
- 0 = erl_close_connection(P,Fd),
- runner:send_eot(P),
- runner:recv_eot(P),
- ok.
-
-
-%%% Interface functions for erl_interface functions.
-
-erl_connect_init(P, Num, Cookie, Creation) ->
- send_command(P, erl_connect_init, [Num,Cookie,Creation]),
- case get_term(P) of
- {term,Int} when is_integer(Int) -> Int
- end.
-
-erl_connect(P, Node) ->
- send_command(P, erl_connect, [Node]),
- case get_term(P) of
- {term,{Fd,_}} when Fd >= 0 -> {ok,Fd};
- {term,{-1,Errno}} -> {error,Errno}
- end.
-
-erl_close_connection(P, FD) ->
- send_command(P, erl_close_connection, [FD]),
- case get_term(P) of
- {term,Int} when is_integer(Int) -> Int
- end.
-
-erl_send(P, Fd, To, Msg) ->
- send_command(P, erl_send, [Fd,To,Msg]),
- get_send_result(P).
-
-erl_reg_send(P, Fd, To, Msg) ->
- send_command(P, erl_reg_send, [Fd,To,Msg]),
- get_send_result(P).
-
-get_send_result(P) ->
- case get_term(P) of
- {term,{1,_}} -> ok;
- {term,{-1,Errno}} -> {error,Errno};
- {term,{Res,Errno}}->
- io:format("Return value: ~p\nerl_errno: ~p", [Res,Errno]),
- ct:fail(bad_return_value)
- end.
-
-send_command(P, Name, Args) ->
- runner:send_term(P, {Name,list_to_tuple(Args)}).
diff --git a/lib/erl_interface/test/erl_connect_SUITE_data/Makefile.first b/lib/erl_interface/test/erl_connect_SUITE_data/Makefile.first
deleted file mode 100644
index 21a7aac0b0..0000000000
--- a/lib/erl_interface/test/erl_connect_SUITE_data/Makefile.first
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2001-2016. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# %CopyrightEnd%
-#
-
-erl_connect_test_decl.c: erl_connect_test.c
- erl -noinput -pa ../all_SUITE_data -s init_tc run erl_connect_test -s erlang halt
diff --git a/lib/erl_interface/test/erl_connect_SUITE_data/Makefile.src b/lib/erl_interface/test/erl_connect_SUITE_data/Makefile.src
deleted file mode 100644
index ff4c382c97..0000000000
--- a/lib/erl_interface/test/erl_connect_SUITE_data/Makefile.src
+++ /dev/null
@@ -1,41 +0,0 @@
-#
-# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2000-2016. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# %CopyrightEnd%
-#
-
-include @erl_interface_mk_include@
-
-CC0 = @CC@
-CC = ..@DS@all_SUITE_data@DS@gccifier@exe@ -CC"$(CC0)"
-LD = @LD@
-LIBERL = @erl_interface_lib@
-LIBEI = @erl_interface_eilib@
-LIBFLAGS = ../all_SUITE_data/runner@obj@ \
- $(LIBERL) $(LIBEI) @LIBS@ @erl_interface_sock_libs@ \
- @erl_interface_threadlib@
-CFLAGS = @EI_CFLAGS@ $(THR_DEFS) -I@erl_interface_include@ -I../all_SUITE_data
-OBJS = erl_connect_test@obj@ erl_connect_test_decl@obj@
-
-all: erl_connect_test@exe@
-
-erl_connect_test@exe@: $(OBJS) $(LIBERL) $(LIBEI)
- $(LD) @CROSSLDFLAGS@ -o $@ $(OBJS) $(LIBFLAGS)
-
-clean:
- $(RM) $(OBJS)
- $(RM) erl_connect_test@exe@
diff --git a/lib/erl_interface/test/erl_connect_SUITE_data/erl_connect_test.c b/lib/erl_interface/test/erl_connect_SUITE_data/erl_connect_test.c
deleted file mode 100644
index 0adaa79a33..0000000000
--- a/lib/erl_interface/test/erl_connect_SUITE_data/erl_connect_test.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 2000-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-
-/*
- * Purpose: Tests the functions in erl_connect.c.
- * Author: Bjorn Gustavsson
- *
- * See the erl_connect_SUITE.erl file for a "table of contents".
- */
-
-#include <stdio.h>
-#include <string.h>
-
-#include "runner.h"
-
-static void cmd_erl_connect_init(ETERM* args);
-static void cmd_erl_connect(ETERM* args);
-static void cmd_erl_send(ETERM* args);
-static void cmd_erl_reg_send(ETERM* args);
-static void cmd_erl_close_connection(ETERM *args);
-
-static void send_errno_result(int value);
-
-static struct {
- char* name;
- int num_args; /* Number of arguments. */
- void (*func)(ETERM* args);
-} commands[] = {
- "erl_connect_init", 3, cmd_erl_connect_init,
- "erl_connect", 1, cmd_erl_connect,
- "erl_close_connection", 1, cmd_erl_close_connection,
- "erl_send", 3, cmd_erl_send,
- "erl_reg_send", 3, cmd_erl_reg_send,
-};
-
-
-/*
- * Sends a list contaning all data types to the Erlang side.
- */
-
-TESTCASE(interpret)
-{
- ETERM* term;
-
- erl_init(NULL, 0);
-
- outer_loop:
-
- term = get_term();
-
- if (term == NULL) {
- report(1);
- return;
- } else {
- ETERM* Func;
- ETERM* Args;
- int i;
-
- if (!ERL_IS_TUPLE(term) || ERL_TUPLE_SIZE(term) != 2) {
- fail("term should be a tuple of size 2");
- }
-
- Func = erl_element(1, term);
- if (!ERL_IS_ATOM(Func)) {
- fail("function name should be an atom");
- }
- Args = erl_element(2, term);
- if (!ERL_IS_TUPLE(Args)) {
- fail("function arguments should be a tuple");
- }
- erl_free_term(term);
- for (i = 0; i < sizeof(commands)/sizeof(commands[0]); i++) {
- int n = strlen(commands[i].name);
- if (ERL_ATOM_SIZE(Func) != n) {
- continue;
- }
- if (memcmp(ERL_ATOM_PTR(Func), commands[i].name, n) == 0) {
- erl_free_term(Func);
- if (ERL_TUPLE_SIZE(Args) != commands[i].num_args) {
- fail("wrong number of arguments");
- }
- commands[i].func(Args);
- erl_free_term(Args);
- goto outer_loop;
- }
- }
- fail("bad command");
- }
-}
-
-#define VERIFY_TYPE(Test, Term) \
-if (!Test(Term)) { \
- fail("wrong type for " #Term); \
-} else { \
-}
-
-static void
-cmd_erl_connect_init(ETERM* args)
-{
- ETERM* number;
- ETERM* res;
- ETERM* cookie;
- char cookie_buffer[256];
-
- number = ERL_TUPLE_ELEMENT(args, 0);
- VERIFY_TYPE(ERL_IS_INTEGER, number);
- cookie = ERL_TUPLE_ELEMENT(args, 1);
- VERIFY_TYPE(ERL_IS_ATOM, cookie);
- if (ERL_ATOM_SIZE(cookie) == 0) {
- res = erl_mk_int(erl_connect_init(ERL_INT_VALUE(number), 0, 0));
- } else {
- memcpy(cookie_buffer, ERL_ATOM_PTR(cookie), ERL_ATOM_SIZE(cookie));
- cookie_buffer[ERL_ATOM_SIZE(cookie)] = '\0';
- res = erl_mk_int(erl_connect_init(ERL_INT_VALUE(number),
- cookie_buffer, 0));
- }
- send_term(res);
- erl_free_term(res);
-}
-
-static void
-cmd_erl_connect(ETERM* args)
-{
- ETERM* node;
- char node_buffer[256];
-
- node = ERL_TUPLE_ELEMENT(args, 0);
- VERIFY_TYPE(ERL_IS_ATOM, node);
- memcpy(node_buffer, ERL_ATOM_PTR(node), ERL_ATOM_SIZE(node));
- node_buffer[ERL_ATOM_SIZE(node)] = '\0';
- send_errno_result(erl_connect(node_buffer));
-}
-
-static void
-cmd_erl_close_connection(ETERM* args)
-{
- ETERM* number;
- ETERM* res;
-
- number = ERL_TUPLE_ELEMENT(args, 0);
- VERIFY_TYPE(ERL_IS_INTEGER, number);
- res = erl_mk_int(erl_close_connection(ERL_INT_VALUE(number)));
- send_term(res);
- erl_free_term(res);
-}
-
-static void
-cmd_erl_send(ETERM* args)
-{
- ETERM* fd_term = ERL_TUPLE_ELEMENT(args, 0);
- ETERM* to = ERL_TUPLE_ELEMENT(args, 1);
- ETERM* msg = ERL_TUPLE_ELEMENT(args, 2);
-
- VERIFY_TYPE(ERL_IS_INTEGER, fd_term);
- send_errno_result(erl_send(ERL_INT_VALUE(fd_term), to, msg));
-}
-
-static void
-cmd_erl_reg_send(ETERM* args)
-{
- ETERM* fd_term = ERL_TUPLE_ELEMENT(args, 0);
- ETERM* to = ERL_TUPLE_ELEMENT(args, 1);
- ETERM* msg = ERL_TUPLE_ELEMENT(args, 2);
- char reg_name[256];
-
- VERIFY_TYPE(ERL_IS_INTEGER, fd_term);
- VERIFY_TYPE(ERL_IS_ATOM, to);
- memcpy(reg_name, ERL_ATOM_PTR(to), ERL_ATOM_SIZE(to));
- reg_name[ERL_ATOM_SIZE(to)] = '\0';
- send_errno_result(erl_reg_send(ERL_INT_VALUE(fd_term), reg_name, msg));
-}
-
-static void
-send_errno_result(int value)
-{
- ETERM* res_array[2];
- ETERM* res_tuple;
-
- res_array[0] = erl_mk_int(value);
- res_array[1] = erl_mk_int(erl_errno);
- res_tuple = erl_mk_tuple(res_array, 2);
- send_term(res_tuple);
- erl_free_term(res_array[0]);
- erl_free_term(res_array[1]);
- erl_free_term(res_tuple);
-}
diff --git a/lib/erl_interface/test/erl_eterm_SUITE.erl b/lib/erl_interface/test/erl_eterm_SUITE.erl
deleted file mode 100644
index 77910a9fc7..0000000000
--- a/lib/erl_interface/test/erl_eterm_SUITE.erl
+++ /dev/null
@@ -1,1084 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2018. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
--module(erl_eterm_SUITE).
-
--include_lib("common_test/include/ct.hrl").
--include("erl_eterm_SUITE_data/eterm_test_cases.hrl").
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%% The tests are organised as follows:
-%%%
-%%% 1. Basic tests (encoding, decoding, memory allocation).
-%%% 2. Constructing terms (the erl_mk_xxx() functions and erl_copy_term()).
-%%% 3. Extracting & info functions (erl_hd(), erl_length() etc).
-%%% 4. I/O list functions.
-%%% 5. Miscellaneous functions.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
--export([all/0, suite/0,
- init_per_testcase/2,
- build_terms/1, round_trip_conversion/1,
- decode_terms/1, decode_float/1,
- t_erl_mk_int/1, t_erl_mk_list/1,
- basic_copy/1,
- t_erl_cons/1,
- t_erl_mk_atom/1,
- t_erl_mk_binary/1,
- t_erl_mk_empty_list/1,
- t_erl_mk_float/1,
- t_erl_mk_pid/1,
- t_erl_mk_xpid/1,
- t_erl_mk_port/1,
- t_erl_mk_xport/1,
- t_erl_mk_ref/1,
- t_erl_mk_long_ref/1,
- t_erl_mk_string/1,
- t_erl_mk_estring/1,
- t_erl_mk_tuple/1,
- t_erl_mk_uint/1,
- t_erl_mk_var/1,
- t_erl_size/1,
- t_erl_var_content/1,
- t_erl_element/1,
- t_erl_length/1, t_erl_hd/1, t_erl_tl/1,
- type_checks/1, extractor_macros/1,
- t_erl_iolist_length/1, t_erl_iolist_to_binary/1,
- t_erl_iolist_to_string/1,
- erl_print_term/1, print_string/1,
- t_erl_free_compound/1,
- high_chaparal/1,
- broken_data/1,
- cnode_1/1]).
-
--export([start_cnode/1]).
-
--import(runner, [get_term/1]).
-
-%% This test suite controls the running of the C language functions
-%% in eterm_test.c and print_term.c.
-
-suite() ->
- [{ct_hooks,[ts_install_cth]}].
-
-all() ->
- [build_terms, round_trip_conversion, decode_terms,
- decode_float, t_erl_mk_int, t_erl_mk_list, basic_copy,
- t_erl_mk_atom, t_erl_mk_binary, t_erl_mk_empty_list,
- t_erl_mk_float, t_erl_mk_pid, t_erl_mk_xpid,
- t_erl_mk_port, t_erl_mk_xport, t_erl_mk_ref,
- t_erl_mk_long_ref, t_erl_mk_string, t_erl_mk_estring,
- t_erl_mk_tuple, t_erl_mk_uint, t_erl_mk_var, t_erl_size,
- t_erl_var_content, t_erl_element, t_erl_cons,
- t_erl_length, t_erl_hd, t_erl_tl, type_checks,
- extractor_macros, t_erl_iolist_length,
- t_erl_iolist_to_binary, t_erl_iolist_to_string,
- erl_print_term, print_string, t_erl_free_compound,
- high_chaparal, broken_data, cnode_1].
-
-
-init_per_testcase(Case, Config) ->
- runner:init_per_testcase(?MODULE, Case, Config).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%
-%%% 1. B a s i c t e s t s
-%%%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%% This test asks the C function to construct all data types in
-%% a list and verifies that the result is as expected.
-
-build_terms(Config) when is_list(Config) ->
- P = runner:start(Config, ?build_terms),
- {term, Term} = get_term(P),
- io:format("Received: ~p", [Term]),
- [ARefLN, ARef, APortLN, APort, APidLN, APid,
- {element1, 42, 767}, "A string",
- 1, -1, 0, 3.0, ABin, 'I am an atom'] = Term,
- "A binary" = binary_to_list(ABin),
- case ARef of
- R when is_reference(R), node(R) == kalle@localhost -> ok
- end,
- case ARefLN of
- R1 when is_reference(R1), node(R1) == abcdefghijabcdefghij@localhost -> ok
- end,
- case APort of
- Port when is_port(Port), node(Port) == kalle@localhost -> ok
- end,
- case APortLN of
- Port1 when is_port(Port1), node(Port1) == abcdefghijabcdefghij@localhost -> ok
- end,
- case APid of
- Pid when is_pid(Pid), node(Pid) == kalle@localhost -> ok
- end,
- case APidLN of
- Pid1 when is_pid(Pid1), node(Pid1) == abcdefghijabcdefghij@localhost -> ok
- end,
-
- runner:recv_eot(P),
- ok.
-
-%% This test is run entirely in C code.
-
-round_trip_conversion(Config) when is_list(Config) ->
- runner:test(Config, ?round_trip_conversion),
- ok.
-
-%% This test sends a list of all data types to the C code function,
-%% which decodes it and verifies it.
-
-decode_terms(Config) when is_list(Config) ->
- Dummy1 = list_to_atom(filename:join(proplists:get_value(priv_dir, Config),
- dummy_file1)),
- Dummy2 = list_to_atom(filename:join(proplists:get_value(priv_dir, Config),
- dummy_file2)),
- Port1 = open_port(Dummy1, [out]),
- Port2 = open_port(Dummy2, [out]),
- ABinary = list_to_binary("A binary"),
- Terms = [make_ref(), make_ref(),
- Port1, Port2,
- self(), self(),
- {element1, 42, 767}, "A string",
- 1, -1, 0, 3.0, ABinary, 'I am an atom'],
-
- P = runner:start(Config, ?decode_terms),
- runner:send_term(P, Terms),
- runner:recv_eot(P),
-
- ok.
-
-%% Decodes the floating point number 3.1415.
-
-decode_float(Config) when is_list(Config) ->
- P = runner:start(Config, ?decode_float),
- runner:send_term(P, 3.1415),
- runner:recv_eot(P),
- ok.
-
-%% Tests the erl_free_compound() function.
-
-t_erl_free_compound(Config) when is_list(Config) ->
- runner:test(Config, ?t_erl_free_compound),
- ok.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%
-%%% 2. C o n s t r u c t i n g t e r m s
-%%%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%% This tests the erl_mk_list() function.
-
-t_erl_mk_list(Config) when is_list(Config) ->
- P = runner:start(Config, ?t_erl_mk_list),
-
- {term, []} = get_term(P),
- {term, [abc]} = get_term(P),
- {term, [abcdef, 42]} = get_term(P),
- {term, [0.0, 23, [], 3.1415]} = get_term(P),
-
- runner:recv_eot(P),
- ok.
-
-
-%% This tests the erl_mk_int() function.
-
-t_erl_mk_int(Config) when is_list(Config) ->
- P = runner:start(Config, ?t_erl_mk_int),
-
- {term, 0} = get_term(P),
- {term, 127} = get_term(P),
- {term, 128} = get_term(P),
- {term, 255} = get_term(P),
- {term, 256} = get_term(P),
-
- {term, 16#FFFF} = get_term(P),
- {term, 16#10000} = get_term(P),
-
- {term, 16#07FFFFFF} = get_term(P),
- {term, 16#0FFFFFFF} = get_term(P),
- {term, 16#1FFFFFFF} = get_term(P),
- {term, 16#3FFFFFFF} = get_term(P),
- {term, 16#7FFFFFFF} = get_term(P),
-
- {term, 16#08000000} = get_term(P),
- {term, 16#10000000} = get_term(P),
- {term, 16#20000000} = get_term(P),
- {term, 16#40000000} = get_term(P),
-
-
- {term, -16#07FFFFFF} = get_term(P),
- {term, -16#0FFFFFFF} = get_term(P),
- {term, -16#1FFFFFFF} = get_term(P),
- {term, -16#3FFFFFFF} = get_term(P),
- {term, -16#7FFFFFFF} = get_term(P),
-
- {term, -16#08000000} = get_term(P),
- {term, -16#10000000} = get_term(P),
- {term, -16#20000000} = get_term(P),
- {term, -16#40000000} = get_term(P),
-
- {term, -16#08000001} = get_term(P),
- {term, -16#10000001} = get_term(P),
- {term, -16#20000001} = get_term(P),
- {term, -16#40000001} = get_term(P),
-
- {term, -16#08000002} = get_term(P),
- {term, -16#10000002} = get_term(P),
- {term, -16#20000002} = get_term(P),
- {term, -16#40000002} = get_term(P),
-
- {term, -1999999999} = get_term(P),
- {term, -2000000000} = get_term(P),
- {term, -2000000001} = get_term(P),
-
- runner:recv_eot(P),
- ok.
-
-
-%% Basic test of erl_copy_term().
-
-basic_copy(Config) when is_list(Config) ->
- runner:test(Config, ?basic_copy),
- ok.
-
-
-%% This tests the erl_mk_tuple() function.
-
-t_erl_mk_tuple(Config) when is_list(Config) ->
- P = runner:start(Config, ?t_erl_mk_tuple),
-
- {term, {madonna, 21, 'mad donna', 12}} = get_term(P),
- {term, {'Madonna',21,{children,{"Isabella",2}},
- {'home page',"http://www.madonna.com/"}}} = get_term(P),
-
- runner:recv_eot(P),
- ok.
-
-
-%% This tests the erl_mk_atom() function.
-
-t_erl_mk_atom(Config) when is_list(Config) ->
- P = runner:start(Config, ?t_erl_mk_atom),
-
- {term, madonna} = (get_term(P)),
- {term, 'Madonna'} = (get_term(P)),
- {term, 'mad donna'} = (get_term(P)),
- {term, '_madonna_'} = (get_term(P)),
- {term, '/home/madonna/tour_plan'} = (get_term(P)),
- {term, 'http://www.madonna.com/tour_plan'} = (get_term(P)),
- {term, '\'madonna\''} = (get_term(P)),
- {term, '\"madonna\"'} = (get_term(P)),
- {term, '\\madonna\\'} = (get_term(P)),
- {term, '{madonna,21,\'mad donna\',12}'} = (get_term(P)),
-
- runner:recv_eot(P),
- ok.
-
-
-%% This tests the erl_mk_binary() function.
-
-t_erl_mk_binary(Config) when is_list(Config) ->
- P = runner:start(Config, ?t_erl_mk_binary),
-
- {term, Bin} = (get_term(P)),
- "{madonna,21,'mad donna',1234.567.890, !#$%&/()=?+-@, \" \\}" = binary_to_list(Bin),
-
- runner:recv_eot(P),
- ok.
-
-
-%% This tests the erl_mk_empty_list() function.
-
-t_erl_mk_empty_list(Config) when is_list(Config) ->
- P = runner:start(Config, ?t_erl_mk_empty_list),
-
- {term, []} = get_term(P),
-
- runner:recv_eot(P),
- ok.
-
-
-%% This tests the erl_mk_float() function.
-
-t_erl_mk_float(Config) when is_list(Config) ->
- case os:type() of
- vxworks ->
- {skipped, "Floating point numbers never compare equal on PPC"};
- _ ->
- P = runner:start(Config, ?t_erl_mk_float),
- {term, {3.1415, 1.999999, 2.000000, 2.000001,
- 2.000002, 12345.67890}} = get_term(P),
- runner:recv_eot(P),
- ok
- end.
-
-
-%% This tests the erl_mk_pid() function.
-
-t_erl_mk_pid(Config) when is_list(Config) ->
- P = runner:start(Config, ?t_erl_mk_pid),
-
- {term, A_pid} = (get_term(P)),
- {pid, kalle@localhost, 3, 2} = nc2vinfo(A_pid),
-
- runner:recv_eot(P),
- ok.
-
-t_erl_mk_xpid(Config) when is_list(Config) ->
- P = runner:start(Config, ?t_erl_mk_xpid),
-
- {term, A_pid} = (get_term(P)),
- {pid, kalle@localhost, 32767, 8191} = nc2vinfo(A_pid),
-
- runner:recv_eot(P),
- ok.
-
-
-%% This tests the erl_mk_port() function.
-
-t_erl_mk_port(Config) when is_list(Config) ->
- P = runner:start(Config, ?t_erl_mk_port),
-
- {term, A_port} = (get_term(P)),
- {port, kalle@localhost, 4} = nc2vinfo(A_port),
-
- runner:recv_eot(P),
- ok.
-
-t_erl_mk_xport(Config) when is_list(Config) ->
- P = runner:start(Config, ?t_erl_mk_xport),
-
- {term, A_port} = (get_term(P)),
- {port, kalle@localhost, 268435455} = nc2vinfo(A_port),
-
- runner:recv_eot(P),
- ok.
-
-
-%% This tests the erl_mk_ref() function.
-
-t_erl_mk_ref(Config) when is_list(Config) ->
- P = runner:start(Config, ?t_erl_mk_ref),
-
- {term, A_ref} = (get_term(P)),
- {ref, kalle@localhost, _Length, [6]} = nc2vinfo(A_ref),
-
- runner:recv_eot(P),
- ok.
-
-t_erl_mk_long_ref(Config) when is_list(Config) ->
- P = runner:start(Config, ?t_erl_mk_long_ref),
-
- {term, A_ref} = (get_term(P)),
- {ref, kalle@localhost, _Length, [4294967295,4294967295,262143]}
- = nc2vinfo(A_ref),
-
- runner:recv_eot(P),
- ok.
-
-
-%% This tests the erl_mk_string() function.
-
-t_erl_mk_string(Config) when is_list(Config) ->
- P = runner:start(Config, ?t_erl_mk_string),
-
- {term, "madonna"} = (get_term(P)),
- {term, "Madonna"} = (get_term(P)),
- {term, "mad donna"} = (get_term(P)),
- {term, "_madonna_"} = (get_term(P)),
- {term, "/home/madonna/tour_plan"} = (get_term(P)),
- {term, "http://www.madonna.com/tour_plan"} = (get_term(P)),
- {term, "\'madonna\'"} = (get_term(P)),
- {term, "\"madonna\""} = (get_term(P)),
- {term, "\\madonna\\"} = (get_term(P)),
- {term, "{madonna,21,'mad donna',12}"} = (get_term(P)),
-
- runner:recv_eot(P),
- ok.
-
-
-%% This tests the erl_mk_estring() function.
-
-t_erl_mk_estring(Config) when is_list(Config) ->
- P = runner:start(Config, ?t_erl_mk_estring),
-
- {term, "madonna"} = (get_term(P)),
- {term, "Madonna"} = (get_term(P)),
- {term, "mad donna"} = (get_term(P)),
- {term, "_madonna_"} = (get_term(P)),
- {term, "/home/madonna/tour_plan"} = (get_term(P)),
- {term, "http://www.madonna.com/tour_plan"} = (get_term(P)),
- {term, "\'madonna\'"} = (get_term(P)),
- {term, "\"madonna\""} = (get_term(P)),
- {term, "\\madonna\\"} = (get_term(P)),
- {term, "{madonna,21,'mad donna',12}"} = (get_term(P)),
-
- runner:recv_eot(P),
- ok.
-
-
-%% This tests the erl_mk_uint() function.
-
-t_erl_mk_uint(Config) when is_list(Config) ->
- P = runner:start(Config, ?t_erl_mk_uint),
-
- {term, 54321} = (get_term(P)),
- {term, 2147483647} = (get_term(P)),
- {term, 2147483648} = (get_term(P)),
- {term, 2147483649} = (get_term(P)),
- {term, 2147483650} = (get_term(P)),
- {term, 4294967295} = (get_term(P)),
-
- runner:recv_eot(P),
- ok.
-
-
-%% This tests the erl_mk_var() function.
-
-t_erl_mk_var(Config) when is_list(Config) ->
- P = runner:start(Config, ?t_erl_mk_var),
-
- {term, 1} = (get_term(P)),
- {term, 0} = (get_term(P)),
- {term, 1} = (get_term(P)),
- {term, 0} = (get_term(P)),
- {term, 1} = (get_term(P)),
- {term, 0} = (get_term(P)),
- {term, 1} = (get_term(P)),
-
- runner:recv_eot(P),
- ok.
-
-
-%% This tests the erl_cons() function.
-
-t_erl_cons(Config) when is_list(Config) ->
- P = runner:start(Config, ?t_erl_cons),
-
- {term, [madonna, 21]} = get_term(P),
-
- runner:recv_eot(P),
- ok.
-
-
-
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%
-%%% 3. E x t r a c t i n g & i n f o f u n c t i o n s
-%%%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%% Tests the erl_length() function.
-
-t_erl_length(Config) when is_list(Config) ->
- P = runner:start(Config, ?t_erl_length),
-
- 0 = erl_length(P, []),
- 1 = erl_length(P, [a]),
- 2 = erl_length(P, [a, b]),
- 3 = erl_length(P, [a, b, c]),
-
- 4 = erl_length(P, [a, [x, y], c, []]),
-
- -1 = erl_length(P, [a|b]),
- -1 = erl_length(P, a),
-
- runner:finish(P),
- ok.
-
-%% Invokes the erl_length() function.
-
-erl_length(Port, List) ->
- call_erl_function(Port, List).
-
-%% Tests the erl_hd() function.
-
-t_erl_hd(Config) when is_list(Config) ->
- P = runner:start(Config, ?t_erl_hd),
-
- 'NULL' = erl_hd(P, 42),
- 'NULL' = erl_hd(P, abc),
- 'NULL' = erl_hd(P, []),
-
- [] = erl_hd(P, [[], a]),
- a = erl_hd(P, [a]),
- a = erl_hd(P, [a, b]),
- a = erl_hd(P, [a, b, c]),
- a = erl_hd(P, [a|b]),
-
- runner:send_eot(P),
- runner:recv_eot(P),
- ok.
-
-%% Invokes the erl_hd() function.
-
-erl_hd(Port, List) ->
- call_erl_function(Port, List).
-
-%% Tests the erl_tail() function.
-
-t_erl_tl(Config) when is_list(Config) ->
- P = runner:start(Config, ?t_erl_tl),
-
- 'NULL' = erl_tl(P, 42),
- 'NULL' = erl_tl(P, abc),
- 'NULL' = erl_tl(P, []),
-
- [] = erl_tl(P, [a]),
- [b] = erl_tl(P, [a, b]),
- [b, c] = erl_tl(P, [a, b, c]),
-
- b = erl_tl(P, [a|b]),
-
- runner:send_eot(P),
- runner:recv_eot(P),
- ok.
-
-%% Invokes the erl_tail() function in erl_interface.
-
-erl_tl(Port, List) ->
- call_erl_function(Port, List).
-
-%% Tests the type checking macros (done in the C program).
-
-type_checks(Config) when is_list(Config) ->
- runner:test(Config, ?type_checks),
- ok.
-
-%% Tests the extractor macros (done in the C program).
-
-extractor_macros(Config) when is_list(Config) ->
- runner:test(Config, ?extractor_macros),
- ok.
-
-
-%% This tests the erl_size() function.
-
-t_erl_size(Config) when is_list(Config) ->
- P = runner:start(Config, ?t_erl_size),
-
- {term, 0} = (get_term(P)),
- {term, 4} = (get_term(P)),
-
- {term, 0} = (get_term(P)),
- {term, 27} = (get_term(P)),
-
- runner:recv_eot(P),
- ok.
-
-
-%% This tests the erl_var_content() function.
-
-t_erl_var_content(Config) when is_list(Config) ->
- P = runner:start(Config, ?t_erl_var_content),
-
- {term, 17} = (get_term(P)),
- {term, "http://www.madonna.com"} = (get_term(P)),
- {term, 2} = (get_term(P)),
- {term, "http://www.madonna.com"} = (get_term(P)),
- {term, 2} = (get_term(P)),
-
- runner:recv_eot(P),
- ok.
-
-
-%% This tests the erl_element() function.
-
-t_erl_element(Config) when is_list(Config) ->
- P = runner:start(Config, ?t_erl_element),
-
- {term, madonna} = get_term(P),
- {term, 21} = get_term(P),
- {term, 'mad donna'} = get_term(P),
- {term, 12} = get_term(P),
-
- {term, 'Madonna'} = get_term(P),
- {term, 21} = get_term(P),
- {term, {children,{"Isabella",2}}} = get_term(P),
- {term, {'home page',"http://www.madonna.com/"}} = get_term(P),
-
- runner:recv_eot(P),
- ok.
-
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%
-%%% 4. I / O l i s t f u n c t i o n s
-%%%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%% Tests the erl_iolist_length() function.
-
-t_erl_iolist_length(Config) when is_list(Config) ->
- P = runner:start(Config, ?t_erl_iolist_length),
-
- %% Flat lists.
-
- 0 = erl_iolist_length(P, []),
- 1 = erl_iolist_length(P, [10]),
- 2 = erl_iolist_length(P, [10, 20]),
- 3 = erl_iolist_length(P, [10, 20, 30]),
- 256 = erl_iolist_length(P, lists:seq(0, 255)),
-
- %% Deep lists.
-
- 0 = erl_iolist_length(P, [[]]),
- 1 = erl_iolist_length(P, [[], 42]),
- 1 = erl_iolist_length(P, [42, []]),
- 2 = erl_iolist_length(P, [42, [], 45]),
-
- 3 = erl_iolist_length(P, [42, [90], 45]),
- 3 = erl_iolist_length(P, [[42, [90]], 45]),
- 3 = erl_iolist_length(P, [[42, [90]], 45]),
-
- %% List with binaries.
-
- 0 = erl_iolist_length(P, [list_to_binary([])]),
- 0 = erl_iolist_length(P, [[], list_to_binary([])]),
- 1 = erl_iolist_length(P, [[1], list_to_binary([])]),
- 1 = erl_iolist_length(P, [[], list_to_binary([2])]),
- 2 = erl_iolist_length(P, [[42], list_to_binary([2])]),
- 4 = erl_iolist_length(P, [[42], list_to_binary([2, 3, 4])]),
-
- %% Binaries as tail.
-
- 0 = erl_iolist_length(P, [[]| list_to_binary([])]),
- 1 = erl_iolist_length(P, [[1]| list_to_binary([])]),
- 1 = erl_iolist_length(P, [[]| list_to_binary([2])]),
- 2 = erl_iolist_length(P, [[42]| list_to_binary([2])]),
-
- %% Binaries only.
-
- 0 = erl_iolist_length(P, list_to_binary("")),
- 1 = erl_iolist_length(P, list_to_binary([1])),
- 2 = erl_iolist_length(P, list_to_binary([1, 2])),
-
- %% Illegal cases.
-
- -1 = erl_iolist_length(P, [42|43]),
- -1 = erl_iolist_length(P, a),
-
- -1 = erl_iolist_length(P, [a]),
- -1 = erl_iolist_length(P, [256]),
- -1 = erl_iolist_length(P, [257]),
- -1 = erl_iolist_length(P, [-1]),
- -1 = erl_iolist_length(P, [-2]),
- -1 = erl_iolist_length(P, [-127]),
- -1 = erl_iolist_length(P, [-128]),
-
- runner:finish(P),
- ok.
-
-%% Invokes the erl_iolist_length() function.
-
-erl_iolist_length(Port, List) ->
- call_erl_function(Port, List).
-
-%% Tests the erl_iolist_to_binary() function.
-
-t_erl_iolist_to_binary(Config) when is_list(Config) ->
- P = runner:start(Config, ?t_erl_iolist_to_binary),
-
- %% Flat lists.
-
- [] = iolist_to_list(P, []),
- [10] = iolist_to_list(P, [10]),
- [10, 20] = iolist_to_list(P, [10, 20]),
- [10, 20, 30] = iolist_to_list(P, [10, 20, 30]),
- AllBytes = lists:seq(0, 255),
- AllBytes = iolist_to_list(P, AllBytes),
-
- %% Deep lists.
-
- [] = iolist_to_list(P, [[]]),
- [42] = iolist_to_list(P, [[], 42]),
- [42] = iolist_to_list(P, [42, []]),
- [42, 45] = iolist_to_list(P, [42, [], 45]),
-
- [42, 90, 45] = iolist_to_list(P, [42, [90], 45]),
- [42, 90, 45] = iolist_to_list(P, [[42, [90]], 45]),
- [42, 90, 45] = iolist_to_list(P, [[42, [90]], 45]),
-
- %% List with binaries.
-
- [] = iolist_to_list(P, [list_to_binary([])]),
- [] = iolist_to_list(P, [[], list_to_binary([])]),
- [1] = iolist_to_list(P, [[1], list_to_binary([])]),
- [2] = iolist_to_list(P, [[], list_to_binary([2])]),
- [42, 2] = iolist_to_list(P, [[42], list_to_binary([2])]),
- [42, 2, 3, 4] = iolist_to_list(P, [[42], list_to_binary([2, 3, 4])]),
-
- %% Binaries as tail.
-
- [] = iolist_to_list(P, [[]| list_to_binary([])]),
- [1] = iolist_to_list(P, [[1]| list_to_binary([])]),
- [2] = iolist_to_list(P, [[]| list_to_binary([2])]),
- [42, 2] = iolist_to_list(P, [[42]| list_to_binary([2])]),
-
- %% Binaries only.
-
- [] = iolist_to_list(P, list_to_binary("")),
- [1] = iolist_to_list(P, list_to_binary([1])),
- [1, 2] = iolist_to_list(P, list_to_binary([1, 2])),
-
- %% Illegal cases.
-
- 'NULL' = iolist_to_list(P, [42|43]),
- 'NULL' = iolist_to_list(P, a),
-
- 'NULL' = iolist_to_list(P, [a]),
- 'NULL' = iolist_to_list(P, [256]),
- 'NULL' = iolist_to_list(P, [257]),
- 'NULL' = iolist_to_list(P, [-1]),
- 'NULL' = iolist_to_list(P, [-2]),
- 'NULL' = iolist_to_list(P, [-127]),
- 'NULL' = iolist_to_list(P, [-128]),
-
- runner:finish(P),
- ok.
-
-iolist_to_list(Port, Term) ->
- case call_erl_function(Port, Term) of
- 'NULL' ->
- 'NULL';
- Bin when is_binary(Bin) ->
- binary_to_list(Bin)
- end.
-
-%% Tests the erl_iolist_to_string() function.
-
-t_erl_iolist_to_string(Config) when is_list(Config) ->
- P = runner:start(Config, ?t_erl_iolist_to_string),
-
- %% Flat lists.
-
- [0] = iolist_to_string(P, []),
- [10, 0] = iolist_to_string(P, [10]),
- [10, 20, 0] = iolist_to_string(P, [10, 20]),
- [10, 20, 30, 0] = iolist_to_string(P, [10, 20, 30]),
- AllBytes = lists:seq(1, 255)++[0],
- AllBytes = iolist_to_string(P, lists:seq(1, 255)),
-
- %% Deep lists.
-
- [0] = iolist_to_string(P, [[]]),
- [42, 0] = iolist_to_string(P, [[], 42]),
- [42, 0] = iolist_to_string(P, [42, []]),
- [42, 45, 0] = iolist_to_string(P, [42, [], 45]),
-
- [42, 90, 45, 0] = iolist_to_string(P, [42, [90], 45]),
- [42, 90, 45, 0] = iolist_to_string(P, [[42, [90]], 45]),
- [42, 90, 45, 0] = iolist_to_string(P, [[42, [90]], 45]),
-
- %% List with binaries.
-
- [0] = iolist_to_string(P, [list_to_binary([])]),
- [0] = iolist_to_string(P, [[], list_to_binary([])]),
- [1, 0] = iolist_to_string(P, [[1], list_to_binary([])]),
- [2, 0] = iolist_to_string(P, [[], list_to_binary([2])]),
- [42, 2, 0] = iolist_to_string(P, [[42], list_to_binary([2])]),
- [42, 2, 3, 4, 0] = iolist_to_string(P, [[42],
- list_to_binary([2, 3, 4])]),
-
- %% Binaries as tail.
-
- [0] = iolist_to_string(P, [[]| list_to_binary([])]),
- [1, 0] = iolist_to_string(P, [[1]| list_to_binary([])]),
- [2, 0] = iolist_to_string(P, [[]| list_to_binary([2])]),
- [42, 2, 0] = iolist_to_string(P, [[42]| list_to_binary([2])]),
-
- %% Binaries only.
-
- [0] = iolist_to_string(P, list_to_binary("")),
- [1, 0] = iolist_to_string(P, list_to_binary([1])),
- [1, 2, 0] = iolist_to_string(P, list_to_binary([1, 2])),
-
- %% Illegal cases.
-
- 'NULL' = iolist_to_string(P, [0]),
- 'NULL' = iolist_to_string(P, [65, 0, 66]),
- 'NULL' = iolist_to_string(P, [65, 66, 67, 0]),
-
- 'NULL' = iolist_to_string(P, [42|43]),
- 'NULL' = iolist_to_string(P, a),
-
- 'NULL' = iolist_to_string(P, [a]),
- 'NULL' = iolist_to_string(P, [256]),
- 'NULL' = iolist_to_string(P, [257]),
- 'NULL' = iolist_to_string(P, [-1]),
- 'NULL' = iolist_to_string(P, [-2]),
- 'NULL' = iolist_to_string(P, [-127]),
- 'NULL' = iolist_to_string(P, [-128]),
-
- runner:finish(P),
- ok.
-
-%% Invokes the erl_iolist_to_string() function.
-
-iolist_to_string(Port, Term) ->
- runner:send_term(Port, Term),
- case get_term(Port) of
- {bytes, Result} -> Result;
- 'NULL' -> 'NULL'
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%
-%%% 5. M i s c e l l a n o u s T e s t s
-%%%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%% Tests the erl_print_term() function
-erl_print_term(Config) when is_list(Config) ->
- PrintTerm = print_term(Config),
- P = open_port({spawn, PrintTerm}, [stream]),
-
- %% Lists.
-
- print(P, "[]", []),
- print(P, "[a]", [a]),
- print(P, "[[a]]", [[a]]),
- print(P, "[[]]", [[]]),
- print(P, "[a,b,c]", [a,b,c]),
- print(P, "[a,b|c]", [a,b|c]),
- print(P, "[a,[],c]", [a,[],c]),
- print(P, "[a,[1000,1],c]", [a,[1000,1],c]),
-
- %% Tuples.
-
- print(P, "{}", {}),
- print(P, "{ok}", {ok}),
- print(P, "{1,2,3}", {1, 2, 3}),
-
- %% Pids.
-
- {_X, Y, Z} = split_pid(self()),
- PidString = lists:flatten(io_lib:format("<~s.~w.~w>",
- [node(), Y, Z])),
- print(P, PidString, self()),
-
- unlink(P),
- exit(P, die),
- ok.
-
-split_pid(Pid) when is_pid(Pid) ->
- split_pid(pid_to_list(Pid), 0, []).
-
-split_pid([$<|Rest], Cur, Result) ->
- split_pid(Rest, Cur, Result);
-split_pid([Digit|Rest], Cur, Result) when $0 =< Digit, Digit =< $9 ->
- split_pid(Rest, 10*Cur+Digit-$0, Result);
-split_pid([$.|Rest], Cur, Result) ->
- split_pid(Rest, 0, Result++[Cur]);
-split_pid([$>], Cur, Result) ->
- list_to_tuple(Result++[Cur]).
-
-%% Test printing a string with erl_print_term()
-print_string(Config) when is_list(Config) ->
- PrintTerm = print_term(Config),
- P = open_port({spawn, PrintTerm}, [stream]),
-
- %% Strings.
-
- print(P, "\"ABC\"", "ABC"),
- {11, "\"\\tABC\\r\\n\""} = print(P, "\tABC\r\n"),
-
- %% Not strings.
-
- print(P, "[65,66,67,0]", "ABC\000"),
-
- unlink(P),
- exit(P, die),
- ok.
-
-print(Port, TermString, Term) ->
- Length = length(TermString),
- {Length, TermString} = print(Port, Term).
-
-%% This function uses the erl_print_term() function in erl_interface
-%% to print a term.
-%% Returns: {NumChars, Chars}
-
-print(Port, Term) ->
- Bin = term_to_binary(Term),
- Size = size(Bin),
- Port ! {self(), {command, [Size div 256, Size rem 256, Bin]}},
- collect_line(Port, []).
-
-collect_line(Port, Result) ->
- receive
- {Port, {data, Data}} ->
- case lists:reverse(Data) of
- [$\n|Rest] ->
- collect_line1(Rest++Result, []);
- Chars ->
- collect_line(Port, Chars++Result)
- end
- after 5000 ->
- ct:fail("No response from C program")
- end.
-
-collect_line1([$\r|Rest], Result) ->
- {list_to_integer(Result), lists:reverse(Rest)};
-collect_line1([C|Rest], Result) ->
- collect_line1(Rest, [C|Result]).
-
-%% Test case submitted by Per Lundgren, ERV.
-
-high_chaparal(Config) when is_list(Config) ->
- P = runner:start(Config, ?high_chaparal),
- {term, [hello, world]} = get_term(P),
- runner:recv_eot(P),
- ok.
-
-%% OTP-7448
-broken_data(Config) when is_list(Config) ->
- P = runner:start(Config, ?broken_data),
- runner:recv_eot(P),
- ok.
-
-%% This calls a C function with one parameter and returns the result.
-
-call_erl_function(Port, Term) ->
- runner:send_term(Port, Term),
- case get_term(Port) of
- {term, Result} -> Result;
- 'NULL' -> 'NULL'
- end.
-
-print_term(Config) when is_list(Config) ->
- filename:join(proplists:get_value(data_dir, Config), "print_term").
-
-
-
-%%% We receive a ref from the cnode, and expect it to be a long ref.
-%%% We also send a ref we created ourselves, and expect to get it
-%%% back, without having been mutated into short form. We must take
-%%% care then to check the actual returned ref, and not the original
-%%% one, which is equal to it.
-
-%% Tests involving cnode: sends a long ref from a cnode to us
-cnode_1(Config) when is_list(Config) ->
- Cnode = filename:join(proplists:get_value(data_dir, Config), "cnode"),
- register(mip, self()),
- spawn_link(?MODULE, start_cnode, [Cnode]),
- Ref1 = get_ref(),
- io:format("Ref1 ~p~n", [Ref1]),
- check_ref(Ref1),
- Ref2 = make_ref(),
- Pid = receive
- Msg -> Msg %% pid
- end,
- Fun1 = fun(X) -> {Pid, X} end, % sneak in a fun test here
- %Fun1 = {wait_with_funs, new_dist_format},
- Term = {Ref2, Fun1, {1,2,3,4,5,6,7,8,9,10}},
- %% A term which will overflow the original buffer used in 'cnode'.
- Pid ! Term,
- receive
- Term2 ->
- io:format("received ~p~n", [Term2]),
- case Term2 of
- Term ->
- {Ref22,_,_} = Term2,
- check_ref(Ref22);
- X ->
- ct:fail({receive1,X})
- end
- after 5000 ->
- ct:fail(receive1)
- end,
- receive
- Pid ->
- ok;
- Y ->
- ct:fail({receive1,Y})
- after 5000 ->
- ct:fail(receive2)
- end,
- io:format("ref = ~p~n", [Ref1]),
- check_ref(Ref1),
- ok.
-
-check_ref(Ref) ->
- case bin_ext_type(Ref) of
- 101 ->
- ct:fail(oldref);
- 114 ->
- ok;
- Type ->
- ct:fail({type, Type})
- end.
-
-bin_ext_type(T) ->
- [131, Type | _] = binary_to_list(term_to_binary(T)),
- Type.
-
-get_ref() ->
- receive
- X when is_reference(X) ->
- X
- after 5000 ->
- ct:fail({cnode, timeout})
- end.
-
-start_cnode(Cnode) ->
- open_port({spawn, Cnode ++ " " ++ atom_to_list(erlang:get_cookie())}, []),
- rec_cnode().
-
-rec_cnode() ->
- receive
- X ->
- io:format("from cnode: ~p~n", [X]),
- rec_cnode()
- end.
-
-nc2vinfo(Pid) when is_pid(Pid) ->
- [_NodeStr, NumberStr, SerialStr]
- = string:tokens(pid_to_list(Pid), "<.>"),
- Number = list_to_integer(NumberStr),
- Serial = list_to_integer(SerialStr),
- {pid, node(Pid), Number, Serial};
-nc2vinfo(Port) when is_port(Port) ->
- ["#Port", _NodeStr, NumberStr]
- = string:tokens(erlang:port_to_list(Port), "<.>"),
- Number = list_to_integer(NumberStr),
- {port, node(Port), Number};
-nc2vinfo(Ref) when is_reference(Ref) ->
- ["#Ref", _NodeStr | NumStrList]
- = string:tokens(erlang:ref_to_list(Ref), "<.>"),
- {Len, RevNumList} = lists:foldl(fun ("0", {N, []}) ->
- {N+1, []};
- (IStr, {N, Is}) ->
- {N+1,
- [list_to_integer(IStr)|Is]}
- end,
- {0, []},
- NumStrList),
- {ref, node(Ref), Len, lists:reverse(RevNumList)};
-nc2vinfo(Other) ->
- {badarg, Other}.
diff --git a/lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.first b/lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.first
deleted file mode 100644
index 0ea872ef49..0000000000
--- a/lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.first
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2000-2016. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# %CopyrightEnd%
-#
-
-eterm_test_decl.c: eterm_test.c
- erl -noinput -pa ../all_SUITE_data -s init_tc run eterm_test -s erlang halt
diff --git a/lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.src b/lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.src
deleted file mode 100644
index 4b1ddf77b6..0000000000
--- a/lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.src
+++ /dev/null
@@ -1,50 +0,0 @@
-#
-# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1997-2016. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# %CopyrightEnd%
-#
-
-include @erl_interface_mk_include@
-
-CC0 = @CC@
-CC = ..@DS@all_SUITE_data@DS@gccifier@exe@ -CC"$(CC0)"
-LD = @LD@
-LIBERL = @erl_interface_lib@
-LIBEI = @erl_interface_eilib@
-LIBFLAGS = ../all_SUITE_data/runner@obj@ \
- $(LIBERL) $(LIBEI) @erl_interface_sock_libs@ @LIBS@ \
- @erl_interface_threadlib@
-CFLAGS = @EI_CFLAGS@ $(THR_DEFS) -I@erl_interface_include@ -I../all_SUITE_data
-ETERM_OBJS = eterm_test@obj@ eterm_test_decl@obj@
-CNODE_OBJS = cnode@obj@
-PRINT_OBJS = print_term@obj@
-EXE_FILES = eterm_test@exe@ print_term@exe@ cnode@exe@
-
-all: $(EXE_FILES)
-
-eterm_test@exe@: $(ETERM_OBJS) $(LIBERL) $(LIBEI)
- $(LD) @CROSSLDFLAGS@ -o $@ $(ETERM_OBJS) $(LIBFLAGS)
-
-cnode@exe@: $(CNODE_OBJS) $(LIBERL) $(LIBEI)
- $(LD) @CROSSLDFLAGS@ -o $@ $(CNODE_OBJS) $(LIBFLAGS)
-
-print_term@exe@: print_term@obj@ $(LIBERL) $(LIBEI)
- $(LD) @CROSSLDFLAGS@ -o $@ $(PRINT_OBJS) $(LIBFLAGS)
-
-clean:
- $(RM) $(ETERM_OBJS) $(CNODE_OBJS) $(PRINT_OBJS)
- $(RM) $(EXE_FILES)
diff --git a/lib/erl_interface/test/erl_eterm_SUITE_data/cnode.c b/lib/erl_interface/test/erl_eterm_SUITE_data/cnode.c
deleted file mode 100644
index b87feb9dfc..0000000000
--- a/lib/erl_interface/test/erl_eterm_SUITE_data/cnode.c
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 1999-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include "ei.h"
-#include "erl_interface.h"
-
-#define MSGSIZE 13
-
-#define SELF(fd) erl_mk_pid(erl_thisnodename(),fd,0,erl_thiscreation())
-
-#ifdef VXWORKS
-#define MAIN cnode
-#else
-#define MAIN main
-#endif
-
-/* FIXME uses mix och ei and erl_interface */
-
-/*
- A small cnode.
- To be called from the test case erl_eterm_SUITE:cnode_1.
-
- 1) Set up connection to node 'test_server' on the same host.
- All sends are done to a registered process named 'mip'.
- 2) Create a long ref and send it.
- 3) Create a pid for ourselves and send it.
- 4) Receive a message.
- 5) Send back the message part of the message.
- 6) Send back the 'to' part of the message.
- 7) Exit.
-*/
-
-MAIN(int argc, char **argv)
-
-{
- unsigned char *msgbufp;
- int msgsize;
- ErlMessage msg;
- char msgbuf[MSGSIZE];
- char buf[100];
- char buf1[100];
- char buf2[100];
- int ix;
- int s;
- int fd;
- char node[80];
- char server[80];
- char host[80];
- int number;
- ETERM *ref, *ref1, *ref2;
- FILE *dfile = fopen("cnode_debug_printout", "w");
-
- erl_init(NULL, 0);
-
- number = 1;
- if (argc >= 2) {
- s = erl_connect_init(number, argv[1], 0);
- } else {
- s = erl_connect_init(number, (char *) 0, 0);
- }
- gethostname(host, sizeof(host));
- sprintf(node, "c%d@%s", number, host);
-
- fprintf(dfile, "s = %d\n", s); fflush(dfile);
-
- sprintf(server, "test_server@%s", host);
- fd = erl_connect(server);
- fprintf(dfile, "fd = %d\n", fd);
-
-/* fprintf(dfile, "dist = %d\n", erl_distversion(fd)); */
-
-#if 1
- ref = erl_mk_long_ref(node, 4711, 113, 98, 0);
-#else
- ref = erl_mk_ref(node, 4711, 0);
-#endif
- fprintf(dfile, "ref = %p\n", ref); fflush(dfile);
-
- s = erl_reg_send(fd, "mip", ref);
- fprintf(dfile, "s = %d\n", s); fflush(dfile);
-
- {
- ETERM* emsg;
- emsg = SELF(fd);
- fprintf(dfile, "pid = %p\n", emsg); fflush(dfile);
- s = erl_reg_send(fd,"mip",emsg);
- fprintf(dfile, "s2 = %d\n", s); fflush(dfile);
- erl_free_term(emsg);
- }
-
- msgsize = 4;
- msgbufp = (unsigned char *) malloc(msgsize);
-
- do {
-#if 0
- s = erl_receive_msg(fd, msgbuf, MSGSIZE, &msg);
-#else
- s = erl_xreceive_msg(fd, &msgbufp, &msgsize, &msg);
-#endif
- switch (s) {
- case ERL_TICK:
- fprintf(dfile, "tick\n");
- break;
- case ERL_ERROR:
- fprintf(dfile, "error: %s (%d)\n", strerror(erl_errno), erl_errno);
- break;
- case ERL_MSG:
- fprintf(dfile, "msg %d\n", msgsize);
- break;
- default:
- fprintf(dfile, "unknown result %d\n", s);
- break;
- }
- fflush(dfile);
- } while (s == ERL_TICK);
-
- s = erl_reg_send(fd, "mip", msg.msg);
- fprintf(dfile, "s = %d\n", s); fflush(dfile);
- s = erl_reg_send(fd, "mip", msg.to);
- fprintf(dfile, "s = %d\n", s); fflush(dfile);
-#if 0
- /* from = NULL! */
- s = erl_reg_send(fd, "mip", msg.from);
- fprintf(dfile, "s = %d\n", s); fflush(dfile);
-#endif
-
-#if 0
- /* Unused code which tests refs in some ways. */
- ix = 0;
- s = ei_encode_term(buf, &ix, ref);
- printf ("ei encode = %d, ix = %d\n", s, ix);
-
- /* Compare old and new ref equal */
- ref1 = erl_mk_long_ref(node, 4711, 113, 98, 0);
- ref2 = erl_mk_ref(node, 4711, 0);
- s = erl_encode(ref1, buf1);
- fprintf(dfile, "enc1 s = %d\n", s); fflush(dfile);
- s = erl_encode(ref2, buf2);
- fprintf(dfile, "enc2 s = %d\n", s); fflush(dfile);
- s = erl_compare_ext(buf1, buf2);
- fprintf(dfile, "comp s = %d\n", s); fflush(dfile);
-
- /* Compare, in another way */
- s = erl_match(ref1, ref2);
- fprintf(dfile, "match s = %d\n", s); fflush(dfile);
-#endif
-
- fclose(dfile);
-
- erl_close_connection(fd);
-
- return 0;
-}
diff --git a/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c b/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c
deleted file mode 100644
index d97f218a26..0000000000
--- a/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c
+++ /dev/null
@@ -1,1604 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 1997-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-
-/*
- * Purpose: Tests the functions in erl_eterm.c and erl_malloc.c.
- * Author: Bjorn Gustavsson
- *
- * See the erl_eterm_SUITE.erl file for a "table of contents".
- */
-
-#include <stdio.h>
-#include <string.h>
-
-#include "runner.h"
-
-/*
- * Find out which version of erl_interface we are using.
- */
-
-#ifdef ERL_IS_STRING
-#undef NEW_ERL_INTERFACE
-#else
-#define NEW_ERL_INTERFACE
-#endif
-
-void dump_term (FILE *fp, ETERM *t);
-
-static ETERM* all_types();
-
-/***********************************************************************
- *
- * 1. B a s i c t e s t s
- *
- ***********************************************************************/
-
-/*
- * Sends a list contaning all data types to the Erlang side.
- */
-
-TESTCASE(build_terms)
-{
- ETERM* t;
-
- erl_init(NULL, 0);
- t = all_types();
- send_term(t);
- report(1);
-}
-
-static int abs_and_sign(ETERM* v, unsigned long long* av, int* sign)
-{
- long long sv;
- switch (ERL_TYPE(v)) {
- case ERL_INTEGER: sv = ERL_INT_VALUE(v); break;
- case ERL_U_INTEGER: *av = ERL_INT_UVALUE(v); *sign = 0; return 1;
- case ERL_LONGLONG: sv = ERL_LL_VALUE(v); break;
- case ERL_U_LONGLONG: *av = ERL_LL_UVALUE(v); *sign = 0; return 1;
- default: return 0;
- }
- if (sv < 0) {
- *av = -sv;
- *sign = 1;
- }
- else {
- *av = sv;
- *sign = 0;
- }
- return 1;
-}
-
-/* Shouldn't erl_match() cope with this?
-*/
-static int eq_ints(ETERM* a, ETERM* b)
-{
- unsigned long long a_abs, b_abs;
- int a_sign, b_sign;
- return abs_and_sign(a, &a_abs, &a_sign) && abs_and_sign(b, &b_abs, &b_sign)
- && (a_abs == b_abs) && (a_sign == b_sign);
-}
-
-static void encode_decode(ETERM* original, const char* text)
-{
- static unsigned char encoded[16*1024];
- ETERM* new_terms;
- ETERM* head;
- int bytes;
- int len;
-
- /* If a list, check the elements one by one first */
- head = erl_hd(original);
- if (head != NULL) {
- encode_decode(head, "CAR");
- encode_decode(erl_tl(original), "CDR");
- }
-
- bytes = erl_encode(original, encoded);
- if (bytes == 0) {
- fail("failed to encode terms");
- }
- else if (bytes > sizeof(encoded)) {
- fail("encoded terms buffer overflow");
- }
- else if (bytes != (len=erl_term_len(original))) {
- fprintf(stderr, "bytes(%d) != len(%d) for term ", bytes, len);
- erl_print_term(stderr, original);
- fprintf(stderr, " [%s]\r\n", text);
- fail("erl_encode and erl_term_len do not agree");
- }
- else if ((new_terms = erl_decode(encoded)) == NULL) {
- fail("failed to decode terms");
- }
- else if (!erl_match(original, new_terms) && !eq_ints(original, new_terms)) {
- erl_print_term(stderr, original);
- fprintf(stderr, "(%i) != (%i)", ERL_TYPE(original), ERL_TYPE(new_terms));
- erl_print_term(stderr, new_terms);
- fprintf(stderr, " [%s]\r\n", text);
- fail("decoded terms didn't match original");
- }
- erl_free_term(original);
- erl_free_term(new_terms);
-}
-/*
- * Converts an Erlang term to the external term format and back again.
- */
-
-TESTCASE(round_trip_conversion)
-{
- int n, i;
-
- erl_init(NULL, 0);
- encode_decode(all_types(), "ALL");
-
- {
- int v;
- for (v = 8, n = 0; n < (sizeof(v)*8-4-1); v <<= 1, n++) {
- for (i=-4; i<4; i++) {
- encode_decode(erl_mk_int(v+i), "INT");
- encode_decode(erl_mk_int(-(v+i)), "NEG INT");
- }
- }
- }
- {
- unsigned int v;
- for (v = 8; v; v <<= 1) {
- for (i=-4; i<4; i++) {
- encode_decode(erl_mk_uint(v+i), "UINT");
- }
- }
- }
- {
- long long v;
- for (v = 8, n = 0; n < (sizeof(v)*8-4-1); v <<= 1, n++) {
- for (i=-4; i<4; i++) {
- encode_decode(erl_mk_longlong(v+i), "LONGLONG");
- encode_decode(erl_mk_longlong(-(v+i)), "NEG LONGLONG");
- }
- }
- }
- {
- unsigned long long v;
- for (v = 8; v; v <<= 1) {
- for (i=-4; i<4; i++) {
- encode_decode(erl_mk_ulonglong(v+i), "ULONGLONG");
- }
- }
- }
-
- report(1);
-}
-
-/*
- * Decodes data from the Erlang side and verifies.
- */
-
-TESTCASE(decode_terms)
-{
- ETERM* terms;
- char* message;
-
- erl_init(NULL, 0);
- terms = get_term();
- if (terms == NULL) {
- fail("unexpected end of file");
- } else {
- ETERM* all;
- ETERM* p;
- ETERM* t;
- int i;
-
- all = p = all_types();
- t = terms;
-
- /*
- * XXX For now, skip the reference, pid, and port, because
- * the match will fail. Must write code here to do some other
- * validating.
- */
-
- for (i=0; i<6; i++) {
-
- p = erl_tl(p);
- t = erl_tl(t);
- erl_free_term(p);
- erl_free_term(t);
-
- }
-
- /*
- * Match the tail of the lists.
- */
-
- if (!erl_match(p, t))
- {
- fail("Received terms didn't match expected");
- }
- erl_free_term(all);
- erl_free_term(terms);
- report(1);
- }
-}
-
-/*
- * Decodes a float from the Erlang side and verifies.
- */
-
-TESTCASE(decode_float)
-{
- ETERM* afnum;
- ETERM* efnum;
- int result;
-
- erl_init(NULL, 0);
- afnum = get_term();
- efnum = erl_mk_float(3.1415);
- result = erl_match(efnum, afnum);
- erl_free_term(afnum);
- erl_free_term(efnum);
- report(result);
-}
-
-/*
- * Tests the erl_free_compound() function.
- */
-
-TESTCASE(t_erl_free_compound)
-{
- ETERM* t;
-
- erl_init(NULL, 0);
-
- t = all_types();
- erl_free_compound(t);
- report(1);
-}
-
-
-/***********************************************************************
- *
- * 2. C o n s t r u c t i n g t e r m s
- *
- ***********************************************************************/
-
-/*
- * Makes various integers, and sends them to Erlang for verification.
- */
-
-TESTCASE(t_erl_mk_int)
-{
-#define SEND_INT(i) \
- do { \
- ETERM* t = erl_mk_int(i); \
- send_term(t); \
- } while (0);
-
- erl_init(NULL, 0);
-
- SEND_INT(0);
- SEND_INT(127);
- SEND_INT(128);
- SEND_INT(255);
- SEND_INT(256);
-
- SEND_INT(0xFFFF);
- SEND_INT(0x10000);
-
- SEND_INT(0x07FFFFFF);
- SEND_INT(0x0FFFFFFF);
- SEND_INT(0x1FFFFFFF);
- SEND_INT(0x3FFFFFFF);
- SEND_INT(0x7FFFFFFF);
-
- SEND_INT(0x08000000);
- SEND_INT(0x10000000);
- SEND_INT(0x20000000);
- SEND_INT(0x40000000);
-
- SEND_INT(-0x07FFFFFF);
- SEND_INT(-0x0FFFFFFF);
- SEND_INT(-0x1FFFFFFF);
- SEND_INT(-0x3FFFFFFF);
- SEND_INT(-0x7FFFFFFF);
-
- SEND_INT(-0x08000000);
- SEND_INT(-0x10000000);
- SEND_INT(-0x20000000);
- SEND_INT(-0x40000000);
-
- SEND_INT(-0x08000001);
- SEND_INT(-0x10000001);
- SEND_INT(-0x20000001);
- SEND_INT(-0x40000001);
-
- SEND_INT(-0x08000002);
- SEND_INT(-0x10000002);
- SEND_INT(-0x20000002);
- SEND_INT(-0x40000002);
-
- SEND_INT(-1999999999);
- SEND_INT(-2000000000);
- SEND_INT(-2000000001);
-
- report(1);
-}
-
-
-/*
- * Makes lists of various sizes, and sends them to Erlang for verification.
- */
-
-TESTCASE(t_erl_mk_list)
-{
- ETERM* a[4];
-
- erl_init(NULL, 0);
-
- /*
- * Empty list.
- */
-
- send_term(erl_mk_list(a, 0));
-
- /*
- * One element: [abc]
- */
-
- a[0] = erl_mk_atom("abc");
- send_term(erl_mk_list(a, 1));
- erl_free_term(a[0]);
-
- /*
- * Two elements: [abcdef, 42].
- */
-
- a[0] = erl_mk_atom("abcdef");
- a[1] = erl_mk_int(42);
- send_term(erl_mk_list(a, 2));
- erl_free_term(a[0]);
- erl_free_term(a[1]);
-
- /*
- * Four elements.
- */
-
- a[0] = erl_mk_float(0.0);
- a[1] = erl_mk_int(23);
- a[2] = erl_mk_empty_list();
- a[3] = erl_mk_float(3.1415);
- send_term(erl_mk_list(a, 4));
- erl_free_term(a[0]);
- erl_free_term(a[1]);
- erl_free_term(a[2]);
- erl_free_term(a[3]);
-
- report(1);
-}
-
-/*
- * A basic test of erl_copy_term().
- */
-
-TESTCASE(basic_copy)
-{
- ETERM* original;
- ETERM* copy;
- int result;
-
- erl_init(NULL, 0);
- original = all_types();
- copy = erl_copy_term(original);
- if (copy == NULL) {
- fail("erl_copy_term() failed");
- } else if (!erl_match(original, copy))
- {
- fail("copy doesn't match original");
- }
-
- erl_free_term(original);
- erl_free_term(copy);
- report(1);
-}
-
-
-/*
- * A basic test of erl_mk_atom().
- */
-
-TESTCASE(t_erl_mk_atom)
-{
- erl_init(NULL, 0);
-
- send_term(erl_mk_atom("madonna"));
- send_term(erl_mk_atom("Madonna"));
- send_term(erl_mk_atom("mad donna"));
- send_term(erl_mk_atom("_madonna_"));
- send_term(erl_mk_atom("/home/madonna/tour_plan"));
- send_term(erl_mk_atom("http://www.madonna.com/tour_plan"));
- send_term(erl_mk_atom("\'madonna\'"));
- send_term(erl_mk_atom("\"madonna\""));
- send_term(erl_mk_atom("\\madonna\\"));
- send_term(erl_mk_atom("{madonna,21,'mad donna',12}"));
-
- report(1);
-}
-
-
-/*
- * A basic test of erl_mk_binary().
- */
-
-TESTCASE(t_erl_mk_binary)
-{
-
- char* string;
- erl_init(NULL, 0);
-
- string = "{madonna,21,'mad donna',1234.567.890, !#$%&/()=?+-@, \" \\}";
- send_term(erl_mk_binary(string,strlen(string)));
-
- report(1);
-}
-
-
-/*
- * A basic test of erl_mk_empty_list().
- */
-
-TESTCASE(t_erl_mk_empty_list)
-{
- erl_init(NULL, 0);
-
- send_term(erl_mk_empty_list());
- report(1);
-}
-
-
-/*
- * A basic test of erl_mk_float().
- */
-
-TESTCASE(t_erl_mk_float)
-{
- ETERM* arr[6];
- ETERM* emsg;
-
- erl_init(NULL, 0);
-
- arr[0] = erl_mk_float(3.1415);
- arr[1] = erl_mk_float(1.999999);
- arr[2] = erl_mk_float(2.000000);
- arr[3] = erl_mk_float(2.000001);
- arr[4] = erl_mk_float(2.000002);
- arr[5] = erl_mk_float(12345.67890);
- emsg = (erl_mk_tuple(arr,6));
-
- send_term(emsg);
-
- erl_free_array(arr,6);
- /* emsg already freed by send_term() */
- /* erl_free_term(emsg); */
-
- report(1);
-}
-
-
-/*
- * A basic test of erl_mk_pid().
- */
-
-TESTCASE(t_erl_mk_pid)
-{
- erl_init(NULL, 0);
-
- send_term(erl_mk_pid("kalle@localhost", 3, 2, 1));
- report(1);
-}
-
-/*
- * A basic test of erl_mk_pid().
- */
-
-TESTCASE(t_erl_mk_xpid)
-{
- erl_init(NULL, 0);
-
- send_term(erl_mk_pid("kalle@localhost", 32767, 8191, 1));
- report(1);
-}
-
-
-/*
- * A basic test of erl_mk_port().
- */
-
-TESTCASE(t_erl_mk_port)
-{
- erl_init(NULL, 0);
-
- send_term(erl_mk_port("kalle@localhost", 4, 1));
- report(1);
-}
-
-/*
- * A basic test of erl_mk_port().
- */
-
-TESTCASE(t_erl_mk_xport)
-{
- erl_init(NULL, 0);
-
- send_term(erl_mk_port("kalle@localhost", 268435455, 1));
- report(1);
-}
-
-/*
- * A basic test of erl_mk_ref().
- */
-
-TESTCASE(t_erl_mk_ref)
-{
- erl_init(NULL, 0);
-
- send_term(erl_mk_ref("kalle@localhost", 6, 1));
- report(1);
-}
-
-/*
- * A basic test of erl_mk_long_ref().
- */
-
-
-TESTCASE(t_erl_mk_long_ref)
-{
- erl_init(NULL, 0);
-
- send_term(erl_mk_long_ref("kalle@localhost",
- 4294967295, 4294967295, 262143,
- 1));
- report(1);
-}
-
-
-/*
- * A basic test of erl_mk_string().
- */
-
-TESTCASE(t_erl_mk_string)
-{
-
- erl_init(NULL, 0);
-
- send_term(erl_mk_string("madonna"));
- send_term(erl_mk_string("Madonna"));
- send_term(erl_mk_string("mad donna"));
- send_term(erl_mk_string("_madonna_"));
- send_term(erl_mk_string("/home/madonna/tour_plan"));
- send_term(erl_mk_string("http://www.madonna.com/tour_plan"));
- send_term(erl_mk_string("\'madonna\'"));
- send_term(erl_mk_string("\"madonna\""));
- send_term(erl_mk_string("\\madonna\\"));
- send_term(erl_mk_string("{madonna,21,'mad donna',12}"));
-
- report(1);
-}
-
-
-/*
- * A basic test of erl_mk_estring().
- */
-
-TESTCASE(t_erl_mk_estring)
-{
- char* string;
- erl_init(NULL, 0);
-
- string = "madonna";
- send_term(erl_mk_estring(string,strlen(string)));
- string = "Madonna";
- send_term(erl_mk_estring(string,strlen(string)));
- string = "mad donna";
- send_term(erl_mk_estring(string,strlen(string)));
- string = "_madonna_";
- send_term(erl_mk_estring(string,strlen(string)));
- string = "/home/madonna/tour_plan";
- send_term(erl_mk_estring(string,strlen(string)));
- string = "http://www.madonna.com/tour_plan";
- send_term(erl_mk_estring(string,strlen(string)));
- string = "\'madonna\'";
- send_term(erl_mk_estring(string,strlen(string)));
- string = "\"madonna\"";
- send_term(erl_mk_estring(string,strlen(string)));
- string = "\\madonna\\";
- send_term(erl_mk_estring(string,strlen(string)));
- string = "{madonna,21,'mad donna',12}";
- send_term(erl_mk_estring(string,strlen(string)));
-
- report(1);
-}
-
-
-/*
- * A basic test of erl_mk_tuple().
- */
-
-TESTCASE(t_erl_mk_tuple)
-{
- ETERM* arr[4];
- ETERM* arr2[2];
- ETERM* arr3[2];
- ETERM* arr4[2];
-
- erl_init(NULL, 0);
-
- /* {madonna,21,'mad donna',12} */
- arr[0] = erl_mk_atom("madonna");
- arr[1] = erl_mk_int(21);
- arr[2] = erl_mk_atom("mad donna");
- arr[3] = erl_mk_int(12);
-
- send_term(erl_mk_tuple(arr,4));
-
- erl_free_array(arr,4);
-
-
- /* {'Madonna',21,{children,{"Isabella",2}},{'home page',"http://www.madonna.com/"} */
- arr4[0] = erl_mk_atom("home page");
- arr4[1] = erl_mk_string("http://www.madonna.com/");
-
- arr3[0] = erl_mk_string("Isabella");
- arr3[1] = erl_mk_int(2);
-
- arr2[0] = erl_mk_atom("children");
- arr2[1] = erl_mk_tuple(arr3,2);
-
- arr[0] = erl_mk_atom("Madonna");
- arr[1] = erl_mk_int(21);
- arr[2] = erl_mk_tuple(arr2,2);
- arr[3] = erl_mk_tuple(arr4,2);
-
- send_term(erl_mk_tuple(arr,4));
-
- erl_free_array(arr,4);
- erl_free_array(arr2,2);
- erl_free_array(arr3,2);
- erl_free_array(arr4,2);
-
-
- report(1);
-}
-
-
-/*
- * A basic test of erl_mk_uint().
- */
-
-TESTCASE(t_erl_mk_uint)
-{
- unsigned i;
-
- erl_init(NULL, 0);
-
- send_term(erl_mk_uint(54321));
- i = 2147483647;
- send_term(erl_mk_uint(i));
- send_term(erl_mk_uint(i+1));
- send_term(erl_mk_uint(i+2));
- send_term(erl_mk_uint(i+3));
- send_term(erl_mk_uint(i+i+1));
-
- report(1);
-}
-
-
-/*
- * A basic test of erl_mk_var().
- */
-
-TESTCASE(t_erl_mk_var)
-{
- ETERM* mk_var;
- ETERM* term;
- ETERM* term2;
- ETERM* arr[4];
- ETERM* arr_term[2];
- ETERM* mk_var_tuple;
- ETERM* term_tuple;
-
- erl_init(NULL, 0);
-
-
- /* match unbound/bound variable against an integer */
- term = erl_mk_int(17);
- term2 = erl_mk_int(2);
- mk_var = erl_mk_var("New_var");
- send_term(erl_mk_int(erl_match(mk_var, term))); /* should be ok */
- send_term(erl_mk_int(erl_match(mk_var, term2))); /* should fail */
- send_term(erl_mk_int(erl_match(mk_var, term))); /* should be ok */
- send_term(erl_mk_int(erl_match(mk_var, term2))); /* should fail */
- erl_free_term(mk_var);
- erl_free_term(term);
- erl_free_term(term2);
-
- /* match unbound variable against a tuple */
- arr[0] = erl_mk_atom("madonna");
- arr[1] = erl_mk_int(21);
- arr[2] = erl_mk_atom("mad donna");
- arr[3] = erl_mk_int(12);
- mk_var = erl_mk_var("New_var");
- term = erl_mk_tuple(arr,4);
- send_term(erl_mk_int(erl_match(mk_var, term))); /* should be ok */
- erl_free_term(mk_var);
- erl_free_term(term);
- erl_free_array(arr,4);
-
-
- /* match (twice) unbound variable against an incorrect tuple */
- arr[0] = erl_mk_var("New_var");
- arr[1] = erl_mk_var("New_var");
- arr_term[0] = erl_mk_int(17);
- arr_term[1] = erl_mk_int(27);
- mk_var_tuple = erl_mk_tuple(arr,2);
- term_tuple = erl_mk_tuple(arr_term,2);
- send_term(erl_mk_int(erl_match(mk_var_tuple, term_tuple))); /* should fail */
- erl_free_array(arr,2);
- erl_free_array(arr_term,2);
- erl_free_term(mk_var_tuple);
- erl_free_term(term_tuple);
-
-
- /* match (twice) unbound variable against a correct tuple */
- arr[0] = erl_mk_var("New_var");
- arr[1] = erl_mk_var("New_var");
- arr_term[0] = erl_mk_int(17);
- arr_term[1] = erl_mk_int(17);
- mk_var_tuple = erl_mk_tuple(arr,2);
- term_tuple = erl_mk_tuple(arr_term,2);
- send_term(erl_mk_int(erl_match(mk_var_tuple, term_tuple))); /* should be ok */
- erl_free_array(arr,2);
- erl_free_array(arr_term,2);
- erl_free_term(mk_var_tuple);
- erl_free_term(term_tuple);
-
- report(1);
-}
-
-
-/*
- * A basic test of erl_size().
- */
-
-TESTCASE(t_erl_size)
-{
- ETERM* arr[4];
- ETERM* tuple;
- ETERM* bin;
- char* string;
-
- erl_init(NULL, 0);
-
- /* size of a tuple */
- tuple = erl_format("{}");
- send_term(erl_mk_int(erl_size(tuple)));
- erl_free_term(tuple);
-
- arr[0] = erl_mk_atom("madonna");
- arr[1] = erl_mk_int(21);
- arr[2] = erl_mk_atom("mad donna");
- arr[3] = erl_mk_int(12);
- tuple = erl_mk_tuple(arr,4);
-
- send_term(erl_mk_int(erl_size(tuple)));
-
- erl_free_array(arr,4);
- erl_free_term(tuple);
-
- /* size of a binary */
- string = "";
- bin = erl_mk_binary(string,strlen(string));
- send_term(erl_mk_int(erl_size(bin)));
- erl_free_term(bin);
-
- string = "{madonna,21,'mad donna',12}";
- bin = erl_mk_binary(string,strlen(string));
- send_term(erl_mk_int(erl_size(bin)));
- erl_free_term(bin);
-
- report(1);
-}
-
-
-/*
- * A basic test of erl_var_content().
- */
-
-TESTCASE(t_erl_var_content)
-{
- ETERM* mk_var;
- ETERM* term;
- ETERM* tuple;
- ETERM* list;
- ETERM* a;
- ETERM* b;
- ETERM* arr[4];
- ETERM* arr2[2];
- ETERM* arr3[2];
- ETERM* arr4[2];
-
- erl_init(NULL, 0);
-
- term = erl_mk_int(17);
- mk_var = erl_mk_var("Var");
-
- /* unbound, should return NULL */
- if (erl_var_content(mk_var,"Var") != NULL)
- fail("t_erl_var_content() failed");
-
- erl_match(mk_var, term);
- send_term(erl_var_content(mk_var,"Var")); /* should return 17 */
-
- /* integer, should return NULL */
- if (erl_var_content(term,"Var") != NULL)
- fail("t_erl_var_content() failed");
-
- /* unknown variable, should return NULL */
- if (erl_var_content(mk_var,"Unknown_Var") != NULL)
- fail("t_erl_var_content() failed");
-
- erl_free_term(mk_var);
- erl_free_term(term);
-
- /* {'Madonna',21,{children,{"Name","Age"}},{"Home_page","Tel_no"}} */
- arr4[0] = erl_mk_var("Home_page");
- arr4[1] = erl_mk_var("Tel_no");
- a = erl_mk_string("http://www.madonna.com");
- erl_match(arr4[0], a);
-
- arr3[0] = erl_mk_var("Name");
- arr3[1] = erl_mk_var("Age");
- b = erl_mk_int(2);
- erl_match(arr3[1], b);
-
- arr2[0] = erl_mk_atom("children");
- arr2[1] = erl_mk_tuple(arr3,2);
-
- arr[0] = erl_mk_atom("Madonna");
- arr[1] = erl_mk_int(21);
- arr[2] = erl_mk_tuple(arr2,2);
- arr[3] = erl_mk_tuple(arr4,2);
-
- tuple = erl_mk_tuple(arr,4);
-
- /* should return "http://www.madonna.com" */
- send_term(erl_var_content(tuple,"Home_page"));
-
- /* unbound, should return NULL */
- if (erl_var_content(tuple,"Tel_no") != NULL)
- fail("t_erl_var_content() failed");
-
- /* unbound, should return NULL */
- if (erl_var_content(tuple,"Name") != NULL)
- fail("t_erl_var_content() failed");
-
- /* should return 2 */
- send_term(erl_var_content(tuple,"Age"));
-
- erl_free_array(arr,4);
- erl_free_array(arr2,2);
- erl_free_array(arr3,2);
- erl_free_array(arr4,2);
- erl_free_term(tuple);
- erl_free_term(a);
- erl_free_term(b);
-
-
- /* [] */
- list = erl_mk_empty_list();
- if (erl_var_content(list,"Tel_no") != NULL)
- fail("t_erl_var_content() failed");
- erl_free_term(list);
-
-
- /* ['Madonna',[],{children,{"Name","Age"}},{"Home_page","Tel_no"}] */
- arr4[0] = erl_mk_var("Home_page");
- arr4[1] = erl_mk_var("Tel_no");
- a = erl_mk_string("http://www.madonna.com");
- erl_match(arr4[0], a);
-
- arr3[0] = erl_mk_var("Name");
- arr3[1] = erl_mk_var("Age");
- b = erl_mk_int(2);
- erl_match(arr3[1], b);
-
- arr2[0] = erl_mk_atom("children");
- arr2[1] = erl_mk_tuple(arr3,2);
-
- arr[0] = erl_mk_atom("Madonna");
- arr[1] = erl_mk_empty_list();
- arr[2] = erl_mk_tuple(arr2,2);
- arr[3] = erl_mk_tuple(arr4,2);
-
- list = erl_mk_list(arr,4);
-
- /* should return "http://www.madonna.com" */
- send_term(erl_var_content(list,"Home_page"));
-
- /* unbound, should return NULL */
- if (erl_var_content(list,"Tel_no") != NULL)
- fail("t_erl_var_content() failed");
-
- /* unbound, should return NULL */
- if (erl_var_content(list,"Name") != NULL)
- fail("t_erl_var_content() failed");
-
- /* should return 2 */
- send_term(erl_var_content(list,"Age"));
-
- erl_free_array(arr,4);
- erl_free_array(arr2,2);
- erl_free_array(arr3,2);
- erl_free_array(arr4,2);
- erl_free_term(list);
- erl_free_term(a);
- erl_free_term(b);
-
- report(1);
-}
-
-
-/*
- * A basic test of erl_element().
- */
-
-TESTCASE(t_erl_element)
-{
- ETERM* arr[4];
- ETERM* arr2[2];
- ETERM* arr3[2];
- ETERM* arr4[2];
- ETERM* tuple;
-
- erl_init(NULL, 0);
-
- arr[0] = erl_mk_atom("madonna");
- arr[1] = erl_mk_int(21);
- arr[2] = erl_mk_atom("mad donna");
- arr[3] = erl_mk_int(12);
- tuple = erl_mk_tuple(arr,4);
-
- send_term(erl_element(1,tuple));
- send_term(erl_element(2,tuple));
- send_term(erl_element(3,tuple));
- send_term(erl_element(4,tuple));
-
- erl_free_array(arr,4);
- erl_free_term(tuple);
-
- /* {'Madonna',21,{children,{"Isabella",2}},{'home page',"http://www.madonna.com/"} */
- arr4[0] = erl_mk_atom("home page");
- arr4[1] = erl_mk_string("http://www.madonna.com/");
-
- arr3[0] = erl_mk_string("Isabella");
- arr3[1] = erl_mk_int(2);
-
- arr2[0] = erl_mk_atom("children");
- arr2[1] = erl_mk_tuple(arr3,2);
-
- arr[0] = erl_mk_atom("Madonna");
- arr[1] = erl_mk_int(21);
- arr[2] = erl_mk_tuple(arr2,2);
- arr[3] = erl_mk_tuple(arr4,2);
-
- tuple = erl_mk_tuple(arr,4);
- send_term(erl_element(1,tuple));
- send_term(erl_element(2,tuple));
- send_term(erl_element(3,tuple));
- send_term(erl_element(4,tuple));
-
- erl_free_term(tuple);
- erl_free_array(arr,4);
- erl_free_array(arr2,2);
- erl_free_array(arr3,2);
- erl_free_array(arr4,2);
-
- report(1);
-}
-
-
-/*
- * A basic test of erl_cons().
- */
-
-TESTCASE(t_erl_cons)
-{
- ETERM* list;
- ETERM* anAtom;
- ETERM* anInt;
-
- erl_init(NULL, 0);
-
- anAtom = erl_mk_atom("madonna");
- anInt = erl_mk_int(21);
- list = erl_mk_empty_list();
- list = erl_cons(anInt, list);
- send_term(erl_cons(anAtom, list));
-
- erl_free_term(anAtom);
- erl_free_term(anInt);
- erl_free_compound(list);
-
- report(1);
-}
-
-
-
-
-/***********************************************************************
- *
- * 3. E x t r a c t i n g & i n f o f u n c t i o n s
- *
- ***********************************************************************/
-
-/*
- * Calculates the length of each list sent to it and sends back the result.
- */
-
-TESTCASE(t_erl_length)
-{
- erl_init(NULL, 0);
-
- for (;;) {
- ETERM* term = get_term();
-
- if (term == NULL) {
- report(1);
- return;
- } else {
- ETERM* len_term;
-
- len_term = erl_mk_int(erl_length(term));
- erl_free_term(term);
- send_term(len_term);
- }
- }
-}
-
-/*
- * Gets the head of each term and sends the result back.
- */
-
-TESTCASE(t_erl_hd)
-{
- erl_init(NULL, 0);
-
- for (;;) {
- ETERM* term = get_term();
-
- if (term == NULL) {
- report(1);
- return;
- } else {
- ETERM* head;
-
- head = erl_hd(term);
- send_term(head);
- erl_free_term(term);
- }
- }
-}
-
-/*
- * Gets the tail of each term and sends the result back.
- */
-
-TESTCASE(t_erl_tl)
-{
- erl_init(NULL, 0);
-
- for (;;) {
- ETERM* term = get_term();
-
- if (term == NULL) {
- report(1);
- return;
- } else {
- ETERM* tail;
-
- tail = erl_tl(term);
- send_term(tail);
- erl_free_term(term);
- }
- }
-}
-
-/*
- * Checks the type checking macros.
- */
-
-TESTCASE(type_checks)
-{
- ETERM* t;
- ETERM* atom;
-
- erl_init(NULL, 0);
- atom = erl_mk_atom("an_atom");
-
-#define TYPE_CHECK(macro, term) \
- { ETERM* t = term; \
- if (macro(t)) { \
- erl_free_term(t); \
- } else { \
- fail("Macro " #macro " failed on " #term); \
- } \
- }
-
- TYPE_CHECK(ERL_IS_INTEGER, erl_mk_int(0x7FFFFFFF));
-#ifdef NEW_ERL_INTERFACE
- TYPE_CHECK(ERL_IS_UNSIGNED_INTEGER, erl_mk_uint(0x7FFFFFFF));
-#endif
- TYPE_CHECK(ERL_IS_FLOAT, erl_mk_float(5.5));
- TYPE_CHECK(ERL_IS_ATOM, erl_mk_atom("another_atom"));
-
- TYPE_CHECK(ERL_IS_EMPTY_LIST, erl_mk_empty_list());
- TYPE_CHECK(!ERL_IS_EMPTY_LIST, erl_cons(atom, atom));
-
-#ifdef NEW_ERL_INTERFACE
- TYPE_CHECK(!ERL_IS_CONS, erl_mk_empty_list());
- TYPE_CHECK(ERL_IS_CONS, erl_cons(atom, atom));
-#endif
-
- TYPE_CHECK(ERL_IS_LIST, erl_mk_empty_list());
- TYPE_CHECK(ERL_IS_LIST, erl_cons(atom, atom));
-
- TYPE_CHECK(ERL_IS_PID, erl_mk_pid("a@a", 42, 1, 1));
- TYPE_CHECK(ERL_IS_PORT, erl_mk_port("a@a", 42, 1));
- TYPE_CHECK(ERL_IS_REF, erl_mk_ref("a@a", 42, 1));
-
- TYPE_CHECK(ERL_IS_BINARY, erl_mk_binary("a", 1));
- TYPE_CHECK(ERL_IS_TUPLE, erl_mk_tuple(&atom, 1));
-#undef TYPE_CHECK
-
- erl_free_term(atom);
-
- report(1);
-}
-
-/*
- * Checks the extractor macros.
- */
-
-TESTCASE(extractor_macros)
-{
- ETERM* t;
-
- erl_init(NULL, 0);
-
-#ifdef NEW_ERL_INTERFACE
-#define MATCH(a, b) ((a) == (b) ? 1 : fail("bad match: " #a))
-#define STR_MATCH(a, b) (strcmp((a), (b)) ? fail("bad match: " #a) : 0)
-
- { /* Integer */
- int anInt = 0x7FFFFFFF;
- t = erl_mk_int(anInt);
- MATCH(ERL_INT_VALUE(t), anInt);
- MATCH(ERL_INT_UVALUE(t), anInt);
- erl_free_term(t);
- }
-
- { /* Float */
- double aFloat = 3.1415;
- t = erl_mk_float(aFloat);
- MATCH(ERL_FLOAT_VALUE(t), aFloat);
- erl_free_term(t);
- }
-
- { /* Atom. */
- char* aString = "nisse";
- t = erl_mk_atom(aString);
- if (memcmp(ERL_ATOM_PTR(t), aString, strlen(aString)) != 0)
- fail("bad match");
- MATCH(ERL_ATOM_SIZE(t), strlen(aString));
- erl_free_term(t);
- }
-
- { /* Pid. */
- char* node = "arne@strider";
- int number = 42;
- int serial = 5;
- int creation = 1;
-
- t = erl_mk_pid(node, number, serial, creation);
- STR_MATCH(ERL_PID_NODE(t), node);
- MATCH(ERL_PID_NUMBER(t), number);
- MATCH(ERL_PID_SERIAL(t), serial);
- MATCH(ERL_PID_CREATION(t), creation);
- erl_free_term(t);
- }
-
- { /* Port. */
- char* node = "kalle@strider";
- int number = 45;
- int creation = 1;
-
- t = erl_mk_port(node, number, creation);
- STR_MATCH(ERL_PORT_NODE(t), node);
- MATCH(ERL_PORT_NUMBER(t), number);
- MATCH(ERL_PORT_CREATION(t), creation);
- erl_free_term(t);
- }
-
- { /* Reference. */
- char* node = "kalle@strider";
- int number = 48;
- int creation = 1;
-
- t = erl_mk_ref(node, number, creation);
- STR_MATCH(ERL_REF_NODE(t), node);
- MATCH(ERL_REF_NUMBER(t), number);
- MATCH(ERL_REF_CREATION(t), creation);
- erl_free_term(t);
- }
-
- { /* Tuple. */
- ETERM* arr[2];
-
- arr[0] = erl_mk_int(51);
- arr[1] = erl_mk_int(52);
- t = erl_mk_tuple(arr, ASIZE(arr));
- MATCH(ERL_TUPLE_SIZE(t), ASIZE(arr));
- MATCH(ERL_TUPLE_ELEMENT(t, 0), arr[0]);
- MATCH(ERL_TUPLE_ELEMENT(t, 1), arr[1]);
- erl_free_array(arr, ASIZE(arr));
- erl_free_term(t);
- }
-
- { /* Binary. */
- static char bin[] = {1, 2, 3, 0, 4, 5};
-
- t = erl_mk_binary(bin, ASIZE(bin));
- MATCH(ERL_BIN_SIZE(t), ASIZE(bin));
- if (memcmp(ERL_BIN_PTR(t), bin, ASIZE(bin)) != 0)
- fail("bad match");
- erl_free_term(t);
- }
-
- {
- ETERM* head = erl_mk_atom("head");
- ETERM* tail = erl_mk_atom("tail");
-
- t = erl_cons(head, tail);
- MATCH(ERL_CONS_HEAD(t), head);
- MATCH(ERL_CONS_TAIL(t), tail);
- erl_free_term(head);
- erl_free_term(tail);
- erl_free_term(t);
- }
-#undef MATCH
-#undef STR_MATCH
-#endif
-
- report(1);
-}
-
-
-
-/***********************************************************************
- *
- * 4. I / O l i s t f u n c t i o n s
- *
- ***********************************************************************/
-
-/*
- * Invokes erl_iolist_length() on each term and send backs the result.
- */
-
-TESTCASE(t_erl_iolist_length)
-{
- erl_init(NULL, 0);
-
- for (;;) {
- ETERM* term = get_term();
-
- if (term == NULL) {
- report(1);
- return;
- } else {
-#ifndef NEW_ERL_INTERFACE
- fail("Function not present in this version of erl_interface");
-#else
- ETERM* len_term;
-
- len_term = erl_mk_int(erl_iolist_length(term));
- erl_free_term(term);
- send_term(len_term);
-#endif
- }
- }
-}
-
-/*
- * Invokes erl_iolist_to_binary() on each term and send backs the result.
- */
-
-TESTCASE(t_erl_iolist_to_binary)
-{
- erl_init(NULL, 0);
-
- for (;;) {
- ETERM* term = get_term();
-
- if (term == NULL) {
- report(1);
- return;
- } else {
-#ifndef NEW_ERL_INTERFACE
- fail("Function not present in this version of erl_interface");
-#else
- ETERM* new_term;
-
- new_term = erl_iolist_to_binary(term);
-
- erl_free_term(term);
- send_term(new_term);
-#endif
- }
- }
-}
-
-/*
- * Invokes erl_iolist_to_string() on each term and send backs the result.
- */
-
-TESTCASE(t_erl_iolist_to_string)
-{
- erl_init(NULL, 0);
-
- for (;;) {
- ETERM* term = get_term();
-
- if (term == NULL) {
- report(1);
- return;
- } else {
-#ifndef NEW_ERL_INTERFACE
- fail("Function not present in this version of erl_interface");
-#else
- char* result;
-
- result = erl_iolist_to_string(term);
- erl_free_term(term);
- if (result != NULL) {
- send_buffer(result, strlen(result)+1);
- erl_free(result);
- } else {
- send_term(NULL);
- }
-#endif
- }
- }
-}
-
-
-/***********************************************************************
- *
- * 5. M i s c e l l a n o u s T e s t s
- *
- ***********************************************************************/
-
-/*
- * Test some combinations of operations to verify that the reference pointers
- * are handled correctly.
- *
- * "Det verkar vara lite High Chaparal med minneshanteringen i erl_interface"
- * Per Lundgren, ERV.
- */
-
-TESTCASE(high_chaparal)
-{
- ETERM *L1, *A1, *L2, *A2, *L3;
-
- erl_init(NULL, 0);
-
- L1 = erl_mk_empty_list();
- A1 = erl_mk_atom("world");
- L2 = erl_cons(A1, L1);
- A2 = erl_mk_atom("hello");
- L3 = erl_cons(A2, L2);
-
- erl_free_term(L1);
- erl_free_term(A1);
- erl_free_term(L2);
- erl_free_term(A2);
-
- send_term(L3);
-
- /* already freed by send_term() */
- /* erl_free_term(L3);*/
-
- report(1);
-}
-
-/*
- * Test erl_decode to recover from broken list data (OTP-7448)
- */
-TESTCASE(broken_data)
-{
- ETERM* original;
- ETERM* new_terms;
- char encoded[16*1024];
- int n;
-
- erl_init(NULL, 0);
- original = all_types();
- if ((n=erl_encode(original, encoded)) == 0)
- {
- fail("failed to encode terms");
- } else
- {
- int offs = n/2;
- memset(encoded+offs,0,n-offs); /* destroy */
-
- if ((new_terms = erl_decode(encoded)) != NULL)
- {
- fail("decode accepted broken data");
- erl_free_term(new_terms);
- }
- }
- erl_free_term(original);
- report(1);
-}
-
-/*
- * Returns a list containing instances of all types.
- *
- * Be careful changing the contents of the list returned, because both
- * the build_terms() and decode_terms() test cases depend on it.
- */
-
-static ETERM*
-all_types(void)
-{
- ETERM* t;
- ETERM* terms[3];
- int i;
- static char a_binary[] = "A binary";
-
-#define CONS_AND_FREE(expr, tail) \
- do { \
- ETERM* term = expr; \
- ETERM* nl = erl_cons(term, tail); \
- erl_free_term(term); \
- erl_free_term(tail); \
- tail = nl; \
- } while (0)
-
- t = erl_mk_empty_list();
-
- CONS_AND_FREE(erl_mk_atom("I am an atom"), t);
- CONS_AND_FREE(erl_mk_binary("A binary", sizeof(a_binary)-1), t);
- CONS_AND_FREE(erl_mk_float(3.0), t);
- CONS_AND_FREE(erl_mk_int(0), t);
- CONS_AND_FREE(erl_mk_int(-1), t);
- CONS_AND_FREE(erl_mk_int(1), t);
-
- CONS_AND_FREE(erl_mk_string("A string"), t);
-
- terms[0] = erl_mk_atom("element1");
- terms[1] = erl_mk_int(42);
- terms[2] = erl_mk_int(767);
- CONS_AND_FREE(erl_mk_tuple(terms, ASIZE(terms)), t);
- for (i = 0; i < ASIZE(terms); i++) {
- erl_free_term(terms[i]);
- }
-
- CONS_AND_FREE(erl_mk_pid("kalle@localhost", 3, 2, 1), t);
- CONS_AND_FREE(erl_mk_pid("abcdefghijabcdefghij@localhost", 3, 2, 1), t);
- CONS_AND_FREE(erl_mk_port("kalle@localhost", 4, 1), t);
- CONS_AND_FREE(erl_mk_port("abcdefghijabcdefghij@localhost", 4, 1), t);
- CONS_AND_FREE(erl_mk_ref("kalle@localhost", 6, 1), t);
- CONS_AND_FREE(erl_mk_ref("abcdefghijabcdefghij@localhost", 6, 1), t);
- return t;
-
-#undef CONS_AND_FREE
-}
-
-/*
- * Dump (print for debugging) a term. Useful if/when things go wrong.
- */
-void
-dump_term (FILE *fp, ETERM *t)
-{
- if (fp == NULL) return;
-
- fprintf(fp, "#<%p ", t);
-
- if(t != NULL)
- {
- fprintf(fp, "count:%d, type:%d", ERL_COUNT(t), ERL_TYPE(t));
-
- switch(ERL_TYPE(t))
- {
- case ERL_UNDEF:
- fprintf(fp, "==undef");
- break;
- case ERL_INTEGER:
- fprintf(fp, "==int, val:%d", ERL_INT_VALUE(t));
- break;
- case ERL_U_INTEGER:
- fprintf(fp, "==uint, val:%u", ERL_INT_UVALUE(t));
- break;
- case ERL_FLOAT:
- fprintf(fp, "==float, val:%g", ERL_FLOAT_VALUE(t));
- break;
- case ERL_ATOM:
- fprintf(fp, "==atom, name:%p \"%s\"",
- ERL_ATOM_PTR(t), ERL_ATOM_PTR(t));
- break;
- case ERL_BINARY:
- fprintf(fp, "==binary, data:%p,%u",
- ERL_BIN_PTR(t), ERL_BIN_SIZE(t));
- break;
- case ERL_PID:
- fprintf(fp, "==pid, node:%p \"%s\"",
- ERL_PID_NODE(t), ERL_PID_NODE(t));
- break;
- case ERL_PORT:
- fprintf(fp, "==port, node:%p \"%s\"",
- ERL_PORT_NODE(t), ERL_PORT_NODE(t));
- break;
- case ERL_REF:
- fprintf(fp, "==ref, node:%p \"%s\"",
- ERL_REF_NODE(t), ERL_REF_NODE(t));
- break;
- case ERL_CONS:
- fprintf(fp, "==cons");
- fprintf(fp, ", car:");
- dump_term(fp, ERL_CONS_HEAD(t));
- fprintf(fp, ", cdr:");
- dump_term(fp, ERL_CONS_TAIL(t));
- break;
- case ERL_NIL:
- fprintf(fp, "==nil");
- break;
- case ERL_TUPLE:
- fprintf(fp, "==tuple, elems:%p,%u",
- ERL_TUPLE_ELEMS(t), ERL_TUPLE_SIZE(t));
- {
- size_t i;
- for(i = 0; i < ERL_TUPLE_SIZE(t); i++)
- {
- fprintf(fp, "elem[%u]:", i);
- dump_term(fp, ERL_TUPLE_ELEMENT(t, i));
- }
- }
- break;
- case ERL_VARIABLE:
- fprintf(fp, "==variable, name:%p \"%s\"",
- ERL_VAR_NAME(t), ERL_VAR_NAME(t));
- fprintf(fp, ", value:");
- dump_term(fp, ERL_VAR_VALUE(t));
- break;
-
- default:
- break;
- }
- }
- fprintf(fp, ">");
-}
-
diff --git a/lib/erl_interface/test/erl_eterm_SUITE_data/print_term.c b/lib/erl_interface/test/erl_eterm_SUITE_data/print_term.c
deleted file mode 100644
index 5b7cb1aec8..0000000000
--- a/lib/erl_interface/test/erl_eterm_SUITE_data/print_term.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 1997-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-
-/*
- * Purpose: Test the erl_print_term() function.
- * Author: Bjorn Gustavsson
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#ifndef __WIN32__
-#include <unistd.h>
-#endif
-
-#include "erl_interface.h"
-
-#ifndef __WIN32__
-#define _O_BINARY 0
-#define _setmode(fd, mode)
-#endif
-
-#define HEADER_SIZE 2
-
-static int readn(int, unsigned char*, int);
-
-/*
- * This program doesn't use the runner, because it needs a packet
- * on input, but the result will be as a stream of bytes (since
- * erl_print_term() prints directly on a file).
- *
- * Input is a package of with a packet header size of two bytes.
- *
- * +------------------------------------------------------------+
- * | length | Encoded term... |
- * | (2 bytes) | (as given by "length") |
- * +------------------------------------------------------------+
- *
- * <------------------- length --------------------->
- *
- * This program decodes the encoded terms and passes it to
- * erl_print_term(). Then this program prints
- *
- * CR <result> LF
- *
- * and waits for a new package. <result> is the return value from
- * erl_print_term(), formatted as an ASCII string.
- */
-
-#ifdef VXWORKS
-int print_term()
-#else
-int main()
-#endif
-{
- _setmode(0, _O_BINARY);
- _setmode(1, _O_BINARY);
-
- erl_init(NULL, 0);
-
- for (;;) {
- char buf[4*1024];
- ETERM* term;
- char* message;
- int n;
-
- if (readn(0, buf, 2) <= 0) {
- /* fprintf(stderr, "error reading message header\n"); */
- /* actually this is where we leave the infinite loop */
- exit(1);
- }
- n = buf[0] * 256 + buf[1];
- if (readn(0, buf, n) < 0) {
- fprintf(stderr, "error reading message contents\n");
- exit(1);
- }
-
- term = erl_decode(buf);
- if (term == NULL) {
- fprintf(stderr, "erl_decode() failed\n");
- exit(1);
- }
- n = erl_print_term(stdout, term);
- erl_free_compound(term);
- fprintf(stdout,"\r%d\n", n);
- fflush(stdout);
- }
-}
-
-/*
- * Reads len number of bytes.
- */
-
-static int
-readn(fd, buf, len)
- int fd; /* File descriptor to read from. */
- unsigned char *buf; /* Store in this buffer. */
- int len; /* Number of bytes to read. */
-{
- int n; /* Byte count in last read call. */
- int sofar = 0; /* Bytes read so far. */
-
- do {
- if ((n = read(fd, buf+sofar, len-sofar)) <= 0)
- /* error or EOF in read */
- return(n);
- sofar += n;
- } while (sofar < len);
- return sofar;
-}
-
diff --git a/lib/erl_interface/test/erl_format_SUITE.erl b/lib/erl_interface/test/erl_format_SUITE.erl
deleted file mode 100644
index 69dfdcc4c8..0000000000
--- a/lib/erl_interface/test/erl_format_SUITE.erl
+++ /dev/null
@@ -1,135 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2018. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
--module(erl_format_SUITE).
-
--include_lib("common_test/include/ct.hrl").
--include("erl_format_SUITE_data/format_test_cases.hrl").
-
--export([all/0, suite/0,
- init_per_testcase/2,
- atoms/1, tuples/1, lists/1]).
-
--import(runner, [get_term/1]).
-
-%% This test suite test the erl_format() function.
-%% It uses the port program "format_test".
-
-suite() ->
- [{ct_hooks,[ts_install_cth]}].
-
-all() ->
- [atoms, tuples, lists].
-
-init_per_testcase(Case, Config) ->
- runner:init_per_testcase(?MODULE, Case, Config).
-
-%% Tests formatting various atoms.
-
-atoms(Config) when is_list(Config) ->
- P = runner:start(Config, ?atoms),
-
- {term, ''} = get_term(P),
- {term, 'a'} = get_term(P),
- {term, 'A'} = get_term(P),
- {term, 'abc'} = get_term(P),
- {term, 'Abc'} = get_term(P),
- {term, 'ab@c'} = get_term(P),
- {term, 'The rain in Spain stays mainly in the plains'} = get_term(P),
-
- {term, a} = get_term(P),
- {term, ab} = get_term(P),
- {term, abc} = get_term(P),
- {term, ab@c} = get_term(P),
- {term, abcdefghijklmnopq} = get_term(P),
-
- {term, ''} = get_term(P),
- {term, 'a'} = get_term(P),
- {term, 'A'} = get_term(P),
- {term, 'abc'} = get_term(P),
- {term, 'Abc'} = get_term(P),
- {term, 'ab@c'} = get_term(P),
- {term, 'The rain in Spain stays mainly in the plains'} = get_term(P),
-
- {term, a} = get_term(P),
- {term, ab} = get_term(P),
- {term, abc} = get_term(P),
- {term, ab@c} = get_term(P),
- {term, ' abcdefghijklmnopq '} = get_term(P),
-
- runner:recv_eot(P),
- ok.
-
-
-
-%% Tests formatting various tuples
-
-tuples(Config) when is_list(Config) ->
- P = runner:start(Config, ?tuples),
-
- {term, {}} = get_term(P),
- {term, {a}} = get_term(P),
- {term, {a, b}} = get_term(P),
- {term, {a, b, c}} = get_term(P),
- {term, {1}} = get_term(P),
- {term, {[]}} = get_term(P),
- {term, {[], []}} = get_term(P),
- {term, {[], a, b, c}} = get_term(P),
- {term, {[], a, [], b, c}} = get_term(P),
- {term, {[], a, '', b, c}} = get_term(P),
-
- runner:recv_eot(P),
- ok.
-
-
-
-%% Tests formatting various lists
-
-lists(Config) when is_list(Config) ->
- P = runner:start(Config, ?lists),
-
- {term, []} = get_term(P),
- {term, [a]} = get_term(P),
- {term, [a, b]} = get_term(P),
- {term, [a, b, c]} = get_term(P),
- {term, [1]} = get_term(P),
- {term, [[]]} = get_term(P),
- {term, [[], []]} = get_term(P),
- {term, [[], a, b, c]} = get_term(P),
- {term, [[], a, [], b, c]} = get_term(P),
- {term, [[], a, '', b, c]} = get_term(P),
-
- {term, [{name, 'Madonna'}, {age, 21}, {data, [{addr, "E-street", 42}]}]} = get_term(P),
- case os:type() of
- vxworks ->
- {term, [{pi, _}, {'cos(70)', _}]} = get_term(P),
- {term, [[pi, _], ['cos(70)', _]]} = get_term(P),
- {term, [[pi, _], [], ["cos(70)", _]]} = get_term(P);
- _ ->
- {term, [{pi, 3.1415}, {'cos(70)', 0.34202}]} = get_term(P),
- {term, [[pi, 3.1415], ['cos(70)', 0.34202]]} = get_term(P),
- {term, [[pi, 3.1415], [], ["cos(70)", 0.34202]]} = get_term(P)
- end,
-
- {term, [-1]} = get_term(P),
-
- runner:recv_eot(P),
- ok.
diff --git a/lib/erl_interface/test/erl_format_SUITE_data/Makefile.first b/lib/erl_interface/test/erl_format_SUITE_data/Makefile.first
deleted file mode 100644
index acbb8c98bb..0000000000
--- a/lib/erl_interface/test/erl_format_SUITE_data/Makefile.first
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2000-2016. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# %CopyrightEnd%
-#
-
-format_test_decl.c: format_test.c
- erl -noinput -pa ../all_SUITE_data -s init_tc run format_test -s erlang halt
diff --git a/lib/erl_interface/test/erl_format_SUITE_data/Makefile.src b/lib/erl_interface/test/erl_format_SUITE_data/Makefile.src
deleted file mode 100644
index 2ba59ab651..0000000000
--- a/lib/erl_interface/test/erl_format_SUITE_data/Makefile.src
+++ /dev/null
@@ -1,43 +0,0 @@
-#
-# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1997-2016. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# %CopyrightEnd%
-#
-
-include @erl_interface_mk_include@
-
-CC0 = @CC@
-CC = ..@DS@all_SUITE_data@DS@gccifier@exe@ -CC"$(CC0)"
-LD = @LD@
-LIBERL = @erl_interface_lib@
-LIBEI = @erl_interface_eilib@
-LIBFLAGS = ../all_SUITE_data/runner@obj@ \
- $(LIBERL) $(LIBEI) @LIBS@ @erl_interface_sock_libs@ \
- @erl_interface_threadlib@
-CFLAGS = @EI_CFLAGS@ $(THR_DEFS) -I@erl_interface_include@ -I../all_SUITE_data
-FORMAT_OBJS = format_test@obj@ format_test_decl@obj@
-
-all: format_test@exe@
-
-clean:
- $(RM) $(FORMAT_OBJS)
- $(RM) format_test@exe@
-
-format_test@exe@: $(FORMAT_OBJS) $(LIBERL) $(LIBEI)
- $(LD) @CROSSLDFLAGS@ -o $@ $(FORMAT_OBJS) $(LIBFLAGS)
-
-
diff --git a/lib/erl_interface/test/erl_format_SUITE_data/format_test.c b/lib/erl_interface/test/erl_format_SUITE_data/format_test.c
deleted file mode 100644
index 258ae92e0f..0000000000
--- a/lib/erl_interface/test/erl_format_SUITE_data/format_test.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 1997-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-
-#include "runner.h"
-
-/*
- * Purpose: Tests the erl_format() function.
- * Author: Bjorn Gustavsson
- */
-
-static void
-send_format(char* format)
-{
- send_term(erl_format(format));
-}
-
-TESTCASE(atoms)
-{
- erl_init(NULL, 0);
-
- send_format("''");
- send_format("'a'");
- send_format("'A'");
- send_format("'abc'");
- send_format("'Abc'");
- send_format("'ab@c'");
- send_format("'The rain in Spain stays mainly in the plains'");
-
- send_format("a");
- send_format("ab");
- send_format("abc");
- send_format("ab@c");
- send_format(" abcdefghijklmnopq ");
-
- send_term(erl_format("~a", ""));
- send_term(erl_format("~a", "a"));
- send_term(erl_format("~a", "A"));
- send_term(erl_format("~a", "abc"));
- send_term(erl_format("~a", "Abc"));
- send_term(erl_format("~a", "ab@c"));
- send_term(erl_format("~a", "The rain in Spain stays mainly in the plains"));
-
- send_term(erl_format("~a", "a"));
- send_term(erl_format("~a", "ab"));
- send_term(erl_format("~a", "abc"));
- send_term(erl_format("~a","ab@c"));
- send_term(erl_format("~a", " abcdefghijklmnopq "));
-
-
- report(1);
-}
-
-TESTCASE(tuples)
-{
- erl_init(NULL, 0);
-
- send_format("{}");
- send_format("{a}");
- send_format("{a, b}");
- send_format("{a, b, c}");
- send_format("{1}");
- send_format("{[]}");
- send_format("{[], []}");
- send_format("{[], a, b, c}");
- send_format("{[], a, [], b, c}");
- send_format("{[], a, '', b, c}");
-
- report(1);
-}
-
-
-
-TESTCASE(lists)
-{
- ETERM* a;
- ETERM* b;
- ETERM* c;
-
- erl_init(NULL, 0);
-
- send_format("[]");
- send_format("[a]");
- send_format("[a, b]");
- send_format("[a, b, c]");
- send_format("[1]");
- send_format("[[]]");
- send_format("[[], []]");
- send_format("[[], a, b, c]");
- send_format("[[], a, [], b, c]");
- send_format("[[], a, '', b, c]");
-
- b = erl_format("[{addr, ~s, ~i}]", "E-street", 42);
- a = erl_format("[{name, ~a}, {age, ~i}, {data, ~w}]", "Madonna", 21, b);
- send_term(a);
- erl_free_term(b);
-
- send_term(erl_format("[{pi, ~f}, {'cos(70)', ~f}]", 3.1415, 0.34202));
-
- a = erl_mk_float(3.1415);
- b = erl_mk_float(0.34202);
- send_term(erl_format("[[pi, ~w], ['cos(70)', ~w]]", a, b));
- erl_free_term(a);
- erl_free_term(b);
-
- a = erl_mk_float(3.1415);
- b = erl_mk_float(0.34202);
- c = erl_mk_empty_list();
- send_term(erl_format("[[~a, ~w], ~w, [~s, ~w]]", "pi", a, c, "cos(70)", b));
- erl_free_term(a);
- erl_free_term(b);
- erl_free_term(c);
-
- send_term(erl_format("[~i]", -1));
-
- report(1);
-}
diff --git a/lib/erl_interface/test/erl_global_SUITE_data/erl_global_test.c b/lib/erl_interface/test/erl_global_SUITE_data/erl_global_test.c
deleted file mode 100644
index 0f08727225..0000000000
--- a/lib/erl_interface/test/erl_global_SUITE_data/erl_global_test.c
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 2000-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-
-/*
- * Purpose: Tests the functions in erl_global.c.
- *
- * See the erl_global_SUITE.erl file for a "table of contents".
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "runner.h"
-
-static void cmd_erl_connect(ETERM* args);
-static void cmd_erl_global_register(ETERM *args);
-static void cmd_erl_global_whereis(ETERM *args);
-static void cmd_erl_global_names(ETERM *args);
-static void cmd_erl_global_unregister(ETERM *args);
-static void cmd_erl_close_connection(ETERM *args);
-
-static void send_errno_result(int value);
-
-static struct {
- char* name;
- int num_args; /* Number of arguments. */
- void (*func)(ETERM* args);
-} commands[] = {
- "erl_connect", 4, cmd_erl_connect,
- "erl_close_connection", 1, cmd_erl_close_connection,
- "erl_global_register", 2, cmd_erl_global_register,
- "erl_global_whereis", 2, cmd_erl_global_whereis,
- "erl_global_names", 1, cmd_erl_global_names,
- "erl_global_unregister", 2, cmd_erl_global_unregister,
-};
-
-
-/*
- * Sends a list contaning all data types to the Erlang side.
- */
-
-TESTCASE(interpret)
-{
- ETERM* term;
-
- erl_init(NULL, 0);
-
- outer_loop:
-
- term = get_term();
-
- if (term == NULL) {
- report(1);
- return;
- } else {
- ETERM* Func;
- ETERM* Args;
- int i;
-
- if (!ERL_IS_TUPLE(term) || ERL_TUPLE_SIZE(term) != 2) {
- fail("term should be a tuple of size 2");
- }
-
- Func = erl_element(1, term);
- if (!ERL_IS_ATOM(Func)) {
- fail("function name should be an atom");
- }
- Args = erl_element(2, term);
- if (!ERL_IS_TUPLE(Args)) {
- fail("function arguments should be a tuple");
- }
- erl_free_term(term);
- for (i = 0; i < sizeof(commands)/sizeof(commands[0]); i++) {
- int n = strlen(commands[i].name);
- if (ERL_ATOM_SIZE(Func) != n) {
- continue;
- }
- if (memcmp(ERL_ATOM_PTR(Func), commands[i].name, n) == 0) {
- erl_free_term(Func);
- if (ERL_TUPLE_SIZE(Args) != commands[i].num_args) {
- fail("wrong number of arguments");
- }
- commands[i].func(Args);
- erl_free_term(Args);
- goto outer_loop;
- }
- }
- fail("bad command");
- }
-}
-
-#define VERIFY_TYPE(Test, Term) \
-if (!Test(Term)) { \
- fail("wrong type for " #Term); \
-} else { \
-}
-
-static void
-cmd_erl_connect(ETERM* args)
-{
- ETERM* number;
- ETERM* node;
- ETERM* cookie;
-
- int res;
- char buffer[256];
-
- number = ERL_TUPLE_ELEMENT(args, 0);
- VERIFY_TYPE(ERL_IS_INTEGER, number);
- node = ERL_TUPLE_ELEMENT(args, 1);
- VERIFY_TYPE(ERL_IS_ATOM, node);
- cookie = ERL_TUPLE_ELEMENT(args, 2);
- VERIFY_TYPE(ERL_IS_ATOM, cookie);
-
- if (ERL_ATOM_SIZE(cookie) == 0) {
- res = erl_connect_init(ERL_INT_VALUE(number), 0, 0);
- } else {
- memcpy(buffer, ERL_ATOM_PTR(cookie), ERL_ATOM_SIZE(cookie));
- buffer[ERL_ATOM_SIZE(cookie)] = '\0';
- res = erl_connect_init(ERL_INT_VALUE(number), buffer, 0);
- }
-
- if(!res) {
- send_errno_result(res);
- return;
- }
-
- memcpy(buffer, ERL_ATOM_PTR(node), ERL_ATOM_SIZE(node));
- buffer[ERL_ATOM_SIZE(node)] = '\0';
- send_errno_result(erl_connect(buffer));
-}
-
-static void
-cmd_erl_close_connection(ETERM* args)
-{
- ETERM* number;
- ETERM* res;
-
- number = ERL_TUPLE_ELEMENT(args, 0);
- VERIFY_TYPE(ERL_IS_INTEGER, number);
- res = erl_mk_int(erl_close_connection(ERL_INT_VALUE(number)));
- send_term(res);
- erl_free_term(res);
-}
-
-static void
-cmd_erl_global_register(ETERM* args)
-{
- ETERM* fd_term = ERL_TUPLE_ELEMENT(args, 0);
- ETERM* name = ERL_TUPLE_ELEMENT(args, 1);
- ETERM* pid = erl_mk_pid(erl_thisnodename(), 14, 0, 0);
-
- char buffer[256];
-
- VERIFY_TYPE(ERL_IS_INTEGER, fd_term);
- VERIFY_TYPE(ERL_IS_ATOM, name);
-
- memcpy(buffer, ERL_ATOM_PTR(name), ERL_ATOM_SIZE(name));
- buffer[ERL_ATOM_SIZE(name)] = '\0';
-
- send_errno_result(erl_global_register(ERL_INT_VALUE(fd_term), buffer, pid));
- erl_free_term(pid);
-}
-
-static void
-cmd_erl_global_whereis(ETERM* args)
-{
- ETERM* fd_term = ERL_TUPLE_ELEMENT(args, 0);
- ETERM* name = ERL_TUPLE_ELEMENT(args, 1);
- ETERM* pid = NULL;
-
- char buffer[256];
-
- VERIFY_TYPE(ERL_IS_INTEGER, fd_term);
- VERIFY_TYPE(ERL_IS_ATOM, name);
-
- memcpy(buffer, ERL_ATOM_PTR(name), ERL_ATOM_SIZE(name));
- buffer[ERL_ATOM_SIZE(name)] = '\0';
-
- pid = erl_global_whereis(ERL_INT_VALUE(fd_term), buffer, NULL);
- send_term(pid);
- erl_free_term(pid);
-}
-
-static void
-cmd_erl_global_names(ETERM* args)
-{
- ETERM* fd_term = ERL_TUPLE_ELEMENT(args, 0);
-
- ETERM* res_array[2], *res_tuple, *name;
- char** names = NULL;
- int count = 0, i;
-
- VERIFY_TYPE(ERL_IS_INTEGER, fd_term);
-
- names = erl_global_names(ERL_INT_VALUE(fd_term), &count);
-
- res_array[0] = erl_mk_empty_list();
- for(i=0; i<count; i++) {
- name = erl_mk_string(names[i]);
- res_array[0] = erl_cons(name, res_array[0]);
- }
-
- free(names);
-
- res_array[1] = erl_mk_int(count);
- res_tuple = erl_mk_tuple(res_array, 2);
-
- send_term(res_tuple);
-
- erl_free_compound(res_array[0]);
- erl_free_term(res_array[1]);
- erl_free_term(res_tuple);
-}
-
-static void
-cmd_erl_global_unregister(ETERM* args)
-{
- ETERM* fd_term = ERL_TUPLE_ELEMENT(args, 0);
- ETERM* name = ERL_TUPLE_ELEMENT(args, 1);
-
- char buffer[256];
-
- VERIFY_TYPE(ERL_IS_INTEGER, fd_term);
- VERIFY_TYPE(ERL_IS_ATOM, name);
-
- memcpy(buffer, ERL_ATOM_PTR(name), ERL_ATOM_SIZE(name));
- buffer[ERL_ATOM_SIZE(name)] = '\0';
-
- send_errno_result(erl_global_unregister(ERL_INT_VALUE(fd_term), buffer));
-}
-
-static void
-send_errno_result(int value)
-{
- ETERM* res_array[2];
- ETERM* res_tuple;
-
- res_array[0] = erl_mk_int(value);
- res_array[1] = erl_mk_int(erl_errno);
- res_tuple = erl_mk_tuple(res_array, 2);
- send_term(res_tuple);
- erl_free_term(res_array[0]);
- erl_free_term(res_array[1]);
- erl_free_term(res_tuple);
-}
diff --git a/lib/erl_interface/test/erl_match_SUITE.erl b/lib/erl_interface/test/erl_match_SUITE.erl
deleted file mode 100644
index bb62d6288d..0000000000
--- a/lib/erl_interface/test/erl_match_SUITE.erl
+++ /dev/null
@@ -1,280 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2018. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
--module(erl_match_SUITE).
-
--include_lib("common_test/include/ct.hrl").
--include("erl_match_SUITE_data/match_test_cases.hrl").
-
--export([all/0, suite/0,
- init_per_testcase/2,
- atoms/1, lists/1, tuples/1, references/1, pids/1, ports/1,
- bind/1, integers/1, floats/1, binaries/1, strings/1]).
-
-%% For interactive running of matcher.
--export([start_matcher/1, erl_match/3]).
-
-%% This test suite tests the erl_match() function.
-
-suite() ->
- [{ct_hooks,[ts_install_cth]}].
-
-all() ->
- [atoms, lists, tuples, references, pids, ports, bind,
- integers, floats, binaries, strings].
-
-init_per_testcase(Case, Config) ->
- runner:init_per_testcase(?MODULE, Case, Config).
-
-atoms(Config) when is_list(Config) ->
- P = start_matcher(Config),
-
- eq(P, '', ''),
- eq(P, a, a),
- ne(P, a, b),
- ne(P, a, aa),
- eq(P, kalle, kalle),
- ne(P, kalle, arne),
-
- ne(P, kalle, 42),
- ne(P, 42, kalle),
-
- runner:finish(P),
- ok.
-
-lists(Config) when is_list(Config) ->
- P = start_matcher(Config),
- eq(P, [], []),
-
- ne(P, [], [a]),
- ne(P, [a], []),
-
- eq(P, [a], [a]),
- ne(P, [a], [b]),
-
- eq(P, [a|b], [a|b]),
- ne(P, [a|b], [a|x]),
-
- eq(P, [a, b], [a, b]),
- ne(P, [a, b], [a, x]),
-
- eq(P, [a, b, c], [a, b, c]),
- ne(P, [a, b|c], [a, b|x]),
- ne(P, [a, b, c], [a, b, x]),
- ne(P, [a, b|c], [a, b|x]),
- ne(P, [a, x|c], [a, b|c]),
- ne(P, [a, b, c], [a, x, c]),
-
- runner:finish(P),
- ok.
-
-tuples(Config) when is_list(Config) ->
- P = start_matcher(Config),
-
- ne(P, {}, {a, b}),
- ne(P, {a, b}, {}),
- ne(P, {a}, {a, b}),
- ne(P, {a, b}, {a}),
-
- eq(P, {}, {}),
-
- eq(P, {a}, {a}),
- ne(P, {a}, {b}),
-
- eq(P, {1}, {1}),
- ne(P, {1}, {2}),
-
- eq(P, {a, b}, {a, b}),
- ne(P, {x, b}, {a, b}),
-
- ne(P, {error, x}, {error, y}),
- ne(P, {error, {undefined, {subscriber, last}}},
- {error, {undefined, {subscriber, name}}}),
-
- runner:finish(P),
- ok.
-
-
-references(Config) when is_list(Config) ->
- P = start_matcher(Config),
- Ref1 = make_ref(),
- Ref2 = make_ref(),
-
- eq(P, Ref1, Ref1),
- eq(P, Ref2, Ref2),
- ne(P, Ref1, Ref2),
- ne(P, Ref2, Ref1),
-
- runner:finish(P),
- ok.
-
-
-pids(Config) when is_list(Config) ->
- P = start_matcher(Config),
- Pid1 = c:pid(0,1,2),
- Pid2 = c:pid(0,1,3),
-
- eq(P, self(), self()),
- eq(P, Pid1, Pid1),
- ne(P, Pid1, self()),
- ne(P, Pid2, Pid1),
-
- runner:finish(P),
- ok.
-
-
-ports(Config) when is_list(Config) ->
- case os:type() of
- vxworks ->
- {skipped,"not on vxworks, pucko"};
- _ ->
- P = start_matcher(Config),
- P2 = start_matcher(Config),
-
- eq(P, P, P),
- ne(P, P, P2),
-
- runner:finish(P),
- runner:finish(P2),
- ok
- end.
-
-integers(Config) when is_list(Config) ->
- P = start_matcher(Config),
- I1 = 123,
- I2 = 12345,
- I3 = -123,
- I4 = 2234,
-
- eq(P, I1, I1),
- eq(P, I2, I2),
- ne(P, I1, I2),
- ne(P, I1, I3),
- eq(P, I4, I4),
-
- runner:finish(P),
- ok.
-
-
-
-floats(Config) when is_list(Config) ->
- P = start_matcher(Config),
- F1 = 3.1414,
- F2 = 3.1415,
- F3 = 3.1416,
-
- S1 = "string",
- S2 = "string2",
-
- eq(P, F1, F1),
- eq(P, F2, F2),
- ne(P, F1, F2),
- ne(P, F3, F2),
-
- eq(P, S2, S2),
- ne(P, S1, S2),
-
- runner:finish(P),
- ok.
-
-
-
-binaries(Config) when is_list(Config) ->
- P = start_matcher(Config),
- Bin1 = term_to_binary({kalle, 146015, {kungsgatan, 23}}),
- Bin2 = term_to_binary(sune),
- Bin3 = list_to_binary("sune"),
-
- eq(P, Bin1, Bin1),
- eq(P, Bin2, Bin2),
- eq(P, Bin3, Bin3),
- ne(P, Bin1, Bin2),
- ne(P, Bin1, Bin3),
- ne(P, Bin2, Bin3),
-
- runner:finish(P),
- ok.
-
-
-strings(Config) when is_list(Config) ->
- P = start_matcher(Config),
-
- S1 = "string",
- S2 = "streng",
- S3 = "String",
-
- eq(P, S1, S1),
- ne(P, S1, S2),
- ne(P, S1, S3),
-
- runner:finish(P),
- ok.
-
-
-bind(Config) when is_list(Config) ->
- P = start_bind(Config),
- S = "[X,Y,Z]",
- L1 = [301,302,302],
- L2 = [65,66,67],
-
- bind_ok(P, S, L1),
- bind_ok(P, S, L2),
-
- runner:finish(P),
- ok.
-
-start_bind(Config) ->
- runner:start(Config, ?erl_match_bind).
-
-bind_ok(Port, Bind, Term) ->
- true = erl_bind(Port, Bind, Term).
-
-%bind_nok(Port, Bind, Term) ->
-% false = erl_bind(Port, Bind, Term).
-
-erl_bind(Port, Pattern, Term) ->
- Port ! {self(), {command, [$b, Pattern, 0]}},
- runner:send_term(Port, Term),
- case runner:get_term(Port) of
- {term, 0} -> false;
- {term, 1} -> true
- end.
-
-
-
-start_matcher(Config) ->
- runner:start(Config, ?erl_match_server).
-
-eq(Port, Pattern, Term) ->
- true = erl_match(Port, Pattern, Term).
-
-ne(Port, Pattern, Term) ->
- false = erl_match(Port, Pattern, Term).
-
-
-
-erl_match(Port, Pattern, Term) ->
- runner:send_term(Port, Pattern),
- runner:send_term(Port, Term),
- case runner:get_term(Port) of
- {term, 0} -> false;
- {term, 1} -> true
- end.
diff --git a/lib/erl_interface/test/erl_match_SUITE_data/Makefile.first b/lib/erl_interface/test/erl_match_SUITE_data/Makefile.first
deleted file mode 100644
index 459b5c14c2..0000000000
--- a/lib/erl_interface/test/erl_match_SUITE_data/Makefile.first
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2000-2016. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# %CopyrightEnd%
-#
-
-match_test_decl.c: match_test.c
- erl -noinput -pa ../all_SUITE_data -s init_tc run match_test -s erlang halt
diff --git a/lib/erl_interface/test/erl_match_SUITE_data/Makefile.src b/lib/erl_interface/test/erl_match_SUITE_data/Makefile.src
deleted file mode 100644
index 156214a269..0000000000
--- a/lib/erl_interface/test/erl_match_SUITE_data/Makefile.src
+++ /dev/null
@@ -1,42 +0,0 @@
-#
-# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1997-2016. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# %CopyrightEnd%
-#
-
-include @erl_interface_mk_include@
-
-CC0 = @CC@
-CC = ..@DS@all_SUITE_data@DS@gccifier@exe@ -CC"$(CC0)"
-LD = @LD@
-LIBERL = @erl_interface_lib@
-LIBEI = @erl_interface_eilib@
-LIBFLAGS = ../all_SUITE_data/runner@obj@ \
- $(LIBERL) $(LIBEI) @LIBS@ @erl_interface_sock_libs@ \
- @erl_interface_threadlib@
-CFLAGS = @EI_CFLAGS@ $(THR_DEFS) -I@erl_interface_include@ -I../all_SUITE_data
-MATCH_OBJS = match_test@obj@ match_test_decl@obj@
-
-all: match_test@exe@
-
-clean:
- $(RM) $(MATCH_OBJS)
- $(RM) match_test@exe@
-
-match_test@exe@: $(MATCH_OBJS) $(LIBERL) $(LIBEI)
- $(LD) @CROSSLDFLAGS@ -o $@ $(MATCH_OBJS) $(LIBFLAGS)
-
diff --git a/lib/erl_interface/test/erl_match_SUITE_data/match_test.c b/lib/erl_interface/test/erl_match_SUITE_data/match_test.c
deleted file mode 100644
index d577417f5b..0000000000
--- a/lib/erl_interface/test/erl_match_SUITE_data/match_test.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * %CopyrightBegin%
- *
- * Copyright Ericsson AB 1997-2016. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * %CopyrightEnd%
- */
-
-/*
- * Purpose: Tests the erl_match() function.
- * Author: Bjorn Gustavsson
- */
-
-#include "runner.h"
-
-TESTCASE(erl_match_server)
-{
- erl_init(NULL, 0);
-
- for (;;) {
- ETERM* pattern;
- ETERM* term;
-
- pattern = get_term();
- if (pattern == NULL) {
- report(1);
- return;
- } else {
- term = get_term();
- if (term == NULL) {
- fail("Unexpected EOF term");
- } else {
- send_term(erl_mk_int(erl_match(pattern, term)));
- erl_free_term(pattern);
- erl_free_term(term);
- }
- }
- }
-
-}
-
-TESTCASE(erl_match_bind)
-{
- erl_init(NULL, 0);
-
- for (;;) {
- char* pattern;
- ETERM* term;
-
- pattern=read_packet(NULL);
-
- switch (pattern[0]) {
- case 'e':
- free(pattern);
- report(1);
- return;
-
- case 'b':
- {
- ETERM* patt_term;
-
- /*
- * Get the pattern string and convert it using erl_format().
- *
- * Note that the call to get_term() below destroys the buffer
- * that the pattern variable points to. Therefore, it is
- * essential to call erl_format() here, before
- * calling get_term().
- */
-
- message("Pattern: %s", pattern+1);
- patt_term = erl_format(pattern+1);
- free(pattern);
-
- if (patt_term == NULL) {
- fail("erl_format() failed");
- }
-
- /*
- * Get the term and send back the result of the erl_match()
- * call.
- */
-
- term = get_term();
- if (term == NULL) {
- fail("Unexpected eof term");
- }
- else {
- send_term(erl_mk_int(erl_match(patt_term, term)));
- }
- erl_free_term(patt_term);
- erl_free_term(term);
- }
- break;
-
- default:
- free(pattern);
- fail("Illegal character received");
- }
-
- }
-}
diff --git a/lib/erl_interface/test/port_call_SUITE_data/Makefile.src b/lib/erl_interface/test/port_call_SUITE_data/Makefile.src
index 0f97ce9f70..0088c11a14 100644
--- a/lib/erl_interface/test/port_call_SUITE_data/Makefile.src
+++ b/lib/erl_interface/test/port_call_SUITE_data/Makefile.src
@@ -23,10 +23,9 @@ include @erl_interface_mk_include@
CC0 = @CC@
CC = ..@DS@all_SUITE_data@DS@gccifier@exe@ -CC"$(CC0)"
LD = @LD@
-LIBERL = @erl_interface_lib_drv@
LIBEI = @erl_interface_eilib_drv@
-SHLIB_EXTRA_LDLIBS = $(LIBERL) $(LIBEI) @erl_interface_threadlib@
+SHLIB_EXTRA_LDLIBS = $(LIBEI) @erl_interface_threadlib@
SHLIB_EXTRA_CFLAGS = -I@erl_interface_include@ -I../all_SUITE_data
diff --git a/lib/erl_interface/test/port_call_SUITE_data/port_call_drv.c b/lib/erl_interface/test/port_call_SUITE_data/port_call_drv.c
index 4617cb0316..8f7303d645 100644
--- a/lib/erl_interface/test/port_call_SUITE_data/port_call_drv.c
+++ b/lib/erl_interface/test/port_call_SUITE_data/port_call_drv.c
@@ -21,7 +21,7 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
-#include "erl_interface.h"
+#include "ei.h"
#include "erl_driver.h"
static ErlDrvPort my_erlang_port;