diff options
Diffstat (limited to 'lib/erl_interface')
266 files changed, 6531 insertions, 6197 deletions
diff --git a/lib/erl_interface/Makefile b/lib/erl_interface/Makefile index 56edcdfabc..9471b0df18 100644 --- a/lib/erl_interface/Makefile +++ b/lib/erl_interface/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1996-2009. All Rights Reserved. +# 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. diff --git a/lib/erl_interface/configure.in b/lib/erl_interface/configure.in index 7a3b5ce378..0a8fbf513c 100644 --- a/lib/erl_interface/configure.in +++ b/lib/erl_interface/configure.in @@ -1,7 +1,7 @@ # -*- Autoconf -*- # %CopyrightBegin% # -# Copyright Ericsson AB 2000-2012. All Rights Reserved. +# 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. @@ -100,7 +100,9 @@ AC_CHECK_SIZEOF(long) AC_CHECK_SIZEOF(void *) AC_CHECK_SIZEOF(long long) -if test $ac_cv_sizeof_void_p = 8; then +dnl We set EI_64BIT mode when long is 8 bytes, this makes things +dnl work on windows and unix correctly +if test $ac_cv_sizeof_long = 8; then CFLAGS="$CFLAGS -DEI_64BIT" fi diff --git a/lib/erl_interface/doc/src/Makefile b/lib/erl_interface/doc/src/Makefile index 53dadec5a3..204a6051b2 100644 --- a/lib/erl_interface/doc/src/Makefile +++ b/lib/erl_interface/doc/src/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1998-2012. All Rights Reserved. +# 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. diff --git a/lib/erl_interface/doc/src/book.xml b/lib/erl_interface/doc/src/book.xml index cf7323f3a2..94bfef7455 100644 --- a/lib/erl_interface/doc/src/book.xml +++ b/lib/erl_interface/doc/src/book.xml @@ -4,14 +4,14 @@ <book xmlns:xi="http://www.w3.org/2001/XInclude"> <header titlestyle="normal"> <copyright> - <year>1998</year><year>2013</year> + <year>1998</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 @@ -19,19 +19,19 @@ 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>Erlang Interface</title> + <title>Erl_Interface</title> <prepared>Gordon Beaton</prepared> <docno></docno> <date>1998-11-30</date> <rev>1.2</rev> - <file>book.sgml</file> + <file>book.xml</file> </header> <insidecover> </insidecover> - <pagetext>Erlang Interface</pagetext> + <pagetext>Erl_Interface</pagetext> <preamble> <contents level="2"></contents> </preamble> @@ -47,4 +47,3 @@ <listofterms></listofterms> <index></index> </book> - diff --git a/lib/erl_interface/doc/src/ei.xml b/lib/erl_interface/doc/src/ei.xml index 8ef433d10f..ddfb4d88a8 100644 --- a/lib/erl_interface/doc/src/ei.xml +++ b/lib/erl_interface/doc/src/ei.xml @@ -4,14 +4,14 @@ <cref> <header> <copyright> - <year>2001</year><year>2014</year> + <year>2001</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 @@ -30,361 +30,508 @@ <checked></checked> <date>2000-11-27</date> <rev>PA1</rev> - <file>ei.sgml</file> + <file>ei.xml</file> </header> <lib>ei</lib> - <libsummary>routines for handling the erlang binary term format</libsummary> + <libsummary>Routines for handling the Erlang binary term format.</libsummary> <description> - <p>The library <c><![CDATA[ei]]></c> contains macros and functions to encode - and decode the erlang binary term format.</p> - <p>With <c><![CDATA[ei]]></c>, you can convert atoms, lists, numbers and + <p>The library <c>ei</c> contains macros and functions to encode + and decode the Erlang binary term format.</p> + + <p><c>ei</c> allows you to convert atoms, lists, numbers, and binaries to and from the binary format. This is useful when - writing port programs and drivers. <c><![CDATA[ei]]></c> uses a given - buffer, and no dynamic memory (with the exception of - <c><![CDATA[ei_decode_fun()]]></c>), and is often quite fast.</p> - <p>It also handles C-nodes, C-programs that talks erlang - distribution with erlang nodes (or other C-nodes) using the - erlang distribution format. The difference between <c><![CDATA[ei]]></c> and - <c><![CDATA[erl_interface]]></c> is that <c><![CDATA[ei]]></c> uses the binary format - directly when sending and receiving terms. It is also thread - safe, and using threads, one process can handle multiple - C-nodes. The <c><![CDATA[erl_interface]]></c> library is built on top of - <c><![CDATA[ei]]></c>, but of legacy reasons, it doesn't allow for multiple - C-nodes. In general, <c><![CDATA[ei]]></c> is the preferred way of doing - C-nodes.</p> - <p>The decode and encode functions use a buffer an index into the + writing port programs and drivers. <c>ei</c> uses a given + buffer, no dynamic memory (except + <c>ei_decode_fun()</c>) and is often quite fast.</p> + + <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 + 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> + + <p>The decode and encode functions use a buffer and an index into the buffer, which points at the point where to encode and decode. The index is updated to point right after the term encoded/decoded. No checking is done whether the term fits in the buffer or not. If encoding goes outside the buffer, the - program may crash.</p> - <p>All functions takes two parameter, <c><![CDATA[buf]]></c> is a pointer to - the buffer where the binary data is / will be, <c><![CDATA[index]]></c> is a - pointer to an index into the buffer. This parameter will be - incremented with the size of the term decoded / encoded. The - data is thus at <c><![CDATA[buf[*index]]]></c> when an <c><![CDATA[ei]]></c> function is - called.</p> - <p>The encode functions all assumes that the <c><![CDATA[buf]]></c> and - <c><![CDATA[index]]></c> parameters points to a buffer big enough for the - data. To get the size of an encoded term, without encoding it, - pass <c><![CDATA[NULL]]></c> instead of a buffer pointer. The <c><![CDATA[index]]></c> - parameter will be incremented, but nothing will be encoded. This - is the way in <c><![CDATA[ei]]></c> to "preflight" term encoding.</p> - <p>There are also encode-functions that uses a dynamic buffer. It + program can crash.</p> + + <p>All functions take two parameters:</p> + + <list type="bulleted"> + <item><p><c>buf</c> is a pointer to + the buffer where the binary data is or will be.</p> + </item> + <item><p><c>index</c> is a pointer to an index into the + buffer. This parameter is incremented with the size of the term + decoded/encoded.</p> + </item> + </list> + + <p>The data is thus at <c>buf[*index]</c> when an + <c>ei</c> function is called.</p> + + <p>All encode functions assume that the <c>buf</c> and + <c>index</c> parameters point to a buffer large enough for + the data. To get the size of an encoded term, without encoding it, + pass <c>NULL</c> instead of a buffer pointer. Parameter + <c>index</c> is incremented, but nothing will be encoded. This + is the way in <c>ei</c> to "preflight" term encoding.</p> + + <p>There are also encode functions that use a dynamic buffer. It is often more convenient to use these to encode data. All encode - functions comes in two versions: those starting with <c><![CDATA[ei_x]]></c>, - uses a dynamic buffer.</p> - <p>All functions return <c><![CDATA[0]]></c> if successful, and <c><![CDATA[-1]]></c> if - not. (For instance, if a term is not of the expected type, or - the data to decode is not a valid erlang term.)</p> - <p>Some of the decode-functions needs a preallocated buffer. This - buffer must be allocated big enough, and for non compound types - the <c><![CDATA[ei_get_type()]]></c> - function returns the size required (note that for strings an - extra byte is needed for the 0 string terminator).</p> + functions comes in two versions; those starting with + <c>ei_x</c> use a dynamic buffer.</p> + + <p>All functions return <c>0</c> if successful, otherwise + <c>-1</c> (for example, if a term is not of the expected + type, or the data to decode is an invalid Erlang term).</p> + + <p>Some of the decode functions need a pre-allocated buffer. This + buffer must be allocated large enough, and for non-compound types + the <c>ei_get_type()</c> + function returns the size required (notice that for strings an + extra byte is needed for the <c>NULL</c>-terminator).</p> </description> - <section> - <title>DATA TYPES</title> + <section> + <title>Data Types</title> <taglist> <tag><marker id="erlang_char_encoding"/>erlang_char_encoding</tag> <item> - <p/> <code type="none"> typedef enum { ERLANG_ASCII = 1, ERLANG_LATIN1 = 2, ERLANG_UTF8 = 4 -}erlang_char_encoding; -</code> - <p>The character encodings used for atoms. <c>ERLANG_ASCII</c> represents 7-bit ASCII. - Latin1 and UTF8 are different extensions of 7-bit ASCII. All 7-bit ASCII characters - are valid Latin1 and UTF8 characters. ASCII and Latin1 both represent each character - by one byte. A UTF8 character can consist of one to four bytes. Note that these - constants are bit-flags and can be combined with bitwise-or.</p> +} erlang_char_encoding;</code> + <p>The character encodings used for atoms. <c>ERLANG_ASCII</c> + represents 7-bit ASCII. Latin-1 and UTF-8 are different extensions + of 7-bit ASCII. All 7-bit ASCII characters are valid Latin-1 and + UTF-8 characters. ASCII and Latin-1 both represent each character + by one byte. An UTF-8 character can consist of 1-4 bytes. + Notice that these constants are bit-flags and can be combined with + bitwise OR.</p> </item> </taglist> </section> + <funcs> + <func> + <name><ret>int</ret><nametext>ei_decode_atom(const char *buf, int *index, char *p)</nametext></name> + <fsummary>Decode an atom.</fsummary> + <desc> + <p>Decodes an atom from the binary format. The <c>NULL</c>-terminated + name of the atom is placed at <c>p</c>. At most + <c>MAXATOMLEN</c> bytes can be placed in the buffer.</p> + </desc> + </func> + + <func> + <name><ret>int</ret><nametext>ei_decode_atom_as(const char *buf, int *index, char *p, int plen, erlang_char_encoding want, erlang_char_encoding* was, erlang_char_encoding* result)</nametext></name> + <fsummary>Decode an atom.</fsummary> + <desc> + <p>Decodes an atom from the binary format. The <c>NULL</c>-terminated + name of the atom is placed in buffer at <c>p</c> of length <c>plen</c> + bytes.</p> + <p>The wanted string encoding is specified by + <seealso marker="#erlang_char_encoding"><c>want</c></seealso>. + The original encoding used in the binary format (Latin-1 or UTF-8) can + be obtained from <c>*was</c>. The encoding of the resulting string + (7-bit ASCII, Latin-1, or UTF-8) can be obtained from <c>*result</c>. + Both <c>was</c> and <c>result</c> can be <c>NULL</c>. <c>*result</c> + can differ from <c>want</c> if <c>want</c> is a bitwise OR'd + combination like <c>ERLANG_LATIN1|ERLANG_UTF8</c> or if + <c>*result</c> turns out to be pure 7-bit ASCII + (compatible with both Latin-1 and UTF-8).</p> + <p>This function fails if the atom is too long for the buffer + or if it cannot be represented with encoding <c>want</c>.</p> + <p>This function was introduced in Erlang/OTP R16 as part of a first + step to support UTF-8 atoms.</p> + </desc> + </func> + + <func> + <name><ret>int</ret><nametext>ei_decode_bignum(const char *buf, int *index, mpz_t obj)</nametext></name> + <fsummary>Decode a GMP arbitrary precision integer.</fsummary> + <desc> + <p>Decodes an integer in the binary format to a GMP + <c>mpz_t</c> integer. To use this function, the <c>ei</c> + library must be configured and compiled to use the GMP library.</p> + </desc> + </func> + + <func> + <name><ret>int</ret><nametext>ei_decode_binary(const char *buf, int *index, void *p, long *len)</nametext></name> + <fsummary>Decode a binary.</fsummary> + <desc> + <p>Decodes a binary from the binary format. Parameter + <c>len</c> is set to the actual size of the + binary. Notice that <c>ei_decode_binary()</c> assumes that + there is enough room for the binary. The size required can be + fetched by <c>ei_get_type()</c>.</p> + </desc> + </func> + + <func> + <name><ret>int</ret><nametext>ei_decode_boolean(const char *buf, int *index, int *p)</nametext></name> + <fsummary>Decode a boolean.</fsummary> + <desc> + <p>Decodes a boolean value from the binary format. + A boolean is actually an atom, <c>true</c> decodes 1 + and <c>false</c> decodes 0.</p> + </desc> + </func> + + <func> + <name><ret>int</ret><nametext>ei_decode_char(const char *buf, int *index, char *p)</nametext></name> + <fsummary>Decode an 8-bit integer between 0-255.</fsummary> + <desc> + <p>Decodes a char (8-bit) integer between 0-255 from the binary format. + For historical reasons the returned integer is of + type <c>char</c>. Your C code is to consider the + returned value to be of type <c>unsigned char</c> even if + the C compilers and system can define <c>char</c> to be + signed.</p> + </desc> + </func> + + <func> + <name><ret>int</ret><nametext>ei_decode_double(const char *buf, int *index, double *p)</nametext></name> + <fsummary>Decode a double.</fsummary> + <desc> + <p>Decodes a double-precision (64-bit) floating + point number from the binary format.</p> + </desc> + </func> + <func> - <name><ret>void</ret><nametext>ei_set_compat_rel(release_number)</nametext></name> - <fsummary>Set the ei library in compatibility mode</fsummary> - <type> - <v>unsigned release_number;</v> - </type> + <name><ret>int</ret><nametext>ei_decode_ei_term(const char* buf, int* index, ei_term* term)</nametext></name> + <fsummary>Decode a term, without previous knowledge of type.</fsummary> + <desc> + <p>Decodes any term, or at least tries to. If the term + pointed at by <c>*index</c> in <c>buf</c> fits + in the <c>term</c> union, it is decoded, and the + appropriate field in <c>term->value</c> is set, and + <c>*index</c> is incremented by the term size.</p> + <p>The function returns <c>1</c> on successful decoding, <c>-1</c> on + error, and <c>0</c> if the term seems alright, but does not fit in the + <c>term</c> structure. If <c>1</c> is returned, the + <c>index</c> is incremented, and <c>term</c> + contains the decoded term.</p> + <p>The <c>term</c> structure contains the arity for a tuple + or list, size for a binary, string, or atom. It contains + a term if it is any of the following: integer, float, atom, + pid, port, or ref.</p> + </desc> + </func> + + <func> + <name><ret>int</ret><nametext>ei_decode_fun(const char *buf, int *index, erlang_fun *p)</nametext></name> + <name><ret>void</ret><nametext>free_fun(erlang_fun* f)</nametext></name> + <fsummary>Decode a fun.</fsummary> <desc> - <marker id="ei_set_compat_rel"></marker> - <p>By default, the <c><![CDATA[ei]]></c> library is only guaranteed - to be compatible with other Erlang/OTP components from the same - release as the <c><![CDATA[ei]]></c> library itself. For example, <c><![CDATA[ei]]></c> from - the OTP R10 release is not compatible with an Erlang emulator - from the OTP R9 release by default.</p> - <p>A call to <c><![CDATA[ei_set_compat_rel(release_number)]]></c> sets the - <c><![CDATA[ei]]></c> library in compatibility mode of release - <c><![CDATA[release_number]]></c>. Valid range of <c><![CDATA[release_number]]></c> - is [7, current release]. This makes it possible to - communicate with Erlang/OTP components from earlier releases.</p> - <note> - <p>If this function is called, it may only be called once - and must be called before any other functions in the <c><![CDATA[ei]]></c> - library is called.</p> - </note> - <warning> - <p>You may run into trouble if this feature is used - carelessly. Always make sure that all communicating - components are either from the same Erlang/OTP release, or - from release X and release Y where all components - from release Y are in compatibility mode of release X.</p> - </warning> + <p>Decodes a fun from the binary format. Parameter + <c>p</c> is to be <c>NULL</c> or point to an + <c>erlang_fun</c> structure. This is the only decode + function that allocates memory. When the <c>erlang_fun</c> + is no longer needed, it is to be freed with + <c>free_fun</c>. (This has to do with the arbitrary size + of the environment for a fun.)</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_encode_version(char *buf, int *index)</nametext></name> - <name><ret>int</ret><nametext>ei_x_encode_version(ei_x_buff* x)</nametext></name> - <fsummary>Encode version</fsummary> + <name><ret>int</ret><nametext>ei_decode_list_header(const char *buf, int *index, int *arity)</nametext></name> + <fsummary>Decode a list.</fsummary> <desc> - <p>Encodes a version magic number for the binary format. Must - be the first token in a binary term.</p> + <p>Decodes a list header from the binary + format. The number of elements is returned in + <c>arity</c>. The <c>arity+1</c> elements + follow (the last one is the tail of the list, normally an empty list). + If <c>arity</c> is <c>0</c>, it is an empty + list.</p> + <p>Notice that lists are encoded as strings if they consist + entirely of integers in the range 0..255. This function do + not decode such strings, use <c>ei_decode_string()</c> + instead.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_encode_long(char *buf, int *index, long p)</nametext></name> - <name><ret>int</ret><nametext>ei_x_encode_long(ei_x_buff* x, long p)</nametext></name> - <fsummary>Encode integer</fsummary> + <name><ret>int</ret><nametext>ei_decode_long(const char *buf, int *index, long *p)</nametext></name> + <fsummary>Decode integer.</fsummary> <desc> - <p>Encodes a long integer in the binary format. - Note that if the code is 64 bits the function ei_encode_long() is - exactly the same as ei_encode_longlong().</p> + <p>Decodes a long integer from the binary format. + If the code is 64 bits, the function <c>ei_decode_long()</c> is + the same as <c>ei_decode_longlong()</c>.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_encode_ulong(char *buf, int *index, unsigned long p)</nametext></name> - <name><ret>int</ret><nametext>ei_x_encode_ulong(ei_x_buff* x, unsigned long p)</nametext></name> - <fsummary>Encode unsigned integer</fsummary> + <name><ret>int</ret><nametext>ei_decode_longlong(const char *buf, int *index, long long *p)</nametext></name> + <fsummary>Decode integer.</fsummary> <desc> - <p>Encodes an unsigned long integer in the binary format. - Note that if the code is 64 bits the function ei_encode_ulong() is - exactly the same as ei_encode_ulonglong().</p> + <p>Decodes a GCC <c>long long</c> or Visual C++ + <c>__int64</c> + (64-bit) integer from the binary format. This + function is missing in the VxWorks port.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_encode_longlong(char *buf, int *index, long long p)</nametext></name> - <name><ret>int</ret><nametext>ei_x_encode_longlong(ei_x_buff* x, long long p)</nametext></name> - <fsummary>Encode integer</fsummary> + <name><ret>int</ret><nametext>ei_decode_map_header(const char *buf, int *index, int *arity)</nametext></name> + <fsummary>Decode a map.</fsummary> <desc> - <p>Encodes a GCC <c><![CDATA[long long]]></c> or Visual C++ <c><![CDATA[__int64]]></c> (64 bit) - integer in the binary format. Note that this function is missing - in the VxWorks port.</p> + <p>Decodes a map header from the binary + format. The number of key-value pairs is returned in + <c>*arity</c>. Keys and values follow in this order: + <c>K1, V1, K2, V2, ..., Kn, Vn</c>. This makes a total of + <c>arity*2</c> terms. If <c>arity</c> is zero, it is an empty map. + A correctly encoded map does not have duplicate keys.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_encode_ulonglong(char *buf, int *index, unsigned long long p)</nametext></name> - <name><ret>int</ret><nametext>ei_x_encode_ulonglong(ei_x_buff* x, unsigned long long p)</nametext></name> - <fsummary>Encode unsigned integer</fsummary> + <name><ret>int</ret><nametext>ei_decode_pid(const char *buf, int *index, erlang_pid *p)</nametext></name> + <fsummary>Decode a <c>pid</c>.</fsummary> <desc> - <p>Encodes a GCC <c><![CDATA[unsigned long long]]></c> or Visual C++ <c><![CDATA[unsigned __int64]]></c> (64 bit) integer in the binary format. Note that - this function is missing in the VxWorks port.</p> + <p>Decodes a process identifier (pid) from the binary format.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_encode_bignum(char *buf, int *index, mpz_t obj)</nametext></name> - <name><ret>int</ret><nametext>ei_x_encode_bignum(ei_x_buff *x, mpz_t obj)</nametext></name> - <fsummary>Encode an arbitrary precision integer</fsummary> + <name><ret>int</ret><nametext>ei_decode_port(const char *buf, int *index, erlang_port *p)</nametext></name> + <fsummary>Decode a port.</fsummary> <desc> - <p>Encodes a GMP <c><![CDATA[mpz_t]]></c> integer to binary format. - To use this function the ei library needs to be configured and compiled - to use the GMP library. </p> + <p>Decodes a port identifier from the binary format.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_encode_double(char *buf, int *index, double p)</nametext></name> - <name><ret>int</ret><nametext>ei_x_encode_double(ei_x_buff* x, double p)</nametext></name> - <fsummary>Encode a double float</fsummary> + <name><ret>int</ret><nametext>ei_decode_ref(const char *buf, int *index, erlang_ref *p)</nametext></name> + <fsummary>Decode a reference.</fsummary> <desc> - <p>Encodes a double-precision (64 bit) floating point number in - the binary format.</p> - <p> - The function returns <c><![CDATA[-1]]></c> if the floating point number is not finite. - </p> + <p>Decodes a reference from the binary format.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_encode_boolean(char *buf, int *index, int p)</nametext></name> - <name><ret>int</ret><nametext>ei_x_encode_boolean(ei_x_buff* x, int p)</nametext></name> - <fsummary>Encode a boolean</fsummary> + <name><ret>int</ret><nametext>ei_decode_string(const char *buf, int *index, char *p)</nametext></name> + <fsummary>Decode a string.</fsummary> <desc> - <p>Encodes a boolean value, as the atom <c><![CDATA[true]]></c> if p is not - zero or <c><![CDATA[false]]></c> if p is zero.</p> + <p>Decodes a string from the binary format. A + string in Erlang is a list of integers between 0 and + 255. Notice that as the string is just a list, sometimes + lists are encoded as strings by <c>term_to_binary/1</c>, + even if it was not intended.</p> + <p>The string is copied to <c>p</c>, and enough space must + be allocated. The returned string is <c>NULL</c>-terminated, so you + must add an extra byte to the memory requirement.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_encode_char(char *buf, int *index, char p)</nametext></name> - <name><ret>int</ret><nametext>ei_x_encode_char(ei_x_buff* x, char p)</nametext></name> - <fsummary>Encode an 8-bit integer between 0-255</fsummary> + <name><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> + <p>Notice that this function is located in the <c>Erl_Interface</c> + library.</p> + </desc> + </func> + + <func> + <name><ret>int</ret><nametext>ei_decode_trace(const char *buf, int *index, erlang_trace *p)</nametext></name> + <fsummary>Decode a trace token.</fsummary> <desc> - <p>Encodes a char (8-bit) as an integer between 0-255 in the binary format. - Note that for historical reasons the integer argument is of - type <c><![CDATA[char]]></c>. Your C code should consider the - given argument to be of type <c><![CDATA[unsigned char]]></c> even if - the C compilers and system may define <c><![CDATA[char]]></c> to be - signed.</p> + <p>Decodes an Erlang trace token from the binary format.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_encode_string(char *buf, int *index, const char *p)</nametext></name> - <name><ret>int</ret><nametext>ei_encode_string_len(char *buf, int *index, const char *p, int len)</nametext></name> - <name><ret>int</ret><nametext>ei_x_encode_string(ei_x_buff* x, const char *p)</nametext></name> - <name><ret>int</ret><nametext>ei_x_encode_string_len(ei_x_buff* x, const char* s, int len)</nametext></name> - <fsummary>Encode a string</fsummary> + <name><ret>int</ret><nametext>ei_decode_tuple_header(const char *buf, int *index, int *arity)</nametext></name> + <fsummary>Decode a tuple.</fsummary> <desc> - <p>Encodes a string in the binary format. (A string in erlang - is a list, but is encoded as a character array in the binary - format.) The string should be zero-terminated, except for - the <c><![CDATA[ei_x_encode_string_len()]]></c> function.</p> + <p>Decodes a tuple header, the number of elements + is returned in <c>arity</c>. The tuple elements follow + in order in the buffer.</p> + </desc> + </func> + + <func> + <name><ret>int</ret><nametext>ei_decode_ulong(const char *buf, int *index, unsigned long *p)</nametext></name> + <fsummary>Decode unsigned integer.</fsummary> + <desc> + <p>Decodes an unsigned long integer from the binary format. + If the code is 64 bits, the function <c>ei_decode_ulong()</c> is + the same as <c>ei_decode_ulonglong()</c>.</p> + </desc> + </func> + + <func> + <name><ret>int</ret><nametext>ei_decode_ulonglong(const char *buf, int *index, unsigned long long *p)</nametext></name> + <fsummary>Decode unsigned integer.</fsummary> + <desc> + <p>Decodes a GCC <c>unsigned long long</c> or Visual C++ + <c>unsigned __int64</c> (64-bit) integer from the binary + format. This function is missing in the VxWorks port.</p> </desc> </func> + + <func> + <name><ret>int</ret><nametext>ei_decode_version(const char *buf, int *index, int *version)</nametext></name> + <fsummary>Decode an empty list (<c>nil</c>).</fsummary> + <desc> + <p>Decodes the version magic number for the + Erlang binary term format. It must be the first token in a + binary term.</p> + </desc> + </func> + <func> <name><ret>int</ret><nametext>ei_encode_atom(char *buf, int *index, const char *p)</nametext></name> <name><ret>int</ret><nametext>ei_encode_atom_len(char *buf, int *index, const char *p, int len)</nametext></name> <name><ret>int</ret><nametext>ei_x_encode_atom(ei_x_buff* x, const char *p)</nametext></name> <name><ret>int</ret><nametext>ei_x_encode_atom_len(ei_x_buff* x, const char *p, int len)</nametext></name> - <fsummary>Encode an atom</fsummary> + <fsummary>Encode an atom.</fsummary> <desc> - <p>Encodes an atom in the binary format. The <c><![CDATA[p]]></c> parameter - is the name of the atom in latin1 encoding. Only upto <c>MAXATOMLEN-1</c> bytes - are encoded. The name should be zero-terminated, except for - the <c><![CDATA[ei_x_encode_atom_len()]]></c> function.</p> + <p>Encodes an atom in the binary format. Parameter <c>p</c> + is the name of the atom in Latin-1 encoding. Only up to + <c>MAXATOMLEN-1</c> bytes + are encoded. The name is to be <c>NULL</c>-terminated, except for + the <c>ei_x_encode_atom_len()</c> function.</p> </desc> </func> + <func> <name><ret>int</ret><nametext>ei_encode_atom_as(char *buf, int *index, const char *p, erlang_char_encoding from_enc, erlang_char_encoding to_enc)</nametext></name> <name><ret>int</ret><nametext>ei_encode_atom_len_as(char *buf, int *index, const char *p, int len, erlang_char_encoding from_enc, erlang_char_encoding to_enc)</nametext></name> <name><ret>int</ret><nametext>ei_x_encode_atom_as(ei_x_buff* x, const char *p, erlang_char_encoding from_enc, erlang_char_encoding to_enc)</nametext></name> <name><ret>int</ret><nametext>ei_x_encode_atom_len_as(ei_x_buff* x, const char *p, int len, erlang_char_encoding from_enc, erlang_char_encoding to_enc)</nametext></name> - <fsummary>Encode an atom</fsummary> + <fsummary>Encode an atom.</fsummary> <desc> <p>Encodes an atom in the binary format with character encoding - <seealso marker="#erlang_char_encoding"><c>to_enc</c></seealso> (latin1 or utf8). - The <c>p</c> parameter is the name of the atom with character encoding - <seealso marker="#erlang_char_encoding"><c>from_enc</c></seealso> (ascii, latin1 or utf8). - The name must either be zero-terminated or a function variant with a <c>len</c> - parameter must be used. If <c>to_enc</c> is set to the bitwise-or'd combination - <c>(ERLANG_LATIN1|ERLANG_UTF8)</c>, utf8 encoding is only used if the atom string - can not be represented in latin1 encoding.</p> - <p>The encoding will fail if <c>p</c> is not a valid string in encoding <c>from_enc</c>, - if the string is too long or if it can not be represented with character encoding <c>to_enc</c>.</p> - <p>These functions were introduced in R16 release of Erlang/OTP as part of a first step - to support UTF8 atoms. Atoms encoded with <c>ERLANG_UTF8</c> - can not be decoded by earlier releases than R16.</p> - </desc> - </func> - <func> - <name><ret>int</ret><nametext>ei_encode_binary(char *buf, int *index, const void *p, long len)</nametext></name> - <name><ret>int</ret><nametext>ei_x_encode_binary(ei_x_buff* x, const void *p, long len)</nametext></name> - <fsummary>Encode a binary</fsummary> - <desc> - <p>Encodes a binary in the binary format. The data is at - <c><![CDATA[p]]></c>, of <c><![CDATA[len]]></c> bytes length.</p> + <seealso marker="#erlang_char_encoding"><c>to_enc</c></seealso> + (Latin-1 or UTF-8). Parameter <c>p</c> is the name of the atom with + character encoding + <seealso marker="#erlang_char_encoding"><c>from_enc</c></seealso> + (ASCII, Latin-1, or UTF-8). The name must either be <c>NULL</c>-terminated or + a function variant with a <c>len</c> parameter must be used. + If <c>to_enc</c> is set to the bitwise OR'd combination + <c>(ERLANG_LATIN1|ERLANG_UTF8)</c>, UTF-8 encoding is only used if the + atom string cannot be represented in Latin-1 encoding.</p> + <p>The encoding fails if <c>p</c> is an invalid string in encoding + <c>from_enc</c>, if the string is too long, or if it cannot be + represented with character encoding <c>to_enc</c>.</p> + <p>These functions were introduced in Erlang/OTP R16 as part of a first + step to support UTF-8 atoms. Atoms encoded with <c>ERLANG_UTF8</c> + cannot be decoded by earlier releases than R16.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_encode_pid(char *buf, int *index, const erlang_pid *p)</nametext></name> - <name><ret>int</ret><nametext>ei_x_encode_pid(ei_x_buff* x, const erlang_pid *p)</nametext></name> - <fsummary>Encode a pid</fsummary> + <name><ret>int</ret><nametext>ei_encode_bignum(char *buf, int *index, mpz_t obj)</nametext></name> + <name><ret>int</ret><nametext>ei_x_encode_bignum(ei_x_buff *x, mpz_t obj)</nametext></name> + <fsummary>Encode an arbitrary precision integer.</fsummary> <desc> - <p>Encodes an erlang process identifier, pid, in the binary - format. The <c><![CDATA[p]]></c> parameter points to an - <c><![CDATA[erlang_pid]]></c> structure (which should have been obtained - earlier with <c><![CDATA[ei_decode_pid()]]></c>).</p> + <p>Encodes a GMP <c>mpz_t</c> integer to binary format. + To use this function, the <c>ei</c> library must be configured and + compiled to use the GMP library.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_encode_fun(char *buf, int *index, const erlang_fun *p)</nametext></name> - <name><ret>int</ret><nametext>ei_x_encode_fun(ei_x_buff* x, const erlang_fun* fun)</nametext></name> - <fsummary>Encode a fun</fsummary> + <name><ret>int</ret><nametext>ei_encode_binary(char *buf, int *index, const void *p, long len)</nametext></name> + <name><ret>int</ret><nametext>ei_x_encode_binary(ei_x_buff* x, const void *p, long len)</nametext></name> + <fsummary>Encode a binary.</fsummary> <desc> - <p>Encodes a fun in the binary format. The <c><![CDATA[p]]></c> parameter - points to an <c><![CDATA[erlang_fun]]></c> structure. The - <c><![CDATA[erlang_fun]]></c> is not freed automatically, the - <c><![CDATA[free_fun]]></c> should be called if the fun is not needed - after encoding.</p> + <p>Encodes a binary in the binary format. The data is at + <c>p</c>, of <c>len</c> bytes length.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_encode_port(char *buf, int *index, const erlang_port *p)</nametext></name> - <name><ret>int</ret><nametext>ei_x_encode_port(ei_x_buff* x, const erlang_port *p)</nametext></name> - <fsummary>Encodes a port</fsummary> + <name><ret>int</ret><nametext>ei_encode_boolean(char *buf, int *index, int p)</nametext></name> + <name><ret>int</ret><nametext>ei_x_encode_boolean(ei_x_buff* x, int p)</nametext></name> + <fsummary>Encode a boolean.</fsummary> <desc> - <p>Encodes an erlang port in the binary format. The <c><![CDATA[p]]></c> - parameter points to a <c><![CDATA[erlang_port]]></c> structure (which - should have been obtained earlier with - <c><![CDATA[ei_decode_port()]]></c>.</p> + <p>Encodes a boolean value as the atom <c>true</c> if + <c>p</c> is not zero, or <c>false</c> if <c>p</c> is + zero.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_encode_ref(char *buf, int *index, const erlang_ref *p)</nametext></name> - <name><ret>int</ret><nametext>ei_x_encode_ref(ei_x_buff* x, const erlang_ref *p)</nametext></name> - <fsummary>Encodes a ref</fsummary> + <name><ret>int</ret><nametext>ei_encode_char(char *buf, int *index, char p)</nametext></name> + <name><ret>int</ret><nametext>ei_x_encode_char(ei_x_buff* x, char p)</nametext></name> + <fsummary>Encode an 8-bit integer between 0-255.</fsummary> <desc> - <p>Encodes an erlang reference in the binary format. The - <c><![CDATA[p]]></c> parameter points to a <c><![CDATA[erlang_ref]]></c> structure - (which should have been obtained earlier with - <c><![CDATA[ei_decode_ref()]]></c>.</p> + <p>Encodes a char (8-bit) as an integer between 0-255 in the binary + format. For historical reasons the integer argument is of + type <c>char</c>. Your C code is to consider the specified + argument to be of type <c>unsigned char</c> even if + the C compilers and system may define <c>char</c> to be + signed.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_encode_term(char *buf, int *index, void *t)</nametext></name> - <name><ret>int</ret><nametext>ei_x_encode_term(ei_x_buff* x, void *t)</nametext></name> - <fsummary>Encode an <c><![CDATA[erl_interface]]></c>term</fsummary> + <name><ret>int</ret><nametext>ei_encode_double(char *buf, int *index, double p)</nametext></name> + <name><ret>int</ret><nametext>ei_x_encode_double(ei_x_buff* x, double p)</nametext></name> + <fsummary>Encode a double float.</fsummary> <desc> - <p>This function encodes an <c><![CDATA[ETERM]]></c>, as obtained from - <c><![CDATA[erl_interface]]></c>. The <c><![CDATA[t]]></c> parameter is actually an - <c><![CDATA[ETERM]]></c> pointer. This function doesn't free the - <c><![CDATA[ETERM]]></c>.</p> + <p>Encodes a double-precision (64-bit) floating point number in + the binary format.</p> + <p>Returns <c>-1</c> if the floating point + number is not finite.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_encode_trace(char *buf, int *index, const erlang_trace *p)</nametext></name> - <name><ret>int</ret><nametext>ei_x_encode_trace(ei_x_buff* x, const erlang_trace *p)</nametext></name> - <fsummary>Encode a trace token</fsummary> + <name><ret>int</ret><nametext>ei_encode_empty_list(char* buf, int* index)</nametext></name> + <name><ret>int</ret><nametext>ei_x_encode_empty_list(ei_x_buff* x)</nametext></name> + <fsummary>Encode an empty list (<c>nil</c>).</fsummary> <desc> - <p>This function encodes an erlang trace token in the binary - format. The <c><![CDATA[p]]></c> parameter points to a - <c><![CDATA[erlang_trace]]></c> structure (which should have been - obtained earlier with <c><![CDATA[ei_decode_trace()]]></c>.</p> + <p>Encodes an empty list. It is often used at the tail of a list.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_encode_tuple_header(char *buf, int *index, int arity)</nametext></name> - <name><ret>int</ret><nametext>ei_x_encode_tuple_header(ei_x_buff* x, int arity)</nametext></name> - <fsummary>Encode a tuple</fsummary> + <name><ret>int</ret><nametext>ei_encode_fun(char *buf, int *index, const erlang_fun *p)</nametext></name> + <name><ret>int</ret><nametext>ei_x_encode_fun(ei_x_buff* x, const erlang_fun* fun)</nametext></name> + <fsummary>Encode a fun.</fsummary> <desc> - <p>This function encodes a tuple header, with a specified - arity. The next <c><![CDATA[arity]]></c> terms encoded will be the - elements of the tuple. Tuples and lists are encoded - recursively, so that a tuple may contain another tuple or - list.</p> - <p>E.g. to encode the tuple <c><![CDATA[{a, {b, {}}}]]></c>:</p> - <pre> -ei_encode_tuple_header(buf, &i, 2); -ei_encode_atom(buf, &i, "a"); -ei_encode_tuple_header(buf, &i, 2); -ei_encode_atom(buf, &i, "b"); -ei_encode_tuple_header(buf, &i, 0); - </pre> + <p>Encodes a fun in the binary format. Parameter <c>p</c> + points to an <c>erlang_fun</c> structure. The + <c>erlang_fun</c> is not freed automatically, the + <c>free_fun</c> is to be called if the fun is not needed + after encoding.</p> </desc> </func> + <func> <name><ret>int</ret><nametext>ei_encode_list_header(char *buf, int *index, int arity)</nametext></name> <name><ret>int</ret><nametext>ei_x_encode_list_header(ei_x_buff* x, int arity)</nametext></name> - <fsummary>Encode a list</fsummary> + <fsummary>Encode a list.</fsummary> <desc> - <p>This function encodes a list header, with a specified - arity. The next <c><![CDATA[arity+1]]></c> terms are the elements - (actually its <c><![CDATA[arity]]></c> cons cells) and the tail of the + <p>Encodes a list header, with a specified + arity. The next <c>arity+1</c> terms are the elements + (actually its <c>arity</c> cons cells) and the tail of the list. Lists and tuples are encoded recursively, so that a - list may contain another list or tuple.</p> - <p>E.g. to encode the list <c><![CDATA[[c, d, [e | f]]]]></c>:</p> + list can contain another list or tuple.</p> + <p>For example, to encode the list + <c>[c, d, [e | f]]</c>:</p> <pre> ei_encode_list_header(buf, &i, 3); ei_encode_atom(buf, &i, "c"); @@ -392,14 +539,13 @@ ei_encode_atom(buf, &i, "d"); ei_encode_list_header(buf, &i, 1); ei_encode_atom(buf, &i, "e"); ei_encode_atom(buf, &i, "f"); -ei_encode_empty_list(buf, &i); - </pre> +ei_encode_empty_list(buf, &i);</pre> <note> <p>It may seem that there is no way to create a list without knowing the number of elements in advance. But indeed - there is a way. Note that the list <c><![CDATA[[a, b, c]]]></c> can be - written as <c><![CDATA[[a | [b | [c]]]]]></c>. Using this, a list can - be written as conses.</p> + there is a way. Notice that the list <c>[a, b, c]</c> + can be written as <c>[a | [b | [c]]]</c>. + Using this, a list can be written as conses.</p> </note> <p>To encode a list, without knowing the arity in advance:</p> <pre> @@ -407,425 +553,350 @@ while (something()) { ei_x_encode_list_header(&x, 1); ei_x_encode_ulong(&x, i); /* just an example */ } -ei_x_encode_empty_list(&x); - </pre> +ei_x_encode_empty_list(&x);</pre> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_encode_empty_list(char* buf, int* index)</nametext></name> - <name><ret>int</ret><nametext>ei_x_encode_empty_list(ei_x_buff* x)</nametext></name> - <fsummary>Encode an empty list (<c><![CDATA[nil]]></c>)</fsummary> + <name><ret>int</ret><nametext>ei_encode_long(char *buf, int *index, long p)</nametext></name> + <name><ret>int</ret><nametext>ei_x_encode_long(ei_x_buff* x, long p)</nametext></name> + <fsummary>Encode integer.</fsummary> <desc> - <p>This function encodes an empty list. It's often used at the - tail of a list.</p> + <p>Encodes a long integer in the binary format. + If the code is 64 bits, the function <c>ei_encode_long()</c> is + the same as <c>ei_encode_longlong()</c>.</p> </desc> </func> + + <func> + <name><ret>int</ret><nametext>ei_encode_longlong(char *buf, int *index, long long p)</nametext></name> + <name><ret>int</ret><nametext>ei_x_encode_longlong(ei_x_buff* x, long long p)</nametext></name> + <fsummary>Encode integer.</fsummary> + <desc> + <p>Encodes a GCC <c>long long</c> or Visual C++ + <c>__int64</c> (64-bit) integer in the binary format. + This function is missing in the VxWorks port.</p> + </desc> + </func> + <func> <name><ret>int</ret><nametext>ei_encode_map_header(char *buf, int *index, int arity)</nametext></name> <name><ret>int</ret><nametext>ei_x_encode_map_header(ei_x_buff* x, int arity)</nametext></name> - <fsummary>Encode a map</fsummary> + <fsummary>Encode a map.</fsummary> <desc> - <p>This function encodes a map header, with a specified arity. The next + <p>Encodes a map header, with a specified arity. The next <c>arity*2</c> terms encoded will be the keys and values of the map encoded in the following order: <c>K1, V1, K2, V2, ..., Kn, Vn</c>. </p> - <p>E.g. to encode the map <c>#{a => "Apple", b => "Banana"}</c>:</p> + <p>For example, to encode the map <c>#{a => "Apple", b => + "Banana"}</c>:</p> <pre> ei_x_encode_map_header(&x, 2); ei_x_encode_atom(&x, "a"); ei_x_encode_string(&x, "Apple"); ei_x_encode_atom(&x, "b"); -ei_x_encode_string(&x, "Banana"); - </pre> - <p>A correctly encoded map can not have duplicate keys.</p> - </desc> - </func> - <func> - <name><ret>int</ret><nametext>ei_get_type(const char *buf, const int *index, int *type, int *size)</nametext></name> - <fsummary>Fetch the type and size of an encoded term</fsummary> - <desc> - <p>This function returns the type in <c><![CDATA[type]]></c> and size in - <c><![CDATA[size]]></c> of the encoded term. - For strings and atoms, size - is the number of characters <em>not</em> including the - terminating 0. For binaries, <c><![CDATA[size]]></c> is the number of - bytes. For lists and tuples, <c><![CDATA[size]]></c> is the arity of the - object. For other types, <c><![CDATA[size]]></c> is 0. In all cases, - <c><![CDATA[index]]></c> is left unchanged.</p> - </desc> - </func> - <func> - <name><ret>int</ret><nametext>ei_decode_version(const char *buf, int *index, int *version)</nametext></name> - <fsummary>Encode an empty list (<c><![CDATA[nil]]></c>)</fsummary> - <desc> - <p>This function decodes the version magic number for the - erlang binary term format. It must be the first token in a - binary term.</p> - </desc> - </func> - <func> - <name><ret>int</ret><nametext>ei_decode_long(const char *buf, int *index, long *p)</nametext></name> - <fsummary>Decode integer</fsummary> - <desc> - <p>This function decodes a long integer from the binary format. - Note that if the code is 64 bits the function ei_decode_long() is - exactly the same as ei_decode_longlong().</p> - </desc> - </func> - <func> - <name><ret>int</ret><nametext>ei_decode_ulong(const char *buf, int *index, unsigned long *p)</nametext></name> - <fsummary>Decode unsigned integer</fsummary> - <desc> - <p>This function decodes an unsigned long integer from - the binary format. - Note that if the code is 64 bits the function ei_decode_ulong() is - exactly the same as ei_decode_ulonglong().</p> - </desc> - </func> - <func> - <name><ret>int</ret><nametext>ei_decode_longlong(const char *buf, int *index, long long *p)</nametext></name> - <fsummary>Decode integer</fsummary> - <desc> - <p>This function decodes a GCC <c><![CDATA[long long]]></c> or Visual C++ <c><![CDATA[__int64]]></c> - (64 bit) integer from the binary format. Note that this - function is missing in the VxWorks port.</p> - </desc> - </func> - <func> - <name><ret>int</ret><nametext>ei_decode_ulonglong(const char *buf, int *index, unsigned long long *p)</nametext></name> - <fsummary>Decode unsigned integer</fsummary> - <desc> - <p>This function decodes a GCC <c><![CDATA[unsigned long long]]></c> or Visual C++ - <c><![CDATA[unsigned __int64]]></c> (64 bit) integer from the binary format. - Note that this function is missing in the VxWorks port.</p> - </desc> - </func> - <func> - <name><ret>int</ret><nametext>ei_decode_bignum(const char *buf, int *index, mpz_t obj)</nametext></name> - <fsummary>Decode a GMP arbitrary precision integer</fsummary> - <desc> - <p>This function decodes an integer in the binary format to a GMP <c><![CDATA[mpz_t]]></c> integer. - To use this function the ei library needs to be configured and compiled - to use the GMP library. </p> - </desc> - </func> - <func> - <name><ret>int</ret><nametext>ei_decode_double(const char *buf, int *index, double *p)</nametext></name> - <fsummary>Decode a double</fsummary> - <desc> - <p>This function decodes an double-precision (64 bit) floating - point number from the binary format.</p> - </desc> - </func> - <func> - <name><ret>int</ret><nametext>ei_decode_boolean(const char *buf, int *index, int *p)</nametext></name> - <fsummary>Decode a boolean</fsummary> - <desc> - <p>This function decodes a boolean value from the binary - format. A boolean is actually an atom, <c><![CDATA[true]]></c> decodes 1 - and <c><![CDATA[false]]></c> decodes 0.</p> +ei_x_encode_string(&x, "Banana");</pre> + <p>A correctly encoded map cannot have duplicate keys.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_decode_char(const char *buf, int *index, char *p)</nametext></name> - <fsummary>Decode an 8-bit integer between 0-255</fsummary> + <name><ret>int</ret><nametext>ei_encode_pid(char *buf, int *index, const erlang_pid *p)</nametext></name> + <name><ret>int</ret><nametext>ei_x_encode_pid(ei_x_buff* x, const erlang_pid *p)</nametext></name> + <fsummary>Encode a pid.</fsummary> <desc> - <p>This function decodes a char (8-bit) integer between 0-255 - from the binary format. - Note that for historical reasons the returned integer is of - type <c><![CDATA[char]]></c>. Your C code should consider the - returned value to be of type <c><![CDATA[unsigned char]]></c> even if - the C compilers and system may define <c><![CDATA[char]]></c> to be - signed.</p> + <p>Encodes an Erlang process identifier (pid) in the binary + format. Parameter <c>p</c> points to an + <c>erlang_pid</c> structure (which should have been + obtained earlier with <c>ei_decode_pid()</c>).</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_decode_string(const char *buf, int *index, char *p)</nametext></name> - <fsummary>Decode a string</fsummary> + <name><ret>int</ret><nametext>ei_encode_port(char *buf, int *index, const erlang_port *p)</nametext></name> + <name><ret>int</ret><nametext>ei_x_encode_port(ei_x_buff* x, const erlang_port *p)</nametext></name> + <fsummary>Encode a port.</fsummary> <desc> - <p>This function decodes a string from the binary format. A - string in erlang is a list of integers between 0 and - 255. Note that since the string is just a list, sometimes - lists are encoded as strings by <c><![CDATA[term_to_binary/1]]></c>, - even if it was not intended.</p> - <p>The string is copied to <c><![CDATA[p]]></c>, and enough space must be - allocated. The returned string is null terminated so you - need to add an extra byte to the memory requirement.</p> + <p>Encodes an Erlang port in the binary format. Parameter + <c>p</c> points to a <c>erlang_port</c> + structure (which should have been obtained earlier with + <c>ei_decode_port()</c>).</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_decode_atom(const char *buf, int *index, char *p)</nametext></name> - <fsummary>Decode an atom</fsummary> + <name><ret>int</ret><nametext>ei_encode_ref(char *buf, int *index, const erlang_ref *p)</nametext></name> + <name><ret>int</ret><nametext>ei_x_encode_ref(ei_x_buff* x, const erlang_ref *p)</nametext></name> + <fsummary>Encode a ref.</fsummary> <desc> - <p>This function decodes an atom from the binary format. The - null terminated name of the atom is placed at <c><![CDATA[p]]></c>. There can be at most - <c><![CDATA[MAXATOMLEN]]></c> bytes placed in the buffer.</p> + <p>Encodes an Erlang reference in the binary format. Parameter + <c>p</c> points to a <c>erlang_ref</c> + structure (which should have been obtained earlier with + <c>ei_decode_ref()</c>).</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_decode_atom_as(const char *buf, int *index, char *p, int plen, erlang_char_encoding want, erlang_char_encoding* was, erlang_char_encoding* result)</nametext></name> - <fsummary>Decode an atom</fsummary> + <name><ret>int</ret><nametext>ei_encode_string(char *buf, int *index, const char *p)</nametext></name> + <name><ret>int</ret><nametext>ei_encode_string_len(char *buf, int *index, const char *p, int len)</nametext></name> + <name><ret>int</ret><nametext>ei_x_encode_string(ei_x_buff* x, const char *p)</nametext></name> + <name><ret>int</ret><nametext>ei_x_encode_string_len(ei_x_buff* x, const char* s, int len)</nametext></name> + <fsummary>Encode a string.</fsummary> <desc> - <p>This function decodes an atom from the binary format. The - null terminated name of the atom is placed in buffer at <c>p</c> of length - <c>plen</c> bytes.</p> - <p>The wanted string encoding is specified by <seealso marker="#erlang_char_encoding"> - <c>want</c></seealso>. The original encoding used in the - binary format (latin1 or utf8) can be obtained from <c>*was</c>. The actual encoding of the resulting string - (7-bit ascii, latin1 or utf8) can be obtained from <c>*result</c>. Both <c>was</c> and <c>result</c> can be <c>NULL</c>. - - <c>*result</c> may differ from <c>want</c> if <c>want</c> is a bitwise-or'd combination like - <c>ERLANG_LATIN1|ERLANG_UTF8</c> or if <c>*result</c> turn out to be pure 7-bit ascii - (compatible with both latin1 and utf8).</p> - <p>This function fails if the atom is too long for the buffer - or if it can not be represented with encoding <c>want</c>.</p> - <p>This function was introduced in R16 release of Erlang/OTP as part of a first step - to support UTF8 atoms.</p> + <p>Encodes a string in the binary format. (A string in Erlang + is a list, but is encoded as a character array in the binary + format.) The string is to be <c>NULL</c>-terminated, except for + the <c>ei_x_encode_string_len()</c> function.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_decode_binary(const char *buf, int *index, void *p, long *len)</nametext></name> - <fsummary>Decode a binary</fsummary> + <name><ret>int</ret><nametext>ei_encode_term(char *buf, int *index, void *t)</nametext></name> + <name><ret>int</ret><nametext>ei_x_encode_term(ei_x_buff* x, void *t)</nametext></name> + <fsummary>Encode an <c>erl_interface</c> term.</fsummary> <desc> - <p>This function decodes a binary from the binary format. The - <c><![CDATA[len]]></c> parameter is set to the actual size of the - binary. Note that <c><![CDATA[ei_decode_binary()]]></c> assumes that there - are enough room for the binary. The size required can be - fetched by <c><![CDATA[ei_get_type()]]></c>.</p> + <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> </desc> </func> <func> - <name><ret>int</ret><nametext>ei_decode_fun(const char *buf, int *index, erlang_fun *p)</nametext></name> - <name><ret>void</ret><nametext>free_fun(erlang_fun* f)</nametext></name> - <fsummary>Decode a fun</fsummary> + <name><ret>int</ret><nametext>ei_encode_trace(char *buf, int *index, const erlang_trace *p)</nametext></name> + <name><ret>int</ret><nametext>ei_x_encode_trace(ei_x_buff* x, const erlang_trace *p)</nametext></name> + <fsummary>Encode a trace token.</fsummary> <desc> - <p>This function decodes a fun from the binary format. The - <c><![CDATA[p]]></c> parameter should be NULL or point to an - <c><![CDATA[erlang_fun]]></c> structure. This is the only decode - function that allocates memory; when the <c><![CDATA[erlang_fun]]></c> - is no longer needed, it should be freed with - <c><![CDATA[free_fun]]></c>. (This has to do with the arbitrary size of - the environment for a fun.)</p> + <p>Encodes an Erlang trace token in the binary format. + Parameter <c>p</c> points to a + <c>erlang_trace</c> structure (which should have been + obtained earlier with <c>ei_decode_trace()</c>).</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_decode_pid(const char *buf, int *index, erlang_pid *p)</nametext></name> - <fsummary>Decode a <c><![CDATA[pid]]></c></fsummary> + <name><ret>int</ret><nametext>ei_encode_tuple_header(char *buf, int *index, int arity)</nametext></name> + <name><ret>int</ret><nametext>ei_x_encode_tuple_header(ei_x_buff* x, int arity)</nametext></name> + <fsummary>Encode a tuple.</fsummary> <desc> - <p>Decodes a pid, process identifier, from the binary format.</p> + <p>Encodes a tuple header, with a specified + arity. The next <c>arity</c> terms encoded will be the + elements of the tuple. Tuples and lists are encoded + recursively, so that a tuple can contain another tuple or list.</p> + <p>For example, to encode the tuple <c>{a, {b, {}}}</c>:</p> + <pre> +ei_encode_tuple_header(buf, &i, 2); +ei_encode_atom(buf, &i, "a"); +ei_encode_tuple_header(buf, &i, 2); +ei_encode_atom(buf, &i, "b"); +ei_encode_tuple_header(buf, &i, 0);</pre> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_decode_port(const char *buf, int *index, erlang_port *p)</nametext></name> - <fsummary>Decode a port</fsummary> + <name><ret>int</ret><nametext>ei_encode_ulong(char *buf, int *index, unsigned long p)</nametext></name> + <name><ret>int</ret><nametext>ei_x_encode_ulong(ei_x_buff* x, unsigned long p)</nametext></name> + <fsummary>Encode unsigned integer.</fsummary> <desc> - <p>This function decodes a port identifier from the binary - format.</p> + <p>Encodes an unsigned long integer in the binary format. + If the code is 64 bits, the function <c>ei_encode_ulong()</c> is + the same as <c>ei_encode_ulonglong()</c>.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_decode_ref(const char *buf, int *index, erlang_ref *p)</nametext></name> - <fsummary>Decode a reference</fsummary> + <name><ret>int</ret><nametext>ei_encode_ulonglong(char *buf, int *index, unsigned long long p)</nametext></name> + <name><ret>int</ret><nametext>ei_x_encode_ulonglong(ei_x_buff* x, unsigned long long p)</nametext></name> + <fsummary>Encode unsigned integer.</fsummary> <desc> - <p>This function decodes a reference from the binary format.</p> + <p>Encodes a GCC <c>unsigned long long</c> or Visual C++ + <c>unsigned __int64</c> (64-bit) integer in the binary + format. This function is missing in the VxWorks port.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_decode_trace(const char *buf, int *index, erlang_trace *p)</nametext></name> - <fsummary>Decode a trace token</fsummary> + <name><ret>int</ret><nametext>ei_encode_version(char *buf, int *index)</nametext></name> + <name><ret>int</ret><nametext>ei_x_encode_version(ei_x_buff* x)</nametext></name> + <fsummary>Encode version.</fsummary> <desc> - <p>Decodes an erlang trace token from the binary format.</p> + <p>Encodes a version magic number for the binary format. Must + be the first token in a binary term.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_decode_tuple_header(const char *buf, int *index, int *arity)</nametext></name> - <fsummary>Decode a tuple</fsummary> + <name><ret>int</ret><nametext>ei_get_type(const char *buf, const int *index, int *type, int *size)</nametext></name> + <fsummary>Fetch the type and size of an encoded term.</fsummary> <desc> - <p>This function decodes a tuple header, the number of elements - is returned in <c><![CDATA[arity]]></c>. The tuple elements follows in order in - the buffer.</p> + <p>Returns the type in <c>type</c> and size in + <c>size</c> of the encoded term. For strings and atoms, + size is the number of characters <em>not</em> including the + terminating <c>NULL</c>. For binaries, <c>size</c> is the number of + bytes. For lists and tuples, <c>size</c> is the arity of + the object. For other types, <c>size</c> is 0. In all + cases, <c>index</c> is left unchanged.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_decode_list_header(const char *buf, int *index, int *arity)</nametext></name> - <fsummary>Decode a list</fsummary> - <desc> - <p>This function decodes a list header from the binary - format. The number of elements is returned in - <c><![CDATA[arity]]></c>. The <c><![CDATA[arity+1]]></c> elements follows (the last - one is the tail of the list, normally an empty list.) If - <c><![CDATA[arity]]></c> is <c><![CDATA[0]]></c>, it's an empty list.</p> - <p>Note that lists are encoded as strings, if they consist - entirely of integers in the range 0..255. This function will - not decode such strings, use <c><![CDATA[ei_decode_string()]]></c> - instead.</p> + <name><ret>int</ret><nametext>ei_print_term(FILE* fp, const char* buf, int* index)</nametext></name> + <name><ret>int</ret><nametext>ei_s_print_term(char** s, const char* buf, int* index)</nametext></name> + <fsummary>Print a term in clear text.</fsummary> + <desc> + <p>Prints a term, in clear text, to the file + specified by <c>fp</c>, or the buffer pointed to by + <c>s</c>. It + tries to resemble the term printing in the Erlang shell.</p> + <p>In <c>ei_s_print_term()</c>, parameter + <c>s</c> is to + point to a dynamically (malloc) allocated string of + <c>BUFSIZ</c> bytes or a <c>NULL</c> pointer. The string + can be reallocated (and <c>*s</c> can be updated) by this + function if the result is more than <c>BUFSIZ</c> + characters. The string returned is <c>NULL</c>-terminated.</p> + <p>The return value is the number of characters written to the file + or string, or <c>-1</c> if <c>buf[index]</c> does not + contain a valid term. + Unfortunately, I/O errors on <c>fp</c> is not checked.</p> + <p>Argument <c>index</c> is updated, that is, this function + can be viewed as a decode function that decodes a term into a + human-readable format.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_decode_map_header(const char *buf, int *index, int *arity)</nametext></name> - <fsummary>Decode a map</fsummary> + <name><ret>void</ret><nametext>ei_set_compat_rel(release_number)</nametext></name> + <fsummary>Set the ei library in compatibility mode.</fsummary> + <type> + <v>unsigned release_number;</v> + </type> <desc> - <p>This function decodes a map header from the binary - format. The number of key-value pairs is returned in - <c>*arity</c>. Keys and values follow in the following order: - <c>K1, V1, K2, V2, ..., Kn, Vn</c>. This makes a total of - <c>arity*2</c> terms. If <c>arity</c> is zero, it's an empty map. - A correctly encoded map does not have duplicate keys.</p> + <marker id="ei_set_compat_rel"></marker> + <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. For example, + <c>ei</c> from + Erlang/OTP R10 is not compatible with an Erlang emulator + from Erlang/OTP R9 by default.</p> + <p>A call to <c>ei_set_compat_rel(release_number)</c> sets + the <c>ei</c> library in compatibility mode of release + <c>release_number</c>. Valid range of + <c>release_number</c> + is <c>[7, current release]</c>. This makes it possible to + communicate with Erlang/OTP components from earlier releases.</p> + <note> + <p>If this function is called, it can only be called once + and must be called before any other functions in the + <c>ei</c> library are called.</p> + </note> + <warning> + <p>You can 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><ret>int</ret><nametext>ei_decode_ei_term(const char* buf, int* index, ei_term* term)</nametext></name> - <fsummary>Decode a term, without prior knowledge of type</fsummary> + <name><ret>int</ret><nametext>ei_skip_term(const char* buf, int* index)</nametext></name> + <fsummary>Skip a term.</fsummary> <desc> - <p>This function decodes any term, or at least tries to. If the - term pointed at by <c><![CDATA[*index]]></c> in <c><![CDATA[buf]]></c> fits in the - <c><![CDATA[term]]></c> union, it is decoded, and the appropriate field - in <c><![CDATA[term->value]]></c> is set, and <c><![CDATA[*index]]></c> is - incremented by the term size.</p> - <p>The function returns 1 on successful decoding, -1 on error, - and 0 if the term seems alright, but does not fit in the - <c><![CDATA[term]]></c> structure. If it returns 1, the <c><![CDATA[index]]></c> - will be incremented, and the <c><![CDATA[term]]></c> contains the - decoded term.</p> - <p>The <c><![CDATA[term]]></c> structure will contain the arity for a tuple - or list, size for a binary, string or atom. It will contains - a term if it's any of the following: integer, float, atom, - pid, port or ref.</p> - </desc> - </func> - <func> - <name><ret>int</ret><nametext>ei_decode_term(const char *buf, int *index, void *t)</nametext></name> - <fsummary>Decode a <c><![CDATA[ETERM]]></c></fsummary> - <desc> - <p>This function decodes a term from the binary format. The - term is return in <c><![CDATA[t]]></c> as a <c><![CDATA[ETERM*]]></c>, so <c><![CDATA[t]]></c> - is actually an <c><![CDATA[ETERM**]]></c> (see - <c><![CDATA[erl_interface(3)]]></c>. The term should later be - deallocated.</p> - <p>Note that this function is located in the erl_interface - library.</p> + <p>Skips a term in the specified buffer; + recursively skips elements of lists and tuples, so that a + full term is skipped. This is a way to get the size of an + Erlang term.</p> + <p><c>buf</c> is the buffer.</p> + <p><c>index</c> is updated to point right after the term + in the buffer.</p> + <note> + <p>This can be useful when you want to hold arbitrary + terms: skip them and copy the binary term data to some + buffer.</p> + </note> + <p>Returns <c>0</c> on success, otherwise + <c>-1</c>.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_print_term(FILE* fp, const char* buf, int* index)</nametext></name> - <name><ret>int</ret><nametext>ei_s_print_term(char** s, const char* buf, int* index)</nametext></name> - <fsummary>Print a term in clear text</fsummary> + <name><ret>int</ret><nametext>ei_x_append(ei_x_buff* x, const ei_x_buff* x2)</nametext></name> + <name><ret>int</ret><nametext>ei_x_append_buf(ei_x_buff* x, const char* buf, int len)</nametext></name> + <fsummary>Append a buffer at the end.</fsummary> <desc> - <p>This function prints a term, in clear text, to the file - given by <c><![CDATA[fp]]></c>, or the buffer pointed to by <c><![CDATA[s]]></c>. It - tries to resemble the term printing in the erlang shell.</p> - <p>In <c><![CDATA[ei_s_print_term()]]></c>, the parameter <c><![CDATA[s]]></c> should - point to a dynamically (malloc) allocated string of - <c><![CDATA[BUFSIZ]]></c> bytes or a NULL pointer. The string may be - reallocated (and <c><![CDATA[*s]]></c> may be updated) by this function - if the result is more than <c><![CDATA[BUFSIZ]]></c> characters. The - string returned is zero-terminated.</p> - <p>The return value is the number of characters written to the - file or string, or -1 if <c><![CDATA[buf[index]]]></c> doesn't contain a - valid term. Unfortunately, I/O errors on <c><![CDATA[fp]]></c> is not - checked.</p> - <p>The argument <c><![CDATA[index]]></c> is updated, i.e. this function can - be viewed as en decode function that decodes a term into a - human readable format.</p> + <p>Appends data at the end of buffer <c>x</c>.</p> </desc> </func> + <func> <name><ret>int</ret><nametext>ei_x_format(ei_x_buff* x, const char* fmt, ...)</nametext></name> <name><ret>int</ret><nametext>ei_x_format_wo_ver(ei_x_buff* x, const char *fmt, ... )</nametext></name> <fsummary>Format a term from a format string and parameters.</fsummary> <desc> - <p>Format a term, given as a string, to a buffer. This - functions works like a sprintf for erlang terms. The - <c><![CDATA[fmt]]></c> contains a format string, with arguments like - <c><![CDATA[~d]]></c>, to insert terms from variables. The following + <p>Formats a term, given as a string, to a buffer. + Works like a sprintf for Erlang terms. + <c>fmt</c> contains a format string, with arguments like + <c>~d</c>, to insert terms from variables. The following formats are supported (with the C types given):</p> - <p></p> <pre> -~a - an atom, char* -~c - a character, char -~s - a string, char* -~i - an integer, int -~l - a long integer, long int -~u - a unsigned long integer, unsigned long int -~f - a float, float -~d - a double float, double float -~p - an Erlang PID, erlang_pid* - </pre> - <p>For instance, to encode a tuple with some stuff:</p> +~a An atom, char* +~c A character, char +~s A string, char* +~i An integer, int +~l A long integer, long int +~u A unsigned long integer, unsigned long int +~f A float, float +~d A double float, double float +~p An Erlang pid, erlang_pid*</pre> + <p>For example, to encode a tuple with some stuff:</p> <pre> ei_x_format("{~a,~i,~d}", "numbers", 12, 3.14159) -encodes the tuple {numbers,12,3.14159} - </pre> - <p>The <c><![CDATA[ei_x_format_wo_ver()]]></c> formats into a buffer, without - the initial version byte.</p> - </desc> - </func> - <func> - <name><ret>int</ret><nametext>ei_x_new(ei_x_buff* x)</nametext></name> - <name><ret>int</ret><nametext>ei_x_new_with_version(ei_x_buff* x)</nametext></name> - <fsummary>Allocate a new buffer</fsummary> - <desc> - <p>This function allocates a new <c><![CDATA[ei_x_buff]]></c> buffer. The - fields of the structure pointed to by <c><![CDATA[x]]></c> parameter is - filled in, and a default buffer is allocated. The - <c><![CDATA[ei_x_new_with_version()]]></c> also puts an initial version - byte, that is used in the binary format. (So that - <c><![CDATA[ei_x_encode_version()]]></c> won't be needed.)</p> +encodes the tuple {numbers,12,3.14159}</pre> + <p><c>ei_x_format_wo_ver()</c> formats into a buffer, + without the initial version byte.</p> </desc> </func> + <func> <name><ret>int</ret><nametext>ei_x_free(ei_x_buff* x)</nametext></name> - <fsummary>Frees a buffer</fsummary> - <desc> - <p>This function frees an <c><![CDATA[ei_x_buff]]></c> buffer. The memory - used by the buffer is returned to the OS.</p> - </desc> - </func> - <func> - <name><ret>int</ret><nametext>ei_x_append(ei_x_buff* x, const ei_x_buff* x2)</nametext></name> - <name><ret>int</ret><nametext>ei_x_append_buf(ei_x_buff* x, const char* buf, int len)</nametext></name> - <fsummary>Appends a buffer at the end</fsummary> + <fsummary>Free a buffer.</fsummary> <desc> - <p>These functions appends data at the end of the buffer <c><![CDATA[x]]></c>.</p> + <p>Frees an <c>ei_x_buff</c> buffer. + The memory used by the buffer is returned to the OS.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_skip_term(const char* buf, int* index)</nametext></name> - <fsummary>skip a term</fsummary> + <name><ret>int</ret><nametext>ei_x_new(ei_x_buff* x)</nametext></name> + <name><ret>int</ret><nametext>ei_x_new_with_version(ei_x_buff* x)</nametext></name> + <fsummary>Allocate a new buffer.</fsummary> <desc> - <p>This function skips a term in the given buffer, it - recursively skips elements of lists and tuples, so that a - full term is skipped. This is a way to get the size of an - erlang term.</p> - <p><c><![CDATA[buf]]></c> is the buffer.</p> - <p><c><![CDATA[index]]></c> is updated to point right after the term in the - buffer.</p> - <note> - <p>This can be useful when you want to hold arbitrary - terms: just skip them and copy the binary term data to some - buffer.</p> - </note> - <p>The function returns <c><![CDATA[0]]></c> on success and <c><![CDATA[-1]]></c> on - failure.</p> + <p>Allocates a new <c>ei_x_buff</c> buffer. The + fields of the structure pointed to by parameter <c>x</c> + is filled in, and a default buffer is allocated. + <c>ei_x_new_with_version()</c> also puts an initial + version byte, which is used in the binary format (so that + <c>ei_x_encode_version()</c> will not be needed.)</p> </desc> </func> </funcs> <section> <title>Debug Information</title> - <p>Some tips on what to check when the emulator doesn't seem to - receive the terms that you send.</p> + <p>Some tips on what to check when the emulator does not seem to + receive the terms that you send:</p> + <list type="bulleted"> - <item>be careful with the version header, use - <c><![CDATA[ei_x_new_with_version()]]></c> when appropriate</item> - <item>turn on distribution tracing on the erlang node</item> - <item>check the result codes from ei_decode_-calls</item> + <item>Be careful with the version header, use + <c>ei_x_new_with_version()</c> when appropriate.</item> + <item>Turn on distribution tracing on the Erlang node.</item> + <item>Check the result codes from <c>ei_decode_-calls</c>.</item> </list> </section> <section> <title>See Also</title> - <p>erl_interface(3)</p> + <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 a06013ed6a..607a7cbff4 100644 --- a/lib/erl_interface/doc/src/ei_connect.xml +++ b/lib/erl_interface/doc/src/ei_connect.xml @@ -4,14 +4,14 @@ <cref> <header> <copyright> - <year>2001</year><year>2013</year> + <year>2001</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 @@ -19,100 +19,233 @@ 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_connect</title> <prepared>Jakob Cederlund</prepared> <docno></docno> - <approved>?</approved> - <checked>?</checked> + <approved></approved> + <checked></checked> <date>2001-09-01</date> <rev>A</rev> - <file>ei_connect.sgml</file> + <file>ei_connect.xml</file> </header> <lib>ei_connect</lib> - <libsummary>Communicate with distributed erlang</libsummary> + <libsummary>Communicate with distributed Erlang.</libsummary> <description> - <p>This module enables C programs to communicate with erlang nodes, - using the erlang distribution over TCP/IP.</p> - <p>A C node appears to Erlang as a - <em>hidden node</em>. + <p>This module enables C-programs to communicate with Erlang nodes, + using the Erlang distribution over TCP/IP.</p> + + <p>A C-node appears to Erlang as a <em>hidden node</em>. That is, Erlang processes that know the name of the - C node are able to communicate with it in a normal manner, but - the node name will not appear in the listing provided by the - Erlang function <c><![CDATA[nodes/0]]></c>.</p> - <p>The environment variable <c><![CDATA[ERL_EPMD_PORT]]></c> can be used - to indicate which logical cluster a C node belongs to.</p> + C-node can communicate with it in a normal manner, but + the node name is not shown in the listing provided by + <seealso marker="erts:erlang#nodes/0"><c>erlang:nodes/0</c></seealso> + in <c>ERTS</c>.</p> + + <p>The environment variable <c>ERL_EPMD_PORT</c> can be used + to indicate which logical cluster a C-node belongs to.</p> </description> <section> - <title>Timeout functions</title> + <title>Time-Out Functions</title> <p>Most functions appear in a version with the suffix - <c><![CDATA[_tmo]]></c> appended to the function name. Those function take - an additional argument, a timeout in <em>milliseconds</em>. The - semantics is this; for each communication primitive involved in + <c>_tmo</c> appended to the function name. Those functions + take an extra argument, a time-out in <em>milliseconds</em>. The + semantics is this: for each communication primitive involved in the operation, if the primitive does not complete within the time - specified, the function will return an error and - <c><![CDATA[erl_errno]]></c> will be set to <c><![CDATA[ETIMEDOUT]]></c>. With - communication primitive is meant an operation on the socket, like - <c><![CDATA[connect]]></c>, <c><![CDATA[accept]]></c>, <c><![CDATA[recv]]></c> or <c><![CDATA[send]]></c>.</p> - <p>Obviously the timeouts are for implementing fault tolerance, - not to keep hard realtime promises. The <c><![CDATA[_tmo]]></c> functions + specified, the function returns an error and + <c>erl_errno</c> is set to <c>ETIMEDOUT</c>. + With communication primitive is meant an operation on the socket, like + <c>connect</c>, <c>accept</c>, + <c>recv</c>, or <c>send</c>.</p> + + <p>Clearly the time-outs are for implementing fault tolerance, + not to keep hard real-time promises. The <c>_tmo</c> functions are for detecting non-responsive peers and to avoid blocking on - socket operations. </p> - <p>A timeout value of <c><![CDATA[0]]></c> (zero), means that timeouts are - disabled. Calling a <c><![CDATA[_tmo]]></c>-function with the last argument as - <c><![CDATA[0]]></c> is therefore exactly the same thing as calling the - function without the <c><![CDATA[_tmo]]></c> suffix.</p> - <p>As with all other ei functions, you are <em>not</em> expected - to put the socket in non blocking mode yourself in the program. Every - use of non blocking mode is embedded inside the timeout + socket operations.</p> + + <p>A time-out value of <c>0</c> (zero) means that time-outs are + disabled. Calling a <c>_tmo</c> function with the last + argument as <c>0</c> is therefore the same thing as calling + the function without the <c>_tmo</c> suffix.</p> + + <p>As with all other functions starting with <c>ei_</c>, + you are <em>not</em> expected + to put the socket in non-blocking mode yourself in the program. Every + use of non-blocking mode is embedded inside the time-out functions. The socket will always be back in blocking mode after the operations are completed (regardless of the result). To - avoid problems, leave the socket options alone. Ei will handle + avoid problems, leave the socket options alone. <c>ei</c> handles any socket options that need modification.</p> - <p>In all other senses, the <c><![CDATA[_tmo]]></c> functions inherit all - the return values and the semantics from the functions without - the <c><![CDATA[_tmo]]></c> suffix.</p> + + <p>In all other senses, the <c>_tmo</c> functions inherit all + the return values and the semantics from the functions without + the <c>_tmo</c> suffix.</p> </section> + <funcs> <func> + <name><ret>struct hostent</ret><nametext>*ei_gethostbyaddr(const char *addr, int len, int type)</nametext></name> + <name><ret>struct hostent</ret><nametext>*ei_gethostbyaddr_r(const char *addr, int length, int type, struct hostent *hostp, char *buffer, int buflen, int *h_errnop)</nametext></name> + <name><ret>struct hostent</ret><nametext>*ei_gethostbyname(const char *name)</nametext></name> + <name><ret>struct hostent</ret><nametext>*ei_gethostbyname_r(const char *name, struct hostent *hostp, char *buffer, int buflen, int *h_errnop)</nametext></name> + <fsummary>Name lookup functions.</fsummary> + <desc> + <p>Convenience functions for some common name lookup functions.</p> + </desc> + </func> + + <func> + <name><ret>int</ret><nametext>ei_accept(ei_cnode *ec, int listensock, ErlConnect *conp)</nametext></name> + <fsummary>Accept a connection from another node.</fsummary> + <desc> + <p>Used by a server process to accept a + connection from a client process.</p> + <list type="bulleted"> + <item> + <p><c>ec</c> is the C-node structure.</p> + </item> + <item> + <p><c>listensock</c> is an open socket descriptor on + which <c>listen()</c> has previously been called.</p> + </item> + <item> + <p><c>conp</c> is a pointer to an + <c>ErlConnect</c> struct, described as follows:</p> + <code type="none"><![CDATA[ +typedef struct { + char ipadr[4]; + char nodename[MAXNODELEN]; +} ErlConnect; + ]]></code> + </item> + </list> + <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><ret>int</ret><nametext>ei_accept_tmo(ei_cnode *ec, int listensock, ErlConnect *conp, unsigned timeout_ms)</nametext></name> + <fsummary>Accept a connection from another node with optional + time-out.</fsummary> + <desc> + <p>Equivalent to + <c>ei_accept</c> with an optional time-out argument, + see the description at the beginning of this manual page.</p> + </desc> + </func> + + <func> + <name><ret>int</ret><nametext>ei_connect(ei_cnode* ec, char *nodename)</nametext></name> + <name><ret>int</ret><nametext>ei_xconnect(ei_cnode* ec, Erl_IpAddr adr, char *alivename)</nametext></name> + <fsummary>Establish a connection to an Erlang node.</fsummary> + <desc> + <p>Sets up a connection to an Erlang node.</p> + <p><c>ei_xconnect()</c> requires the IP address of the + 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> + <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>These functions return an open file descriptor on success, or + a negative value indicating that an error occurred. In the latter + case they set <c>erl_errno</c> to one of the + following:</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 may be propagated into <c>erl_errno</c>.</p> + <p><em>Example:</em></p> + <code type="none"><![CDATA[ +#define NODE "[email protected]" +#define ALIVE "madonna" +#define IP_ADDR "150.236.14.75" + +/*** Variant 1 ***/ +int fd = ei_connect(&ec, NODE); + +/*** Variant 2 ***/ +struct in_addr addr; +addr.s_addr = inet_addr(IP_ADDR); +fd = ei_xconnect(&ec, &addr, ALIVE); + ]]></code> + </desc> + </func> + + <func> <name><ret>int</ret><nametext>ei_connect_init(ei_cnode* ec, const char* this_node_name, const char *cookie, short creation)</nametext></name> <name><ret>int</ret><nametext>ei_connect_xinit(ei_cnode* ec, const char *thishostname, const char *thisalivename, const char *thisnodename, Erl_IpAddr thisipaddr, const char *cookie, short creation)</nametext></name> <fsummary>Initialize for a connection.</fsummary> <desc> - <p>These function initializes the <c><![CDATA[ec]]></c> structure, to + <p>Initializes the <c>ec</c> structure, to identify the node name and cookie of the server. One of them - has to be called before other functions that works on the - type <c><![CDATA[ei_cnode]]></c> or a file descriptor associated with a - connection to another node are used.</p> - <p><c><![CDATA[ec]]></c> is a structure containing information about the - C-node. It is used in other <c><![CDATA[ei]]></c> functions for - connecting and receiving data.</p> - <p><c><![CDATA[this_node_name]]></c> is the registered name of the process - (the name before '@').</p> - <p><c><![CDATA[cookie]]></c> is the cookie for the node.</p> - <p><c><![CDATA[creation]]></c> identifies a specific instance of a C - node. It can help prevent the node from receiving messages - sent to an earlier process with the same registered name.</p> - <p><c><![CDATA[thishostname]]></c> is the name of the machine we're running - on. If long names are to be used, it should be fully - qualified (i.e. <c><![CDATA[durin.erix.ericsson.se]]></c> instead of - <c><![CDATA[durin]]></c>).</p> - <p><c><![CDATA[thisalivename]]></c> is the registered name of the process.</p> - <p><c><![CDATA[thisnodename]]></c> is the full name of the node, - i.e. <c><![CDATA[einode@durin]]></c>.</p> - <p><c><![CDATA[thispaddr]]></c> if the IP address of the host.</p> - <p>A C node acting as a server will be assigned a creation - number when it calls <c><![CDATA[ei_publish()]]></c>.</p> - <p>A connection is closed by simply closing the socket. Refer - to system documentation to close the socket gracefully (when - there are outgoing packets before close).</p> - <p>This function return a negative value indicating that an error + must be called before other functions that works on the + <c>ei_cnode</c> type or a file descriptor associated with + a connection to another node is used.</p> + <list type="bulleted"> + <item> + <p><c>ec</c> is a structure containing information about + the C-node. It is used in other <c>ei</c> functions + for connecting and receiving data.</p> + </item> + <item> + <p><c>this_node_name</c> is the registered name of the + process (the name before '@').</p> + </item> + <item> + <p><c>cookie</c> is the cookie for the node.</p> + </item> + <item> + <p><c>creation</c> identifies a specific instance of a + C-node. It can help prevent the node from receiving messages + sent to an earlier process with the same registered name.</p> + </item> + <item> + <p><c>thishostname</c> is the name of the machine we are + running on. If long names are to be used, they are to be fully + qualified (that is, <c>durin.erix.ericsson.se</c> + instead of <c>durin</c>).</p> + </item> + <item> + <p><c>thisalivename</c> is the registered name of the + process.</p> + </item> + <item> + <p><c>thisnodename</c> is the full name of the node, + that is, <c>einode@durin</c>.</p> + </item> + <item> + <p><c>thispaddr</c> if the IP address of the host.</p> + </item> + </list> + <p>A C-node acting as a server is assigned a creation + number when it calls <c>ei_publish()</c>.</p> + <p>A connection is closed by simply closing the socket. + For information about how to close the socket gracefully (when + there are outgoing packets before close), see the relevant system + documentation.</p> + <p>These functions return a negative value indicating that an error occurred.</p> - <p>Example 1: - </p> + <p><em>Example 1:</em></p> <code type="none"><![CDATA[ int n = 0; struct in_addr addr; @@ -129,8 +262,7 @@ if (ei_connect_xinit(&ec, exit(-1); } ]]></code> - <p>Example 2: - </p> + <p><em>Example 2:</em></p> <code type="none"><![CDATA[ if (ei_connect_init(&ec, "madonna", "cookie...", n++) < 0) { fprintf(stderr,"ERROR when initializing: %d",erl_errno); @@ -139,114 +271,184 @@ if (ei_connect_init(&ec, "madonna", "cookie...", n++) < 0) { ]]></code> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_connect(ei_cnode* ec, char *nodename)</nametext></name> - <name><ret>int</ret><nametext>ei_xconnect(ei_cnode* ec, Erl_IpAddr adr, char *alivename)</nametext></name> - <fsummary>Establishe a connection to an Erlang node</fsummary> + <name><ret>int</ret><nametext>ei_connect_tmo(ei_cnode* ec, char *nodename, unsigned timeout_ms)</nametext></name> + <name><ret>int</ret><nametext>ei_xconnect_tmo(ei_cnode* ec, Erl_IpAddr adr, char *alivename, unsigned timeout_ms)</nametext></name> + <fsummary>Establish a connection to an Erlang node with optional + time-out.</fsummary> <desc> - <p>These functions set up a connection to an Erlang node.</p> - <p><c><![CDATA[ei_xconnect()]]></c> requires the IP address of the remote - host and the alive name of the remote node - to be specified. <c><![CDATA[ei_connect()]]></c> provides an alternative - interface, and determines the information from the node name - provided.</p> - <p><c><![CDATA[addr]]></c> is the 32-bit IP address of the remote host.</p> - <p><c><![CDATA[alive]]></c> is the alivename of the remote node.</p> - <p><c><![CDATA[node]]></c> is the name of the remote node.</p> - <p>These functions return an open file descriptor on success, or - a negative value indicating that an error occurred --- in - which case they will set <c><![CDATA[erl_errno]]></c> to one of:</p> - <taglist> - <tag><c><![CDATA[EHOSTUNREACH]]></c></tag> - <item>The remote host <c><![CDATA[node]]></c> is unreachable</item> - <tag><c><![CDATA[ENOMEM]]></c></tag> - <item>No more memory available.</item> - <tag><c><![CDATA[EIO]]></c></tag> - <item>I/O error.</item> - </taglist> - <p>Additionally, <c><![CDATA[errno]]></c> values from - <c><![CDATA[socket]]></c><em>(2)</em> and <c><![CDATA[connect]]></c><em>(2)</em> - system calls may be propagated into <c><![CDATA[erl_errno]]></c>.</p> - <p>Example:</p> - <code type="none"><![CDATA[ -#define NODE "[email protected]" -#define ALIVE "madonna" -#define IP_ADDR "150.236.14.75" + <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> + </desc> + </func> -/*** Variant 1 ***/ -int fd = ei_connect(&ec, NODE); + <func> + <name><ret>int</ret><nametext>ei_get_tracelevel(void)</nametext></name> + <name><ret>void</ret><nametext>ei_set_tracelevel(int level)</nametext></name> + <fsummary>Get and set functions for tracing.</fsummary> + <desc> + <p>Used to set tracing on the distribution. The levels are different + verbosity levels. A higher level means more information. See also + section <seealso marker="#debug_information"> + Debug Information</seealso>.</p> + <p>These functions are not thread safe.</p> + </desc> + </func> -/*** Variant 2 ***/ -struct in_addr addr; -addr.s_addr = inet_addr(IP_ADDR); -fd = ei_xconnect(&ec, &addr, ALIVE); - ]]></code> + <func> + <name><ret>int</ret><nametext>ei_publish(ei_cnode *ec, int port)</nametext></name> + <fsummary>Publish a node name.</fsummary> + <desc> + <p>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 either of these functions, the process should + have called <c>bind()</c> and <c>listen()</c> + on an open socket.</p> + <list type="bulleted"> + <item> + <p><c>ec</c> is the C-node structure.</p> + </item> + <item> + <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> + </item> + <item> + <p><c>addr</c> is the 32-bit IP address of the local + host.</p> + </item> + </list> + <p>To unregister with EPMD, simply close the returned descriptor. Do + not use <c>ei_unpublish()</c>, which is deprecated + anyway.</p> + <p>On success, the function returns a descriptor connecting the + calling process to EPMD. On failure, <c>-1</c> is returned and + <c>erl_errno</c> is set to <c>EIO</c>.</p> + <p>Also, <c>errno</c> values from + <c>socket</c><em>(2)</em> and + <c>connect</c><em>(2)</em> system calls may be propagated + into <c>erl_errno</c>.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_connect_tmo(ei_cnode* ec, char *nodename, unsigned timeout_ms)</nametext></name> - <name><ret>int</ret><nametext>ei_xconnect_tmo(ei_cnode* ec, Erl_IpAddr adr, char *alivename, unsigned timeout_ms)</nametext></name> - <fsummary>Establish a connection to an Erlang node with optional timeout</fsummary> + <name><ret>int</ret><nametext>ei_publish_tmo(ei_cnode *ec, int port, unsigned timeout_ms)</nametext></name> + <fsummary>Publish a node name with optional time-out.</fsummary> <desc> - <p>ei_connect and ei_xconnect with an optional timeout argument, - see the description at the beginning of this document.</p> + <p>Equivalent to + <c>ei_publish</c> with an optional time-out argument, + see the description at the beginning of this manual page.</p> </desc> </func> + <func> <name><ret>int</ret><nametext>ei_receive(int fd, unsigned char* bufp, int bufsize)</nametext></name> - <fsummary>Receive a message</fsummary> + <fsummary>Receive a message.</fsummary> <desc> - <p>This function receives a message consisting of a sequence + <p>Receives a message consisting of a sequence of bytes in the Erlang external format.</p> - <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection. It - is obtained from a previous <c><![CDATA[ei_connect]]></c> or - <c><![CDATA[ei_accept]]></c>.</p> - <p><c><![CDATA[bufp]]></c> is a buffer large enough to hold the expected - message. </p> - <p><c><![CDATA[bufsize]]></c> indicates the size of <c><![CDATA[bufp]]></c>.</p> - <p>If a <em>tick</em> occurs, i.e., the Erlang node on the + <list type="bulleted"> + <item> + <p><c>fd</c> is an open descriptor to an Erlang + connection. It is obtained from a previous + <c>ei_connect</c> or <c>ei_accept</c>.</p> + </item> + <item> + <p><c>bufp</c> is a buffer large enough to hold the + expected message.</p> + </item> + <item> + <p><c>bufsize</c> indicates the size of + <c>bufp</c>.</p> + </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 will return <c><![CDATA[ERL_TICK]]></c> and - no message will be placed in the buffer. Also, - <c><![CDATA[erl_errno]]></c> will be set to <c><![CDATA[EAGAIN]]></c>.</p> + 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 <c><![CDATA[ERL_ERROR]]></c> and will set - <c><![CDATA[erl_errno]]></c> to one of:</p> + failure, the function returns <c>ERL_ERROR</c> and sets + <c>erl_errno</c> to one of the following:</p> <taglist> - <tag><c><![CDATA[EAGAIN]]></c></tag> + <tag><c>EAGAIN</c></tag> <item>Temporary error: Try again.</item> - <tag><c><![CDATA[EMSGSIZE]]></c></tag> - <item>Buffer too small.</item> - <tag><c><![CDATA[EIO]]></c></tag> + <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><ret>int</ret><nametext>ei_receive_tmo(int fd, unsigned char* bufp, int bufsize, unsigned timeout_ms)</nametext></name> - <fsummary>Receive a message with optional timeout</fsummary> + <name><ret>int</ret><nametext>ei_receive_encoded(int fd, char **mbufp, int *bufsz, erlang_msg *msg, int *msglen)</nametext></name> + <fsummary>Obsolete function for receiving a message.</fsummary> <desc> - <p>ei_receive with an optional timeout argument, - see the description at the beginning of this document.</p> + <p>This function is retained for compatibility with code + generated by the interface compiler and with code following + examples in the same application.</p> + <p>In essence, the function performs the same operation as + <c>ei_xreceive_msg</c>, but instead of using an + <c>ei_x_buff</c>, the function expects a pointer to a character + pointer (<c>mbufp</c>), where the character pointer + is to point to a memory area allocated by <c>malloc</c>. + Argument <c>bufsz</c> is to be a pointer to an integer + containing the exact size (in bytes) of the memory area. The function + may reallocate the memory area and will in such cases put the new + size in <c>*bufsz</c> and update + <c>*mbufp</c>.</p> + <p>Returns either <c>ERL_TICK</c> or the + <c>msgtype</c> field of the + <c>erlang_msg *msg</c>. The length + of the message is put in <c>*msglen</c>. On error + a value <c>< 0</c> is returned.</p> + <p>It is recommended to use <c>ei_xreceive_msg</c> instead when + possible, for the sake of readability. However, the function will + be retained in the interface for compatibility and + will <em>not</em> be removed in future releases without prior + notice.</p> + </desc> + </func> + + <func> + <name><ret>int</ret><nametext>ei_receive_encoded_tmo(int fd, char **mbufp, int *bufsz, erlang_msg *msg, int *msglen, unsigned timeout_ms)</nametext></name> + <fsummary>Obsolete function for receiving a message with time-out. + </fsummary> + <desc> + <p>Equivalent to + <c>ei_receive_encoded</c> with an optional time-out argument, + see the description at the beginning of this manual page.</p> </desc> </func> + <func> <name><ret>int</ret><nametext>ei_receive_msg(int fd, erlang_msg* msg, ei_x_buff* x)</nametext></name> <name><ret>int</ret><nametext>ei_xreceive_msg(int fd, erlang_msg* msg, ei_x_buff* x)</nametext></name> - <fsummary>Receive a message</fsummary> + <fsummary>Receive a message.</fsummary> <desc> - <p>These functions receives a message to the buffer in - <c><![CDATA[x]]></c>. <c><![CDATA[ei_xreceive_msg]]></c> allows the buffer in - <c><![CDATA[x]]></c> to grow, but <c><![CDATA[ei_receive_msg]]></c> fails if the - message is bigger than the preallocated buffer in <c><![CDATA[x]]></c>.</p> - <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.</p> - <p><c><![CDATA[msg]]></c> is a pointer to an <c><![CDATA[erlang_msg]]></c> structure - and contains information on the message received.</p> - <p><c><![CDATA[x]]></c> is buffer obtained from <c><![CDATA[ei_x_new]]></c>.</p> - <p>On success, the function returns <c><![CDATA[ERL_MSG]]></c> and the - <c><![CDATA[msg]]></c> struct will be initialized. <c><![CDATA[erlang_msg]]></c> - is defined as follows:</p> + <p>Receives a message to the buffer in <c>x</c>. + <c>ei_xreceive_msg</c> allows the buffer in + <c>x</c> to grow, but <c>ei_receive_msg</c> + fails if the message is larger than the pre-allocated buffer in + <c>x</c>.</p> + <list type="bulleted"> + <item><c>fd</c> is an open descriptor to an Erlang + connection.</item> + <item><c>msg</c> is a pointer to an + <c>erlang_msg</c> structure + and contains information on the message received.</item> + <item><c>x</c> is buffer obtained from + <c>ei_x_new</c>.</item> + </list> + <p>On success, the functions return <c>ERL_MSG</c> and the + <c>msg</c> struct is initialized. + <c>erlang_msg</c> is defined as follows:</p> <code type="none"><![CDATA[ typedef struct { long msgtype; @@ -257,125 +459,82 @@ typedef struct { erlang_trace token; } erlang_msg; ]]></code> - <p><c><![CDATA[msgtype]]></c> identifies the type of message, and is one of - <c><![CDATA[ERL_SEND]]></c>, <c><![CDATA[ERL_REG_SEND]]></c>, <c><![CDATA[ERL_LINK]]></c>, - <c><![CDATA[ERL_UNLINK]]></c> and <c><![CDATA[ERL_EXIT]]></c>.</p> - <p>If <c><![CDATA[msgtype]]></c> is <c><![CDATA[ERL_SEND]]></c> this indicates that an - ordinary send operation has taken place, and <c><![CDATA[msg->to]]></c> - contains the Pid of the recipient (the C-node). If - <c><![CDATA[type]]></c> is <c><![CDATA[ERL_REG_SEND]]></c> then a registered send - operation took place, and <c><![CDATA[msg->from]]></c> contains the Pid - of the sender.</p> - <p>If <c><![CDATA[msgtype]]></c> is <c><![CDATA[ERL_LINK]]></c> or <c><![CDATA[ERL_UNLINK]]></c>, then - <c><![CDATA[msg->to]]></c> and <c><![CDATA[msg->from]]></c> contain the pids of the - sender and recipient of the link or unlink.</p> - <p>If <c><![CDATA[msgtype]]></c> is <c><![CDATA[ERL_EXIT]]></c>, then this indicates that - a link has been broken. In this case, <c><![CDATA[msg->to]]></c> and - <c><![CDATA[msg->from]]></c> contain the pids of the linked processes.</p> - <p>The return value is the same as for <c><![CDATA[ei_receive]]></c>, see - above.</p> + <p><c>msgtype</c> identifies the type of message, and is + one of the following:</p> + <taglist> + <tag><c>ERL_SEND</c></tag> + <item> + <p>Indicates that an ordinary send operation has occurred. + <c>msg->to</c> contains the pid of the recipient (the + C-node).</p> + </item> + <tag><c>ERL_REG_SEND</c></tag> + <item> + <p>A registered send operation occurred. + <c>msg->from</c> contains the pid of the sender.</p> + </item> + <tag><c>ERL_LINK</c> or + <c>ERL_UNLINK</c></tag> + <item> + <p><c>msg->to</c> and + <c>msg->from</c> contain the pids of the + sender and recipient of the link or unlink.</p> + </item> + <tag><c>ERL_EXIT</c></tag> + <item> + <p>Indicates a broken link. <c>msg->to</c> and + <c>msg->from</c> contain the pids of the linked + processes.</p> + </item> + </taglist> + <p>The return value is the same as for + <seealso marker="#ei_receive"><c>ei_receive</c></seealso>.</p> </desc> </func> + <func> <name><ret>int</ret><nametext>ei_receive_msg_tmo(int fd, erlang_msg* msg, ei_x_buff* x, unsigned imeout_ms)</nametext></name> <name><ret>int</ret><nametext>ei_xreceive_msg_tmo(int fd, erlang_msg* msg, ei_x_buff* x, unsigned timeout_ms)</nametext></name> - <fsummary>Receive a message with optional timeout</fsummary> - <desc> - <p>ei_receive_msg and ei_xreceive_msg with an optional timeout argument, - see the description at the beginning of this document.</p> - </desc> - </func> - <func> - <name><ret>int</ret><nametext>ei_receive_encoded(int fd, char **mbufp, int *bufsz, erlang_msg *msg, int *msglen)</nametext></name> - <fsummary>Obsolete function for receiving a message</fsummary> - <desc> - <p>This function is retained for compatibility with code - generated by the interface compiler and with code following - examples in the same application.</p> - <p>In essence the function performs the same operation as - <c><![CDATA[ei_xreceive_msg]]></c>, but instead of using an ei_x_buff, the - function expects a pointer to a character pointer - (<c><![CDATA[mbufp]]></c>), where the character pointer should point to a - memory area allocated by <c><![CDATA[malloc]]></c>. The argument - <c><![CDATA[bufsz]]></c> should be a pointer to an integer containing the - exact size (in bytes) of the memory area. The function may - reallocate the memory area and will in such cases put the new - size in <c><![CDATA[*bufsz]]></c> and update <c><![CDATA[*mbufp]]></c>.</p> - <p>Furthermore the function returns either ERL_TICK or the - <c><![CDATA[msgtype]]></c> field of the <c><![CDATA[erlang_msg *msg]]></c>. The actual - length of the message is put in <c><![CDATA[*msglen]]></c>. On error it - will return a value <c><![CDATA[< 0]]></c>.</p> - <p>It is recommended to use ei_xreceive_msg instead when - possible, for the sake of readability. The function will - however be retained in the interface for compatibility and - will <em>not</em> be removed not be removed in future releases - without notice.</p> - </desc> - </func> - <func> - <name><ret>int</ret><nametext>ei_receive_encoded_tmo(int fd, char **mbufp, int *bufsz, erlang_msg *msg, int *msglen, unsigned timeout_ms)</nametext></name> - <fsummary>Obsolete function for receiving a message with timeout</fsummary> - <desc> - <p>ei_receive_encoded with an optional timeout argument, - see the description at the beginning of this document.</p> - </desc> - </func> - <func> - <name><ret>int</ret><nametext>ei_send(int fd, erlang_pid* to, char* buf, int len)</nametext></name> - <fsummary>Send a message</fsummary> - <desc> - <p>This function sends an Erlang term to a process.</p> - <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.</p> - <p><c><![CDATA[to]]></c> is the Pid of the intended recipient of the - message.</p> - <p><c><![CDATA[buf]]></c> is the buffer containing the term in binary - format.</p> - <p><c><![CDATA[len]]></c> is the length of the message in bytes.</p> - <p>The function returns 0 if successful, otherwise -1, in the - latter case it will set <c><![CDATA[erl_errno]]></c> to <c><![CDATA[EIO]]></c>.</p> - </desc> - </func> - <func> - <name><ret>int</ret><nametext>ei_send_tmo(int fd, erlang_pid* to, char* buf, int len, unsigned timeout_ms)</nametext></name> - <fsummary>Send a message with optional timeout</fsummary> + <fsummary>Receive a message with optional time-out.</fsummary> <desc> - <p>ei_send with an optional timeout argument, - see the description at the beginning of this document.</p> - </desc> - </func> - <func> - <name><ret>int</ret><nametext>ei_send_encoded(int fd, erlang_pid* to, char* buf, int len)</nametext></name> - <fsummary>Obsolete function to send a message</fsummary> - <desc> - <p>Works exactly as ei_send, the alternative name retained for - backward compatibility. The function will <em>not</em> be - removed without notice.</p> + <p>Equivalent to <c>ei_receive_msg</c> and <c>ei_xreceive_msg</c> + with an optional time-out argument, + see the description at the beginning of this manual page.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_send_encoded_tmo(int fd, erlang_pid* to, char* buf, int len, unsigned timeout_ms)</nametext></name> - <fsummary>Obsolete function to send a message with optional timeout</fsummary> + <name><ret>int</ret><nametext>ei_receive_tmo(int fd, unsigned char* bufp, int bufsize, unsigned timeout_ms)</nametext></name> + <fsummary>Receive a message with optional time-out.</fsummary> <desc> - <p>ei_send_encoded with an optional timeout argument, - see the description at the beginning of this document.</p> + <p>Equivalent to + <c>ei_receive</c> with an optional time-out argument, + see the description at the beginning of this manual page.</p> </desc> </func> + <func> <name><ret>int</ret><nametext>ei_reg_send(ei_cnode* ec, int fd, char* server_name, char* buf, int len)</nametext></name> - <fsummary>Send a message to a registered name</fsummary> + <fsummary>Send a message to a registered name.</fsummary> <desc> - <p>This function sends an Erlang term to a registered process. - </p> - <p>This function sends an Erlang term to a process.</p> - <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.</p> - <p><c><![CDATA[server_name]]></c> is the registered name of the intended - recipient.</p> - <p><c><![CDATA[buf]]></c> is the buffer containing the term in binary - format.</p> - <p><c><![CDATA[len]]></c> is the length of the message in bytes.</p> - <p>The function returns 0 if successful, otherwise -1, in the - latter case it will set <c><![CDATA[erl_errno]]></c> to <c><![CDATA[EIO]]></c>.</p> - <p>Example, send the atom "ok" to the process "worker":</p> + <p>Sends an Erlang term to a registered process.</p> + <list type="bulleted"> + <item> + <p><c>fd</c> is an open descriptor to an Erlang + connection.</p> + </item> + <item><c>server_name</c> is the registered name of the + intended recipient.</item> + <item><c>buf</c> is the buffer containing the term in + binary format.</item> + <item><c>len</c> is the length of the message in bytes. + </item> + </list> + <p>Returns <c>0</c> if successful, otherwise <c>-1</c>. In + the latter case it sets <c>erl_errno</c> to + <c>EIO</c>.</p> + <p><em>Example:</em></p> + <p>Send the atom "ok" to the process "worker":</p> <code type="none"><![CDATA[ ei_x_buff x; ei_x_new_with_version(&x); @@ -385,96 +544,98 @@ if (ei_reg_send(&ec, fd, x.buff, x.index) < 0) ]]></code> </desc> </func> + <func> <name><ret>int</ret><nametext>ei_reg_send_tmo(ei_cnode* ec, int fd, char* server_name, char* buf, int len, unsigned timeout_ms)</nametext></name> - <fsummary>Send a message to a registered name with optional timeout</fsummary> - <desc> - <p>ei_reg_send with an optional timeout argument, - see the description at the beginning of this document.</p> - </desc> - </func> - <func> - <name><ret>int</ret><nametext>ei_send_reg_encoded(int fd, const erlang_pid *from, const char *to, const char *buf, int len)</nametext></name> - <fsummary>Obsolete function to send a message to a registered name</fsummary> - <desc> - <p>This function is retained for compatibility with code - generated by the interface compiler and with code following - examples in the same application.</p> - <p>The function works as <c><![CDATA[ei_reg_send]]></c> with one - exception. Instead of taking the <c><![CDATA[ei_cnode]]></c> as a first - argument, it takes a second argument, an <c><![CDATA[erlang_pid]]></c> - which should be the process identifier of the sending process - (in the erlang distribution protocol). </p> - <p>A suitable <c><![CDATA[erlang_pid]]></c> can be constructed from the - <c><![CDATA[ei_cnode]]></c> structure by the following example code:</p> - <code type="none"><![CDATA[ - ei_cnode ec; - erlang_pid *self; - int fd; /* the connection fd */ - ... - self = ei_self(&ec); - self->num = fd; - ]]></code> - </desc> - </func> - <func> - <name><ret>int</ret><nametext>ei_send_reg_encoded_tmo(int fd, const erlang_pid *from, const char *to, const char *buf, int len)</nametext></name> - <fsummary>Obsolete function to send a message to a registered name with timeout</fsummary> + <fsummary>Send a message to a registered name with optional time-out + </fsummary> <desc> - <p>ei_send_reg_encoded with an optional timeout argument, - see the description at the beginning of this document.</p> + <p>Equivalent to + <c>ei_reg_send</c> with an optional time-out argument, + see the description at the beginning of this manual page.</p> </desc> </func> + <func> <name><ret>int</ret><nametext>ei_rpc(ei_cnode *ec, int fd, char *mod, char *fun, const char *argbuf, int argbuflen, ei_x_buff *x)</nametext></name> <name><ret>int</ret><nametext>ei_rpc_to(ei_cnode *ec, int fd, char *mod, char *fun, const char *argbuf, int argbuflen)</nametext></name> <name><ret>int</ret><nametext>ei_rpc_from(ei_cnode *ec, int fd, int timeout, erlang_msg *msg, ei_x_buff *x)</nametext></name> - <fsummary>Remote Procedure Call from C to Erlang</fsummary> + <fsummary>Remote Procedure Call from C to Erlang.</fsummary> <desc> - <p>These functions support calling Erlang functions on remote nodes. - <c><![CDATA[ei_rpc_to()]]></c> sends an rpc request to a remote node and - <c><![CDATA[ei_rpc_from()]]></c> receives the results of such a call. - <c><![CDATA[ei_rpc()]]></c> combines the functionality of these two functions - by sending an rpc request and waiting for the results. See also - <c><![CDATA[rpc:call/4]]></c>. </p> - <p><c><![CDATA[ec]]></c> is the C-node structure previously initiated by a - call to <c><![CDATA[ei_connect_init()]]></c> or - <c><![CDATA[ei_connect_xinit()]]></c></p> - <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.</p> - <p><c><![CDATA[timeout]]></c> is the maximum time (in ms) to wait for - results. Specify <c><![CDATA[ERL_NO_TIMEOUT]]></c> to wait forever. - <c><![CDATA[ei_rpc()]]></c> will wait infinitely for the answer, - i.e. the call will never time out.</p> - <p><c><![CDATA[mod]]></c> is the name of the module containing the function - to be run on the remote node.</p> - <p><c><![CDATA[fun]]></c> is the name of the function to run.</p> - <p><c><![CDATA[argbuf]]></c> is a pointer to a buffer with an encoded - Erlang list, without a version magic number, containing the - arguments to be passed to the function.</p> - <p><c><![CDATA[argbuflen]]></c> is the length of the buffer containing the - encoded Erlang list.</p> - <p><c><![CDATA[msg]]></c> structure of type <c><![CDATA[erlang_msg]]></c> and contains - information on the message received. See <c><![CDATA[ei_receive_msg()]]></c> - for a description of the <c><![CDATA[erlang_msg]]></c> format.</p> - <p><c><![CDATA[x]]></c> points to the dynamic buffer that receives the - result. For for <c><![CDATA[ei_rpc()]]></c> this will be the result - without the version magic number. For <c><![CDATA[ei_rpc_from()]]></c> - the result will return a version magic number and a 2-tuple - <c><![CDATA[{rex,Reply}]]></c>.</p> - <p><c><![CDATA[ei_rpc()]]></c> returns the number of bytes in the result - on success and -1 on failure. <c><![CDATA[ei_rpc_from()]]></c> returns - number of bytes or one of <c><![CDATA[ERL_TICK]]></c>, <c><![CDATA[ERL_TIMEOUT]]></c> - and <c><![CDATA[ERL_ERROR]]></c> otherwise. When failing, - all three functions set <c><![CDATA[erl_errno]]></c> to one of:</p> + <p>Supports calling Erlang functions on remote nodes. + <c>ei_rpc_to()</c> sends an RPC request to a remote node + and <c>ei_rpc_from()</c> receives the results of such a + call. <c>ei_rpc()</c> combines the functionality of these + two functions by sending an RPC request and waiting for the results. + See also <seealso marker="kernel:rpc#call/4"> + <c>rpc:call/4</c></seealso> in Kernel.</p> + <list type="bulleted"> + <item> + <p><c>ec</c> is the C-node structure previously + initiated by a call to <c>ei_connect_init()</c> or + <c>ei_connect_xinit()</c>.</p> + </item> + <item> + <p><c>fd</c> is an open descriptor to an Erlang + connection.</p> + </item> + <item> + <p><c>timeout</c> is the maximum time (in milliseconds) + to wait for results. Specify <c>ERL_NO_TIMEOUT</c> to + wait forever. + <c>ei_rpc()</c> waits infinitely for the answer, + that is, the call will never time out.</p> + </item> + <item> + <p><c>mod</c> is the name of the module containing the + function to be run on the remote node.</p> + </item> + <item> + <p><c>fun</c> is the name of the function to run.</p> + </item> + <item> + <p><c>argbuf</c> is a pointer to a buffer with an + encoded Erlang list, without a version magic number, containing + the arguments to be passed to the function.</p> + </item> + <item> + <p><c>argbuflen</c> is the length of the buffer + containing the encoded Erlang list.</p> + </item> + <item> + <p><c>msg</c> is structure of type + <c>erlang_msg</c> and contains information on the + message + received. For a description of the <c>erlang_msg</c> + format, see <seealso marker="#ei_receive_msg"> + <c>ei_receive_msg</c></seealso>.</p> + </item> + <item> + <p><c>x</c> points to the dynamic buffer that receives + the result. For <c>ei_rpc()</c> this is the result + without the version magic number. For + <c>ei_rpc_from()</c> the result returns a version + magic number and a 2-tuple <c>{rex,Reply}</c>.</p> + </item> + </list> + <p><c>ei_rpc()</c> returns the number of bytes in the + result on success and <c>-1</c> on failure. + <c>ei_rpc_from()</c> returns the + number of bytes, otherwise one of <c>ERL_TICK</c>, + <c>ERL_TIMEOUT</c>, + and <c>ERL_ERROR</c>. When failing, all three + functions set <c>erl_errno</c> to one of the + following:</p> <taglist> - <tag><c><![CDATA[EIO]]></c></tag> + <tag><c>EIO</c></tag> <item>I/O error.</item> - <tag><c><![CDATA[ETIMEDOUT]]></c></tag> - <item>Timeout expired.</item> - <tag><c><![CDATA[EAGAIN]]></c></tag> + <tag><c>ETIMEDOUT</c></tag> + <item>Time-out expired.</item> + <tag><c>EAGAIN</c></tag> <item>Temporary error: Try again.</item> </taglist> - <p>Example, check to see if an erlang process is alive:</p> + <p><em>Example:</em></p> + <p>Check to see if an Erlang process is alive:</p> <code type="none"><![CDATA[ int index = 0, is_alive; ei_x_buff args, result; @@ -495,170 +656,190 @@ if (ei_decode_version(result.buff, &index) < 0 ]]></code> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_publish(ei_cnode *ec, int port)</nametext></name> - <fsummary>Publish a node name</fsummary> + <name><ret>erlang_pid *</ret><nametext>ei_self(ei_cnode *ec)</nametext></name> + <fsummary>Retrieve the pid of the C-node.</fsummary> <desc> - <p>These functions are used by a server process to register - with the local name server <em>epmd</em>, thereby allowing - other processes to send messages by using the registered name. - Before calling either of these functions, the process should - have called <c><![CDATA[bind()]]></c> and <c><![CDATA[listen()]]></c> on an open socket.</p> - <p><c><![CDATA[ec]]></c> is the C-node structure.</p> - <p><c><![CDATA[port]]></c> is the local name to register, and should be the - same as the port number that was previously bound to the socket.</p> - <p><c><![CDATA[addr]]></c> is the 32-bit IP address of the local host.</p> - <p>To unregister with epmd, simply close the returned - descriptor. Do not use <c><![CDATA[ei_unpublish()]]></c>, which is deprecated anyway.</p> - <p>On success, the functions return a descriptor connecting the - calling process to epmd. On failure, they return -1 and set - <c><![CDATA[erl_errno]]></c> to <c><![CDATA[EIO]]></c>.</p> - <p>Additionally, <c><![CDATA[errno]]></c> values from <c><![CDATA[socket]]></c><em>(2)</em> - and <c><![CDATA[connect]]></c><em>(2)</em> system calls may be propagated - into <c><![CDATA[erl_errno]]></c>.</p> + <p>Retrieves the pid of the C-node. Every C-node + has a (pseudo) pid used in <c>ei_send_reg</c>, + <c>ei_rpc</c>, + and others. This is contained in a field in the <c>ec</c> + structure. It will be safe for a long time to fetch this + field directly from the <c>ei_cnode</c> structure.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_publish_tmo(ei_cnode *ec, int port, unsigned timeout_ms)</nametext></name> - <fsummary>Publish a node name with optional timeout</fsummary> + <name><ret>int</ret><nametext>ei_send(int fd, erlang_pid* to, char* buf, int len)</nametext></name> + <fsummary>Send a message.</fsummary> <desc> - <p>ei_publish with an optional timeout argument, - see the description at the beginning of this document.</p> + <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 the pid of the intended recipient of + the message.</item> + <item><c>buf</c> is the buffer containing the term in + binary format.</item> + <item><c>len</c> is the length of the message in bytes. + </item> + </list> + <p>Returns <c>0</c> if successful, otherwise <c>-1</c>. In + the latter case it sets <c>erl_errno</c> to + <c>EIO</c>.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_accept(ei_cnode *ec, int listensock, ErlConnect *conp)</nametext></name> - <fsummary>Accept a connection from another node</fsummary> + <name><ret>int</ret><nametext>ei_send_encoded(int fd, erlang_pid* to, char* buf, int len)</nametext></name> + <fsummary>Obsolete function to send a message.</fsummary> <desc> - <p>This function is used by a server process to accept a - connection from a client process.</p> - <p><c><![CDATA[ec]]></c> is the C-node structure.</p> - <p><c><![CDATA[listensock]]></c> is an open socket descriptor on which - <c><![CDATA[listen()]]></c> has previously been called.</p> - <p><c><![CDATA[conp]]></c> is a pointer to an <c><![CDATA[ErlConnect]]></c> struct, - described as follows:</p> - <code type="none"><![CDATA[ -typedef struct { - char ipadr[4]; - char nodename[MAXNODELEN]; -} ErlConnect; - ]]></code> - <p>On success, <c><![CDATA[conp]]></c> is filled in with the address and - node name of the connecting client and a file descriptor is - returned. On failure, <c><![CDATA[ERL_ERROR]]></c> is returned and - <c><![CDATA[erl_errno]]></c> is set to <c><![CDATA[EIO]]></c>.</p> + <p>Works exactly as <c>ei_send</c>, the alternative name is retained for + backward compatibility. The function will <em>not</em> be + removed without prior notice.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_accept_tmo(ei_cnode *ec, int listensock, ErlConnect *conp, unsigned timeout_ms)</nametext></name> - <fsummary>Accept a connection from another node with optional timeout</fsummary> + <name><ret>int</ret><nametext>ei_send_encoded_tmo(int fd, erlang_pid* to, char* buf, int len, unsigned timeout_ms)</nametext></name> + <fsummary>Obsolete function to send a message with optional time-out. + </fsummary> <desc> - <p>ei_accept with an optional timeout argument, - see the description at the beginning of this document.</p> + <p>Equivalent to + <c>ei_send_encoded</c> with an optional time-out argument, + see the description at the beginning of this manual page.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_unpublish(ei_cnode *ec)</nametext></name> - <fsummary>Forcefully unpublish a node name</fsummary> + <name><ret>int</ret><nametext>ei_send_reg_encoded(int fd, const erlang_pid *from, const char *to, const char *buf, int len)</nametext></name> + <fsummary>Obsolete function to send a message to a registered name. + </fsummary> <desc> - <p>This function can be called by a process to unregister a - specified node from epmd on the localhost. This is however usually not - allowed, unless epmd was started with the -relaxed_command_check - flag, which it normally isn't.</p> - - <p>To unregister a node you have published, you should - close the descriptor that was returned by - <c><![CDATA[ei_publish()]]></c>.</p> + <p>This function is retained for compatibility with code + generated by the interface compiler and with code following + examples in the same application.</p> + <p>The function works as <c>ei_reg_send</c> with one + exception. Instead of taking <c>ei_cnode</c> as first + argument, it takes a second argument, an + <c>erlang_pid</c>, + which is to be the process identifier of the sending process + (in the Erlang distribution protocol).</p> + <p>A suitable <c>erlang_pid</c> can be constructed from the + <c>ei_cnode</c> structure by the following example + code:</p> + <code type="none"><![CDATA[ +ei_cnode ec; +erlang_pid *self; +int fd; /* the connection fd */ +... +self = ei_self(&ec); +self->num = fd; + ]]></code> + </desc> + </func> - <warning> - <p>This function is deprecated and will be removed in a future - release.</p> - </warning> - <p><c><![CDATA[ec]]></c> is the node structure of the node to unregister.</p> - <p>If the node was successfully unregistered from epmd, the - function returns 0. Otherwise, it returns -1 and sets - <c><![CDATA[erl_errno]]></c> is to <c><![CDATA[EIO]]></c>.</p> + <func> + <name><ret>int</ret><nametext>ei_send_reg_encoded_tmo(int fd, const erlang_pid *from, const char *to, const char *buf, int len)</nametext></name> + <fsummary>Obsolete function to send a message to a registered name with + time-out.</fsummary> + <desc> + <p>Equivalent to + <c>ei_send_reg_encoded</c> with an optional time-out argument, + see the description at the beginning of this manual page.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_unpublish_tmo(ei_cnode *ec, unsigned timeout_ms)</nametext></name> - <fsummary>Unpublish a node name with optional timeout</fsummary> + <name><ret>int</ret><nametext>ei_send_tmo(int fd, erlang_pid* to, char* buf, int len, unsigned timeout_ms)</nametext></name> + <fsummary>Send a message with optional time-out.</fsummary> <desc> - <p>ei_unpublish with an optional timeout argument, - see the description at the beginning of this document.</p> + <p>Equivalent to + <c>ei_send</c> with an optional time-out argument, + see the description at the beginning of this manual page.</p> </desc> </func> + <func> <name><ret>const char *</ret><nametext>ei_thisnodename(ei_cnode *ec)</nametext></name> <name><ret>const char *</ret><nametext>ei_thishostname(ei_cnode *ec)</nametext></name> <name><ret>const char *</ret><nametext>ei_thisalivename(ei_cnode *ec)</nametext></name> - <fsummary>Retrieve some values</fsummary> + <fsummary>Retrieve some values.</fsummary> <desc> - <p>These functions can be used to retrieve information about - the C Node. These values are initially set with - <c><![CDATA[ei_connect_init()]]></c> or <c><![CDATA[ei_connect_xinit()]]></c>.</p> - <p>They simply fetches the appropriate field from the <c><![CDATA[ec]]></c> + <p>Can be used to retrieve information about + the C-node. These values are initially set with + <c>ei_connect_init()</c> or + <c>ei_connect_xinit()</c>.</p> + <p>These function simply fetch the appropriate field from the + <c>ec</c> structure. Read the field directly will probably be safe for a long time, so these functions are not really needed.</p> </desc> </func> + <func> - <name><ret>erlang_pid *</ret><nametext>ei_self(ei_cnode *ec)</nametext></name> - <fsummary>Retrieve the Pid of the C-node</fsummary> - <desc> - <p>This function retrieves the Pid of the C-node. Every C-node - has a (pseudo) pid used in <c><![CDATA[ei_send_reg]]></c>, <c><![CDATA[ei_rpc]]></c> - and others. This is contained in a field in the <c><![CDATA[ec]]></c> - structure. It will be safe for a long time to fetch this - field directly from the <c><![CDATA[ei_cnode]]></c> structure.</p> - </desc> - </func> - <func> - <name><ret>struct hostent</ret><nametext>*ei_gethostbyname(const char *name)</nametext></name> - <name><ret>struct hostent</ret><nametext>*ei_gethostbyaddr(const char *addr, int len, int type)</nametext></name> - <name><ret>struct hostent</ret><nametext>*ei_gethostbyname_r(const char *name, struct hostent *hostp, char *buffer, int buflen, int *h_errnop)</nametext></name> - <name><ret>struct hostent</ret><nametext>*ei_gethostbyaddr_r(const char *addr, int length, int type, struct hostent *hostp, char *buffer, int buflen, int *h_errnop)</nametext></name> - <fsummary>Name lookup functions</fsummary> + <name><ret>int</ret><nametext>ei_unpublish(ei_cnode *ec)</nametext></name> + <fsummary>Forcefully unpublish a node name.</fsummary> <desc> - <p>These are convenience functions for some common name lookup functions.</p> + <p>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 + 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>ec</c> is the node structure of the node to + unregister.</p> + <p>If the node was successfully unregistered from EPMD, the + function returns <c>0</c>. Otherwise, <c>-1</c> is returned and + <c>erl_errno</c> is set to <c>EIO</c>.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_get_tracelevel(void)</nametext></name> - <name><ret>void</ret><nametext>ei_set_tracelevel(int level)</nametext></name> - <fsummary>Get and set functions for tracing.</fsummary> + <name><ret>int</ret><nametext>ei_unpublish_tmo(ei_cnode *ec, unsigned timeout_ms)</nametext></name> + <fsummary>Unpublish a node name with optional time-out.</fsummary> <desc> - <p>These functions are used to set tracing on the distribution. The levels are different verbosity levels. A higher level means more information. - See also Debug Information and <c><![CDATA[EI_TRACELEVEL]]></c> below. </p> - <p> <c><![CDATA[ei_set_tracelevel]]></c> and <c><![CDATA[ei_get_tracelevel]]></c> are not thread safe. </p> + <p>Equivalent to + <c>ei_unpublish</c> with an optional time-out argument, + see the description at the beginning of this manual page.</p> </desc> </func> </funcs> <section> + <marker id="debug_information"></marker> <title>Debug Information</title> <p>If a connection attempt fails, the following can be checked:</p> + <list type="bulleted"> - <item><c><![CDATA[erl_errno]]></c></item> - <item>that the right cookie was used</item> - <item>that <em>epmd</em> is running</item> - <item>the remote Erlang node on the other side is running the - same version of Erlang as the <c><![CDATA[ei]]></c> - library.</item> - <item>the environment variable <c><![CDATA[ERL_EPMD_PORT]]></c> - is set correctly.</item> + <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>ei</c> library</item> + <item>That environment variable <c>ERL_EPMD_PORT</c> + is set correctly</item> </list> - <p>The connection attempt can be traced by setting a tracelevel by either using - <c><![CDATA[ei_set_tracelevel]]></c> or by setting the environment variable <c><![CDATA[EI_TRACELEVEL]]></c>. - The different tracelevels has the following messages:</p> + + <p>The connection attempt can be traced by setting a trace level by either + using <c>ei_set_tracelevel</c> or by setting environment + variable <c>EI_TRACELEVEL</c>. + The trace levels have the following messages:</p> + <list> - <item>1: Verbose error messages</item> - <item>2: Above messages and verbose warning messages </item> - <item>3: Above messages and progress reports for connection handling</item> - <item>4: Above messages and progress reports for communication</item> - <item>5: Above messages and progress reports for data conversion</item> + <item>1: Verbose error messages</item> + <item>2: Above messages and verbose warning messages</item> + <item>3: Above messages and progress reports for connection handling + </item> + <item>4: Above messages and progress reports for communication</item> + <item>5: Above messages and progress reports for data conversion</item> </list> </section> </cref> - diff --git a/lib/erl_interface/doc/src/ei_users_guide.xml b/lib/erl_interface/doc/src/ei_users_guide.xml index cdf3a912bb..0eed50b50b 100644 --- a/lib/erl_interface/doc/src/ei_users_guide.xml +++ b/lib/erl_interface/doc/src/ei_users_guide.xml @@ -4,14 +4,14 @@ <chapter> <header> <copyright> - <year>2002</year><year>2013</year> + <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 @@ -19,10 +19,10 @@ 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 El Library User's Guide</title> + <title>Erl_Interface User's Guide</title> <prepared>Kent Boortz</prepared> <responsible>Kent Boortz</responsible> <docno></docno> @@ -32,100 +32,158 @@ <rev></rev> <file>ei_users_guide.xml</file> </header> - <p>The Erl_Interface library contains functions. which help you - integrate programs written in C and Erlang. The functions in - Erl_Interface support the following:</p> - <list type="bulleted"> - <item>manipulation of data represented as Erlang data types</item> - <item>conversion of data between C and Erlang formats</item> - <item>encoding and decoding of Erlang data types for transmission or storage</item> - <item>communication between C nodes and Erlang processes</item> - <item>backup and restore of C node state to and from Mnesia</item> - </list> - <p>In the following sections, these topics are described:</p> - <list type="bulleted"> - <item>compiling your code for use with Erl_Interface</item> - <item>initializing Erl_Interface</item> - <item>encoding, decoding, and sending Erlang terms</item> - <item>building terms and patterns</item> - <item>pattern matching</item> - <item>connecting to a distributed Erlang node</item> - <item>using EPMD</item> - <item>sending and receiving Erlang messages</item> - <item>remote procedure calls</item> - <item>global names</item> - <item>the registry</item> - </list> + + <section> + <title>Introduction</title> + <p>The <c>Erl_Interface</c> library contains functions that help you + integrate programs written in C and Erlang. The functions in + <c>Erl_Interface</c> 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 + <seealso marker="mnesia:mnesia">Mnesia</seealso></item> + </list> + <note> + <p>By default, the <c>Erl_Interface</c> libraries are 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> + </note> + + <section> + <title>Scope</title> + <p>In the following sections, these topics are described:</p> + <list type="bulleted"> + <item>Compiling your code for use with <c>Erl_Interface</c></item> + <item>Initializing <c>Erl_Interface</c></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 the Erlang Port Mapper Daemon (EPMD)</item> + <item>Sending and receiving Erlang messages</item> + <item>Remote procedure calls</item> + <item>Using global names</item> + <item>Using the registry</item> + </list> + </section> + + <section> + <title>Prerequisites</title> + <p>It is assumed that the reader is familiar with the Erlang programming + language.</p> + </section> + </section> <section> <title>Compiling and Linking Your Code</title> - <p>In order to use any of the Erl_Interface functions, include the + <p>To use any of the <c>Erl_Interface</c> 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 + + <p>Determine where the top directory of your OTP installation is. + To find this, start Erlang and enter the following command at the Eshell prompt:</p> + <code type="none"><![CDATA[ Eshell V4.7.4 (abort with ^G) 1> code:root_dir(). /usr/local/otp ]]></code> - <p>To compile your code, make sure that your C compiler knows where - to find <c><![CDATA[erl_interface.h]]></c> by specifying an appropriate <c><![CDATA[-I]]></c> - argument on the command line, or by adding it to the <c><![CDATA[CFLAGS]]></c> - definition in your <c><![CDATA[Makefile]]></c>. The correct value for this path is - <c><![CDATA[$OTPROOT/lib/erl_interface]]></c><em>Vsn</em><c><![CDATA[/include]]></c>, where <c><![CDATA[$OTPROOT]]></c> is the path - reported by <c><![CDATA[code:root_dir/0]]></c> in the above example, and <em>Vsn</em> is - the version of the Erl_interface application, for example - <c><![CDATA[erl_interface-3.2.3]]></c></p> + + <p>To compile your code, ensure 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 add it to + the <c>CFLAGS</c> definition in your + <c>Makefile</c>. The correct value for this path is + <c>$OTPROOT/lib/erl_interface-$EIVSN/include</c>, + where:</p> + + <list type="bulleted"> + <item> + <p><c>$OTPROOT</c> is the path reported by + <c>code:root_dir/0</c> in the example above.</p> + </item> + <item> + <p><c>$EIVSN</c> is the version of the <c>Erl_Interface</c> application, + for example, <c>erl_interface-3.2.3</c>.</p> + </item> + </list> + + <p>Compiling the code:</p> + <code type="none"><![CDATA[ $ cc -c -I/usr/local/otp/lib/erl_interface-3.2.3/include myprog.c ]]></code> - <p>When linking, you will need to specify the path to - <c><![CDATA[liberl_interface.a]]></c> and <c><![CDATA[libei.a]]></c> with - <c><![CDATA[-L$OTPROOT/lib/erl_interface-3.2.3/lib]]></c>, and you will need to specify the - name of the libraries with <c><![CDATA[-lerl_interface -lei]]></c>. You can do - this on the command line or by adding the flags to the <c><![CDATA[LDFLAGS]]></c> - definition in your <c><![CDATA[Makefile]]></c>.</p> + + <p>When linking:</p> + + <list type="bulleted"> + <item>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>.</item> + <item>Specify the name of the libraries with + <c>-lerl_interface -lei</c>.</item> + </list> + + <p>Do this on the command line or add the flags to the + <c>LDFLAGS</c> definition in your + <c>Makefile</c>.</p> + + <p>Linking the code:</p> + <code type="none"><![CDATA[ $ ld -L/usr/local/otp/lib/erl_interface-3.2.3/ lib myprog.o -lerl_interface -lei -o myprog ]]></code> - <p>Also, on some systems it may be necessary to link with some - additional libraries (e.g. <c><![CDATA[libnsl.a]]></c> and <c><![CDATA[libsocket.a]]></c> on - Solaris, or <c><![CDATA[wsock32.lib]]></c> on Windows) in order to use the - communication facilities of Erl_Interface.</p> - <p>If you are using Erl_Interface functions in a threaded + + <p>On some systems it can be necessary to link with some more + libraries (for example, <c>libnsl.a</c> and + <c>libsocket.a</c> on Solaris, or + <c>wsock32.lib</c> on Windows) to use the + communication facilities of <c>Erl_Interface</c>.</p> + + <p>If you use the <c>Erl_Interface</c> functions in a threaded application based on POSIX threads or Solaris threads, then - Erl_Interface needs access to some of the synchronization - facilities in your threads package, and you will need to specify - additional compiler flags in order to indicate which of the packages - you are using. Define <c><![CDATA[_REENTRANT]]></c> and either <c><![CDATA[STHREADS]]></c> or - <c><![CDATA[PTHREADS]]></c>. The default is to use POSIX threads if - <c><![CDATA[_REENTRANT]]></c> is specified.</p> + <c>Erl_Interface</c> needs access to some of the synchronization + facilities in your threads package. You must specify extra + compiler flags to indicate which of the packages you use. 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> </section> <section> - <title>Initializing the erl_interface Library</title> - <p>Before calling any of the other Erl_Interface functions, you - must call <c><![CDATA[erl_init()]]></c> exactly once to initialize the library. - <c><![CDATA[erl_init()]]></c> takes two arguments, however the arguments are no - longer used by Erl_Interface, and should therefore be specified - as <c><![CDATA[erl_init(NULL,0)]]></c>.</p> + <title>Initializing the Erl_Interface Library</title> + <p>Before calling any of the other <c>Erl_Interface</c> functions, 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 <c>Erl_Interface</c> and are therefore to be + specified as <c>erl_init(NULL,0)</c>.</p> </section> <section> - <title>Encoding, Decoding and Sending Erlang Terms</title> + <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 external format. You must therefore 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 + protocol to communicate between a C program and Erlang.</p> + + <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 example below shows how to create and encode an Erlang tuple - <c><![CDATA[{tobbe,3928}]]></c>:</p> - <code type="none"><![CDATA[ + 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; @@ -134,58 +192,70 @@ arr[0] = erl_mk_atom("tobbe"); arr[1] = erl_mk_integer(3928); tuple = erl_mk_tuple(arr, 2); i = erl_encode(tuple, buf); ]]></code> - <p>Alternatively, you can use <c><![CDATA[erl_send()]]></c> and - <c><![CDATA[erl_receive_msg]]></c>, which handle the encoding and decoding of - messages transparently.</p> - <p>Refer to the Reference Manual for a complete description of the - following modules:</p> + + <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>the <c><![CDATA[erl_eterm]]></c> module for creating Erlang terms</item> - <item>the <c><![CDATA[erl_marshal]]></c> module for encoding and decoding routines.</item> + <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> </section> <section> + <marker id="building_terms_and_patterns"/> <title>Building Terms and Patterns</title> - <p>The previous example can be simplified by using - <c><![CDATA[erl_format()]]></c> to create an Erlang term.</p> - <code type="none"><![CDATA[ + <p>The previous example can be simplified by using the + <seealso marker="erl_format"><c>erl_format</c></seealso> module + to create an Erlang term:</p> + <code type="none"><![CDATA[ ETERM *ep; ep = erl_format("{~a,~i}", "tobbe", 3928); ]]></code> - <p>Refer to the Reference Manual, the <c><![CDATA[erl_format]]></c> module, for a - full description of the different format directives. The following - example is more complex:</p> - <code type="none"><![CDATA[ + <p>For a complete description of the different format directives, see + the <seealso marker="erl_format"><c>erl_format</c></seealso> module.</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> - <p>As in previous examples, it is your responsibility to free the - memory allocated for Erlang terms. In this example, - <c><![CDATA[erl_free_compound()]]></c> ensures that the complete term pointed to - by <c><![CDATA[ep]]></c> is released. This is necessary, because the pointer from - the second call to <c><![CDATA[erl_format()]]></c> is lost. </p> - <p>The following - example shows a slightly different solution:</p> - <code type="none"><![CDATA[ + <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><![CDATA[ep]]></c> and <c><![CDATA[ep2]]></c> is not important, - because the Erl_Interface library uses reference counting to - determine when it is safe to actually remove objects. </p> - <p>If you are not sure whether you have freed the terms properly, you + 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; @@ -196,36 +266,49 @@ printf("length of freelist: %ld\n",freed); /* really free the freelist */ erl_eterm_release(); ]]></code> - <p>Refer to the Reference Manual, the <c><![CDATA[erl_malloc]]></c> module for more - information.</p> + + <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 may contain unbound variables or - <c><![CDATA["do not care"]]></c> symbols. Such a pattern can be matched against a + <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[ + variable can then be retrieved:</p> + <code type="none"><![CDATA[ ETERM *pattern; pattern = erl_format("{madonna,Age,_}"); ]]></code> - <p><c><![CDATA[erl_match()]]></c> is used to perform pattern matching. It takes a + + <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, we - create a pattern with a variable <em>Age</em> which appears at two + 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="ordered"> - <item><c><![CDATA[erl_match()]]></c> will bind the contents of - <em>Age</em> to <em>21</em> the first time it reaches the variable</item> - <item>the second occurrence of <em>Age</em> will cause a test for - equality between the terms since <em>Age</em> is already bound to - <em>21</em>. Since <em>Age</em> is bound to 21, the equality test will - succeed and the match continues until the end of the pattern.</item> - <item>if the end of the pattern is reached, the match succeeds and you - can retrieve the contents of the variable</item> + + <list 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}"); @@ -239,99 +322,136 @@ if (erl_match(pattern, term)) { } erl_free_term(pattern); erl_free_term(term); ]]></code> - <p>Refer to the Reference Manual, the <c><![CDATA[erl_match()]]></c> function for - more information.</p> + + <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>In order to connect to a distributed Erlang node you need to first - initialize the connection routine with <c><![CDATA[erl_connect_init()]]></c>, - which stores information such as the host name, node name, and IP + <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> + <code type="none"><![CDATA[ int identification_number = 99; int creation=1; char *cookie="a secret cookie string"; /* An example */ erl_connect_init(identification_number, cookie, creation); ]]></code> - <p>Refer to the Reference Manual, the <c><![CDATA[erl_connect]]></c> module for more information.</p> + + <p>For more information, see the + <seealso marker="erl_connect"><c>erl_connect</c></seealso> module.</p> + <p>After initialization, you set up the connection to the Erlang node. - Use <c><![CDATA[erl_connect()]]></c> to specify the Erlang node you want to - connect to. The following example sets up the connection and should - result in a valid socket file descriptor:</p> + To specify the Erlang node you want to connect to, use + <c>erl_connect()</c>. 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="[email protected]"; /* An example */ if ((sockfd = erl_connect(nodename)) < 0) erl_err_quit("ERROR: erl_connect failed"); ]]></code> - <p><c><![CDATA[erl_err_quit()]]></c> prints the specified string and terminates - the program. Refer to the Reference Manual, the <c><![CDATA[erl_error()]]></c> - function for more information.</p> + + <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> <title>Using EPMD</title> - <p><c><![CDATA[Epmd]]></c> is the Erlang Port Mapper Daemon. Distributed Erlang nodes - register with <c><![CDATA[epmd]]></c> on the localhost to indicate to other nodes that - they exist and can accept connections. <c><![CDATA[Epmd]]></c> maintains a register of + <p><seealso marker="erts:epmd"><c>erts:epmd</c></seealso> + is the Erlang Port Mapper Daemon. Distributed + Erlang nodes register with <c>epmd</c> on the local host 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><![CDATA[epmd]]></c> in order to find out the correct - port number to connect to.</p> - <p>When you use <c><![CDATA[erl_connect()]]></c> to connect to an Erlang node, a - connection is first made to <c><![CDATA[epmd]]></c> and, if the node is known, a + another node, it first contacts <c>epmd</c> to find the + correct port number to connect to.</p> + + <p>When you use + <seealso marker="erl_connect"><c>erl_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> - <p>C nodes can also register themselves with <c><![CDATA[epmd]]></c> if they want other + + <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><![CDATA[epmd]]></c>, you need to first create a listen socket - and bind it to a port. Then:</p> + + <p>Before registering with <c>epmd</c>, you must first + create a listen socket and bind it to a port. Then:</p> + <code type="none"><![CDATA[ int pub; pub = erl_publish(port); ]]></code> - <p><c><![CDATA[pub]]></c> is a file descriptor now connected to <c><![CDATA[epmd]]></c>. <c><![CDATA[Epmd]]></c> - monitors the other end of the connection, and if it detects that the - connection has been closed, the node will be unregistered. So, if you - explicitly close the descriptor or if your node fails, it will be - unregistered from <c><![CDATA[epmd]]></c>.</p> - <p>Be aware that on some systems (such as VxWorks), a failed node will - not be detected by this mechanism since the operating system does not + + <p><c>pub</c> is a file descriptor now connected to + <c>epmd</c>. <c>epmd</c> + monitors the other end of the connection. If it detects that the + connection has been closed, the node becomes unregistered. So, if you + explicitly close the descriptor or if your node fails, it becomes + unregistered from <c>epmd</c>.</p> + + <p>Notice that on some systems (such as VxWorks), a failed node is + not detected by this mechanism, as the operating system does not automatically close descriptors that were left open when the node - failed. If a node has failed in this way, <c><![CDATA[epmd]]></c> will prevent you from - registering a new node with the old name, since it thinks that the old + 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> + <code type="none"><![CDATA[ erl_unpublish(node); ]]></code> - <p>This will cause <c><![CDATA[epmd]]></c> to close the connection from the far end. Note + + <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 may be consumed.</p> + local end of the connection to close, so resources can be consumed.</p> </section> <section> <title>Sending and Receiving Erlang Messages</title> <p>Use one of the following two functions to send messages:</p> + <list type="bulleted"> - <item><c><![CDATA[erl_send()]]></c></item> - <item><c><![CDATA[erl_reg_send()]]></c></item> + <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> </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>As in Erlang, messages can be sent to a + pid or to a registered name. It is easier to send a + message to a registered name, as it avoids the problem of finding + a suitable pid.</p> + <p>Use one of the following two functions to receive messages:</p> + <list type="bulleted"> - <item><c><![CDATA[erl_receive()]]></c></item> - <item><c><![CDATA[erl_receive_msg()]]></c></item> + <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> </list> - <p><c><![CDATA[erl_receive()]]></c> receives the message into a buffer, while - <c><![CDATA[erl_receive_msg()]]></c> decodes the message into an Erlang term. </p> + + <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><![CDATA[{Pid, hello_world}]]></c> is - sent to a registered process <c><![CDATA[my_server]]></c>. The message is encoded - by <c><![CDATA[erl_send()]]></c>:</p> + <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); @@ -345,16 +465,19 @@ emsg = erl_mk_tuple(arr, 2); erl_reg_send(sockfd, "my_server", emsg); erl_free_term(emsg); ]]></code> + <p>The first element of the tuple that is sent is your own - <em>Pid</em>. This enables <c><![CDATA[my_server]]></c> to reply. Refer to the - Reference Manual, the <c><![CDATA[erl_connect]]></c> module for more information - about send primitives.</p> + 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> </section> <section> <title>Example of Receiving Messages</title> - <p>In this example <c><![CDATA[{Pid, Something}]]></c> is received. The - received Pid is then used to return <c><![CDATA[{goodbye,Pid}]]></c></p> + <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; @@ -370,22 +493,25 @@ if ((rc = erl_receive_msg(sockfd , buf, BUFSIZE, &emsg)) == ERL_MSG) { erl_free_term(emsg.msg); erl_free_term(emsg.to); } ]]></code> - <p>In order to provide robustness, a distributed Erlang node - occasionally polls all its connected neighbours in an attempt to - detect failed nodes or communication links. A node which receives such - a message is expected to respond immediately with an <c><![CDATA[ERL_TICK]]></c> message. - This is done automatically by <c><![CDATA[erl_receive()]]></c>, however when this - has occurred <c><![CDATA[erl_receive]]></c> returns <c><![CDATA[ERL_TICK]]></c> to the caller - without storing a message into the <c><![CDATA[ErlMessage]]></c> structure.</p> + + <p>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 + 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><![CDATA[emsg.msg]]></c> as well as <c><![CDATA[emsg.to]]></c> - or <c><![CDATA[emsg.from]]></c>, depending on the type of message received.</p> - <p>Refer to the Reference Manual for additional information about the - following modules:</p> - <list type="bulleted"> - <item><c><![CDATA[erl_connect]]></c></item> - <item><c><![CDATA[erl_eterm]]></c>.</item> - </list> + 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> + + <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> </section> </section> @@ -394,10 +520,12 @@ if ((rc = erl_receive_msg(sockfd , buf, BUFSIZE, &emsg)) == ERL_MSG) { <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[ + procedure call.</p> + <p>The following example shows how the + <c>Erl_Interface</c> library supports remote procedure calls:</p> + + <code type="none"><![CDATA[ char modname[]=THE_MODNAME; ETERM *reply,*ep; ep = erl_format("[~a,[]]", modname); @@ -409,26 +537,34 @@ if (!erl_match(ep, reply)) erl_err_msg("<ERROR> compiler errors !\n"); erl_free_term(ep); erl_free_term(reply); ]]></code> - <p><c><![CDATA[c:c/1]]></c> is called to compile the specified module on the - remote node. <c><![CDATA[erl_match()]]></c> checks that the compilation was - successful by testing for the expected <c><![CDATA[ok]]></c>.</p> - <p>Refer to the Reference Manual, the <c><![CDATA[erl_connect]]></c> module for - more information about <c><![CDATA[erl_rpc()]]></c>, and its companions - <c><![CDATA[erl_rpc_to()]]></c> and <c><![CDATA[erl_rpc_from()]]></c>.</p> + + <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> </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 + <p>A C node has access to names registered through the + <seealso marker="kernel:global"><c>global</c></seealso> + module in Kernel. 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, + nodes.</p> + + <p><c>Erl_Interface</c> does not provide a native implementation of the + global service. Instead it uses the global services provided by a "nearby" + Erlang node. 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; @@ -441,71 +577,102 @@ if (names) printf("%s\n",names[i]); free(names); ]]></code> - <p><c><![CDATA[erl_global_names()]]></c> allocates and returns a buffer containing - all the names known to global. <c><![CDATA[count]]></c> will be initialized to - indicate how many names are in the array. The array of strings in - names is terminated by a NULL pointer, so it is not necessary to use - <c><![CDATA[count]]></c> to determine when the last name is reached.</p> + + <p><seealso marker="erl_global#erl_global_names"> + <c>erl_global:erl_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 + indicate the number of names in the array. The array of strings in names + is terminated by a <c>NULL</c> 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><![CDATA[erl_global_names()]]></c> allocates the array and all of the strings - using a single call to <c><![CDATA[malloc()]]></c>, so <c><![CDATA[free(names)]]></c> is all - that is necessary.</p> + <c>erl_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> + <p>To look up one of the names:</p> + <code type="none"><![CDATA[ ETERM *pid; char node[256]; pid = erl_global_whereis(fd,"schedule",node); ]]></code> - <p>If <c><![CDATA["schedule"]]></c> is known to global, an Erlang pid is returned - that can be used to send messages to the schedule service. - Additionally, <c><![CDATA[node]]></c> will be initialized to contain the name of + + <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. + 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 <c><![CDATA[erl_connect()]]></c>.</p> + connection to it by simply passing the variable to + <seealso marker="erl_connect"><c>erl_connect</c></seealso>.</p> + <p>Before registering a name, you should already have registered your - port number with <c><![CDATA[epmd]]></c>. This is not strictly necessary, but if you + 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> + service cannot find or connect to your process.</p> + <p>Create a pid that Erlang processes can use to communicate with your service:</p> + <code type="none"><![CDATA[ ETERM *pid; pid = erl_mk_pid(thisnode,14,0,0); erl_global_register(fd,servicename,pid); ]]></code> - <p>After registering the name, you should use <c><![CDATA[erl_accept()]]></c> to wait for - incoming connections.</p> - <p>Do not forget to free <c><![CDATA[pid]]></c> later with <c><![CDATA[erl_free_term()]]></c>!</p> + + <p>After registering the name, use + <seealso marker="erl_connect#erl_accept"> + <c>erl_connect:erl_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> + </note> + <p>To unregister a name:</p> + <code type="none"><![CDATA[ erl_global_unregister(fd,servicename); ]]></code> </section> <section> - <title>The Registry</title> + <title>Using the Registry</title> <p>This section describes the use of the registry, a simple mechanism for storing key-value pairs in a C-node, as well as backing them up or - restoring them from a Mnesia table on an Erlang node. More detailed - information about the individual API functions can be found in the - Reference Manual.</p> - <p>Keys are strings, i.e. 0-terminated arrays of characters, and values - are arbitrary objects. Although integers and floating point numbers + restoring them from an <c>Mnesia</c> table on an Erlang node. For more + detailed information about the individual API functions, see the + <seealso marker="registry"><c>registry</c></seealso> module.</p> + + <p>Keys are strings, that is, <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> + + <p>To start, 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 + + <p>The number <c>45</c> 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> + contain, but if performance or memory usage is important, then you + are to 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 + + <p>Objects are stored and retrieved through set and get functions. + The following example shows 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); @@ -519,13 +686,16 @@ 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 + + <p>If you try to store an object in the registry and there is an + existing object with the same key, the new value replaces 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 + integer. If the existing value is a string or binary, it is 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; @@ -537,77 +707,100 @@ 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 + + <p>In all 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> + type of an 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>Buf is initialized to contain object attributes.</p> + <p>Objects can be removed from the registry:</p> + <code type="none"><![CDATA[ ei_reg_delete(reg,"name"); ]]></code> + <p>When you are finished with a registry, close it to remove all the objects and free the memory back to the system:</p> + <code type="none"><![CDATA[ ei_reg_close(reg); ]]></code> <section> <title>Backing Up the Registry to Mnesia</title> - <p>The contents of a registry can be backed up to Mnesia on a "nearby" - Erlang node. You need to provide an open connection to the Erlang node - (see <c><![CDATA[erl_connect()]]></c>). Also, Mnesia 3.0 or later must be running + <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>). + Also, <c>Mnesia</c> 3.0 or later must be running on the Erlang node before the backup is initiated:</p> + <code type="none"><![CDATA[ ei_reg_dump(fd, reg, "mtab", dumpflags); ]]></code> - <p>The example above will backup the contents of the registry to the - specified Mnesia table <c><![CDATA["mtab"]]></c>. Once a registry has been backed - up to Mnesia in this manner, additional backups will only affect - objects that have been modified since the most recent backup, i.e. - objects that have been created, changed or deleted. The backup - operation is done as a single atomic transaction, so that the entire - backup will be performed or none of it will.</p> - <p>In the same manner, a registry can be restored from a Mnesia table:</p> + + <p>This example back up the contents of the registry to the + specified <c>Mnesia</c> table <c>"mtab"</c>. + Once a registry has been backed + up to <c>Mnesia</c> like this, more backups only affect + objects that have been modified since the most recent backup, that is, + objects that have been created, changed, or deleted. The backup + operation is done as a single atomic transaction, so that either the + entire backup is performed or none of it.</p> + + <p>Likewise, a registry can be restored from a <c>Mnesia</c> table:</p> + <code type="none"><![CDATA[ ei_reg_restore(fd, reg, "mtab"); ]]></code> - <p>This will read the entire contents of <c><![CDATA["mtab"]]></c> into the specified - registry. After the restore, all of the objects in the registry will - be marked as unmodified, so a subsequent backup will only affect + + <p>This reads the entire contents of <c>"mtab"</c> into the + specified registry. After the restore, all the objects in the registry + are marked as unmodified, so a later backup only affects 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, + + <p>Notice that if you restore to a non-empty registry, objects in the + table 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> + 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> + important that some simple guidelines are followed.</p> + <p>Most importantly, the object must have been created with a single call - to <c><![CDATA[malloc()]]></c> (or similar), so that it can later be removed by a - single call to <c><![CDATA[free()]]></c>. Objects will be freed by the registry + to <c>malloc()</c> (or similar), so that it can later be + removed by a single call to <c>free()</c>. + Objects are 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>Notice that if you store binary objects that are context-dependent + (for example, containing pointers or open file descriptors), + they lose their meaning if they are backed up to a <c>Mnesia</c> table + and later 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> + runtime error occurs that likely causes the C-node to crash.</p> + <p>You are free to modify the contents of an object retrieved this way. - However when you do so, the registry will not be aware of the changes - you make, possibly causing it to be missed the next time you make a - Mnesia backup of the registry contents. This can be avoided if you - mark the object as dirty after any such changes with - <c><![CDATA[ei_reg_markdirty()]]></c>, or pass appropriate flags to - <c><![CDATA[ei_reg_dump()]]></c>.</p> + However, when you do so, the registry is not aware of your changes, + possibly causing it to be missed the next time you make an + <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 + <seealso marker="registry#ei_reg_dump"> + <c>registry: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.xml index e982bf89e1..73b9b13e4d 100644 --- a/lib/erl_interface/doc/src/erl_call.xml +++ b/lib/erl_interface/doc/src/erl_call.xml @@ -4,14 +4,14 @@ <comref> <header> <copyright> - <year>1996</year><year>2013</year> + <year>1996</year><year>2017</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 @@ -28,135 +28,146 @@ <docno></docno> <approved>Bjarne Däcker</approved> <checked>Torbjörn Törnkvist</checked> - <date>97-05-16</date> + <date>1997-05-16</date> <rev>B</rev> - <file>erl_call.sgml</file> + <file>erl_call.xml</file> </header> <com>erl_call</com> - <comsummary>Call/Start a Distributed Erlang Node</comsummary> + <comsummary>Call/start a distributed Erlang node.</comsummary> <description> - <p><c><![CDATA[erl_call]]></c> makes it possible to start and/or communicate with - a distributed Erlang node. It is built upon the <c><![CDATA[erl_interface]]></c> - library as an example application. Its purpose is to use an Unix shell script to interact with a distributed Erlang node. It performs all - communication with the Erlang <em>rex server</em>, using the standard Erlang RPC facility. It does not require any special - software to be run at the Erlang target node.</p> + <p><c>erl_call</c> makes it possible to start and/or + communicate with a distributed Erlang node. It is built upon the + <c>Erl_Interface</c> library as an example application. + Its purpose is to use a Unix shell script to interact with a distributed + Erlang node. It performs all communication with the Erlang + <em>rex server</em>, using the standard Erlang RPC facility. It does not + require any special software to be run at the Erlang target node.</p> + <p>The main use is to either start a distributed Erlang node or to make an ordinary function call. However, it is also - possible to pipe an Erlang module to <c><![CDATA[erl_call]]></c> and have it - compiled, or to pipe a sequence of Erlang expressions to be evaluated + possible to pipe an Erlang module to <c>erl_call</c> and have + it compiled, or to pipe a sequence of Erlang expressions to be evaluated (similar to the Erlang shell).</p> - <p>Options, which cause <c><![CDATA[stdin]]></c> to be read, can be used with - advantage - as scripts from within (Unix) shell scripts. Another - nice use of <c><![CDATA[erl_call]]></c> could be from (http) CGI-bin scripts.</p> + + <p>Options, which cause <c>stdin</c> to be read, can be used + with advantage, + as scripts from within (Unix) shell scripts. Another nice use + of <c>erl_call</c> could be from (HTTP) CGI-bin scripts.</p> </description> + <funcs> <func> <name>erl_call <options></name> - <fsummary>Start/Call Erlang</fsummary> + <fsummary>Start/call Erlang.</fsummary> <desc> - <p>Each option flag is described below with its name, type and - meaning. </p> + <p>Starts/calls Erlang.</p> + <p>Each option flag is described below with its name, type, and + meaning.</p> <taglist> - <tag>-a [Mod [Fun [Args]]]]</tag> + <tag><c>-a [Mod [Fun [Args]]]]</c></tag> <item> - <p>(<em>optional</em>): Applies the specified function - and returns the result. <c><![CDATA[Mod]]></c> must be specified, however - <c>start</c> and <c>[]</c> are assumed for unspecified <c><![CDATA[Fun]]></c> and <c><![CDATA[Args]]></c>, respectively. <c><![CDATA[Args]]></c> should - be in the same format as for <c><![CDATA[erlang:apply/3]]></c>. Note - that this flag takes exactly one argument, so quoting - may be necessary in order to group <c><![CDATA[Mod]]></c>, <c><![CDATA[Fun]]></c> - and <c><![CDATA[Args]]></c>, in a manner dependent on the behavior - of your command shell.</p> - <p></p> + <p>(<em>Optional.</em>) Applies the specified function + and returns the result. <c>Mod</c> must be specified. + However, <c>start</c> and <c>[]</c> are assumed for unspecified + <c>Fun</c> and <c>Args</c>, respectively. + <c>Args</c> is to be in the same format as for + <seealso marker="erts:erlang#apply/3"> + <c>erlang:apply/3</c></seealso> in <c>ERTS</c>.</p> + <p>Notice that this flag takes exactly one argument, so quoting + can be necessary to group <c>Mod</c>, + <c>Fun</c>, and <c>Args</c> in a manner + dependent on the behavior of your command shell.</p> </item> - <tag>-c Cookie</tag> + <tag><c>-c Cookie</c></tag> <item> - <p>(<em>optional</em>): Use this option to specify a certain cookie. If no cookie is specified, the <c><![CDATA[~/.erlang.cookie]]></c> file is read and its content are used as cookie. The Erlang node we want to communicate with must have the same cookie.</p> + <p>(<em>Optional.</em>) Use this option to specify a certain cookie. + If no cookie is specified, the <c>~/.erlang.cookie</c> + file is read and its content is used as cookie. The Erlang node + we want to communicate with must have the same cookie.</p> </item> - <tag>-d</tag> + <tag><c>-d</c></tag> <item> - <p>(<em>optional</em>): Debug mode. This causes all IO to be output - to the file <c><![CDATA[~/.erl_call.out.Nodename]]></c>, where <c><![CDATA[Nodename]]></c> + <p>(<em>Optional.</em>) Debug mode. This causes all I/O to be output + to the <c>~/.erl_call.out.Nodename</c> file, where + <c>Nodename</c> is the node name of the Erlang node in question.</p> - <p></p> </item> - <tag>-e</tag> + <tag><c>-e</c></tag> <item> - <p>(<em>optional</em>): Reads a sequence of Erlang expressions, separated - by '<em>,</em>' and ended with a '<em>.</em>', from <c><![CDATA[stdin]]></c> until - EOF (Control-D). Evaluates the expressions and returns the result from - the last expression. Returns <c><![CDATA[{ok,Result}]]></c> if successful.</p> - <p></p> + <p>(<em>Optional.</em>) Reads a sequence of Erlang expressions, + separated by comma (,) and ended with a full stop (.), from + <c>stdin</c> until EOF (Control-D). Evaluates the + expressions and returns the result from the last expression. + Returns <c>{ok,Result}</c> on success.</p> </item> - <tag>-h HiddenName</tag> + <tag><c>-h HiddenName</c></tag> <item> - <p>(<em>optional</em>): Specifies the name of the hidden node - that <c><![CDATA[erl_call]]></c> represents.</p> - <p></p> + <p>(<em>Optional.</em>) Specifies the name of the hidden node + that <c>erl_call</c> represents.</p> </item> - <tag>-m</tag> + <tag><c>-m</c></tag> <item> - <p>(<em>optional</em>): Reads an Erlang module from <c><![CDATA[stdin]]></c> and - compiles it.</p> - <p></p> + <p>(<em>Optional.</em>) Reads an Erlang module from + <c>stdin</c> and compiles it.</p> </item> - <tag>-n Node</tag> + <tag><c>-n Node</c></tag> <item> - <p>(one of <c><![CDATA[-n, -name, -sname]]></c> is required): - Has the same meaning as <c><![CDATA[-name]]></c> and can still be used for - backwards compatibility reasons.</p> - <p></p> + <p>(One of <c>-n, -name, -sname</c> is required.) + Has the same meaning as <c>-name</c> and can still be + used for backward compatibility reasons.</p> </item> - <tag>-name Node</tag> + <tag><c>-name Node</c></tag> <item> - <p>(one of <c><![CDATA[-n, -name, -sname]]></c> is required): <c><![CDATA[Node]]></c> is the name of the node to be - started or communicated with. It is assumed that - <c><![CDATA[Node]]></c> is started with <c><![CDATA[erl -name]]></c>, which means that fully - qualified long node names are used. - If the <c><![CDATA[-s]]></c> option is given, an Erlang node will (if necessary) - be started with <c><![CDATA[erl -name]]></c>.</p> - <p></p> + <p>(One of <c>-n, -name, -sname</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 -name</c>, which means that fully + qualified long node names are used. If option + <c>-s</c> is specified, an Erlang node will (if + necessary) be started with <c>erl -name</c>.</p> </item> - <tag>-q</tag> + <tag><c>-q</c></tag> <item> - <p>(<em>optional</em>): Halts the Erlang node specified - with the -n switch. This switch overrides the -s switch.</p> - <p></p> + <p>(<em>Optional.</em>) Halts the Erlang node specified + with switch <c>-n</c>. This switch overrides switch <c>-s</c>.</p> </item> - <tag>-r</tag> + <tag><c>-r</c></tag> <item> - <p>(<em>optional</em>): Generates a random name of the hidden node - that <c><![CDATA[erl_call]]></c> represents.</p> - <p></p> + <p>(<em>Optional.</em>) Generates a random name of the hidden node + that <c>erl_call</c> represents.</p> </item> - <tag>-s</tag> + <tag><c>-s</c></tag> <item> - <p>(<em>optional</em>): Starts a distributed Erlang node if necessary. - This means that in a sequence of calls, where the '<c><![CDATA[-s]]></c>' - and '<c><![CDATA[-n Node]]></c>' are constant, only the first call will start - the Erlang node. This makes the rest of the communication - very fast. This flag is currently only available on the Unix platform.</p> - <p></p> + <p>(<em>Optional.</em>) Starts a distributed Erlang node if + necessary. This means that in a sequence of calls, where + '<c>-s</c>' and '<c>-n Node</c>' are + constant, only the first call starts the Erlang node. This makes + the rest of the communication very fast. This flag is currently + only available on Unix-like platforms (Linux, Mac OS X, Solaris, + and so on).</p> </item> - <tag>-sname Node</tag> + <tag><c>-sname Node</c></tag> <item> - <p>(one of <c><![CDATA[-n, -name, -sname]]></c> is required): <c><![CDATA[Node]]></c> is the name of the node to - be started or communicated with. It is assumed that <c><![CDATA[Node]]></c> is started with <c><![CDATA[erl -sname]]></c> which means that short node names are used. - If <c><![CDATA[-s]]></c> option is given, an Erlang node will be started (if necessary) with <c><![CDATA[erl -sname]]></c>.</p> - <p></p> + <p>(One of <c>-n, -name, -sname</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 + short node names are used. If option <c>-s</c> is + specified, an Erlang node is started (if necessary) with + <c>erl -sname</c>.</p> </item> - <tag>-v</tag> + <tag><c>-v</c></tag> <item> - <p>(<em>optional</em>): Prints a lot of <c><![CDATA[verbose]]></c> information. - This is only useful for the developer and maintainer of <c><![CDATA[erl_call]]></c>.</p> - <p></p> + <p>(<em>Optional.</em>) Prints a lot of <c>verbose</c> + information. This is only useful for the developer and maintainer + of <c>erl_call</c>.</p> </item> - <tag>-x ErlScript</tag> + <tag><c>-x ErlScript</c></tag> <item> - <p>(<em>optional</em>): Specifies another name of the Erlang start-up script - to be used. If not specified, the standard <c><![CDATA[erl]]></c> start-up script - is used.</p> + <p>(<em>Optional.</em>) Specifies another name of the Erlang + startup script to be used. If not specified, the standard + <c>erl</c> startup script is used.</p> </item> </taglist> </desc> @@ -165,20 +176,29 @@ <section> <title>Examples</title> - <p>Starts an Erlang node and calls <c><![CDATA[erlang:time/0]]></c>.</p> + <p>To start an Erlang node and call <c>erlang:time/0</c>:</p> + <code type="none"><![CDATA[ erl_call -s -a 'erlang time' -n madonna {18,27,34} ]]></code> - <p>Terminates an Erlang node by calling <c><![CDATA[erlang:halt/0]]></c>.</p> + + <p>To terminate an Erlang node by calling + <c>erlang:halt/0</c>:</p> + <code type="none"><![CDATA[ erl_call -s -a 'erlang halt' -n madonna ]]></code> - <p>An apply with several arguments.</p> + + <p>To apply with many arguments:</p> + <code type="none"><![CDATA[ -erl_call -s -a 'lists map [{math,sqrt},[1,4,9,16,25]]' -n madonna +erl_call -s -a 'lists seq [1,10]' -n madonna ]]></code> - <p>Evaluates a couple of expressions. <em>The input ends with EOF (Control-D)</em>.</p> + + <p>To evaluate some expressions + (<em>the input ends with EOF (Control-D)</em>):</p> + <code type="none"><![CDATA[ erl_call -s -e -n madonna statistics(runtime), @@ -189,10 +209,14 @@ Y=2, ^D {ok,{3,0}} ]]></code> - <p>Compiles a module and runs it. <em>Again, the input ends with EOF (Control-D)</em>. (In the example shown, the output has been formatted afterwards).</p> + + <p>To compile a module and run it (<em>again, the input ends with EOF + (Control-D)</em>):</p> + <p>(In the example, the output has been formatted afterwards.)</p> + <code type="none"><![CDATA[ -erl_call -s -m -a lolita -n madonna --module(lolita). +erl_call -s -m -a procnames -n madonna +-module(procnames). -compile(export_all). start() -> P = processes(), @@ -238,4 +262,3 @@ start() -> ]]></code> </section> </comref> - diff --git a/lib/erl_interface/doc/src/erl_connect.xml b/lib/erl_interface/doc/src/erl_connect.xml index 86b2648918..76ef6588c2 100644 --- a/lib/erl_interface/doc/src/erl_connect.xml +++ b/lib/erl_interface/doc/src/erl_connect.xml @@ -4,14 +4,14 @@ <cref> <header> <copyright> - <year>1996</year><year>2013</year> + <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 @@ -19,7 +19,7 @@ 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> @@ -28,127 +28,110 @@ <docno></docno> <approved>Bjarne Däcker</approved> <checked>Torbjörn Törnkvist</checked> - <date>980703</date> + <date>1998-07-03</date> <rev>A</rev> - <file>erl_connect.sgml</file> + <file>erl_connect.xml</file> </header> <lib>erl_connect</lib> - <libsummary>Communicate with Distributed Erlang</libsummary> + <libsummary>Communicate with distributed Erlang.</libsummary> <description> <p>This module provides support for communication between distributed - Erlang nodes and C nodes, in a manner that is transparent to Erlang + 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>. + + <p>A C-node appears to Erlang as a <em>hidden node</em>. That is, Erlang processes that know the name of the - C node are able to communicate with it in a normal manner, but - the node name will not appear in the listing provided by the - Erlang function <c><![CDATA[nodes/0]]></c>.</p> + 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><ret>int</ret><nametext>erl_connect_init(number, cookie, creation)</nametext></name> - <name><ret>int</ret><nametext>erl_connect_xinit(host, alive, node, addr, cookie, creation)</nametext></name> - <fsummary>Initialize communication</fsummary> + <name><ret>int</ret><nametext>erl_accept(listensock, conp)</nametext></name> + <fsummary>Accept a connection.</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> + <v>int listensock;</v> + <v>ErlConnect *conp;</v> </type> <desc> - <p>These functions initialize the <c><![CDATA[erl_connect]]></c> - module. In particular, they are used to identify the name of the - C-node from which they are called. One of these functions must - be called before any of the other functions in the erl_connect - module are used.</p> - <p><c><![CDATA[erl_connect_xinit()]]></c> stores for later use information about - the node's host name <c><![CDATA[host]]></c>, alive name <c><![CDATA[alive]]></c>, node - name <c><![CDATA[node]]></c>, IP address <c><![CDATA[addr]]></c>, cookie <c><![CDATA[cookie]]></c>, - and creation number <c><![CDATA[creation]]></c>. <c><![CDATA[erl_connect_init()]]></c> - provides an alternative interface which does not require as much - information from the caller. Instead, <c><![CDATA[erl_connect_init()]]></c> - uses <c><![CDATA[gethostbyname()]]></c> to obtain default values. - </p> - <p>If you use <c><![CDATA[erl_connect_init()]]></c> your node will have a - short name, i.e., it will not be fully qualified. If you need to - use fully qualified (a.k.a. long) names, use - <c><![CDATA[erl_connect_xinit()]]></c> instead. - </p> - <p><c><![CDATA[host]]></c> is the name of the host on which the node is running.</p> - <p><c><![CDATA[alive]]></c> is the alivename of the node.</p> - <p><c><![CDATA[node]]></c> is the name of the node. The nodename should - be of the form <em>alivename@hostname</em>.</p> - <p><c><![CDATA[addr]]></c> is the 32-bit IP address of <c><![CDATA[host]]></c>.</p> - <p><c><![CDATA[cookie]]></c> is the authorization string required for access - to the remote node. If NULL the user HOME directory is - searched for a cookie file <c><![CDATA[.erlang.cookie]]></c>. The path to - the home directory is retrieved from the environment variable - <c><![CDATA[HOME]]></c> on Unix and from the <c><![CDATA[HOMEDRIVE]]></c> and - <c><![CDATA[HOMEPATH]]></c> variables on Windows. Refer to the <c><![CDATA[auth]]></c> - module for more details.</p> - <p><c><![CDATA[creation]]></c> helps identify a particular instance of a C - node. In particular, it can help prevent us from receiving - messages sent to an earlier process with the same registered - name.</p> - <p>A C node acting as a server will be assigned a creation number - when it calls <c><![CDATA[erl_publish()]]></c>.</p> - <p><c><![CDATA[number]]></c> is used by <c><![CDATA[erl_connect_init()]]></c> to - construct the actual node name. In the second example shown - below, <em>"[email protected]"</em> will be the resulting node - name.</p> - <p>Example 1:</p> - <code type="none"><![CDATA[ -struct in_addr addr; -addr = inet_addr("150.236.14.75"); -if (!erl_connect_xinit("chivas", - "madonna", - "[email protected]", - &addr; - "samplecookiestring..."), - 0) - erl_err_quit("<ERROR> when initializing !"); - ]]></code> - <p>Example 2:</p> + <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[ -if (!erl_connect_init(17, "samplecookiestring...", 0)) - erl_err_quit("<ERROR> when initializing !"); +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><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><ret>int</ret><nametext>erl_connect(node)</nametext></name> <name><ret>int</ret><nametext>erl_xconnect(addr, alive)</nametext></name> - <fsummary>Establishe a connection to an Erlang node</fsummary> + <fsummary>Establish a connection to an Erlang node.</fsummary> <type> <v>char *node, *alive;</v> <v>struct in_addr *addr;</v> </type> <desc> - <p>These functions set up a connection to an Erlang node.</p> - <p><c><![CDATA[erl_xconnect()]]></c> requires the IP address of the remote - host and the alive name of the remote node - to be specified. <c><![CDATA[erl_connect()]]></c> provides an alternative + <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> - <p><c><![CDATA[addr]]></c> is the 32-bit IP address of the remote host.</p> - <p><c><![CDATA[alive]]></c> is the alivename of the remote node.</p> - <p><c><![CDATA[node]]></c> is the name of the remote node.</p> - <p>These functions return an open file descriptor on success, or - a negative value indicating that an error occurred --- in - which case they will set <c><![CDATA[erl_errno]]></c> to one of:</p> + <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><![CDATA[EHOSTUNREACH]]></c></tag> - <item>The remote host <c><![CDATA[node]]></c> is unreachable</item> - <tag><c><![CDATA[ENOMEM]]></c></tag> - <item>No more memory available.</item> - <tag><c><![CDATA[EIO]]></c></tag> + <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>Additionally, <c><![CDATA[errno]]></c> values from - <c><![CDATA[socket]]></c><em>(2)</em> and <c><![CDATA[connect]]></c><em>(2)</em> - system calls may be propagated into <c><![CDATA[erl_errno]]></c>.</p> + <p>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 "[email protected]" #define ALIVE "madonna" @@ -164,59 +147,177 @@ erl_xconnect( &addr , ALIVE ); ]]></code> </desc> </func> + <func> - <name><ret>int</ret><nametext>erl_close_connection(fd)</nametext></name> - <fsummary>Close a connection to an Erlang node</fsummary> + <name><ret>int</ret><nametext>erl_connect_init(number, cookie, creation)</nametext></name> + <name><ret>int</ret><nametext>erl_connect_xinit(host, alive, node, addr, cookie, creation)</nametext></name> + <fsummary>Initialize communication.</fsummary> <type> - <v>int fd;</v> + <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>"[email protected]"</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", + "[email protected]", + &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><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 closes an open connection to an Erlang node.</p> - <p><c><![CDATA[Fd]]></c> is a file descriptor obtained from - <c><![CDATA[erl_connect()]]></c> or <c><![CDATA[erl_xconnect()]]></c>.</p> - <p>On success, 0 is returned. If the call fails, a non-zero value - is returned, and the reason for - the error can be obtained with the appropriate platform-dependent - call.</p> + <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><ret>int</ret><nametext>erl_receive(fd, bufp, bufsize)</nametext></name> - <fsummary>Receive a message</fsummary> + <fsummary>Receive a message.</fsummary> <type> <v>int fd;</v> <v>char *bufp;</v> <v>int bufsize;</v> </type> <desc> - <p>This function receives a message consisting of a sequence + <p>Receives a message consisting of a sequence of bytes in the Erlang external format.</p> - <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.</p> - <p><c><![CDATA[bufp]]></c> is a buffer large enough to hold the expected - message. </p> - <p><c><![CDATA[bufsize]]></c> indicates the size of <c><![CDATA[bufp]]></c>.</p> - <p>If a <em>tick</em> occurs, i.e., the Erlang node on the + <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 will return <c><![CDATA[ERL_TICK]]></c> and - no message will be placed in the buffer. Also, - <c><![CDATA[erl_errno]]></c> will be set to <c><![CDATA[EAGAIN]]></c>.</p> + 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 will set - <c><![CDATA[erl_errno]]></c> to one of:</p> + failure, the function returns a negative value and sets + <c>erl_errno</c> to one of:</p> <taglist> - <tag><c><![CDATA[EAGAIN]]></c></tag> + <tag><c>EAGAIN</c></tag> <item>Temporary error: Try again.</item> - <tag><c><![CDATA[EMSGSIZE]]></c></tag> - <item>Buffer too small.</item> - <tag><c><![CDATA[EIO]]></c></tag> + <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><ret>int</ret><nametext>erl_receive_msg(fd, bufp, bufsize, emsg)</nametext></name> - <fsummary>Receive and decodes a message</fsummary> + <fsummary>Receive and decode a message.</fsummary> <type> <v>int fd;</v> <v>unsigned char *bufp;</v> @@ -224,14 +325,20 @@ erl_xconnect( &addr , ALIVE ); <v>ErlMessage *emsg;</v> </type> <desc> - <p>This function receives the message into the specified buffer, - and decodes into the <c><![CDATA[(ErlMessage *) emsg]]></c>.</p> - <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.</p> - <p><c><![CDATA[bufp]]></c> is a buffer large enough to hold the expected message.</p> - <p><c><![CDATA[bufsize]]></c> indicates the size of <c><![CDATA[bufp]]></c>.</p> - <p><c><![CDATA[emsg]]></c> is a pointer to an <c><![CDATA[ErlMessage]]></c> structure, - into which the message will be decoded. <c><![CDATA[ErlMessage]]></c> is - defined as follows:</p> + <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; @@ -242,144 +349,100 @@ typedef struct { } ErlMessage; ]]></code> <note> - <p>The definition of <c><![CDATA[ErlMessage]]></c> has changed since - earlier versions of Erl_Interface.</p> + <p>The definition of <c>ErlMessage</c> has changed since + earlier versions of <c>Erl_Interface</c>.</p> </note> - <p><c><![CDATA[type]]></c> identifies the type of message, one of - <c><![CDATA[ERL_SEND]]></c>, <c><![CDATA[ERL_REG_SEND]]></c>, <c><![CDATA[ERL_LINK]]></c>, - <c><![CDATA[ERL_UNLINK]]></c> and <c><![CDATA[ERL_EXIT]]></c>. - </p> - <p>If <c><![CDATA[type]]></c> contains <c><![CDATA[ERL_SEND]]></c> - this indicates that an ordinary send operation has taken - place, and <c><![CDATA[emsg->to]]></c> contains the Pid of the - recipient. If <c><![CDATA[type]]></c> contains <c><![CDATA[ERL_REG_SEND]]></c> then a - registered send operation took place, and <c><![CDATA[emsg->from]]></c> - contains the Pid of the sender. In both cases, the actual - message will be in <c><![CDATA[emsg->msg]]></c>. - </p> - <p>If <c><![CDATA[type]]></c> contains one of <c><![CDATA[ERL_LINK]]></c> or - <c><![CDATA[ERL_UNLINK]]></c>, then <c><![CDATA[emsg->to]]></c> and <c><![CDATA[emsg->from]]></c> - contain the pids of the sender and recipient of the link or unlink. - <c><![CDATA[emsg->msg]]></c> is not used in these cases. - </p> - <p>If <c><![CDATA[type]]></c> contains <c><![CDATA[ERL_EXIT]]></c>, then this - indicates that a link has been broken. In this case, - <c><![CDATA[emsg->to]]></c> and <c><![CDATA[emsg->from]]></c> contain the pids of the - linked processes, and <c><![CDATA[emsg->msg]]></c> contains the reason for - the exit. - </p> + <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><![CDATA[emsg->msg]]></c>, <c><![CDATA[emsg->to]]></c> and - <c><![CDATA[emsg->from]]></c>.</p> + 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, i.e., the Erlang node on the + <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 will return <c><![CDATA[ERL_TICK]]></c> + is still alive, the function returns <c>ERL_TICK</c> indicating that the tick has been received and responded to, - but no message will be placed in the buffer. In this case you - should call <c><![CDATA[erl_receive_msg()]]></c> again.</p> - <p>On success, the function returns <c><![CDATA[ERL_MSG]]></c> and the - <c><![CDATA[Emsg]]></c> struct will be initialized as described above, or - <c><![CDATA[ERL_TICK]]></c>, in which case no message is returned. On - failure, the function returns <c><![CDATA[ERL_ERROR]]></c> and will set - <c><![CDATA[erl_errno]]></c> to one of:</p> + 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><![CDATA[EMSGSIZE]]></c></tag> - <item>Buffer too small.</item> - <tag><c><![CDATA[ENOMEM]]></c></tag> - <item>No more memory available.</item> - <tag><c><![CDATA[EIO]]></c></tag> - <item>I/O error.</item> - </taglist> - </desc> - </func> - <func> - <name><ret>int</ret><nametext>erl_xreceive_msg(fd, bufpp, bufsizep, emsg)</nametext></name> - <fsummary>Receive and decodes a message</fsummary> - <type> - <v>int fd;</v> - <v>unsigned char **bufpp;</v> - <v>int *bufsizep;</v> - <v>ErlMessage *emsg;</v> - </type> - <desc> - <p>This function is similar to <c><![CDATA[erl_receive_msg]]></c>. The - difference is that <c><![CDATA[erl_xreceive_msg]]></c> expects the buffer to - have been allocated by <c><![CDATA[malloc]]></c>, and reallocates it if the received - message does not fit into the original buffer. For that reason, - both buffer and buffer length are given as pointers - their values - may change by the call. - </p> - <p>On success, the function returns <c><![CDATA[ERL_MSG]]></c> and the - <c><![CDATA[Emsg]]></c> struct will be initialized as described above, or - <c><![CDATA[ERL_TICK]]></c>, in which case no message is returned. On - failure, the function returns <c><![CDATA[ERL_ERROR]]></c> and will set - <c><![CDATA[erl_errno]]></c> to one of:</p> - <taglist> - <tag><c><![CDATA[EMSGSIZE]]></c></tag> - <item>Buffer too small.</item> - <tag><c><![CDATA[ENOMEM]]></c></tag> - <item>No more memory available.</item> - <tag><c><![CDATA[EIO]]></c></tag> - <item>I/O error.</item> - </taglist> - </desc> - </func> - <func> - <name><ret>int</ret><nametext>erl_send(fd, to, msg)</nametext></name> - <fsummary>Send a message</fsummary> - <type> - <v>int fd;</v> - <v>ETERM *to, *msg;</v> - </type> - <desc> - <p>This function sends an Erlang term to a process.</p> - <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.</p> - <p><c><![CDATA[to]]></c> is an Erlang term containing the Pid of the - intended recipient of the message.</p> - <p><c><![CDATA[msg]]></c> is the Erlang term to be sent.</p> - <p>The function returns 1 if successful, otherwise 0 --- in - which case it will set <c><![CDATA[erl_errno]]></c> to one of:</p> - <taglist> - <tag><c><![CDATA[EINVAL]]></c></tag> - <item>Invalid argument: <c><![CDATA[to]]></c> is not a valid Erlang pid.</item> - <tag><c><![CDATA[ENOMEM]]></c></tag> - <item>No more memory available.</item> - <tag><c><![CDATA[EIO]]></c></tag> + <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><ret>int</ret><nametext>erl_reg_send(fd, to, msg)</nametext></name> - <fsummary>Send a message to a registered name</fsummary> + <fsummary>Send a message to a registered name.</fsummary> <type> <v>int fd;</v> <v>char *to;</v> <v>ETERM *msg;</v> </type> <desc> - <p>This function sends an Erlang term to a registered process.</p> - <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.</p> - <p><c><![CDATA[to]]></c> is a string containing the registered name of - the intended recipient of the message.</p> - <p><c><![CDATA[msg]]></c> is the Erlang term to be sent.</p> - <p>The function returns 1 if successful, otherwise 0 --- in - which case it will set <c><![CDATA[erl_errno]]></c> to one of:</p> + <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><![CDATA[ENOMEM]]></c></tag> - <item>No more memory available.</item> - <tag><c><![CDATA[EIO]]></c></tag> + <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><ret>ETERM *</ret><nametext>erl_rpc(fd, mod, fun, args)</nametext></name> - <name><ret>int</ret><nametext>erl_rpc_to(fd, mod, fun, args)</nametext></name> <name><ret>int</ret><nametext>erl_rpc_from(fd, timeout, emsg)</nametext></name> - <fsummary>Remote Procedure Call</fsummary> + <name><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> @@ -387,158 +450,178 @@ typedef struct { <v>ErlMessage *emsg;</v> </type> <desc> - <p>These functions support calling Erlang functions on remote nodes. - <c><![CDATA[erl_rpc_to()]]></c> sends an rpc request to a remote node and - <c><![CDATA[erl_rpc_from()]]></c> receives the results of such a call. - <c><![CDATA[erl_rpc()]]></c> combines the functionality of these two functions - by sending an rpc request and waiting for the results. See also - <c><![CDATA[rpc:call/4]]></c>. </p> - <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection.</p> - <p><c><![CDATA[timeout]]></c> is the maximum time (in ms) to wait for - results. Specify <c><![CDATA[ERL_NO_TIMEOUT]]></c> to wait forever. - When erl_rpc() calls erl_rpc_from(), the call will never - timeout.</p> - <p><c><![CDATA[mod]]></c> is the name of the module containing the function - to be run on the remote node.</p> - <p><c><![CDATA[fun]]></c> is the name of the function to run.</p> - <p><c><![CDATA[args]]></c> is an Erlang list, containing the arguments to be - passed to the function. </p> - <p><c><![CDATA[emsg]]></c> is a message containing the result of the - function call.</p> - <p>The actual message returned by the rpc server - is a 2-tuple <c><![CDATA[{rex,Reply}]]></c>. If you are using - <c><![CDATA[erl_rpc_from()]]></c> in your code then this is the message you - will need to parse. If you are using <c><![CDATA[erl_rpc()]]></c> then the + <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><![CDATA[Reply]]></c> only. Replies - to rpc requests are always ERL_SEND messages. - </p> + 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><![CDATA[ETERM]]></c> structure as well as the memory pointed to by - <c><![CDATA[emsg->msg]]></c> and <c><![CDATA[emsg->to]]></c>. </p> + <c>ETERM</c> structure and the memory pointed to by + <c>emsg->msg</c> and <c>emsg->to</c>.</p> </note> - <p><c><![CDATA[erl_rpc()]]></c> returns the remote function's return value (or - <c><![CDATA[NULL]]></c> if it failed). <c><![CDATA[erl_rpc_to()]]></c> returns 0 on - success, and a negative number on failure. <c><![CDATA[erl_rcp_from()]]></c> - returns <c><![CDATA[ERL_MSG]]></c> when successful (with <c><![CDATA[Emsg]]></c> now - containing the reply tuple), and one of <c><![CDATA[ERL_TICK]]></c>, - <c><![CDATA[ERL_TIMEOUT]]></c> and <c><![CDATA[ERL_ERROR]]></c> otherwise. When failing, - all three functions set <c><![CDATA[erl_errno]]></c> to one of:</p> + <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><![CDATA[ENOMEM]]></c></tag> - <item>No more memory available.</item> - <tag><c><![CDATA[EIO]]></c></tag> + <tag><c>ENOMEM</c></tag> + <item>No more memory is available.</item> + <tag><c>EIO</c></tag> <item>I/O error.</item> - <tag><c><![CDATA[ETIMEDOUT]]></c></tag> - <item>Timeout expired.</item> - <tag><c><![CDATA[EAGAIN]]></c></tag> + <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><ret>int</ret><nametext>erl_publish(port)</nametext></name> - <fsummary>Publish a node name</fsummary> + <name><ret>int</ret><nametext>erl_send(fd, to, msg)</nametext></name> + <fsummary>Send a message.</fsummary> <type> - <v>int port;</v> + <v>int fd;</v> + <v>ETERM *to, *msg;</v> </type> <desc> - <p>These functions are used by a server process to register - with the local name server <em>epmd</em>, thereby allowing - other processes to send messages by using the registered name. - Before calling either of these functions, the process should - have called <c><![CDATA[bind()]]></c> and <c><![CDATA[listen()]]></c> on an open socket.</p> - <p><c><![CDATA[port]]></c> is the local name to register, and should be the - same as the port number that was previously bound to the socket.</p> - <p>To unregister with epmd, simply close the returned - descriptor. - </p> - <p>On success, the functions return a descriptor connecting the - calling process to epmd. On failure, they return -1 and set - <c><![CDATA[erl_errno]]></c> to:</p> + <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><![CDATA[EIO]]></c></tag> - <item>I/O error</item> + <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> - <p>Additionally, <c><![CDATA[errno]]></c> values from <c><![CDATA[socket]]></c><em>(2)</em> - and <c><![CDATA[connect]]></c><em>(2)</em> system calls may be propagated - into <c><![CDATA[erl_errno]]></c>. - </p> - </desc> - </func> - <func> - <name><ret>int</ret><nametext>erl_accept(listensock, conp)</nametext></name> - <fsummary>Accept a connection</fsummary> - <type> - <v>int listensock;</v> - <v>ErlConnect *conp;</v> - </type> - <desc> - <p>This function is used by a server process to accept a - connection from a client process.</p> - <p><c><![CDATA[listensock]]></c> is an open socket descriptor on which - <c><![CDATA[listen()]]></c> has previously been called.</p> - <p><c><![CDATA[conp]]></c> is a pointer to an <c><![CDATA[ErlConnect]]></c> struct, - described as follows:</p> - <code type="none"><![CDATA[ -typedef struct { - char ipadr[4]; - char nodename[MAXNODELEN]; -} ErlConnect; - ]]></code> - <p>On success, <c><![CDATA[conp]]></c> is filled in with the address and - node name of the connecting client and a file descriptor is - returned. On failure, <c><![CDATA[ERL_ERROR]]></c> is returned and - <c><![CDATA[erl_errno]]></c> is set to <c><![CDATA[EIO]]></c>.</p> </desc> </func> + <func> - <name><ret>const char *</ret><nametext>erl_thiscookie()</nametext></name> - <name><ret>const char *</ret><nametext>erl_thisnodename()</nametext></name> - <name><ret>const char *</ret><nametext>erl_thishostname()</nametext></name> <name><ret>const char *</ret><nametext>erl_thisalivename()</nametext></name> + <name><ret>const char *</ret><nametext>erl_thiscookie()</nametext></name> <name><ret>short</ret><nametext>erl_thiscreation()</nametext></name> - <fsummary>Retrieve some values</fsummary> + <name><ret>const char *</ret><nametext>erl_thishostname()</nametext></name> + <name><ret>const char *</ret><nametext>erl_thisnodename()</nametext></name> + <fsummary>Retrieve some values.</fsummary> <desc> - <p>These functions can be used to retrieve information about - the C Node. These values are initially set with - <c><![CDATA[erl_connect_init()]]></c> or <c><![CDATA[erl_connect_xinit()]]></c>.</p> + <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><ret>int</ret><nametext>erl_unpublish(alive)</nametext></name> - <fsummary>Forcefully unpublish a node name</fsummary> + <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 localhost. This is however usually not - allowed, unless epmd was started with the -relaxed_command_check - flag, which it normally isn't.</p> - - <p>To unregister a node you have published, you should instead - close the descriptor that was returned by - <c><![CDATA[ei_publish()]]></c>.</p> - + 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> + <p>This function is deprecated and will be removed in a future + release.</p> </warning> - <p><c><![CDATA[alive]]></c> is the name of the node to unregister, i.e., the - first component of the nodename, without the <c><![CDATA[@hostname]]></c>.</p> - <p>If the node was successfully unregistered from epmd, the - function returns 0. Otherwise, it returns -1 and sets - <c><![CDATA[erl_errno]]></c> is to <c><![CDATA[EIO]]></c>.</p> + <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><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><ret>struct hostent</ret><nametext>*erl_gethostbyname(name)</nametext></name> <name><ret>struct hostent</ret><nametext>*erl_gethostbyaddr(addr, length, type)</nametext></name> - <name><ret>struct hostent</ret><nametext>*erl_gethostbyname_r(name, hostp, buffer, buflen, h_errnop)</nametext></name> <name><ret>struct hostent</ret><nametext>*erl_gethostbyaddr_r(addr, length, type, hostp, buffer, buflen, h_errnop)</nametext></name> - <fsummary>Name lookup functions</fsummary> + <name><ret>struct hostent</ret><nametext>*erl_gethostbyname(name)</nametext></name> + <name><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> @@ -550,7 +633,7 @@ typedef struct { <v>int *h_errnop;</v> </type> <desc> - <p>These are convenience functions for some common name lookup functions.</p> + <p>Convenience functions for some common name lookup functions.</p> </desc> </func> </funcs> @@ -558,13 +641,13 @@ typedef struct { <section> <title>Debug Information</title> <p>If a connection attempt fails, the following can be checked:</p> + <list type="bulleted"> - <item><c><![CDATA[erl_errno]]></c></item> - <item>that the right cookie was used</item> - <item>that <em>epmd</em> is running</item> - <item>the remote Erlang node on the other side is running the same - version of Erlang as the <c><![CDATA[erl_interface]]></c> library.</item> + <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 index 8b8c2e95d8..8139c9b343 100644 --- a/lib/erl_interface/doc/src/erl_error.xml +++ b/lib/erl_interface/doc/src/erl_error.xml @@ -4,14 +4,14 @@ <cref> <header> <copyright> - <year>1996</year><year>2013</year> + <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 @@ -19,7 +19,7 @@ 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> @@ -28,61 +28,66 @@ <docno></docno> <approved>Bjarne Däcker</approved> <checked>Torbjörn Törnkvist</checked> - <date>961014</date> + <date>1996-10-14</date> <rev>A</rev> - <file>erl_error.sgml</file> + <file>erl_error.xml</file> </header> <lib>erl_error</lib> - <libsummary>Error Print Routines</libsummary> + <libsummary>Error print routines.</libsummary> <description> <p>This module contains some error printing routines taken - from <em>Advanced Programming in the UNIX Environment</em> - by W. Richard Stevens. </p> + from "Advanced Programming in the UNIX Environment" + by W. Richard Stevens.</p> + <p>These functions are all called in the same manner as - <c><![CDATA[printf()]]></c>, i.e. with a string containing format specifiers - followed by a list of corresponding arguments. All output from - these functions is to <c><![CDATA[stderr]]></c>.</p> + <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><ret>void</ret><nametext>erl_err_msg(FormatStr, ... )</nametext></name> - <fsummary>Non-fatal error, and not system call error</fsummary> + <fsummary>Non-fatal error, and not system call error.</fsummary> <type> <v>const char *FormatStr;</v> </type> <desc> <p>The message provided by the caller is printed. This - function is simply a wrapper for <c><![CDATA[fprintf()]]></c>.</p> + function is simply a wrapper for <c>fprintf()</c>.</p> </desc> </func> + <func> <name><ret>void</ret><nametext>erl_err_quit(FormatStr, ... )</nametext></name> - <fsummary>Fatal error, but not system call error</fsummary> + <fsummary>Fatal error, but not system call error.</fsummary> <type> <v>const char *FormatStr;</v> </type> <desc> <p>Use this function when a fatal error has occurred that - is not due to a system call. The message provided by the - caller is printed and the process terminates with an exit - value of 1. The function does not return.</p> + 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><ret>void</ret><nametext>erl_err_ret(FormatStr, ... )</nametext></name> - <fsummary>Non-fatal system call error</fsummary> + <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> + describing the reason for failure.</p> </desc> </func> + <func> <name><ret>void</ret><nametext>erl_err_sys(FormatStr, ... )</nametext></name> - <fsummary>Fatal system call error</fsummary> + <fsummary>Fatal system call error.</fsummary> <type> <v>const char *FormatStr;</v> </type> @@ -90,7 +95,7 @@ <p>Use this function after a failed system call. The message provided by the caller is printed followed by a string describing the reason for failure, and the process - terminates with an exit value of 1. The function does not + terminates with exit value <c>1</c>. This function does not return.</p> </desc> </func> @@ -98,40 +103,43 @@ <section> <title>Error Reporting</title> - <p>Most functions in erl_interface report failures to the caller by - returning some otherwise meaningless value (typically <c><![CDATA[NULL]]></c> + <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, you will have to examine the error code in - <c><![CDATA[erl_errno]]></c> if you want to find out more about the failure.</p> + 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><ret>volatile int</ret><nametext>erl_errno</nametext></name> - <fsummary>The variable <c><![CDATA[erl_errno]]></c>contains the erl_interface error number. You can change the value if you wish. </fsummary> + <fsummary>Variable <c>erl_errno</c> contains the + Erl_Interface error number. You can change the value if you wish. + </fsummary> <desc> - <p><c><![CDATA[erl_errno]]></c> is initially (at program startup) zero and - is then set by many erl_interface functions on failure to a - non-zero error code to indicate what kind of error it - encountered. A successful function call might change - <c><![CDATA[erl_errno]]></c> (by calling some other function that - fails), but no function will ever set it to zero. This means - that you cannot use <c><![CDATA[erl_errno]]></c> to see <em>if</em> a + <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><![CDATA[NULL]]></c>), in which case you can examine <c><![CDATA[erl_errno]]></c> - for details.</p> - <p><c><![CDATA[erl_errno]]></c> uses the error codes defined in your - system's <c><![CDATA[<errno.h>]]></c>.</p> + <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><errno.h></c>.</p> <note> - <p>Actually, <c><![CDATA[erl_errno]]></c> is a "modifiable lvalue" (just - like ISO C defines <c><![CDATA[errno]]></c> to be) rather than a - variable. This means it might be implemented as a macro - (expanding to, e.g., <c><![CDATA[*_erl_errno()]]></c>). For reasons of - thread- (or task-)safety, this is exactly what we do on most - platforms.</p> + <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 index 713a90a390..9a05196a70 100644 --- a/lib/erl_interface/doc/src/erl_eterm.xml +++ b/lib/erl_interface/doc/src/erl_eterm.xml @@ -4,14 +4,14 @@ <cref> <header> <copyright> - <year>1996</year><year>2013</year> + <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 @@ -19,7 +19,7 @@ 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> @@ -28,131 +28,145 @@ <docno></docno> <approved>Bjarne Däcker</approved> <checked>Torbjörn Törnkvist</checked> - <date>980703</date> + <date>1998-07-03</date> <rev>A</rev> - <file>erl_eterm.sgml</file> + <file>erl_eterm.xml</file> </header> <lib>erl_eterm</lib> - <libsummary>Functions for Erlang Term Construction</libsummary> + <libsummary>Functions for Erlang term construction.</libsummary> <description> - <p>This module contains functions for creating and manipulating - Erlang terms. </p> + <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><![CDATA[ETERM]]></c>. Applications should not reference any fields in this - structure directly, because it may be changed in future releases + <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 us the macros and functions provided. </p> - <p>The following macros each take a single ETERM pointer as an - argument. They return a non-zero value if the test is true, and 0 - otherwise:</p> + 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><![CDATA[ERL_IS_INTEGER(t)]]></c></tag> - <item>True if <c><![CDATA[t]]></c> is an integer.</item> - <tag><c><![CDATA[ERL_IS_UNSIGNED_INTEGER(t)]]></c></tag> - <item>True if <c><![CDATA[t]]></c> is an integer.</item> - <tag><c><![CDATA[ERL_IS_FLOAT(t)]]></c></tag> - <item>True if <c><![CDATA[t]]></c> is a floating point number.</item> - <tag><c><![CDATA[ERL_IS_ATOM(t)]]></c></tag> - <item>True if <c><![CDATA[t]]></c> is an atom.</item> - <tag><c><![CDATA[ERL_IS_PID(t)]]></c></tag> - <item>True if <c><![CDATA[t]]></c> is a Pid (process identifier).</item> - <tag><c><![CDATA[ERL_IS_PORT(t)]]></c></tag> - <item>True if <c><![CDATA[t]]></c> is a port.</item> - <tag><c><![CDATA[ERL_IS_REF(t)]]></c></tag> - <item>True if <c><![CDATA[t]]></c> is a reference.</item> - <tag><c><![CDATA[ERL_IS_TUPLE(t)]]></c></tag> - <item>True if <c><![CDATA[t]]></c> is a tuple.</item> - <tag><c><![CDATA[ERL_IS_BINARY(t)]]></c></tag> - <item>True if <c><![CDATA[t]]></c> is a binary.</item> - <tag><c><![CDATA[ERL_IS_LIST(t)]]></c></tag> - <item>True if <c><![CDATA[t]]></c> is a list with zero or more elements.</item> - <tag><c><![CDATA[ERL_IS_EMPTY_LIST(t)]]></c></tag> - <item>True if <c><![CDATA[t]]></c> is an empty list.</item> - <tag><c><![CDATA[ERL_IS_CONS(t)]]></c></tag> - <item>True if <c><![CDATA[t]]></c> is a list with at least one element.</item> + <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 ETERM* containing the wrong type. For example, - passing a tuple to ERL_ATOM_PTR() will likely result in garbage. - </p> + 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><![CDATA[char *ERL_ATOM_PTR(t)]]></c></tag> - <item/> - <tag><c><![CDATA[char *ERL_ATOM_PTR_UTF8(t)]]></c></tag> - <item>A string representing atom <c><![CDATA[t]]></c>. - </item> - <tag><c><![CDATA[int ERL_ATOM_SIZE(t)]]></c></tag> - <item/> - <tag><c><![CDATA[int ERL_ATOM_SIZE_UTF8(t)]]></c></tag> - <item>The length (in bytes) of atom t.</item> - <tag><c><![CDATA[void *ERL_BIN_PTR(t)]]></c></tag> - <item>A pointer to the contents of <c><![CDATA[t]]></c></item> - <tag><c><![CDATA[int ERL_BIN_SIZE(t)]]></c></tag> - <item>The length (in bytes) of binary object <c><![CDATA[t]]></c>.</item> - <tag><c><![CDATA[int ERL_INT_VALUE(t)]]></c></tag> - <item>The integer of <c><![CDATA[t]]></c>.</item> - <tag><c><![CDATA[unsigned int ERL_INT_UVALUE(t)]]></c></tag> - <item>The unsigned integer value of <c><![CDATA[t]]></c>.</item> - <tag><c><![CDATA[double ERL_FLOAT_VALUE(t)]]></c></tag> - <item>The floating point value of <c><![CDATA[t]]></c>.</item> - <tag><c><![CDATA[ETERM *ERL_PID_NODE(t)]]></c></tag> - <item/> - <tag><c><![CDATA[ETERM *ERL_PID_NODE_UTF8(t)]]></c></tag> - <item>The Node in pid <c><![CDATA[t]]></c>.</item> - <tag><c><![CDATA[int ERL_PID_NUMBER(t)]]></c></tag> - <item>The sequence number in pid <c><![CDATA[t]]></c>.</item> - <tag><c><![CDATA[int ERL_PID_SERIAL(t)]]></c></tag> - <item>The serial number in pid <c><![CDATA[t]]></c>.</item> - <tag><c><![CDATA[int ERL_PID_CREATION(t)]]></c></tag> - <item>The creation number in pid <c><![CDATA[t]]></c>.</item> - <tag><c><![CDATA[int ERL_PORT_NUMBER(t)]]></c></tag> - <item>The sequence number in port <c><![CDATA[t]]></c>.</item> - <tag><c><![CDATA[int ERL_PORT_CREATION(t)]]></c></tag> - <item>The creation number in port <c><![CDATA[t]]></c>.</item> - <tag><c><![CDATA[ETERM *ERL_PORT_NODE(t)]]></c></tag> - <item/> - <tag><c><![CDATA[ETERM *ERL_PORT_NODE_UTF8(t)]]></c></tag> - <item>The node in port <c><![CDATA[t]]></c>.</item> - <tag><c><![CDATA[int ERL_REF_NUMBER(t)]]></c></tag> - <item>The first part of the reference number in ref <c><![CDATA[t]]></c>. Use - only for compatibility.</item> - <tag><c><![CDATA[int ERL_REF_NUMBERS(t)]]></c></tag> - <item>Pointer to the array of reference numbers in ref <c><![CDATA[t]]></c>.</item> - <tag><c><![CDATA[int ERL_REF_LEN(t)]]></c></tag> - <item>The number of used reference numbers in ref <c><![CDATA[t]]></c>.</item> - <tag><c><![CDATA[int ERL_REF_CREATION(t)]]></c></tag> - <item>The creation number in ref <c><![CDATA[t]]></c>.</item> - <tag><c><![CDATA[int ERL_TUPLE_SIZE(t)]]></c></tag> - <item>The number of elements in tuple <c><![CDATA[t]]></c>.</item> - <tag><c><![CDATA[ETERM *ERL_CONS_HEAD(t)]]></c></tag> - <item>The head element of list <c><![CDATA[t]]></c>.</item> - <tag><c><![CDATA[ETERM *ERL_CONS_TAIL(t)]]></c></tag> - <item>A List representing the tail elements of list <c><![CDATA[t]]></c>.</item> + <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><ret>ETERM *</ret><nametext>erl_cons(head, tail)</nametext></name> - <fsummary>Prepends a term to the head of a list.</fsummary> + <fsummary>Prepend a term to the head of a list.</fsummary> <type> <v>ETERM *head;</v> <v>ETERM *tail;</v> </type> <desc> - <p>This function concatenates two Erlang terms, prepending - <c><![CDATA[head]]></c> onto <c><![CDATA[tail]]></c> and thereby creating a <c><![CDATA[cons]]></c> cell. - To make a proper list, <c><![CDATA[tail]]></c> should always be a - list or an empty list. Note that NULL is not a valid list.</p> - <p><c><![CDATA[head]]></c> is the new term to be added.</p> - <p><c><![CDATA[tail]]></c> is the existing list to which <c><![CDATA[head]]></c> will - be concatenated.</p> + <p>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><![CDATA[ERL_CONS_HEAD(list)]]></c> and <c><![CDATA[ERL_CONS_TAIL(list)]]></c> + <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><![CDATA[erl_hd(list)]]></c> and <c><![CDATA[erl_tl(list)]]></c> will do + 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>For example:</p> + <p><em>Example:</em></p> <code type="none"><![CDATA[ ETERM *list,*anAtom,*anInt; anAtom = erl_mk_atom("madonna"); @@ -165,79 +179,102 @@ erl_free_compound(list); ]]></code> </desc> </func> + <func> <name><ret>ETERM *</ret><nametext>erl_copy_term(term)</nametext></name> - <fsummary>Creates a copy of an Erlang term</fsummary> + <fsummary>Create a copy of an Erlang term.</fsummary> <type> <v>ETERM *term;</v> </type> <desc> - <p>This function creates and returns a copy of the Erlang term - <c><![CDATA[term]]></c>.</p> + <p>Creates and returns a copy of the Erlang term + <c>term</c>.</p> </desc> </func> + <func> <name><ret>ETERM *</ret><nametext>erl_element(position, tuple)</nametext></name> - <fsummary>Extracts an element from an Erlang tuple</fsummary> + <fsummary>Extract an element from an Erlang tuple.</fsummary> <type> <v>int position;</v> <v>ETERM *tuple;</v> </type> <desc> - <p>This function extracts a specified element from an Erlang - tuple. </p> - <p><c><![CDATA[position]]></c> specifies which element to retrieve from - <c><![CDATA[tuple]]></c>. The elements are numbered starting from 1.</p> - <p><c><![CDATA[tuple]]></c> is an Erlang term containing at least - <c><![CDATA[position]]></c> elements.</p> - <p>The function returns a new Erlang term corresponding to the - requested element, or NULL if <c><![CDATA[position]]></c> was greater than - the arity of <c><![CDATA[tuple]]></c>.</p> + <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><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><ret>void</ret><nametext>erl_init(NULL, 0)</nametext></name> - <fsummary>Initialization routine</fsummary> + <fsummary>Initialization routine.</fsummary> <type> <v>void *NULL;</v> <v>int 0;</v> </type> <desc> - <marker id="erl_init"></marker> - <p>This function must be called before any of the others in - the <c><![CDATA[erl_interface]]></c> library in order to initialize the - library functions. The arguments must be specified as - <c><![CDATA[erl_init(NULL,0)]]></c>.</p> + <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><ret>ETERM *</ret><nametext>erl_hd(list)</nametext></name> - <fsummary>Extracts the first element from a list</fsummary> + <name><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>Extracts the first element from a list.</p> - <p><c><![CDATA[list]]></c> is an Erlang term containing a list.</p> - <p>The function returns an Erlang term corresponding to the - head element in the list, or a NULL pointer if <c><![CDATA[list]]></c> was - not a list.</p> + <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><ret>ETERM *</ret><nametext>erl_iolist_to_binary(term)</nametext></name> - <fsummary>Converts an IO list to a binary</fsummary> + <fsummary>Convert an I/O list to a binary.</fsummary> <type> <v>ETERM *list;</v> </type> <desc> - <p>This function converts an IO list to a binary term.</p> - <p><c><![CDATA[list]]></c> is an Erlang term containing a list.</p> - <p>This function an Erlang binary term, or NULL if <c><![CDATA[list]]></c> - was not an IO list. </p> - <p>Informally, an IO list is a deep list of characters and - binaries which can be sent to an Erlang port. In BNF, an IO - list is formally defined as follows: </p> + <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 @@ -250,158 +287,164 @@ iohead ::= Binary ]]></code> </desc> </func> + <func> <name><ret>char *</ret><nametext>erl_iolist_to_string(list)</nametext></name> - <fsummary>Converts an IO list to a zero terminated string</fsummary> + <fsummary>Convert an I/O list to a <c>NULL</c>-terminated string.</fsummary> <type> <v>ETERM *list;</v> </type> <desc> - <p>This function converts an IO list to a '\0' terminated C - string. </p> - <p><c><![CDATA[list]]></c> is an Erlang term containing an IO list. The IO - list must not contain the integer 0, since C strings may not + <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>This function returns a pointer to a dynamically allocated - buffer containing a string. If <c><![CDATA[list]]></c> is not an IO list, - or if <c><![CDATA[list]]></c> contains the integer 0, NULL is returned. It - is the caller's responsibility free the allocated buffer - with <c><![CDATA[erl_free()]]></c>. </p> - <p>Refer to <c><![CDATA[erl_iolist_to_binary()]]></c> for the definition of an - IO list. </p> - </desc> - </func> - <func> - <name><ret>int</ret><nametext>erl_iolist_length(list)</nametext></name> - <fsummary>Return the length of an IO list</fsummary> - <type> - <v>ETERM *list;</v> - </type> - <desc> - <p>Returns the length of an IO list. - </p> - <p><c><![CDATA[list]]></c> is an Erlang term containing an IO list. </p> - <p>The function returns the length of <c><![CDATA[list]]></c>, or -1 if - <c><![CDATA[list]]></c> is not an IO list.</p> - <p>Refer to <c><![CDATA[erl_iolist_to_binary()]]></c> for the definition of - an IO list. </p> + <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><ret>int</ret><nametext>erl_length(list)</nametext></name> - <fsummary>Determines the length of a list</fsummary> + <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><![CDATA[list]]></c> is an Erlang term containing proper list. In a - proper list, all tails except the last point to another list + <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 -1 if <c><![CDATA[list]]></c> is not a proper list.</p> + <p>Returns <c>-1</c> if <c>list</c> is not a proper + list.</p> </desc> </func> + <func> <name><ret>ETERM *</ret><nametext>erl_mk_atom(string)</nametext></name> - <fsummary>Creates an atom</fsummary> + <fsummary>Create an atom.</fsummary> <type> <v>const char *string;</v> </type> <desc> <p>Creates an atom.</p> - <p><c><![CDATA[string]]></c> is the sequence of characters that will be + <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. Note that it is - the callers responsibility to make sure that <c><![CDATA[string]]></c> + <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><![CDATA[ERL_ATOM_PTR(atom)]]></c> and <c><![CDATA[ERL_ATOM_PTR_UTF8(atom)]]></c> - can be used to retrieve the atom name (as a null terminated string). <c><![CDATA[ERL_ATOM_SIZE(atom)]]></c> - and <c><![CDATA[ERL_ATOM_SIZE_UTF8(atom)]]></c> returns the length of the atom name.</p> - <note><p>Note that the UTF8 variants were introduced in Erlang/OTP releases R16 - and the string returned by <c>ERL_ATOM_PTR(atom)</c> was not null terminated on older releases.</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><ret>ETERM *</ret><nametext>erl_mk_binary(bptr, size)</nametext></name> - <fsummary>Creates a binary object</fsummary> + <fsummary>Create a binary object.</fsummary> <type> <v>char *bptr;</v> <v>int size;</v> </type> <desc> - <p>This function produces an Erlang binary object from a + <p>Produces an Erlang binary object from a buffer containing a sequence of bytes.</p> - <p><c><![CDATA[bptr]]></c> is a pointer to a buffer containing data to be converted.</p> - <p><c><![CDATA[size]]></c> indicates the length of <c><![CDATA[bptr]]></c>.</p> - <p>The function returns an Erlang binary object.</p> - <p><c><![CDATA[ERL_BIN_PTR(bin)]]></c> retrieves a pointer to - the binary data. <c><![CDATA[ERL_BIN_SIZE(bin)]]></c> retrieves the - size. </p> + <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><ret>ETERM *</ret><nametext>erl_mk_empty_list()</nametext></name> - <fsummary>Creates an empty Erlang list</fsummary> + <fsummary>Create an empty Erlang list.</fsummary> <desc> - <p>This function creates and returns an empty Erlang list. - Note that NULL is not used to represent an empty list; + <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><ret>ETERM *</ret><nametext>erl_mk_estring(string, len)</nametext></name> - <fsummary>Creates an Erlang string</fsummary> + <fsummary>Create an Erlang string.</fsummary> <type> <v>char *string;</v> <v>int len;</v> </type> <desc> - <p>This function creates a list from a sequence of bytes.</p> - <p><c><![CDATA[string]]></c> is a buffer containing a sequence of - bytes. The buffer does not need to be zero-terminated.</p> - <p><c><![CDATA[len]]></c> is the length of <c><![CDATA[string]]></c>.</p> - <p>The function returns an Erlang list object corresponding to - the character sequence in <c><![CDATA[string]]></c>.</p> + <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><ret>ETERM *</ret><nametext>erl_mk_float(f)</nametext></name> - <fsummary>Creates an Erlang float</fsummary> + <fsummary>Create an Erlang float.</fsummary> <type> <v>double f;</v> </type> <desc> <p>Creates an Erlang float.</p> - <p><c><![CDATA[f]]></c> is a value to be converted to an Erlang float.</p> - <p></p> - <p>The function returns an Erlang float object with the value - specified in <c><![CDATA[f]]></c> or <c><![CDATA[NULL]]></c> if - <c><![CDATA[f]]></c> is not finite. - </p> - <p><c><![CDATA[ERL_FLOAT_VALUE(t)]]></c> can be used to retrieve the - value from 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><ret>ETERM *</ret><nametext>erl_mk_int(n)</nametext></name> - <fsummary>Creates an Erlang integer</fsummary> + <fsummary>Create an Erlang integer.</fsummary> <type> <v>int n;</v> </type> <desc> <p>Creates an Erlang integer.</p> - <p><c><![CDATA[n]]></c> is a value to be converted to an Erlang integer.</p> - <p></p> - <p>The function returns an Erlang integer object with the - value specified in <c><![CDATA[n]]></c>.</p> - <p><c><![CDATA[ERL_INT_VALUE(t)]]></c> can be used to retrieve the value + <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><ret>ETERM *</ret><nametext>erl_mk_list(array, arrsize)</nametext></name> - <fsummary>Creates a list from an array</fsummary> + <fsummary>Create a list from an array.</fsummary> <type> <v>ETERM **array;</v> <v>int arrsize;</v> @@ -409,280 +452,316 @@ iohead ::= Binary <desc> <p>Creates an Erlang list from an array of Erlang terms, such that each element in the list corresponds to one element in - the array. </p> - <p><c><![CDATA[array]]></c> is an array of Erlang terms.</p> - <p><c><![CDATA[arrsize]]></c> is the number of elements in <c><![CDATA[array]]></c>.</p> + 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><![CDATA[arrsize]]></c> and whose elements are taken from the terms in - <c><![CDATA[array]]></c>.</p> + <c>arrsize</c> and whose elements are taken from the + terms in <c>array</c>.</p> </desc> </func> + <func> - <name><ret>ETERM *</ret><nametext>erl_mk_pid(node, number, serial, creation)</nametext></name> - <fsummary>Creates a process identifier</fsummary> + <name><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 number;</v> - <v>unsigned int serial;</v> + <v>unsigned int n1, n2, n3;</v> <v>unsigned int creation;</v> </type> <desc> - <p>This function creates an Erlang process identifier. The - resulting pid can be used by Erlang processes wishing to - communicate with the C node.</p> - <p><c><![CDATA[node]]></c> is the name of the C node.</p> - <p><c><![CDATA[number]]></c>, <c><![CDATA[serial]]></c> and <c><![CDATA[creation]]></c> are - arbitrary numbers. Note though, that these are limited in - precision, so only the low 15, 3 and 2 bits of these numbers - are actually used.</p> - <p>The function returns an Erlang pid object.</p> - <p><c><![CDATA[ERL_PID_NODE(pid)]]></c>, <c><![CDATA[ERL_PID_NUMBER(pid)]]></c>, - <c><![CDATA[ERL_PID_SERIAL(pid)]]></c> and <c><![CDATA[ERL_PID_CREATION(pid)]]></c> - can be used to retrieve the four values used to create the pid.</p> + <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><ret>ETERM *</ret><nametext>erl_mk_port(node, number, creation)</nametext></name> - <fsummary>Creates a port identifier</fsummary> + <name><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>This function creates an Erlang port identifier. </p> - <p><c><![CDATA[node]]></c> is the name of the C node.</p> - <p><c><![CDATA[number]]></c> and <c><![CDATA[creation]]></c> are arbitrary numbers. - Note though, that these are limited in - precision, so only the low 18 and 2 bits of these numbers - are actually used.</p> - <p>The function returns an Erlang port object.</p> - <p><c><![CDATA[ERL_PORT_NODE(port)]]></c>, <c><![CDATA[ERL_PORT_NUMBER(port)]]></c> - and <c><![CDATA[ERL_PORT_CREATION]]></c> can be used to retrieve the three - values used to create the port. </p> + <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><ret>ETERM *</ret><nametext>erl_mk_ref(node, number, creation)</nametext></name> - <fsummary>Creates an old Erlang reference</fsummary> + <name><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>This function creates an old Erlang reference, with - only 18 bits - use <c><![CDATA[erl_mk_long_ref]]></c> instead.</p> - <p><c><![CDATA[node]]></c> is the name of the C node.</p> - <p><c><![CDATA[number]]></c> should be chosen uniquely for each reference - created for a given C node.</p> - <p><c><![CDATA[creation]]></c> is an arbitrary number.</p> - <p>Note that <c><![CDATA[number]]></c> and <c><![CDATA[creation]]></c> are limited in - precision, so only the low 18 and 2 bits of these numbers - are actually used. - </p> - <p>The function returns an Erlang reference object.</p> - <p><c><![CDATA[ERL_REF_NODE(ref)]]></c>, <c><![CDATA[ERL_REF_NUMBER(ref)]]></c>, and - <c><![CDATA[ERL_REF_CREATION(ref)]]></c> to retrieve the three values used - to create the reference. </p> + <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><ret>ETERM *</ret><nametext>erl_mk_long_ref(node, n1, n2, n3, creation)</nametext></name> - <fsummary>Creates an Erlang reference</fsummary> + <name><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 n1, n2, n3;</v> + <v>unsigned int number;</v> <v>unsigned int creation;</v> </type> <desc> - <p>This function creates an Erlang reference, with 82 bits.</p> - <p><c><![CDATA[node]]></c> is the name of the C node.</p> - <p><c><![CDATA[n1]]></c>, <c><![CDATA[n2]]></c> and <c><![CDATA[n3]]></c> can be seen as one big number - <c><![CDATA[n1*2^64+n2*2^32+n3]]></c> which should be chosen uniquely for - each reference - created for a given C node.</p> - <p><c><![CDATA[creation]]></c> is an arbitrary number.</p> - <p>Note that <c><![CDATA[n3]]></c> and <c><![CDATA[creation]]></c> are limited in - precision, so only the low 18 and 2 bits of these numbers - are actually used. - </p> - <p>The function returns an Erlang reference object.</p> - <p><c><![CDATA[ERL_REF_NODE(ref)]]></c>, <c><![CDATA[ERL_REF_NUMBERS(ref)]]></c>, - <c><![CDATA[ERL_REF_LEN(ref)]]></c> and - <c><![CDATA[ERL_REF_CREATION(ref)]]></c> to retrieve the values used - to create the reference. </p> + <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><ret>ETERM *</ret><nametext>erl_mk_string(string)</nametext></name> - <fsummary>Creates a string</fsummary> + <fsummary>Create a string.</fsummary> <type> <v>char *string;</v> </type> <desc> - <p>This function creates a list from a zero terminated string.</p> - <p><c><![CDATA[string]]></c> is the zero-terminated sequence of characters - (i.e. a C string) from which the list will be created.</p> - <p>The function returns an Erlang list.</p> + <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><ret>ETERM *</ret><nametext>erl_mk_tuple(array, arrsize)</nametext></name> - <fsummary>Creates an Erlang tuple from an array</fsummary> + <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> - <p><c><![CDATA[array]]></c> is an array of Erlang terms.</p> - <p><c><![CDATA[arrsize]]></c> is the number of elements in <c><![CDATA[array]]></c>.</p> + <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><![CDATA[size]]></c> and whose elements are taken from the terms in - <c><![CDATA[array]]></c>.</p> - <p>To retrieve the size of a tuple, either use the - <c><![CDATA[erl_size]]></c> function (which checks the type of the checked - term and works for a binary as well as for a tuple), or the - <c><![CDATA[ERL_TUPLE_SIZE(tuple)]]></c> returns the arity of a tuple. - <c><![CDATA[erl_size()]]></c> will do the same thing, but it checks that - the argument really is a tuple. - <c><![CDATA[erl_element(index,tuple)]]></c> returns the element - corresponding to a given position in the tuple. </p> + <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><ret>ETERM *</ret><nametext>erl_mk_uint(n)</nametext></name> - <fsummary>Creates an unsigned integer</fsummary> + <fsummary>Create an unsigned integer.</fsummary> <type> <v>unsigned int n;</v> </type> <desc> <p>Creates an Erlang unsigned integer.</p> - <p><c><![CDATA[n]]></c> is a value to be converted to an Erlang + <p><c>n</c> is a value to be converted to an Erlang unsigned integer.</p> - <p></p> - <p>The function returns an Erlang unsigned integer object with - the value specified in <c><![CDATA[n]]></c>.</p> - <p><c><![CDATA[ERL_INT_UVALUE(t)]]></c> can be used to retrieve the + <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><ret>ETERM *</ret><nametext>erl_mk_var(name)</nametext></name> - <fsummary>Creates an Erlang variable</fsummary> + <fsummary>Create an Erlang variable.</fsummary> <type> <v>char *name;</v> </type> <desc> - <p>This function creates an unbound Erlang variable. The - variable can later be bound through pattern matching or assignment.</p> - <p><c><![CDATA[name]]></c> specifies a name for the variable.</p> - <p>The function returns an Erlang variable object with the - name <c><![CDATA[name]]></c>. </p> + <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><ret>int</ret><nametext>erl_print_term(stream, term)</nametext></name> - <fsummary>Prints an Erlang term</fsummary> + <fsummary>Print an Erlang term.</fsummary> <type> <v>FILE *stream;</v> <v>ETERM *term;</v> </type> <desc> - <p>This function prints the specified Erlang term to the given - output stream.</p> - <p><c><![CDATA[stream]]></c> indicates where the function should send its - output.</p> - <p><c><![CDATA[term]]></c> is the Erlang term to print.</p> - <p>The function returns the number of characters written, or a - negative value if there was an error.</p> + <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><ret>void</ret><nametext>erl_set_compat_rel(release_number)</nametext></name> - <fsummary>Set the erl_interface library in compatibility mode</fsummary> + <fsummary>Set the Erl_Interface library in compatibility mode.</fsummary> <type> <v>unsigned release_number;</v> </type> <desc> - <marker id="erl_set_compat_rel"></marker> - <p>By default, the <c><![CDATA[erl_interface]]></c> library is only guaranteed - to be compatible with other Erlang/OTP components from the same - release as the <c><![CDATA[erl_interface]]></c> library itself. For example, - <c><![CDATA[erl_interface]]></c> from the OTP R10 release is not compatible - with an Erlang emulator from the OTP R9 release by default.</p> - <p>A call to <c><![CDATA[erl_set_compat_rel(release_number)]]></c> sets the - <c><![CDATA[erl_interface]]></c> library in compatibility mode of release - <c><![CDATA[release_number]]></c>. Valid range of <c><![CDATA[release_number]]></c> + <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 the - <seealso marker="#erl_init">erl_init()</seealso> function.</p> + 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 make sure that all communicating + 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><ret>int</ret><nametext>erl_size(term)</nametext></name> - <fsummary>Return the arity of a tuple or binary</fsummary> + <fsummary>Return the arity of a tuple or binary.</fsummary> <type> <v>ETERM *term;</v> </type> <desc> - <p>Returns the arity of an Erlang tuple, or the - number of bytes in an Erlang binary object. </p> - <p><c><![CDATA[term]]></c> is an Erlang tuple or an Erlang binary object.</p> - <p>The function returns the size of <c><![CDATA[term]]></c> as described - above, or -1 if <c><![CDATA[term]]></c> is not one of the two supported - types. </p> + <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><ret>ETERM *</ret><nametext>erl_tl(list)</nametext></name> - <fsummary>Extracts the tail from a list</fsummary> + <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><![CDATA[list]]></c> is an Erlang term containing a list.</p> - <p>The function returns an Erlang list corresponding to the - original list minus the first element, or NULL pointer if - <c><![CDATA[list]]></c> was not a list.</p> + <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><ret>ETERM *</ret><nametext>erl_var_content(term, name)</nametext></name> - <fsummary>Extracts the content of a variable</fsummary> + <fsummary>Extract the content of a variable.</fsummary> <type> <v>ETERM *term;</v> <v>char *name;</v> </type> <desc> - <p>This function returns the contents of the specified - variable in an Erlang term. - </p> - <p><c><![CDATA[term]]></c> is an Erlang term. In order for this function - to succeed, <c><![CDATA[term]]></c> must be an Erlang variable with the - specified name, or it must be an Erlang list or tuple - containing a variable with the specified name. Other Erlang - types cannot contain variables.</p> - <p><c><![CDATA[name]]></c> is the name of an Erlang variable.</p> + <p>Returns the 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><![CDATA[name]]></c> in <c><![CDATA[term]]></c>. If no variable with the name - <c><![CDATA[name]]></c> was found in <c><![CDATA[term]]></c>, or if <c><![CDATA[term]]></c> is - not a valid Erlang term, NULL is returned.</p> + <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 index 2918cb8b84..5b8b7b5e78 100644 --- a/lib/erl_interface/doc/src/erl_format.xml +++ b/lib/erl_interface/doc/src/erl_format.xml @@ -4,14 +4,14 @@ <cref> <header> <copyright> - <year>1996</year><year>2013</year> + <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 @@ -19,7 +19,7 @@ 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> @@ -28,51 +28,42 @@ <docno></docno> <approved>Bjarne Däcker</approved> <checked>Torbjörn Törnkvist</checked> - <date>961016</date> + <date>1996-10-16</date> <rev>A</rev> - <file>erl_format.sgml</file> + <file>erl_format.xml</file> </header> <lib>erl_format</lib> - <libsummary>Create and Match Erlang Terms</libsummary> + <libsummary>Create and match Erlang terms.</libsummary> <description> - <p>This module contains two routines - one general function for + <p>This module contains two routines: one general function for creating Erlang terms and one for pattern matching Erlang terms.</p> </description> + <funcs> <func> - <name><ret>ETERM *</ret><nametext>erl_format(FormatStr, ... )</nametext></name> - <fsummary>Creates an Erlang term</fsummary> + <name><ret>ETERM *</ret><nametext>erl_format(FormatStr, ...)</nametext></name> + <fsummary>Create an Erlang term.</fsummary> <type> <v>char *FormatStr;</v> </type> <desc> - <p>This is a general function for creating Erlang terms using + <p>A general function for creating Erlang terms using a format specifier and a corresponding set of arguments, much - in the way <c><![CDATA[printf()]]></c> works.</p> - <p><c><![CDATA[FormatStr]]></c> is a format specification string. The set - of valid format specifiers is as follows:</p> + 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> - <p>~i - Integer</p> - </item> - <item> - <p>~f - Floating point</p> - </item> - <item> - <p>~a - Atom</p> - </item> - <item> - <p>~s - String</p> - </item> - <item> - <p>~w - Arbitrary Erlang term</p> - </item> + <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 that appears in <c><![CDATA[FormatStr]]></c>, + <p>For each format specifier included in <c>FormatStr</c>, there must be a corresponding argument following - <c><![CDATA[FormatStr]]></c>. An Erlang term is built according to the - <c><![CDATA[FormatStr]]></c> with values and Erlang terms substituted from - the corresponding arguments and according to the individual + <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}]", @@ -80,34 +71,40 @@ erl_format("[{name,~a},{age,~i},{data,~w}]", 21, erl_format("[{adr,~s,~i}]","E-street",42)); ]]></code> - <p>This will create an <c><![CDATA[(ETERM *)]]></c> structure corresponding - to the Erlang term: - <c><![CDATA[[{name,madonna},{age,21},{data,[{adr,"E-street",42}]}]]]></c></p> - <p>The function returns an Erlang term, or NULL if - <c><![CDATA[FormatStr]]></c> does not describe a valid Erlang term.</p> + <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><ret>int</ret><nametext>erl_match(Pattern, Term)</nametext></name> - <fsummary>Performs pattern matching</fsummary> + <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. Refer to an Erlang manual for matching - rules and more examples.</p> - <p><c><![CDATA[Pattern]]></c> is an Erlang term, possibly containing unbound - variables. </p> - <p><c><![CDATA[Term]]></c> is an Erlang term that we wish to match against - <c><![CDATA[Pattern]]></c>.</p> - <p><c><![CDATA[Term]]></c> and <c><![CDATA[Pattern]]></c> are compared, and any - unbound variables in <c><![CDATA[Pattern]]></c> are bound to corresponding - values in <c><![CDATA[Term]]></c>. </p> - <p>If <c><![CDATA[Term]]></c> and <c><![CDATA[Pattern]]></c> can be matched, the - function returns a non-zero value and binds any unbound - variables in <c><![CDATA[Pattern]]></c>. If <c><![CDATA[Term]]></c> <c><![CDATA[Pattern]]></c> do - not match, the function returns 0. For example:</p> + 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}"); @@ -132,11 +129,10 @@ if (erl_match(pattern2, term2)) { ... } ]]></code> - <p><c><![CDATA[erl_var_content()]]></c> can be used to retrieve the + <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><![CDATA[erl_match()]]></c>.</p> + <c>erl_match()</c>.</p> </desc> </func> </funcs> </cref> - diff --git a/lib/erl_interface/doc/src/erl_global.xml b/lib/erl_interface/doc/src/erl_global.xml index ec5e51a0b6..2fa0045adf 100644 --- a/lib/erl_interface/doc/src/erl_global.xml +++ b/lib/erl_interface/doc/src/erl_global.xml @@ -4,14 +4,14 @@ <cref> <header> <copyright> - <year>1998</year><year>2013</year> + <year>1998</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 @@ -19,7 +19,7 @@ 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_global</title> @@ -28,115 +28,125 @@ <docno></docno> <approved>Gordon Beaton</approved> <checked>Gordon Beaton</checked> - <date>980703</date> + <date>1998-07-03</date> <rev>A</rev> - <file>erl_global.sgml</file> + <file>erl_global.xml</file> </header> <lib>erl_global</lib> - <libsummary>Access globally registered names</libsummary> + <libsummary>Access globally registered names.</libsummary> <description> <p>This module provides support for registering, looking - up and unregistering names in the Erlang Global module. For more - information, see the description of Global in the reference manual.</p> - <p>Note that the functions below perform an RPC using an open file - descriptor provided by the caller. This file descriptor must - not be used for other traffic during the global operation or the - function may receive unexpected data and fail.</p> + up, and unregistering names in the <c>global</c> module. + For more information, see + <seealso marker="kernel:global"><c>kernel:global</c></seealso>.</p> + + <p>Notice that the functions below perform an RPC using an open file + descriptor provided by the caller. This file descriptor must + not be used for other traffic during the global operation, as the + function can then receive unexpected data and fail.</p> </description> + <funcs> <func> <name><ret>char **</ret><nametext>erl_global_names(fd,count)</nametext></name> - <fsummary>Obtain list of Global names</fsummary> + <fsummary>Obtain list of global names.</fsummary> <type> <v>int fd;</v> <v>int *count;</v> </type> <desc> - <p>Retrieve a list of all known global names. - </p> - <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection. - </p> - <p><c><![CDATA[count]]></c> is the address of an integer, or NULL. If - <c><![CDATA[count]]></c> is not NULL, it will be set by the function to - the number of names found. - </p> + <p>Retrieves a list of all known global names.</p> + <list type="bulleted"> + <item><c>fd</c> is an open descriptor to an Erlang + connection.</item> + <item><c>count</c> is the address of an integer, or + <c>NULL</c>. If <c>count</c> is not <c>NULL</c>, it is + set by the function to the number of names found.</item> + </list> <p>On success, the function returns an array of strings, each - containing a single registered name, and sets <c><![CDATA[count]]></c> to + containing a single registered name, and sets + <c>count</c> to the number of names found. The array is terminated - by a single NULL pointer. On failure, the function returns - NULL and <c><![CDATA[count]]></c> is not modified. - </p> + by a single <c>NULL</c> pointer. On failure, the function returns + <c>NULL</c> and <c>count</c> is not modified.</p> <note> <p>It is the caller's responsibility to free the array afterwards. It has been allocated by the function with a - single call to <c><![CDATA[malloc()]]></c>, so a single <c><![CDATA[free()]]></c> is - all that is necessary.</p> + single call to <c>malloc()</c>, so a single + <c>free()</c> is all that is necessary.</p> </note> </desc> </func> + <func> <name><ret>int</ret><nametext>erl_global_register(fd,name,pid)</nametext></name> - <fsummary>Register a name in Global</fsummary> + <fsummary>Register a name in global.</fsummary> <type> <v>int fd;</v> <v>const char *name;</v> <v>ETERM *pid;</v> </type> <desc> - <p>This function registers a name in Global. - </p> - <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection. - </p> - <p><c><![CDATA[name]]></c> is the name to register in Global. - </p> - <p><c><![CDATA[pid]]></c> is the pid that should be associated with - <c><![CDATA[name]]></c>. This is the value that Global will return when - processes request the location of <c><![CDATA[name]]></c>. - </p> - <p>The function returns 0 on success, or -1 on failure.</p> + <p>Registers a name in <c>global</c>.</p> + <list type="bulleted"> + <item><c>fd</c> is an open descriptor to an Erlang + connection.</item> + <item><c>name</c> is the name to register in + <c>global</c>.</item> + <item><c>pid</c> is the pid that is to be associated with + <c>name</c>. This value is returned by <c>global</c> + when processes request the location of <c>name</c>. + </item> + </list> + <p>Returns <c>0</c> on success, otherwise <c>-1</c>.</p> </desc> </func> + <func> <name><ret>int</ret><nametext>erl_global_unregister(fd,name)</nametext></name> - <fsummary>Unregister a name in Global</fsummary> + <fsummary>Unregister a name from global.</fsummary> <type> <v>int fd;</v> <v>const char *name;</v> </type> <desc> - <p>This function unregisters a name from Global. - </p> - <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection. - </p> - <p><c><![CDATA[name]]></c> is the name to unregister from Global. - </p> - <p>The function returns 0 on success, or -1 on failure.</p> + <p>Unregisters a name from <c>global</c>.</p> + <list type="bulleted"> + <item><c>fd</c> is an open descriptor to an Erlang + connection.</item> + <item><c>name</c> is the name to unregister from + <c>global</c>.</item> + </list> + <p>Returns <c>0</c> on success, otherwise <c>-1</c>.</p> </desc> </func> + <func> <name><ret>ETERM *</ret><nametext>erl_global_whereis(fd,name,node)</nametext></name> - <fsummary>Look up a name in global</fsummary> + <fsummary>Look up a name in global.</fsummary> <type> <v>int fd;</v> <v>const char *name;</v> <v>char *node;</v> </type> <desc> - <p><c><![CDATA[fd]]></c> is an open descriptor to an Erlang connection. - </p> - <p><c><![CDATA[name]]></c> is the name that is to be looked up in Global. - </p> - <p>If <c><![CDATA[node]]></c> is not NULL, it is a pointer to a buffer - where the function can fill in the name of the node where - <c><![CDATA[name]]></c> is found. <c><![CDATA[node]]></c> can be passed directly to - <c><![CDATA[erl_connect()]]></c> if necessary. - </p> - <p>On success, the function returns an Erlang Pid containing the address - of the given name, and node will be initialized to - the nodename where <c><![CDATA[name]]></c> is found. On failure NULL will be - returned and <c><![CDATA[node]]></c> will not be modified.</p> + <p>Looks up a name in <c>global</c>.</p> + <list type="bulleted"> + <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>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 + the node name where <c>name</c> is found. On failure, + <c>NULL</c> is returned and <c>node</c> is not + modified.</p> </desc> </func> </funcs> </cref> - diff --git a/lib/erl_interface/doc/src/erl_interface.xml b/lib/erl_interface/doc/src/erl_interface.xml index 3a01cba74e..4e66655b39 100644 --- a/lib/erl_interface/doc/src/erl_interface.xml +++ b/lib/erl_interface/doc/src/erl_interface.xml @@ -4,14 +4,14 @@ <chapter> <header> <copyright> - <year>1996</year><year>2013</year> + <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 @@ -19,7 +19,7 @@ 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> @@ -72,51 +72,51 @@ Eshell V4.7.4 (abort with ^G) 1> code:root_dir(). /usr/local/otp ]]></code> <p>To compile your code, make sure that your C compiler knows where - to find <c><![CDATA[erl_interface.h]]></c> by specifying an appropriate <c><![CDATA[-I]]></c> - argument on the command line, or by adding it to the <c><![CDATA[CFLAGS]]></c> - definition in your <c><![CDATA[Makefile]]></c>. The correct value for this path is - <c><![CDATA[$OTPROOT/lib/erl_interface]]></c><em>Vsn</em><c><![CDATA[/include]]></c>, where <c><![CDATA[$OTPROOT]]></c> is the path - reported by <c><![CDATA[code:root_dir/0]]></c> in the above example, and <em>Vsn</em> is + 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><![CDATA[erl_interface-3.2.3]]></c></p> + <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><![CDATA[liberl_interface.a]]></c> and <c><![CDATA[libei.a]]></c> with - <c><![CDATA[-L$OTPROOT/lib/erl_interface-3.2.3/lib]]></c>, and you will need to specify the - name of the libraries with <c><![CDATA[-lerl_interface -lei]]></c>. You can do - this on the command line or by adding the flags to the <c><![CDATA[LDFLAGS]]></c> - definition in your <c><![CDATA[Makefile]]></c>.</p> + <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><![CDATA[libnsl.a]]></c> and <c><![CDATA[libsocket.a]]></c> on - Solaris, or <c><![CDATA[wsock32.lib]]></c> on Windows) in order to use the + 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><![CDATA[_REENTRANT]]></c> and either <c><![CDATA[STHREADS]]></c> or - <c><![CDATA[PTHREADS]]></c>. The default is to use POSIX threads if - <c><![CDATA[_REENTRANT]]></c> is specified.</p> + 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><![CDATA[liberl_interface_st]]></c> and <c><![CDATA[libei_st]]></c>). Whether the default + <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><![CDATA[eidefs.mk]]></c> file in the erl_interface src directory.</p> + 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><![CDATA[erl_init()]]></c> exactly once to initialize the library. - <c><![CDATA[erl_init()]]></c> takes two arguments, however the arguments are no + 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><![CDATA[erl_init(NULL,0)]]></c>.</p> + as <c>erl_init(NULL,0)</c>.</p> </section> <section> @@ -129,7 +129,7 @@ $ ld -L/usr/local/otp/lib/erl_interface-3.2.3/ number of C functions which create and manipulate Erlang data structures. The library also contains an encode and a decode function. The example below shows how to create and encode an Erlang tuple - <c><![CDATA[{tobbe,3928}]]></c>:</p> + <c>{tobbe,3928}</c>:</p> <code type="none"><![CDATA[ ETERM *arr[2], *tuple; @@ -140,26 +140,26 @@ arr[0] = erl_mk_atom("tobbe"); arr[1] = erl_mk_integer(3928); tuple = erl_mk_tuple(arr, 2); i = erl_encode(tuple, buf); ]]></code> - <p>Alternatively, you can use <c><![CDATA[erl_send()]]></c> and - <c><![CDATA[erl_receive_msg]]></c>, which handle the encoding and decoding of + <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><![CDATA[erl_eterm]]></c> module for creating Erlang terms</item> - <item>the <c><![CDATA[erl_marshal]]></c> module for encoding and decoding routines.</item> + <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><![CDATA[erl_format()]]></c> to create an Erlang term.</p> + <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><![CDATA[erl_format]]></c> module, for a + <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[ @@ -171,10 +171,10 @@ ep = erl_format("[{name,~a},{age,~i},{data,~w}]", erl_format("[{adr,~s,~i}]", "E-street", 42)); erl_free_compound(ep); ]]></code> <p>As in previous examples, it is your responsibility to free the - memory allocated for Erlang terms. In this example, - <c><![CDATA[erl_free_compound()]]></c> ensures that the complete term pointed to - by <c><![CDATA[ep]]></c> is released. This is necessary, because the pointer from - the second call to <c><![CDATA[erl_format()]]></c> is lost. </p> + 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[ @@ -186,7 +186,7 @@ ep = erl_format("[{name,~a},{age,~i},{data,~w}]", erl_free_term(ep); erl_free_term(ep2); ]]></code> <p>In this case, you free the two terms independently. The order in - which you free the terms <c><![CDATA[ep]]></c> and <c><![CDATA[ep2]]></c> is not important, + 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 @@ -204,14 +204,14 @@ printf("length of freelist: %ld\ /* really free the freelist */ erl_eterm_release(); ]]></code> - <p>Refer to the Reference Manual, the <c><![CDATA[erl_malloc]]></c> module for more + <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><![CDATA["do not care"]]></c> symbols. Such a pattern can be matched against a + <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> @@ -219,13 +219,13 @@ erl_eterm_release(); ETERM *pattern; pattern = erl_format("{madonna,Age,_}"); ]]></code> - <p><c><![CDATA[erl_match()]]></c> is used to perform pattern matching. It takes a + <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><![CDATA[erl_match()]]></c> will bind the contents of + <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 @@ -248,14 +248,14 @@ if (erl_match(pattern, term)) { } erl_free_term(pattern); erl_free_term(term); ]]></code> - <p>Refer to the Reference Manual, the <c><![CDATA[erl_match()]]></c> function for + <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><![CDATA[erl_connect_init()]]></c>, + 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[ @@ -263,9 +263,9 @@ int identification_number = 99; int creation=1; char *cookie="a secret cookie string"; /* An example */ erl_connect_init(identification_number, cookie, creation); ]]></code> - <p>Refer to the Reference Manual, the <c><![CDATA[erl_connect]]></c> module for more information.</p> + <p>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><![CDATA[erl_connect()]]></c> to specify the Erlang node you want to + 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[ @@ -273,45 +273,45 @@ int sockfd; char *nodename="[email protected]"; /* An example */ if ((sockfd = erl_connect(nodename)) < 0) erl_err_quit("ERROR: erl_connect failed"); ]]></code> - <p><c><![CDATA[erl_err_quit()]]></c> prints the specified string and terminates - the program. Refer to the Reference Manual, the <c><![CDATA[erl_error()]]></c> + <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><![CDATA[Epmd]]></c> is the Erlang Port Mapper Daemon. Distributed Erlang nodes - register with <c><![CDATA[epmd]]></c> on the localhost to indicate to other nodes that - they exist and can accept connections. <c><![CDATA[Epmd]]></c> maintains a register of + <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><![CDATA[epmd]]></c> in order to find out the correct + 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><![CDATA[erl_connect()]]></c> to connect to an Erlang node, a - connection is first made to <c><![CDATA[epmd]]></c> and, if the node is known, a + <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><![CDATA[epmd]]></c> if they want other + <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><![CDATA[epmd]]></c>, you need to first create a listen socket + <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><![CDATA[pub]]></c> is a file descriptor now connected to <c><![CDATA[epmd]]></c>. <c><![CDATA[Epmd]]></c> + <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><![CDATA[epmd]]></c>.</p> + 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><![CDATA[epmd]]></c> will prevent you from + 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><![CDATA[epmd]]></c> to close the connection from the far end. Note + <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> @@ -321,8 +321,8 @@ erl_unpublish(node); ]]></code> <title>Sending and Receiving Erlang Messages</title> <p>Use one of the following two functions to send messages:</p> <list type="bulleted"> - <item><c><![CDATA[erl_send()]]></c></item> - <item><c><![CDATA[erl_reg_send()]]></c></item> + <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 @@ -330,17 +330,17 @@ erl_unpublish(node); ]]></code> a suitable <em>Pid</em>.</p> <p>Use one of the following two functions to receive messages:</p> <list type="bulleted"> - <item><c><![CDATA[erl_receive()]]></c></item> - <item><c><![CDATA[erl_receive_msg()]]></c></item> + <item><c>erl_receive()</c></item> + <item><c>erl_receive_msg()</c></item> </list> - <p><c><![CDATA[erl_receive()]]></c> receives the message into a buffer, while - <c><![CDATA[erl_receive_msg()]]></c> decodes the message into an Erlang term. </p> + <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><![CDATA[{Pid, hello_world}]]></c> is - sent to a registered process <c><![CDATA[my_server]]></c>. The message is encoded - by <c><![CDATA[erl_send()]]></c>:</p> + <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); @@ -355,15 +355,15 @@ emsg = erl_mk_tuple(arr, 2); erl_reg_send(sockfd, "my_server", emsg); erl_free_term(emsg); ]]></code> <p>The first element of the tuple that is sent is your own - <em>Pid</em>. This enables <c><![CDATA[my_server]]></c> to reply. Refer to the - Reference Manual, the <c><![CDATA[erl_connect]]></c> module for more information + <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><![CDATA[{Pid, Something}]]></c> is received. The - received Pid is then used to return <c><![CDATA[{goodbye,Pid}]]></c></p> + <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; @@ -383,18 +383,18 @@ if ((rc = erl_receive_msg(sockfd , buf, BUFSIZE, &emsg)) == ERL_MSG) { <p>In order to provide robustness, a distributed Erlang node occasionally polls all its connected neighbours in an attempt to detect failed nodes or communication links. A node which receives such - a message is expected to respond immediately with an <c><![CDATA[ERL_TICK]]></c> message. - This is done automatically by <c><![CDATA[erl_receive()]]></c>, however when this - has occurred <c><![CDATA[erl_receive]]></c> returns <c><![CDATA[ERL_TICK]]></c> to the caller - without storing a message into the <c><![CDATA[ErlMessage]]></c> structure.</p> + 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><![CDATA[emsg.msg]]></c> as well as <c><![CDATA[emsg.to]]></c> - or <c><![CDATA[emsg.from]]></c>, depending on the type of message received.</p> + 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><![CDATA[erl_connect]]></c></item> - <item><c><![CDATA[erl_eterm]]></c>.</item> + <item><c>erl_connect</c></item> + <item><c>erl_eterm</c>.</item> </list> </section> </section> @@ -421,12 +421,12 @@ if (!erl_match(ep, reply)) "); erl_free_term(ep); erl_free_term(reply); ]]></code> - <p><c><![CDATA[c:c/1]]></c> is called to compile the specified module on the - remote node. <c><![CDATA[erl_match()]]></c> checks that the compilation was - successful by testing for the expected <c><![CDATA[ok]]></c>.</p> - <p>Refer to the Reference Manual, the <c><![CDATA[erl_connect]]></c> module for - more information about <c><![CDATA[erl_rpc()]]></c>, and its companions - <c><![CDATA[erl_rpc_to()]]></c> and <c><![CDATA[erl_rpc_from()]]></c>.</p> + <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> @@ -454,14 +454,14 @@ if (names) ",names[i]); free(names); ]]></code> - <p><c><![CDATA[erl_global_names()]]></c> allocates and returns a buffer containing - all the names known to global. <c><![CDATA[count]]></c> will be initialized to + <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><![CDATA[count]]></c> to determine when the last name is reached.</p> + <c>count</c> to determine when the last name is reached.</p> <p>It is the caller's responsibility to free the array. - <c><![CDATA[erl_global_names()]]></c> allocates the array and all of the strings - using a single call to <c><![CDATA[malloc()]]></c>, so <c><![CDATA[free(names)]]></c> is all + <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[ @@ -469,13 +469,13 @@ ETERM *pid; char node[256]; pid = erl_global_whereis(fd,"schedule",node); ]]></code> - <p>If <c><![CDATA["schedule"]]></c> is known to global, an Erlang pid is returned + <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><![CDATA[node]]></c> will be initialized to contain the name of + 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><![CDATA[erl_connect()]]></c>.</p> + 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><![CDATA[epmd]]></c>. This is not strictly necessary, but if you + 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 @@ -485,9 +485,9 @@ ETERM *pid; pid = erl_mk_pid(thisnode,14,0,0); erl_global_register(fd,servicename,pid); ]]></code> - <p>After registering the name, you should use <c><![CDATA[erl_accept()]]></c> to wait for + <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><![CDATA[pid]]></c> later with <c><![CDATA[erl_free_term()]]></c>!</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> @@ -500,7 +500,7 @@ erl_global_unregister(fd,servicename); ]]></code> restoring them from a Mnesia table on an Erlang node. More detailed information about the individual API functions can be found in the Reference Manual.</p> - <p>Keys are strings, i.e. 0-terminated arrays of characters, and values + <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> @@ -570,12 +570,12 @@ ei_reg_close(reg); ]]></code> <title>Backing Up the Registry to Mnesia</title> <p>The contents of a registry can be backed up to Mnesia on a "nearby" Erlang node. You need to provide an open connection to the Erlang node - (see <c><![CDATA[erl_connect()]]></c>). Also, Mnesia 3.0 or later must be running + (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><![CDATA["mtab"]]></c>. Once a registry has been backed + 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 @@ -584,7 +584,7 @@ ei_reg_dump(fd, reg, "mtab", dumpflags); ]]></code> <p>In the same manner, a registry can be restored from a Mnesia table:</p> <code type="none"><![CDATA[ ei_reg_restore(fd, reg, "mtab"); ]]></code> - <p>This will read the entire contents of <c><![CDATA["mtab"]]></c> into the specified + <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> @@ -600,8 +600,8 @@ ei_reg_restore(fd, reg, "mtab"); ]]></code> <p>When string or binary objects are stored in the registry it is important that a number of simple guidelines are followed. </p> <p>Most importantly, the object must have been created with a single call - to <c><![CDATA[malloc()]]></c> (or similar), so that it can later be removed by a - single call to <c><![CDATA[free()]]></c>. Objects will be freed by the registry + 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 @@ -618,9 +618,8 @@ ei_reg_restore(fd, reg, "mtab"); ]]></code> you make, possibly causing it to be missed the next time you make a Mnesia backup of the registry contents. This can be avoided if you mark the object as dirty after any such changes with - <c><![CDATA[ei_reg_markdirty()]]></c>, or pass appropriate flags to - <c><![CDATA[ei_reg_dump()]]></c>.</p> + <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 index 0a9830f612..c0eebc29e9 100644 --- a/lib/erl_interface/doc/src/erl_malloc.xml +++ b/lib/erl_interface/doc/src/erl_malloc.xml @@ -4,14 +4,14 @@ <cref> <header> <copyright> - <year>1996</year><year>2013</year> + <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 @@ -19,7 +19,7 @@ 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> @@ -28,174 +28,177 @@ <docno></docno> <approved>Bjarne Däcker</approved> <checked>Torbjörn Törnkvist</checked> - <date>980703</date> + <date>1998-07-03</date> <rev>A</rev> - <file>erl_malloc.sgml</file> + <file>erl_malloc.xml</file> </header> <lib>erl_malloc</lib> - <libsummary>Memory Allocation Functions</libsummary> + <libsummary>Memory allocation functions.</libsummary> <description> <p>This module provides functions for allocating and deallocating memory.</p> </description> + <funcs> <func> <name><ret>ETERM *</ret><nametext>erl_alloc_eterm(etype)</nametext></name> - <fsummary>Allocates an ETERM structure</fsummary> + <fsummary>Allocate an ETERM structure.</fsummary> <type> <v>unsigned char etype;</v> </type> <desc> - <p>This function allocates an <c><![CDATA[(ETERM)]]></c> structure. - Specify <c><![CDATA[etype]]></c> as one of the following constants:</p> + <p>Allocates an <c>(ETERM)</c> structure.</p> + <p>Specify <c>etype</c> as one of the following + constants:</p> <list type="bulleted"> - <item> - <p>ERL_INTEGER</p> + <item><c>ERL_INTEGER</c> </item> - <item> - <p>ERL_U_INTEGER <c><![CDATA[/* unsigned integer */]]></c></p> + <item><c>ERL_U_INTEGER</c> (unsigned integer) </item> - <item> - <p>ERL_ATOM</p> + <item><c>ERL_ATOM</c> </item> - <item> - <p>ERL_PID <c><![CDATA[/* Erlang process identifier */]]></c></p> + <item><c>ERL_PID</c> (Erlang process identifier) </item> - <item> - <p>ERL_PORT</p> + <item><c>ERL_PORT</c> </item> - <item> - <p>ERL_REF <c><![CDATA[/* Erlang reference */]]></c></p> + <item><c>ERL_REF</c> (Erlang reference) </item> - <item> - <p>ERL_LIST</p> + <item><c>ERL_LIST</c> </item> - <item> - <p>ERL_EMPTY_LIST</p> + <item><c>ERL_EMPTY_LIST</c> </item> - <item> - <p>ERL_TUPLE</p> + <item><c>ERL_TUPLE</c> </item> - <item> - <p>ERL_BINARY</p> + <item><c>ERL_BINARY</c> </item> - <item> - <p>ERL_FLOAT</p> + <item><c>ERL_FLOAT</c> </item> - <item> - <p>ERL_VARIABLE</p> + <item><c>ERL_VARIABLE</c> </item> - <item> - <p>ERL_SMALL_BIG <c><![CDATA[/* bignum */]]></c></p> + <item><c>ERL_SMALL_BIG</c> (bignum) </item> - <item> - <p>ERL_U_SMALL_BIG <c><![CDATA[/* bignum */]]></c></p> + <item><c>ERL_U_SMALL_BIG</c> (bignum) </item> </list> - <p><c><![CDATA[ERL_SMALL_BIG]]></c> and <c><![CDATA[ERL_U_SMALL_BIG]]></c> are for - creating Erlang <c><![CDATA[bignums]]></c>, which can contain integers of - arbitrary size. The size of an integer in Erlang is machine - dependent, but in general any integer larger than 2^28 - requires a bignum.</p> + <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 > 2^28 requires a bignum.</p> </desc> </func> + <func> <name><ret>void</ret><nametext>erl_eterm_release(void)</nametext></name> - <fsummary>Clears the ETERM freelist</fsummary> + <fsummary>Clear the ETERM freelist.</fsummary> <desc> - <p>Clears the - freelist, where blocks are placed when they are - released by <c><![CDATA[erl_free_term()]]></c> and - <c><![CDATA[erl_free_compound()]]></c>. </p> + <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><ret>void</ret><nametext>erl_eterm_statistics(allocated, freed)</nametext></name> - <fsummary>Reports term allocation statistics</fsummary> + <fsummary>Report term allocation statistics.</fsummary> <type> <v>long *allocated;</v> <v>long *freed;</v> </type> <desc> - <p><c><![CDATA[allocated]]></c> and <c><![CDATA[freed]]></c> are initialized to + <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 - ETERM components. <c><![CDATA[allocated]]></c> is the number of blocks - currently allocated to ETERM objects. <c><![CDATA[freed]]></c> is the - length of the freelist, where blocks are placed when they are - released by <c><![CDATA[erl_free_term()]]></c> and - <c><![CDATA[erl_free_compound()]]></c>. </p> + <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><ret>void</ret><nametext>erl_free_array(array, size)</nametext></name> - <fsummary>Frees an array of ETERM structures</fsummary> + <name><ret>void</ret><nametext>erl_free(ptr)</nametext></name> + <fsummary>Free some memory.</fsummary> <type> - <v>ETERM **array;</v> - <v>int size;</v> + <v>void *ptr;</v> </type> <desc> - <p>This function frees an array of Erlang terms.</p> - <p><c><![CDATA[array]]></c> is an array of ETERM* objects. - </p> - <p><c><![CDATA[size]]></c> is the number of terms in the array.</p> + <p>Calls the standard + <c>free()</c> function.</p> </desc> </func> + <func> - <name><ret>void</ret><nametext>erl_free_term(t)</nametext></name> - <fsummary>Frees an ETERM structure</fsummary> + <name><ret>void</ret><nametext>erl_free_array(array, size)</nametext></name> + <fsummary>Free an array of ETERM structures.</fsummary> <type> - <v>ETERM *t;</v> + <v>ETERM **array;</v> + <v>int size;</v> </type> <desc> - <p>Use this function to free an Erlang term.</p> + <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><ret>void</ret><nametext>erl_free_compound(t)</nametext></name> - <fsummary>Frees an array of ETERM structures</fsummary> + <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><![CDATA[erl_interface]]></c> functions. However since many 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 may be difficult for the - programmer to maintain pointers to all such terms in order to - free them individually. - </p> - <p><c><![CDATA[erl_free_compound()]]></c> will recursively free all of the - sub-terms associated with a given Erlang term, regardless of - whether we are still holding pointers to the sub-terms. - </p> - <p>There is an example in the User Manual under "Building - Terms and Patterns" - </p> + 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><ret>void</ret><nametext>erl_malloc(size)</nametext></name> - <fsummary>Allocates some memory</fsummary> + <name><ret>void</ret><nametext>erl_free_term(t)</nametext></name> + <fsummary>Free an ETERM structure.</fsummary> <type> - <v>long size;</v> + <v>ETERM *t;</v> </type> <desc> - <p>This function calls the standard - <c><![CDATA[malloc()]]></c> function. </p> + <p>Frees an Erlang term.</p> </desc> </func> + <func> - <name><ret>void</ret><nametext>erl_free(ptr)</nametext></name> - <fsummary>Frees some memory</fsummary> + <name><ret>void</ret><nametext>erl_malloc(size)</nametext></name> + <fsummary>Allocate some memory.</fsummary> <type> - <v>void *ptr;</v> + <v>long size;</v> </type> <desc> - <p>This function calls the standard - <c><![CDATA[free()]]></c> function. </p> + <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 index 9b9622dcc2..2ad658f78b 100644 --- a/lib/erl_interface/doc/src/erl_marshal.xml +++ b/lib/erl_interface/doc/src/erl_marshal.xml @@ -4,14 +4,14 @@ <cref> <header> <copyright> - <year>1996</year><year>2013</year> + <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 @@ -19,7 +19,7 @@ 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> @@ -28,246 +28,241 @@ <docno></docno> <approved>Bjarne Däcker</approved> <checked>Torbjörn Törnkvist</checked> - <date>980703</date> + <date>1998-07-03</date> <rev>A</rev> - <file>erl_marshal.sgml</file> + <file>erl_marshal.xml</file> </header> <lib>erl_marshal</lib> - <libsummary>Encoding and Decoding of Erlang terms</libsummary> + <libsummary>Encoding and decoding of Erlang terms.</libsummary> <description> <p>This module contains functions for encoding Erlang terms into a sequence of bytes, and for decoding Erlang terms from a sequence of bytes.</p> </description> + <funcs> <func> <name><ret>int</ret><nametext>erl_compare_ext(bufp1, bufp2)</nametext></name> - <fsummary>Compares encoded byte sequences</fsummary> + <fsummary>Compare encoded byte sequences.</fsummary> <type> <v>unsigned char *bufp1,*bufp2;</v> </type> <desc> - <p>This function compares two encoded terms. - </p> - <p><c><![CDATA[bufp1]]></c> is a buffer containing an encoded Erlang - term term1. - </p> - <p><c><![CDATA[bufp2]]></c> is a buffer containing an encoded Erlang - term term2. - </p> - <p>The function returns 0 if the terms are equal, -1 if term1 - is less than term2, or 1 if term2 is less than term1. - </p> + <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> < <c>term2</c>, or <c>1</c> if <c>term2</c> < + <c>term1</c>.</p> </desc> </func> + <func> <name><ret>ETERM *</ret><nametext>erl_decode(bufp)</nametext></name> <name><ret>ETERM *</ret><nametext>erl_decode_buf(bufpp)</nametext></name> - <fsummary>Converts a term from Erlang external format</fsummary> + <fsummary>Convert a term from Erlang external format.</fsummary> <type> <v>unsigned char *bufp;</v> <v>unsigned char **bufpp;</v> </type> <desc> - <p><c><![CDATA[erl_decode()]]></c> and <c><![CDATA[erl_decode_buf()]]></c> decode + <p><c>erl_decode()</c> and + <c>erl_decode_buf()</c> decode the contents of a buffer and return the corresponding - Erlang term. <c><![CDATA[erl_decode_buf()]]></c> provides a simple + Erlang term. <c>erl_decode_buf()</c> provides a simple mechanism for dealing with several encoded terms stored consecutively in the buffer.</p> - <p><c><![CDATA[bufp]]></c> is a pointer to a buffer containing one or - more encoded Erlang terms. - </p> - <p><c><![CDATA[bufpp]]></c> is the address of a buffer pointer. The buffer - contains one or more consecutively encoded Erlang terms. - Following a successful call to <c><![CDATA[erl_decode_buf()]]></c>, - <c><![CDATA[bufpp]]></c> will be updated so that it points to the next - encoded term. - </p> - <p><c><![CDATA[erl_decode()]]></c> returns an Erlang term - corresponding to the contents of <c><![CDATA[bufp]]></c> on success, or - NULL on failure. <c><![CDATA[erl_decode_buf()]]></c> returns an Erlang + <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><![CDATA[bufpp]]></c> and moves <c><![CDATA[bufpp]]></c> forward to point to the + <c>bufpp</c> and moves <c>bufpp</c> forward + to point to the next term in the buffer. On failure, each of the functions - returns NULL. - </p> + return <c>NULL</c>.</p> </desc> </func> + <func> <name><ret>int</ret><nametext>erl_encode(term, bufp)</nametext></name> <name><ret>int</ret><nametext>erl_encode_buf(term, bufpp)</nametext></name> - <fsummary>Converts a term into Erlang external format</fsummary> + <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><![CDATA[erl_encode()]]></c> and <c><![CDATA[erl_encode_buf()]]></c> encode + <p><c>erl_encode()</c> and + <c>erl_encode_buf()</c> encode Erlang terms into external format for storage or transmission. - <c><![CDATA[erl_encode_buf()]]></c> provides a simple mechanism for - encoding several terms consecutively in the same - buffer. - </p> - <p><c>term</c> is an Erlang term to be encoded. - </p> - <p><c>bufp</c> is a pointer to a buffer containing one or - more encoded Erlang terms. - </p> - <p><c>bufpp</c> is a pointer to a pointer to a buffer - containing one or more consecutively encoded Erlang terms. - Following a successful call to <c><![CDATA[erl_encode_buf()]]></c>, - <c>bufpp</c> will be updated so that it points to the - position for the next encoded term. - </p> - <p> - These functions returns the number of bytes written to buffer - if successful, otherwise returns 0. - </p> - <p>Note that no bounds checking is done on the buffer. It is - the caller's responsibility to make sure that the buffer is + <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><![CDATA[erl_term_len()]]></c> - to determine the exact requirements for a given term. - </p> + 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. Note that this information is - implementation specific, and may change in future versions. - If you are unsure, use <c><![CDATA[erl_term_len()]]></c>. - </p> + 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> + and then the data itself. Specifically:</p> <taglist> - <tag><c><![CDATA[Tuples]]></c></tag> - <item>need 5 bytes, plus the space for each element.</item> - <tag><c><![CDATA[Lists]]></c></tag> - <item>need 5 bytes, plus the space for each element, and 1 - additional byte for the empty list at the end.</item> - <tag><c><![CDATA[Strings and atoms]]></c></tag> - <item>need 3 bytes, plus 1 byte for each character (the - terminating 0 is not encoded). Really long strings (more - than 64k characters) are encoded as lists. Atoms cannot - contain more than 256 characters.</item> - <tag><c><![CDATA[Integers]]></c></tag> - <item>need 5 bytes.</item> - <tag><c><![CDATA[Characters]]></c></tag> - <item>(integers < 256) need 2 bytes.</item> - <tag><c><![CDATA[Floating point numbers]]></c></tag> - <item>need 32 bytes.</item> - <tag><c><![CDATA[Pids]]></c></tag> - <item>need 10 bytes, plus the space for the node name, which - is an atom.</item> - <tag><c><![CDATA[Ports and Refs]]></c></tag> - <item>need 6 bytes, plus the space for the node name, which - is an atom.</item> + <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 < 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 will be the result calculated - from the information above, plus 1 additional byte for a - version identifier. - </p> + <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><ret>int</ret><nametext>erl_ext_size(bufp)</nametext></name> - <fsummary>Counts elements in encoded term</fsummary> + <fsummary>Count elements in encoded term.</fsummary> <type> <v>unsigned char *bufp;</v> </type> <desc> - <p>This function returns the number of elements in an - encoded term.</p> + <p>Returns the number of elements in an encoded term.</p> </desc> </func> + <func> <name><ret>unsigned char</ret><nametext>erl_ext_type(bufp)</nametext></name> - <fsummary>Determines type of an encoded byte sequence</fsummary> + <fsummary>Determine type of an encoded byte sequence.</fsummary> <type> <v>unsigned char *bufp;</v> </type> <desc> - <p>This function identifies and returns the type of Erlang term encoded - in a buffer. It will skip a trailing <em>magic</em> identifier. - Returns <c><![CDATA[0]]></c> if the type can't be determined or one of</p> + <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> - <p>ERL_INTEGER</p> + <item><c>ERL_INTEGER</c> </item> - <item> - <p>ERL_ATOM</p> + <item><c>ERL_ATOM</c> </item> - <item> - <p>ERL_PID <c><![CDATA[/* Erlang process identifier */]]></c></p> + <item><c>ERL_PID</c> (Erlang process identifier) </item> - <item> - <p>ERL_PORT</p> + <item><c>ERL_PORT</c> </item> - <item> - <p>ERL_REF <c><![CDATA[/* Erlang reference */]]></c></p> + <item><c>ERL_REF</c> (Erlang reference) </item> - <item> - <p>ERL_EMPTY_LIST</p> + <item><c>ERL_EMPTY_LIST</c> </item> - <item> - <p>ERL_LIST</p> + <item><c>ERL_LIST</c> </item> - <item> - <p>ERL_TUPLE</p> + <item><c>ERL_TUPLE</c> </item> - <item> - <p>ERL_FLOAT</p> + <item><c>ERL_FLOAT</c> </item> - <item> - <p>ERL_BINARY</p> + <item><c>ERL_BINARY</c> </item> - <item> - <p>ERL_FUNCTION</p> + <item><c>ERL_FUNCTION</c> </item> </list> </desc> </func> + <func> <name><ret>unsigned char *</ret><nametext>erl_peek_ext(bufp, pos)</nametext></name> - <fsummary>Steps over encoded term</fsummary> + <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, in order to directly access a - later term. - </p> - <p><c><![CDATA[bufp]]></c> is a pointer to a buffer containing one or - more encoded Erlang terms. - </p> - <p><c><![CDATA[pos]]></c> indicates how many terms to step over in the - buffer. - </p> - <p>The function returns a pointer to a sub-term that can be - used in a subsequent call to <c><![CDATA[erl_decode()]]></c> in order to retrieve - the term at that position. If there is no term, or <c><![CDATA[pos]]></c> - would exceed the size of the terms in the buffer, NULL is returned. - </p> + 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><ret>int</ret><nametext>erl_term_len(t)</nametext></name> - <fsummary>Determines encoded size of term</fsummary> + <fsummary>Determine encoded size of term.</fsummary> <type> <v>ETERM *t;</v> </type> <desc> - <p>This function determines the buffer space that would be - needed by <c><![CDATA[t]]></c> if it were encoded into Erlang external - format by <c><![CDATA[erl_encode()]]></c>. - </p> - <p>The size in bytes is returned. - </p> + <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/fascicules.xml b/lib/erl_interface/doc/src/fascicules.xml deleted file mode 100644 index f7edd8a973..0000000000 --- a/lib/erl_interface/doc/src/fascicules.xml +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="utf-8" ?> -<!DOCTYPE fascicules SYSTEM "fascicules.dtd"> - -<fascicules> - <fascicule file="part_ei" href="part_ei_frame.html" entry="no"> - EI User's Guide - </fascicule> - <fascicule file="ref_man_ei" href="ref_man_ei_frame.html" entry="yes"> - EI Library Reference - </fascicule> - <fascicule file="ref_man_erl_interface" href="ref_man_erl_interface_frame.html" entry="no"> - Erl_interface Library Reference - </fascicule> - <fascicule file="ref_man" href="ref_man_frame.html" entry="no"> - Command Reference - </fascicule> - <fascicule file="part_notes" href="part_notes_frame.html" entry="no"> - Release Notes - </fascicule> - <fascicule file="" href="../../../../doc/print.html" entry="no"> - Off-Print - </fascicule> -</fascicules> - diff --git a/lib/erl_interface/doc/src/notes.xml b/lib/erl_interface/doc/src/notes.xml index 37266d9354..b5d8def655 100644 --- a/lib/erl_interface/doc/src/notes.xml +++ b/lib/erl_interface/doc/src/notes.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2004</year><year>2013</year> + <year>2004</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -31,6 +31,109 @@ </header> <p>This document describes the changes made to the Erl_interface application.</p> +<section><title>Erl_Interface 3.9.3</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Minor documentation update</p> + <p> + Own Id: OTP-14233 Aux Id: PR-1343 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erl_Interface 3.9.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fix <c>ei_connect_init</c> and <c>ei_connect_xinit</c> to + adjust the <c>creation</c> argument to be compatible with + nodes older than OTP-19.</p> + <p> + Own Id: OTP-13981</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Editorial documentation changes</p> + <p> + Own Id: OTP-13980</p> + </item> + </list> + </section> + +</section> + +<section><title>Erl_Interface 3.9.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Look for .erlang.cookie in windows system directory if + HOMEDRIVE and HOMEPATH is not set. The same behaviour as + the VM.</p> + <p> + Own Id: OTP-13849</p> + </item> + </list> + </section> + +</section> + +<section><title>Erl_Interface 3.9</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fix decoding of LLONG_MIN in erl_decode</p> + <p> + Own Id: OTP-13666 Aux Id: ERL-158 </p> + </item> + <item> + <p> + On windows <c>ei_decode_ulong</c> and + <c>ei_decode_long</c> now correctly returns an error when + trying to decode a number that does not fit in a long. + Fixed a bug on windows where enabling ei tracing would + cause a segmentation fault.</p> + <p> + Own Id: OTP-13673</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Handle terms (pids,ports and refs) from nodes with a + 'creation' value larger than 3. This is a preparation of + the distribution protocol to allow OTP 19 nodes to + correctly communicate with future nodes (20 or higher). + The 'creation' value differentiates different + incarnations of the same node (name).</p> + <p> + Own Id: OTP-13488</p> + </item> + </list> + </section> + +</section> + <section><title>Erl_Interface 3.8.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/erl_interface/doc/src/notes_history.xml b/lib/erl_interface/doc/src/notes_history.xml index f3cf8d01ae..c8cdc8832d 100644 --- a/lib/erl_interface/doc/src/notes_history.xml +++ b/lib/erl_interface/doc/src/notes_history.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2006</year><year>2013</year> + <year>2006</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/lib/erl_interface/doc/src/part.xml b/lib/erl_interface/doc/src/part.xml index ec598f0339..3b761df221 100644 --- a/lib/erl_interface/doc/src/part.xml +++ b/lib/erl_interface/doc/src/part.xml @@ -4,7 +4,7 @@ <part xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>2002</year><year>2013</year> + <year>2002</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -22,7 +22,7 @@ </legalnotice> - <title>EI User's Guide</title> + <title>Erl_Interface User's Guide</title> <prepared>Gordon Beaton</prepared> <docno></docno> <date>1998-11-30</date> diff --git a/lib/erl_interface/doc/src/part_erl_interface.xml b/lib/erl_interface/doc/src/part_erl_interface.xml index 08225133e0..e256cfa193 100644 --- a/lib/erl_interface/doc/src/part_erl_interface.xml +++ b/lib/erl_interface/doc/src/part_erl_interface.xml @@ -4,14 +4,14 @@ <part xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>1996</year><year>2013</year> + <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 @@ -19,7 +19,7 @@ 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> @@ -31,4 +31,3 @@ </header> <xi:include href="erl_interface.xml"/> </part> - diff --git a/lib/erl_interface/doc/src/part_notes.xml b/lib/erl_interface/doc/src/part_notes.xml index f2d5bd962b..facdf821ee 100644 --- a/lib/erl_interface/doc/src/part_notes.xml +++ b/lib/erl_interface/doc/src/part_notes.xml @@ -4,7 +4,7 @@ <part xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>2004</year><year>2013</year> + <year>2004</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/lib/erl_interface/doc/src/part_notes_history.xml b/lib/erl_interface/doc/src/part_notes_history.xml index 7cf1b25f54..401fea4dd4 100644 --- a/lib/erl_interface/doc/src/part_notes_history.xml +++ b/lib/erl_interface/doc/src/part_notes_history.xml @@ -4,7 +4,7 @@ <part xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>2006</year><year>2013</year> + <year>2006</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/lib/erl_interface/doc/src/ref_man.xml b/lib/erl_interface/doc/src/ref_man.xml index 2e115dba5b..1e20637cb7 100644 --- a/lib/erl_interface/doc/src/ref_man.xml +++ b/lib/erl_interface/doc/src/ref_man.xml @@ -4,14 +4,14 @@ <application xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>1998</year><year>2013</year> + <year>1998</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 @@ -19,9 +19,9 @@ 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 Command Reference</title> + <title>Erl_Interface Reference Manual</title> <prepared>Gordon Beaton</prepared> <docno></docno> <date>1998-11.30</date> @@ -29,17 +29,6 @@ <file>ref_man.xml</file> </header> <description> - <p>The <c>ei</c> and <c>erl_interface</c> are <c>C</c> interface libraries for - communication with <c>Erlang</c>.</p> - <note> - <p>By default, the <c>ei</c> and <c>erl_interface</c> libraries are only guaranteed - to be compatible with other Erlang/OTP components from the same - release as the libraries themself. See the documentation of the - <seealso marker="ei#ei_set_compat_rel">ei_set_compat_rel()</seealso> and - <seealso marker="erl_eterm#erl_set_compat_rel">erl_set_compat_rel()</seealso> - functions on how to communicate with Erlang/OTP components from earlier - releases.</p> - </note> </description> <xi:include href="ei.xml"/> <xi:include href="ei_connect.xml"/> @@ -53,4 +42,3 @@ <xi:include href="erl_marshal.xml"/> <xi:include href="erl_call.xml"/> </application> - diff --git a/lib/erl_interface/doc/src/ref_man_ei.xml b/lib/erl_interface/doc/src/ref_man_ei.xml index bbb2b402cd..92ff9ed328 100644 --- a/lib/erl_interface/doc/src/ref_man_ei.xml +++ b/lib/erl_interface/doc/src/ref_man_ei.xml @@ -4,14 +4,14 @@ <application xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>2002</year><year>2013</year> + <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 @@ -19,7 +19,7 @@ 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> @@ -30,12 +30,12 @@ <file>ref_man_ei.xml</file> </header> <description> - <p>The <c><![CDATA[ei]]></c> library is a <c><![CDATA[C]]></c> interface library for - communication with <c><![CDATA[Erlang]]></c>.</p> + <p>The <c>ei</c> library is a <c>C</c> interface library for + communication with <c>Erlang</c>.</p> <note> - <p>By default, the <c><![CDATA[ei]]></c> library is only guaranteed + <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><![CDATA[ei]]></c> library itself. See the documentation of the + 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> @@ -45,4 +45,3 @@ <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 index c5836c11c3..4b1d0e9981 100644 --- a/lib/erl_interface/doc/src/ref_man_erl_interface.xml +++ b/lib/erl_interface/doc/src/ref_man_erl_interface.xml @@ -4,14 +4,14 @@ <application xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>1996</year><year>2013</year> + <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 @@ -19,7 +19,7 @@ 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> @@ -50,4 +50,3 @@ <xi:include href="erl_malloc.xml"/> <xi:include href="erl_marshal.xml"/> </application> - diff --git a/lib/erl_interface/doc/src/registry.xml b/lib/erl_interface/doc/src/registry.xml index cd7e5d976d..6d70fb3475 100644 --- a/lib/erl_interface/doc/src/registry.xml +++ b/lib/erl_interface/doc/src/registry.xml @@ -4,14 +4,14 @@ <cref> <header> <copyright> - <year>1998</year><year>2013</year> + <year>1998</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 @@ -19,7 +19,7 @@ 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>registry</title> @@ -28,457 +28,585 @@ <docno></docno> <approved>Gordon Beaton</approved> <checked>Gordon Beaton</checked> - <date>980707</date> + <date>1998-07-07</date> <rev>A</rev> - <file>registry.sgml</file> + <file>registry.xml</file> </header> <lib>registry</lib> - <libsummary>Store and backup key-value pairs</libsummary> + <libsummary>Store and back up key-value pairs.</libsummary> <description> <p>This module provides support for storing key-value pairs in a table known as a registry, backing up registries to - Mnesia in an atomic manner, and later restoring the contents of a - registry from Mnesia.</p> + <seealso marker="mnesia:mnesia">Mnesia</seealso> + in an atomic manner, and later restoring the contents of a + registry from <c>Mnesia</c>.</p> </description> + <funcs> <func> - <name><ret>ei_reg *</ret><nametext>ei_reg_open(size)</nametext></name> - <fsummary>Create and open a registry</fsummary> + <name><ret>int</ret><nametext>ei_reg_close(reg)</nametext></name> + <fsummary>Close a registry.</fsummary> <type> - <v>int size;</v> + <v>ei_reg *reg;</v> </type> <desc> - <p>Open (create) a registry. The registry will be - initially empty. Use <c><![CDATA[ei_reg_close()]]></c> to close the registry - later. - </p> - <p><c><![CDATA[size]]></c> is the approximate number of objects you intend - to store in the registry. Since the registry uses a hash table - with collision chaining, there is no absolute upper limit on the - number of objects that can be stored in it. However for reasons - of efficiency, it is a good idea to choose a number that is - appropriate for your needs. It is possible to use - <c><![CDATA[ei_reg_resize()]]></c> to change the size later. Note that the - number you provide will be increased to the nearest larger prime - number. - </p> - <p>On success, an empty registry will be returned. On failure, NULL - will be returned.</p> + <p>A registry that has previously been created with + <c>ei_reg_open()</c> is closed, and all the objects it + contains are freed.</p> + <p><c>reg</c> is the registry to close.</p> + <p>Returns <c>0</c>.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_reg_resize(reg,newsize)</nametext></name> - <fsummary>Resize a registry</fsummary> + <name><ret>int</ret><nametext>ei_reg_delete(reg,key)</nametext></name> + <fsummary>Delete an object from the registry.</fsummary> <type> <v>ei_reg *reg;</v> - <v>int newsize;</v> + <v>const char *key;</v> </type> <desc> - <p>Change the size of a registry. - </p> - <p><c><![CDATA[newsize]]></c> is the new size to make the registry. The - number will be increased to the nearest larger prime number. - </p> - <p>On success, the registry will be resized, all contents - rehashed, and the function will return 0. On failure, the - registry will be left unchanged and the function will return -1.</p> + <p>Deletes an object from the registry. The object is not + removed from the registry, it is only marked for later + removal so that on later backups to <c>Mnesia</c>, the + corresponding object can be removed from the <c>Mnesia</c> table as + well. If another object is later created with the same key, the + object will be reused. </p> + <p>The object is removed from the registry after a call to + <c>ei_reg_dump()</c> or <c>ei_reg_purge()</c>. + </p> + <list type="bulleted"> + <item><c>reg</c> is the registry containing + <c>key</c>.</item> + <item><c>key</c> is the object to remove.</item> + </list> + <p>Returns <c>0</c> on success, otherwise <c>-1</c>.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_reg_close(reg)</nametext></name> - <fsummary>Close a registry </fsummary> + <name><ret>int</ret><nametext>ei_reg_dump(fd,reg,mntab,flags)</nametext></name> + <fsummary>Back up a registry to Mnesia.</fsummary> <type> + <v>int fd;</v> <v>ei_reg *reg;</v> + <v>const char *mntab;</v> + <v>int flags;</v> </type> <desc> - <p>A registry that has previously been created with - <c><![CDATA[ei_reg_open()]]></c> is closed, and all the objects it contains - are freed. - </p> - <p><c><![CDATA[reg]]></c> is the registry to close. - </p> - <p>The function returns 0.</p> + <p>Dumps the contents of a registry to a <c>Mnesia</c> table in an + atomic manner, that is, either all data or no data is updated. + If any errors are encountered while backing up + the data, the entire operation is aborted.</p> + <list type="bulleted"> + <item><c>fd</c> is an open connection to Erlang. + <c>Mnesia</c> 3.0 or later must be running on the Erlang node. + </item> + <item><c>reg</c> is the registry to back up.</item> + <item><c>mntab</c> is the name of the <c>Mnesia</c> table + where the backed up data is to be placed. If the table does not + exist, it is created automatically using configurable defaults. + For information about configuring this behavior, see + <seealso marker="mnesia:mnesia"><c>Mnesia</c></seealso>.</item> + </list> + <p>If <c>flags</c> is <c>0</c>, the backup includes only + those objects that have been created, modified, or deleted since the + last backup or restore (that is, an incremental backup). After the + backup, any objects that were marked dirty are now clean, and any + objects that had been marked for deletion are deleted.</p> + <p>Alternatively, setting flags to <c>EI_FORCE</c> causes a full + backup to be done, and <c>EI_NOPURGE</c> causes the deleted objects + to be left in the registry afterwards. These can be bitwise OR'ed + together if both behaviors are desired. If <c>EI_NOPURGE</c> was + specified, <c>ei_reg_purge()</c> can be used to + explicitly remove the deleted items from the registry later.</p> + <p>Returns <c>0</c> on success, otherwise <c>-1</c>.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_reg_setival(reg,key,i)</nametext></name> - <fsummary>Assign an integer object</fsummary> + <name><ret>double</ret><nametext>ei_reg_getfval(reg,key)</nametext></name> + <fsummary>Get a floating point object.</fsummary> <type> <v>ei_reg *reg;</v> <v>const char *key;</v> - <v>int i;</v> </type> <desc> - <p>Create a key-value pair with the specified <c><![CDATA[key]]></c> and integer - value <c><![CDATA[i]]></c>. If an object already existed with the same - <c><![CDATA[key]]></c>, the new value replaces the old one. If the previous - value was a binary or string, it is freed with <c><![CDATA[free()]]></c>. - </p> - <p><c><![CDATA[reg]]></c> is the registry where the object should be placed. - </p> - <p><c><![CDATA[key]]></c> is the name of the object. - </p> - <p><c><![CDATA[i]]></c> is the integer value to assign. - </p> - <p>The function returns 0 on success, or -1 on failure.</p> + <p>Gets the value associated with <c>key</c> in the + registry. The value must be a floating point type.</p> + <list type="bulleted"> + <item><c>reg</c> is the registry where the object will be + looked up.</item> + <item><c>key</c> is the name of the object to look up. + </item> + </list> + <p>On success, the function returns the value associated with + <c>key</c>. + If the object is not found or if it is not a floating point + object, <c>-1.0</c> is returned. To avoid problems with in-band error + reporting (that is, if you cannot distinguish between <c>-1.0</c> and + a valid result), use the more general function + <c>ei_reg_getval()</c> instead.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_reg_setfval(reg,key,f)</nametext></name> - <fsummary>Assign a floating point object</fsummary> + <name><ret>int</ret><nametext>ei_reg_getival(reg,key)</nametext></name> + <fsummary>Get an integer object.</fsummary> <type> <v>ei_reg *reg;</v> <v>const char *key;</v> - <v>double f;</v> </type> <desc> - <p>Create a key-value pair with the specified <c><![CDATA[key]]></c> and - floating point value <c><![CDATA[f]]></c>. If an object already existed with - the same <c><![CDATA[key]]></c>, the new value replaces the old one. If the - previous value was a binary or string, it is freed with <c><![CDATA[free()]]></c>. - </p> - <p><c><![CDATA[reg]]></c> is the registry where the object should be placed. - </p> - <p><c><![CDATA[key]]></c> is the name of the object. - </p> - <p><c><![CDATA[f]]></c> is the floating point value to assign. - </p> - <p>The function returns 0 on success, or -1 on failure.</p> + <p>Gets the value associated with <c>key</c> in the + registry. The value must be an integer.</p> + <list type="bulleted"> + <item><c>reg</c> is the registry where the object will be + looked up.</item> + <item><c>key</c> is the name of the object to look up. + </item> + </list> + <p>On success, the function returns the value associated with + <c>key</c>. + If the object is not found or if it is not an integer + object, <c>-1</c> is returned. To avoid problems with in-band error + reporting (that is, if you cannot distinguish between <c>-1</c> and a + valid result), use the more general function + <c>ei_reg_getval()</c> instead.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_reg_setsval(reg,key,s)</nametext></name> - <fsummary>Assign a string object</fsummary> + <name><ret>const void *</ret><nametext>ei_reg_getpval(reg,key,size)</nametext></name> + <fsummary>Get a binary object.</fsummary> <type> <v>ei_reg *reg;</v> <v>const char *key;</v> - <v>const char *s;</v> + <v>int size;</v> </type> <desc> - <p>Create a key-value pair with the specified <c><![CDATA[key]]></c> whose - "value" is the specified string <c><![CDATA[s]]></c>. If an object already - existed with the same <c><![CDATA[key]]></c>, the new value replaces the old - one. If the previous value was a binary or string, it is freed - with <c><![CDATA[free()]]></c>. - </p> - <p><c><![CDATA[reg]]></c> is the registry where the object should be placed. - </p> - <p><c><![CDATA[key]]></c> is the name of the object. - </p> - <p><c><![CDATA[s]]></c> is the string to assign. The string itself - must have been created through a single call to <c><![CDATA[malloc()]]></c> or - similar function, so that the registry can later delete it if - necessary by calling <c><![CDATA[free()]]></c>. - </p> - <p>The function returns 0 on success, or -1 on failure.</p> + <p>Gets the value associated with <c>key</c> in the + registry. The value must be a binary (pointer) type.</p> + <list type="bulleted"> + <item><c>reg</c> is the registry where the object will be + looked up.</item> + <item><c>key</c> is the name of the object to look up. + </item> + <item><c>size</c> is initialized to contain the length in + bytes of the object, if it is found.</item> + </list> + <p>On success, the function returns the value associated with + <c>key</c> and indicates its length in + <c>size</c>. + If the object is not found or if it is not a binary object, + <c>NULL</c> is returned. To avoid problems with in-band error + reporting (that is, if you cannot distinguish between <c>NULL</c> and + a valid result), use the more general function + <c>ei_reg_getval()</c> instead.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_reg_setpval(reg,key,p,size)</nametext></name> - <fsummary>Assign a binary object</fsummary> + <name><ret>const char *</ret><nametext>ei_reg_getsval(reg,key)</nametext></name> + <fsummary>Get a string object.</fsummary> <type> <v>ei_reg *reg;</v> <v>const char *key;</v> - <v>const void *p;</v> - <v>int size;</v> </type> <desc> - <p>Create a key-value pair with the specified <c><![CDATA[key]]></c> whose - "value" is the binary object pointed to by <c><![CDATA[p]]></c>. If an - object already existed with the same <c><![CDATA[key]]></c>, the new value - replaces the old one. If the previous value was a binary or - string, it is freed with <c><![CDATA[free()]]></c>. - </p> - <p><c><![CDATA[reg]]></c> is the registry where the object should be placed. - </p> - <p><c><![CDATA[key]]></c> is the name of the object. - </p> - <p><c><![CDATA[p]]></c> is a pointer to the binary object. The object itself - must have been created through a single call to <c><![CDATA[malloc()]]></c> or - similar function, so that the registry can later delete it if - necessary by calling <c><![CDATA[free()]]></c>. - </p> - <p><c><![CDATA[size]]></c> is the length in bytes of the binary object. - </p> - <p>The function returns 0 on success, or -1 on failure.</p> + <p>Gets the value associated with <c>key</c> in the + registry. The value must be a string.</p> + <list type="bulleted"> + <item><c>reg</c> is the registry where the object will be + looked up.</item> + <item><c>key</c> is the name of the object to look up. + </item> + </list> + <p>On success, the function returns the value associated with + <c>key</c>. If the object is not found or if it is not a + string, <c>NULL</c> is returned. To avoid problems with in-band error + reporting (that is, if you cannot distinguish between <c>NULL</c> and + a valid result), use the more general function + <c>ei_reg_getval()</c> instead.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_reg_setval(reg,key,flags,v,...)</nametext></name> - <fsummary>Assign a value to any object type</fsummary> + <name><ret>int</ret><nametext>ei_reg_getval(reg,key,flags,v,...)</nametext></name> + <fsummary>Get any object.</fsummary> <type> <v>ei_reg *reg;</v> <v>const char *key;</v> <v>int flags;</v> - <v>v (see below)</v> + <v>void *v (see below)</v> </type> <desc> - <p>Create a key-value pair with the specified <c><![CDATA[key]]></c> whose - value is specified by <c><![CDATA[v]]></c>. If an object already - existed with the same <c><![CDATA[key]]></c>, the new value replaces the old - one. If the previous value was a binary or string, it is freed - with <c><![CDATA[free()]]></c>. - </p> - <p><c><![CDATA[reg]]></c> is the registry where the object should be placed. - </p> - <p><c><![CDATA[key]]></c> is the name of the object. - </p> - <p><c><![CDATA[flags]]></c> indicates the type of the object specified by - <c><![CDATA[v]]></c>. Flags must be one of EI_INT, EI_FLT, EI_STR and - EI_BIN, indicating whether <c><![CDATA[v]]></c> is <c><![CDATA[int]]></c>, <c><![CDATA[double]]></c>, - <c><![CDATA[char*]]></c> or <c><![CDATA[void*]]></c>. If <c><![CDATA[flags]]></c> is EI_BIN, then a - fifth argument <c><![CDATA[size]]></c> is required, indicating the size - in bytes of the object pointed to by <c><![CDATA[v]]></c>. - </p> - <p>If you wish to store an arbitrary pointer in the registry, - specify a <c><![CDATA[size]]></c> of 0. In this case, the object itself will - not be transferred by an <c><![CDATA[ei_reg_dump()]]></c> operation, just - the pointer value. - </p> - <p>The function returns 0 on success, or -1 on failure.</p> + <p>A general function for retrieving any kind of + object from the registry.</p> + <list type="bulleted"> + <item> + <p><c>reg</c> is the registry where the object will be + looked up.</p> + </item> + <item> + <p><c>key</c> is the name of the object to look up.</p> + </item> + <item> + <p><c>flags</c> indicates the type of object that you + are looking for. If <c>flags</c> is <c>0</c>, any + kind of object is returned. + If <c>flags</c> is <c>EI_INT</c>, <c>EI_FLT</c>, + <c>EI_STR</c>, or <c>EI_BIN</c>, then only values of + that kind are returned.</p> + <p>The buffer pointed to by <c>v</c> + must be large enough to hold the return data, that is, it must be + a pointer to one of <c>int</c>, + <c>double</c>, <c>char*</c>, or + <c>void*</c>, respectively.</p> + <p>If <c>flags</c> is <c>EI_BIN</c>, a fifth argument + <c>int *size</c> is required, so that the size of the + object can be returned.</p> + </item> + </list> + <p>On success, <c>v</c> (and <c>size</c> if the + object is binary) is initialized with the value associated + with <c>key</c>, and the function returns <c>EI_INT</c>, + <c>EI_FLT</c>, <c>EI_STR</c>, or <c>EI_BIN</c>, indicating the type + of object. On failure, <c>-1</c> is returned and the + arguments are not updated.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_reg_getival(reg,key)</nametext></name> - <fsummary>Get an integer object</fsummary> + <name><ret>int</ret><nametext>ei_reg_markdirty(reg,key)</nametext></name> + <fsummary>Mark an object as dirty.</fsummary> <type> <v>ei_reg *reg;</v> <v>const char *key;</v> </type> <desc> - <p>Get the value associated with <c><![CDATA[key]]></c> in the - registry. The value must be an integer. - </p> - <p><c><![CDATA[reg]]></c> is the registry where the object will be looked - up. - </p> - <p><c><![CDATA[key]]></c> is the name of the object to look up. - </p> - <p>On success, the function returns the value associated with <c><![CDATA[key]]></c>. - If the object was not found or it was not an integer - object, -1 is returned. To avoid problems with in-band error - reporting (i.e. if you cannot distinguish between -1 and a - valid result) use the more general function <c><![CDATA[ei_reg_getval()]]></c> - instead.</p> + <p>Marks a registry object as dirty. This ensures that + it is included in the next backup to <c>Mnesia</c>. Normally this + operation is not necessary, as all of the normal registry + 'set' functions do this automatically. However, if you have + retrieved the value of a string or binary object from the + registry and modified the contents, then the change is + invisible to the registry and the object is assumed to be + unmodified. This function allows you to make such modifications + and then let the registry know about them.</p> + <list type="bulleted"> + <item><c>reg</c> is the registry containing the object. + </item> + <item><c>key</c> is the name of the object to mark. + </item> + </list> + <p>Returns <c>0</c> on success, otherwise <c>-1</c>.</p> </desc> </func> + <func> - <name><ret>double</ret><nametext>ei_reg_getfval(reg,key)</nametext></name> - <fsummary>Get a floating point object</fsummary> + <name><ret>ei_reg *</ret><nametext>ei_reg_open(size)</nametext></name> + <fsummary>Create and open a registry.</fsummary> + <type> + <v>int size;</v> + </type> + <desc> + <p>Opens (creates) a registry, which initially is empty. To + close the registry later, use <c>ei_reg_close()</c>.</p> + <p><c>size</c> is the approximate number of objects you + intend to store in the registry. As the registry uses a hash table + with collision chaining, no absolute upper limit exists on the + number of objects that can be stored in it. However, for reasons + of efficiency, it is a good idea to choose a number that is + appropriate for your needs. To change the size later, use + <c>ei_reg_resize()</c>. Notice that the number + you provide is increased to the nearest larger prime number.</p> + <p>Returns an empty registry on success, otherwise <c>NULL</c>.</p> + </desc> + </func> + + <func> + <name><ret>int</ret><nametext>ei_reg_purge(reg)</nametext></name> + <fsummary>Remove deleted objects.</fsummary> <type> <v>ei_reg *reg;</v> - <v>const char *key;</v> </type> <desc> - <p>Get the value associated with <c><![CDATA[key]]></c> in the - registry. The value must be a floating point type. - </p> - <p><c><![CDATA[reg]]></c> is the registry where the object will be looked - up. - </p> - <p><c><![CDATA[key]]></c> is the name of the object to look up. - </p> - <p>On success, the function returns the value associated with <c><![CDATA[key]]></c>. - If the object was not found or it was not a floating point - object, -1.0 is returned. To avoid problems with in-band error - reporting (i.e. if you cannot distinguish between -1.0 and a - valid result) use the more general function <c><![CDATA[ei_reg_getval()]]></c> - instead.</p> + <p>Removes all objects marked for deletion. When objects + are deleted with <c>ei_reg_delete()</c> they are not + removed from the registry, only marked for later removal. + On a later backup to <c>Mnesia</c>, the + objects can also be removed from the <c>Mnesia</c> table. If you are + not backing up to <c>Mnesia</c>, you may wish to remove the objects + manually with this function.</p> + <p><c>reg</c> is a registry containing objects marked for + deletion.</p> + <p>Returns <c>0</c> on success, otherwise <c>-1</c>.</p> </desc> </func> + <func> - <name><ret>const char *</ret><nametext>ei_reg_getsval(reg,key)</nametext></name> - <fsummary>Get a string object</fsummary> + <name><ret>int</ret><nametext>ei_reg_resize(reg,newsize)</nametext></name> + <fsummary>Resize a registry.</fsummary> + <type> + <v>ei_reg *reg;</v> + <v>int newsize;</v> + </type> + <desc> + <p>Changes the size of a registry.</p> + <p><c>newsize</c> is the new size to make the registry. The + number is increased to the nearest larger prime number.</p> + <p>On success, the registry is resized, all contents + rehashed, and <c>0</c> is returned. On failure, the + registry is left unchanged and <c>-1</c> is returned.</p> + </desc> + </func> + + <func> + <name><ret>int</ret><nametext>ei_reg_restore(fd,reg,mntab)</nametext></name> + <fsummary>Restore a registry from Mnesia.</fsummary> + <type> + <v>int fd;</v> + <v>ei_reg *reg;</v> + <v>const char *mntab;</v> + </type> + <desc> + <p>The contents of a <c>Mnesia</c> table are read into the registry.</p> + <list type="bulleted"> + <item><c>fd</c> is an open connection to Erlang. + <c>Mnesia</c> 3.0 or later must be running on the Erlang node. + </item> + <item><c>reg</c> is the registry where the data is to be + placed.</item> + <item><c>mntab</c> is the name of the <c>Mnesia</c> table + to read data from.</item> + </list> + <p>Notice that only tables of a certain format can be + restored, that is, those that have been created and backed up to + with <c>ei_reg_dump()</c>. If the registry was not empty + before the operation, the contents of the table are added to the + contents of the registry. If the table contains objects with the + same keys as those already in the registry, the registry objects + are overwritten with the new values. If the registry + contains objects that were not in the table, they are + unchanged by this operation.</p> + <p>After the restore operation, the entire contents of the + registry is marked as unmodified. Notice that this includes any + objects that were modified before the restore and not + overwritten by the restore.</p> + <p>Returns <c>0</c> on success, otherwise <c>-1</c>.</p> + </desc> + </func> + + <func> + <name><ret>int</ret><nametext>ei_reg_setfval(reg,key,f)</nametext></name> + <fsummary>Assign a floating point object.</fsummary> <type> <v>ei_reg *reg;</v> <v>const char *key;</v> + <v>double f;</v> </type> <desc> - <p>Get the value associated with <c><![CDATA[key]]></c> in the - registry. The value must be a string. - </p> - <p><c><![CDATA[reg]]></c> is the registry where the object will be looked - up. - </p> - <p><c><![CDATA[key]]></c> is the name of the object to look up. - </p> - <p>On success, the function returns the value associated with - <c><![CDATA[key]]></c>. If the object was not found or it was not a string, - NULL is returned. To avoid problems with in-band error - reporting (i.e. if you cannot distinguish between NULL and a - valid result) use the more general function <c><![CDATA[ei_reg_getval()]]></c> - instead.</p> + <p>Creates a key-value pair with the specified <c>key</c> + and floating point value <c>f</c>. If an object already + exists with the same <c>key</c>, the new value replaces + the old one. If the previous value was a binary or string, it is + freed with <c>free()</c>.</p> + <list type="bulleted"> + <item><c>reg</c> is the registry where the object is to be + placed.</item> + <item><c>key</c> is the object name.</item> + <item><c>f</c> is the floating point value to assign. + </item> + </list> + <p>Returns <c>0</c> on success, otherwise <c>-1</c>.</p> </desc> </func> + <func> - <name><ret>const void *</ret><nametext>ei_reg_getpval(reg,key,size)</nametext></name> - <fsummary>Get a binary object</fsummary> + <name><ret>int</ret><nametext>ei_reg_setival(reg,key,i)</nametext></name> + <fsummary>Assign an integer object.</fsummary> <type> <v>ei_reg *reg;</v> <v>const char *key;</v> - <v>int size;</v> + <v>int i;</v> </type> <desc> - <p>Get the value associated with <c><![CDATA[key]]></c> in the - registry. The value must be a binary (pointer) type. - </p> - <p><c><![CDATA[reg]]></c> is the registry where the object will be looked - up. - </p> - <p><c><![CDATA[key]]></c> is the name of the object to look up. - </p> - <p><c><![CDATA[size]]></c> will be initialized to contain the length in - bytes of the object, if it is found. - </p> - <p>On success, the function returns the value associated with - <c><![CDATA[key]]></c> and indicates its length in <c><![CDATA[size]]></c>. - If the object was not found or it was not a binary object, - NULL is returned. To avoid problems with in-band error - reporting (i.e. if you cannot distinguish between NULL and a - valid result) use the more general function <c><![CDATA[ei_reg_getval()]]></c> - instead.</p> + <p>Creates a key-value pair with the specified <c>key</c> + and integer value <c>i</c>. If an object already exists + with the same <c>key</c>, the new value replaces the old + one. If the previous value was a binary or string, it is freed with + <c>free()</c>.</p> + <list type="bulleted"> + <item><c>reg</c> is the registry where the object is to be + placed.</item> + <item><c>key</c> is the object name.</item> + <item><c>i</c> is the integer value to assign.</item> + </list> + <p>Returns <c>0</c> on success, otherwise <c>-1</c>.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_reg_getval(reg,key,flags,v,...)</nametext></name> - <fsummary>Get any object</fsummary> + <name><ret>int</ret><nametext>ei_reg_setpval(reg,key,p,size)</nametext></name> + <fsummary>Assign a binary object.</fsummary> <type> <v>ei_reg *reg;</v> <v>const char *key;</v> - <v>int flags;</v> - <v>void *v (see below)</v> + <v>const void *p;</v> + <v>int size;</v> </type> <desc> - <p>This is a general function for retrieving any kind of - object from the registry. - </p> - <p><c><![CDATA[reg]]></c> is the registry where the object will be looked - up. - </p> - <p><c><![CDATA[key]]></c> is the name of the object to look up. - </p> - <p><c><![CDATA[flags]]></c> indicates the type of object that you are - looking for. If <c><![CDATA[flags]]></c> is 0, then any kind of object will - be returned. If <c><![CDATA[flags]]></c> is one of EI_INT, EI_FLT, EI_STR or - EI_BIN, then only values of that kind will be returned. The - buffer pointed to by <c><![CDATA[v]]></c> must be large enough to hold the return - data, i.e. it must be a pointer to one of <c><![CDATA[int]]></c>, - <c><![CDATA[double]]></c>, <c><![CDATA[char*]]></c> or <c><![CDATA[void*]]></c>, respectively. Also, - if <c><![CDATA[flags]]></c> is EI_BIN, then a fifth argument <c><![CDATA[int *size]]></c> is required, so that the size of the object can be - returned. - </p> - <p>If the function succeeds, <c><![CDATA[v]]></c> (and <c><![CDATA[size]]></c> if the - object is binary) will be initialized with the value associated - with <c><![CDATA[key]]></c>, and the function will return one of EI_INT, - EI_FLT, EI_STR or EI_BIN, indicating the type of object. On failure the - function will return -1 and the arguments will not be updated.</p> + <p>Creates a key-value pair with the specified <c>key</c> + whose "value" is the binary object pointed to by <c>p</c>. + If an object already exists with the same <c>key</c>, + the new value replaces the old one. If the previous value was a + binary or string, it is freed with <c>free()</c>.</p> + <list type="bulleted"> + <item><c>reg</c> is the registry where the object is to be + placed.</item> + <item><c>key</c> is the object name.</item> + <item><c>p</c> is a pointer to the binary object. The + object itself must have been created through a single call to + <c>malloc()</c> or a similar function, so that the + registry can later delete it if necessary by calling + <c>free()</c>.</item> + <item><c>size</c> is the length in bytes of the binary + object.</item> + </list> + <p>Returns <c>0</c> on success, otherwise <c>-1</c>.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_reg_markdirty(reg,key)</nametext></name> - <fsummary>Mark an object as dirty </fsummary> + <name><ret>int</ret><nametext>ei_reg_setsval(reg,key,s)</nametext></name> + <fsummary>Assign a string object.</fsummary> <type> <v>ei_reg *reg;</v> <v>const char *key;</v> + <v>const char *s;</v> </type> <desc> - <p>Mark a registry object as dirty. This will ensure that - it is included in the next backup to Mnesia. Normally this - operation will not be necessary since all of the normal registry - 'set' functions do this automatically. However if you have - retrieved the value of a string or binary object from the - registry and modified the contents, then the change will be - invisible to the registry and the object will be assumed to be - unmodified. This function allows you to make such modifications - and then let the registry know about them. - </p> - <p><c><![CDATA[reg]]></c> is the registry containing the object. - </p> - <p><c><![CDATA[key]]></c> is the name of the object to mark. - </p> - <p>The function returns 0 on success, or -1 on failure.</p> + <p>Creates a key-value pair with the specified <c>key</c> + whose "value" is the specified string <c>s</c>. If an + object already exists with the same <c>key</c>, the new + value replaces the old one. If the previous value was a binary or + string, it is freed with <c>free()</c>.</p> + <list type="bulleted"> + <item><c>reg</c> is the registry where the object is to be + placed.</item> + <item><c>key</c> is the object name.</item> + <item><c>s</c> is the string to assign. The string itself + must have been created through a single call to + <c>malloc()</c> or similar a function, + so that the registry can later delete it if + necessary by calling <c>free()</c>.</item> + </list> + <p>Returns <c>0</c> on success, otherwise <c>-1</c>.</p> </desc> </func> + <func> - <name><ret>int</ret><nametext>ei_reg_delete(reg,key)</nametext></name> - <fsummary>Delete an object from the registry</fsummary> + <name><ret>int</ret><nametext>ei_reg_setval(reg,key,flags,v,...)</nametext></name> + <fsummary>Assign a value to any object type.</fsummary> <type> <v>ei_reg *reg;</v> <v>const char *key;</v> + <v>int flags;</v> + <v>v (see below)</v> </type> <desc> - <p>Delete an object from the registry. The object is not - actually removed from the registry, it is only marked for later - removal so that on subsequent backups to Mnesia, the - corresponding object can be removed from the Mnesia table as - well. If another object is later created with the same key, the - object will be reused. - </p> - <p>The object will be removed from the registry after a call to - <c><![CDATA[ei_reg_dump()]]></c> or <c><![CDATA[ei_reg_purge()]]></c>. - </p> - <p><c><![CDATA[reg]]></c> is the registry containing <c><![CDATA[key]]></c>. - </p> - <p><c><![CDATA[key]]></c> is the object to remove. - </p> - <p>If the object was found, the function returns 0 indicating - success. Otherwise the function returns -1.</p> + <p>Creates a key-value pair with the specified <c>key</c> + whose value is specified by <c>v</c>. If an object already + exists with the same <c>key</c>, the new value replaces + the old one. If the previous value was a binary or string, it is freed + with <c>free()</c>.</p> + <list type="bulleted"> + <item> + <p><c>reg</c> is the registry where the object is to be + placed.</p> + </item> + <item> + <p><c>key</c> is the object name.</p> + </item> + <item> + <p><c>flags</c> indicates the type of the object + specified by <c>v</c>. Flags must be one of + <c>EI_INT</c>, <c>EI_FLT</c>, <c>EI_STR</c>, and <c>EI_BIN</c>, + indicating whether + <c>v</c> is <c>int</c>, + <c>double</c>, <c>char*</c>, or + <c>void*</c>.</p> + <p>If <c>flags</c> is <c>EI_BIN</c>, a fifth argument + <c>size</c> is required, indicating the size + in bytes of the object pointed to by <c>v</c>.</p> + </item> + </list> + <p>If you wish to store an arbitrary pointer in the registry, + specify a <c>size</c> of <c>0</c>. In this case, the + object itself is not transferred by an + <c>ei_reg_dump()</c> operation, only the pointer + value.</p> + <p>Returns <c>0</c> on success, otherwise <c>-1</c>.</p> </desc> </func> + <func> <name><ret>int</ret><nametext>ei_reg_stat(reg,key,obuf)</nametext></name> - <fsummary>Get object information</fsummary> + <fsummary>Get object information.</fsummary> <type> <v>ei_reg *reg;</v> <v>const char *key;</v> <v>struct ei_reg_stat *obuf;</v> </type> <desc> - <p>Return information about an object. - </p> - <p><c><![CDATA[reg]]></c> is the registry containing the object. - </p> - <p><c><![CDATA[key]]></c> is the name of the object. - </p> - <p><c><![CDATA[obuf]]></c> is a pointer to an <c><![CDATA[ei_reg_stat]]></c> structure, - defined below: - </p> + <p>Returns information about an object.</p> + <list type="bulleted"> + <item><c>reg</c> is the registry containing the object. + </item> + <item><c>key</c> is the object name.</item> + <item><c>obuf</c> is a pointer to an + <c>ei_reg_stat</c> structure, defined as follows:</item> + </list> <code type="none"><![CDATA[ struct ei_reg_stat { int attr; int size; }; ]]></code> - <p>In <c><![CDATA[attr]]></c> the object's attributes are stored as the logical - OR of its type (one of EI_INT, EI_FLT, EI_BIN and EI_STR), - whether it is marked for deletion (EI_DELET) and whether it has - been modified since the last backup to Mnesia (EI_DIRTY). - </p> - <p>The <c><![CDATA[size]]></c> field indicates the size in bytes required to store - EI_STR (including the terminating 0) and EI_BIN objects, or 0 - for EI_INT and EI_FLT. - </p> - <p>The function returns 0 and initializes <c><![CDATA[obuf]]></c> on - success, or returns -1 on failure.</p> + <p>In <c>attr</c> the attributes of the object are stored + as the logical <em>OR</em> of its type (one of <c>EI_INT</c>, + <c>EI_FLT</c>, <c>EI_BIN</c>, and <c>EI_STR</c>), + whether it is marked for deletion (<c>EI_DELET</c>), and whether it + has been modified since the last backup to <c>Mnesia</c> + (<c>EI_DIRTY</c>).</p> + <p>Field <c>size</c> indicates the size in bytes required + to store <c>EI_STR</c> (including the terminating <c>0</c>) and + <c>EI_BIN</c> objects, or <c>0</c> for <c>EI_INT</c> and + <c>EI_FLT</c>.</p> + <p>Returns <c>0</c> and initializes <c>obuf</c> on success, + otherwise <c>-1</c>.</p> </desc> </func> + <func> <name><ret>int</ret><nametext>ei_reg_tabstat(reg,obuf)</nametext></name> - <fsummary>Get registry information</fsummary> + <fsummary>Get registry information.</fsummary> <type> <v>ei_reg *reg;</v> <v>struct ei_reg_tabstat *obuf;</v> </type> <desc> - <p>Return information about a registry. Using information + <p>Returns information about a registry. Using information returned by this function, you can see whether the size of the - registry is suitable for the amount of data it contains. - </p> - <p><c><![CDATA[reg]]></c> is the registry to return information about. - </p> - <p><c><![CDATA[obuf]]></c> is a pointer to an <c><![CDATA[ei_reg_tabstat]]></c> structure, - defined below: - </p> + registry is suitable for the amount of data it contains.</p> + <list type="bulleted"> + <item><c>reg</c> is the registry to return information + about.</item> + <item><c>obuf</c> is a pointer to an + <c>ei_reg_tabstat</c> structure, defined as follows: + </item> + </list> <code type="none"><![CDATA[ struct ei_reg_tabstat { int size; @@ -487,126 +615,23 @@ struct ei_reg_tabstat { int collisions; }; ]]></code> - <p>The <c><![CDATA[size]]></c> field indicates the number of hash positions + <p>Field <c>size</c> indicates the number of hash positions in the registry. This is the number you provided when you created or last resized the registry, rounded up to the nearest - prime. - </p> - <p><c><![CDATA[nelem]]></c> indicates the number of elements stored in the - registry. It includes objects that are deleted but not purged. - </p> - <p><c><![CDATA[npos]]></c> indicates the number of unique positions that are - occupied in the registry. - </p> - <p><c><![CDATA[collisions]]></c> indicates how many elements are sharing - positions in the registry. - </p> - <p>On success, the function returns 0 and <c><![CDATA[obuf]]></c> is - initialized to contain table statistics. On failure, the function - returns -1.</p> - </desc> - </func> - <func> - <name><ret>int</ret><nametext>ei_reg_dump(fd,reg,mntab,flags)</nametext></name> - <fsummary>Back up a registry to Mnesia</fsummary> - <type> - <v>int fd;</v> - <v>ei_reg *reg;</v> - <v>const char *mntab;</v> - <v>int flags;</v> - </type> - <desc> - <p>Dump the contents of a registry to a Mnesia table in an - atomic manner, i.e. either all data will be updated, or none of - it will. If any errors are encountered while backing up - the data, the entire operation is aborted. - </p> - <p><c><![CDATA[fd]]></c> is an open connection to Erlang. - Mnesia 3.0 or later must be running on the Erlang node. - </p> - <p><c><![CDATA[reg]]></c> is the registry to back up. - </p> - <p><c><![CDATA[mntab]]></c> is the name of the Mnesia table where the backed - up data should be placed. If the table does not exist, it will - be created automatically using configurable defaults. See your - Mnesia documentation for information about configuring this - behaviour. - </p> - <p>If <c><![CDATA[flags]]></c> is 0, the backup will include only those - objects which have been created, modified or deleted since the - last backup or restore (i.e. an incremental backup). After the - backup, any objects that were marked dirty are now clean, and any - objects that had been marked for deletion are deleted. - </p> - <p>Alternatively, setting flags to EI_FORCE will cause a full - backup to be done, and EI_NOPURGE will cause the deleted objects - to be left in the registry afterwards. These can be bitwise ORed - together if both behaviours are desired. If EI_NOPURGE was - specified, you can use <c><![CDATA[ei_reg_purge()]]></c> to explicitly remove - the deleted items from the registry later. - </p> - <p>The function returns 0 on success, or -1 on failure.</p> - </desc> - </func> - <func> - <name><ret>int</ret><nametext>ei_reg_restore(fd,reg,mntab)</nametext></name> - <fsummary>Restore a registry from Mnesia</fsummary> - <type> - <v>int fd;</v> - <v>ei_reg *reg;</v> - <v>const char *mntab;</v> - </type> - <desc> - <p>The contents of a Mnesia table are read into the - registry. - </p> - <p><c><![CDATA[fd]]></c> is an open connection to Erlang. - Mnesia 3.0 or later must be running on the Erlang node. - </p> - <p><c><![CDATA[reg]]></c> is the registry where the data should be placed. - </p> - <p><c><![CDATA[mntab]]></c> is the name of the Mnesia table to read data - from. - </p> - <p>Note that only tables of a certain format can be - restored, i.e. those that have been created and backed up to - with <c><![CDATA[ei_reg_dump()]]></c>. If the registry was not empty before - the operation, then the contents of the table are added to the - contents of the registry. If the table contains objects with the - same keys as those already in the registry, the registry objects - will be overwritten with the new values. If the registry - contains objects that were not in the table, they will be - unchanged by this operation. - </p> - <p>After the restore operation, the entire contents of the - registry is marked as unmodified. Note that this includes any - objects that were modified before the restore and not - overwritten by the restore. - </p> - <p>The function returns 0 on success, or -1 on failure.</p> - </desc> - </func> - <func> - <name><ret>int</ret><nametext>ei_reg_purge(reg)</nametext></name> - <fsummary>Remove deleted objects</fsummary> - <type> - <v>ei_reg *reg;</v> - </type> - <desc> - <p>Remove all objects marked for deletion. When objects - are deleted with <c><![CDATA[ei_reg_delete()]]></c> they are not actually - removed from the registry, only marked for later removal. This - is so that on a subsequent backup to Mnesia, the - objects can also be removed from the Mnesia table. If you are - not backing up to Mnesia then you may wish to remove the objects - manually with this function. - </p> - <p><c><![CDATA[reg]]></c> is a registry containing objects marked for - deletion. - </p> - <p>The function returns 0 on success, or -1 on failure.</p> + prime number.</p> + <list type="bulleted"> + <item><c>nelem</c> indicates the number of elements stored + in the registry. It includes objects that are deleted but not + purged.</item> + <item><c>npos</c> indicates the number of unique positions + that are occupied in the registry.</item> + <item><c>collisions</c> indicates how many elements are + sharing positions in the registry.</item> + </list> + <p>On success, <c>0</c> is returned and + <c>obuf</c> is initialized to contain table statistics, + otherwise <c>-1</c> is returned.</p> </desc> </func> </funcs> </cref> - diff --git a/lib/erl_interface/include/ei.h b/lib/erl_interface/include/ei.h index c1dbc8470d..948f89be85 100644 --- a/lib/erl_interface/include/ei.h +++ b/lib/erl_interface/include/ei.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2014. All Rights Reserved. + * 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. @@ -121,8 +121,11 @@ #define ERL_SMALL_ATOM_UTF8_EXT 'w' #define ERL_REFERENCE_EXT 'e' #define ERL_NEW_REFERENCE_EXT 'r' +#define ERL_NEWER_REFERENCE_EXT 'Z' #define ERL_PORT_EXT 'f' +#define ERL_NEW_PORT_EXT 'Y' #define ERL_PID_EXT 'g' +#define ERL_NEW_PID_EXT 'X' #define ERL_SMALL_TUPLE_EXT 'h' #define ERL_LARGE_TUPLE_EXT 'i' #define ERL_NIL_EXT 'j' diff --git a/lib/erl_interface/include/ei_connect.h b/lib/erl_interface/include/ei_connect.h index c8eeba7ae0..825fee0165 100644 --- a/lib/erl_interface/include/ei_connect.h +++ b/lib/erl_interface/include/ei_connect.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2003-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/include/eicode.h b/lib/erl_interface/include/eicode.h index 1077528d3c..efba630d13 100644 --- a/lib/erl_interface/include/eicode.h +++ b/lib/erl_interface/include/eicode.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2003-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/include/erl_interface.h b/lib/erl_interface/include/erl_interface.h index 3f9804da7d..c22f21af2b 100644 --- a/lib/erl_interface/include/erl_interface.h +++ b/lib/erl_interface/include/erl_interface.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2013. All Rights Reserved. + * 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. @@ -211,14 +211,14 @@ typedef struct { Erl_Atom_data node; unsigned int number; unsigned int serial; - unsigned char creation; + unsigned int creation; } Erl_Pid; typedef struct { Erl_Header h; Erl_Atom_data node; unsigned int number; - unsigned char creation; + unsigned int creation; } Erl_Port; typedef struct { @@ -226,7 +226,7 @@ typedef struct { Erl_Atom_data node; int len; unsigned int n[3]; - unsigned char creation; + unsigned int creation; } Erl_Ref; typedef struct { diff --git a/lib/erl_interface/src/Makefile b/lib/erl_interface/src/Makefile index 868407a23f..31f34d4bba 100644 --- a/lib/erl_interface/src/Makefile +++ b/lib/erl_interface/src/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1996-2013. All Rights Reserved. +# 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. diff --git a/lib/erl_interface/src/Makefile.in b/lib/erl_interface/src/Makefile.in index 777d709b1e..4f393e952c 100644 --- a/lib/erl_interface/src/Makefile.in +++ b/lib/erl_interface/src/Makefile.in @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1997-2012. All Rights Reserved. +# 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. @@ -126,11 +126,7 @@ else WARNFLAGS = @WFLAGS@ endif -ifneq ($(findstring ose,$(TARGET)),ose) CFLAGS = @LIB_CFLAGS@ $(WARNFLAGS) $(INCFLAGS) $(TYPE_FLAGS) -else -CFLAGS = @CFLAGS@ $(INCFLAGS) -endif PROG_CFLAGS = @CFLAGS@ $(WARNFLAGS) $(INCFLAGS) $(TYPE_FLAGS) -Ilegacy ifeq ($(findstring vxworks,$(TARGET)),vxworks) @@ -210,12 +206,8 @@ MDD_ERLLIB = $(OBJDIR)/$(LIBPRE)erl_interface_mdd$(LIBEXT) # Specify targets to build ########################################################################### -ifneq ($(findstring ose,$(TARGET)),ose) EXE_TARGETS = \ $(ERL_CALL) -else -EXE_TARGETS = -endif ifeq ($(USING_VC),yes) @@ -480,44 +472,6 @@ ERLSOURCES = \ SOURCES = $(EISOURCES) $(ERLSOURCES) -OSE_EISOURCES = \ - $(DECODESRC) \ - $(ENCODESRC) \ - misc/ei_decode_term.c \ - misc/ei_format.c \ - misc/ei_locking.c \ - misc/ei_malloc.c \ - misc/ei_printterm.c \ - misc/ei_pthreads.c \ - misc/ei_trace.c \ - misc/ei_x_encode.c \ - misc/eimd5.c \ - misc/get_type.c \ - misc/show_msg.c \ - misc/ei_compat.c \ - registry/hash_dohash.c \ - registry/hash_foreach.c \ - registry/hash_freetab.c \ - registry/hash_insert.c \ - registry/hash_isprime.c \ - registry/hash_lookup.c \ - registry/hash_newtab.c \ - registry/hash_remove.c \ - registry/hash_resize.c \ - registry/hash_rlookup.c - -OSE_ERLSOURCES = \ - legacy/decode_term.c \ - legacy/encode_term.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 - -OSE_SOURCES = $(OSE_EISOURCES) $(OSE_ERLSOURCES) - NEVERUSED = \ whereis.c \ ei_send.c \ @@ -532,13 +486,8 @@ ERLCALL = \ # Note that encode/decode_term.c defines ei functions that is # located in the erl_interface library, not ei library. -ifneq ($(findstring ose,$(TARGET)),ose) ST_EIOBJECTS = $(addprefix $(ST_OBJDIR)/,$(notdir $(EISOURCES:.c=.o))) ST_ERLOBJECTS = $(addprefix $(ST_OBJDIR)/,$(notdir $(ERLSOURCES:.c=.o))) -else -ST_EIOBJECTS = $(addprefix $(ST_OBJDIR)/,$(notdir $(OSE_EISOURCES:.c=.o))) -ST_ERLOBJECTS = $(addprefix $(ST_OBJDIR)/,$(notdir $(OSE_ERLSOURCES:.c=.o))) -endif 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))) @@ -587,14 +536,6 @@ $(TARGET)/config.h: $(V_at)echo "#define HAVE_SOCKLEN_T 1" >> $@ endif -ifeq ($(findstring ose,$(TARGET)),ose) -$(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 ########################################################################### @@ -719,9 +660,6 @@ $(ST_OBJDIR)/erl_start.o: prog/erl_start.c $(V_CC) $(CFLAGS) -c $< -o $@ else -ifeq ($(findstring ose,$(TARGET)),ose) -$(ERL_CALL): -else ifdef THR_DEFS $(ERL_CALL): $(ERLCALL) ../include/ei.h $(MT_EILIB) $(ld_verbose)$(PURIFY) $(CC) $(PROG_CFLAGS) $(THR_DEFS) $(LDFLAGS) -o $@ $(ERLCALL) \ @@ -733,7 +671,6 @@ $(ERL_CALL): $(ERLCALL) ../include/ei.h $(ST_EILIB) endif endif endif -endif ########################################################################### # Fake application targets used to test header files and linking diff --git a/lib/erl_interface/src/connect/ei_connect.c b/lib/erl_interface/src/connect/ei_connect.c index 7b1b2810bb..c193fd804a 100644 --- a/lib/erl_interface/src/connect/ei_connect.c +++ b/lib/erl_interface/src/connect/ei_connect.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2000-2014. All Rights Reserved. + * 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. @@ -423,7 +423,7 @@ int ei_connect_xinit(ei_cnode* ec, const char *thishostname, } #endif /* _REENTRANT */ - ec->creation = creation; + ec->creation = creation & 0x3; /* 2 bits */ if (cookie) { if (strlen(cookie) >= sizeof(ec->ei_connect_cookie)) { @@ -462,7 +462,7 @@ int ei_connect_xinit(ei_cnode* ec, const char *thishostname, strcpy(ec->self.node,thisnodename); ec->self.num = 0; ec->self.serial = 0; - ec->self.creation = creation; + ec->self.creation = creation & 0x3; /* 2 bits */ if ((dbglevel = getenv("EI_TRACELEVEL")) != NULL || (dbglevel = getenv("ERL_DEBUG_DIST")) != NULL) @@ -1342,7 +1342,8 @@ static int send_name_or_challenge(int fd, char *nodename, | DFLAG_NEW_FLOATS | DFLAG_SMALL_ATOM_TAGS | DFLAG_UTF8_ATOMS - | DFLAG_MAP_TAG)); + | DFLAG_MAP_TAG + | DFLAG_BIG_CREATION)); if (f_chall) put32be(s, challenge); memcpy(s, nodename, strlen(nodename)); @@ -1707,28 +1708,36 @@ error: static int get_home(char *buf, int size) { - char* homedrive; - char* homepath; - #ifdef __WIN32__ - homedrive = getenv("HOMEDRIVE"); - homepath = getenv("HOMEPATH"); -#else - homedrive = ""; - homepath = getenv("HOME"); -#endif + char* homedrive = getenv("HOMEDRIVE"); + char* homepath = getenv("HOMEPATH"); - if (!homedrive || !homepath) { - buf[0] = '.'; - buf[1] = '\0'; - return 1; - } else if (strlen(homedrive)+strlen(homepath) < size-1) { + if (homedrive && homepath) { + if (strlen(homedrive)+strlen(homepath) >= size) + return 0; strcpy(buf, homedrive); strcat(buf, homepath); return 1; } - - return 0; + else { + int len = GetWindowsDirectory(buf, size); + if (len) { + return (len < size); + } + } +#else + char* homepath = getenv("HOME"); + if (homepath) { + if (strlen(homepath) >= size) + return 0; + strcpy(buf, homepath); + return 1; + } +#endif + + buf[0] = '.'; + buf[1] = '\0'; + return 1; } diff --git a/lib/erl_interface/src/connect/ei_connect_int.h b/lib/erl_interface/src/connect/ei_connect_int.h index efb6719a1d..0bcccaa84b 100644 --- a/lib/erl_interface/src/connect/ei_connect_int.h +++ b/lib/erl_interface/src/connect/ei_connect_int.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2014. All Rights Reserved. + * 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. @@ -106,6 +106,7 @@ extern int h_errno; #define DFLAG_SMALL_ATOM_TAGS 0x4000 #define DFLAG_UTF8_ATOMS 0x10000 #define DFLAG_MAP_TAG 0x20000 +#define DFLAG_BIG_CREATION 0x40000 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 414cb8be3e..fd0c659373 100644 --- a/lib/erl_interface/src/connect/ei_resolve.c +++ b/lib/erl_interface/src/connect/ei_resolve.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1997-2013. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/connect/ei_resolve.h b/lib/erl_interface/src/connect/ei_resolve.h index 71ebeab20b..10a49ffbc6 100644 --- a/lib/erl_interface/src/connect/ei_resolve.h +++ b/lib/erl_interface/src/connect/ei_resolve.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1997-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/connect/eirecv.c b/lib/erl_interface/src/connect/eirecv.c index b036c8969e..7b9dbfc387 100644 --- a/lib/erl_interface/src/connect/eirecv.c +++ b/lib/erl_interface/src/connect/eirecv.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2013. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/connect/eirecv.h b/lib/erl_interface/src/connect/eirecv.h index d56f36b286..bd40061c07 100644 --- a/lib/erl_interface/src/connect/eirecv.h +++ b/lib/erl_interface/src/connect/eirecv.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2002-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/connect/eisend.h b/lib/erl_interface/src/connect/eisend.h index 6762c4cf40..d555208ed0 100644 --- a/lib/erl_interface/src/connect/eisend.h +++ b/lib/erl_interface/src/connect/eisend.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/connect/send.c b/lib/erl_interface/src/connect/send.c index 826bc1f22a..37d7db6d68 100644 --- a/lib/erl_interface/src/connect/send.c +++ b/lib/erl_interface/src/connect/send.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2011. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/connect/send_exit.c b/lib/erl_interface/src/connect/send_exit.c index f71acfa155..2e298e3221 100644 --- a/lib/erl_interface/src/connect/send_exit.c +++ b/lib/erl_interface/src/connect/send_exit.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2011. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/connect/send_reg.c b/lib/erl_interface/src/connect/send_reg.c index dac3877d2a..62478f042d 100644 --- a/lib/erl_interface/src/connect/send_reg.c +++ b/lib/erl_interface/src/connect/send_reg.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2011. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/decode/decode_atom.c b/lib/erl_interface/src/decode/decode_atom.c index df1e5b9350..b3bba82434 100644 --- a/lib/erl_interface/src/decode/decode_atom.c +++ b/lib/erl_interface/src/decode/decode_atom.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2013. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/decode/decode_big.c b/lib/erl_interface/src/decode/decode_big.c index 5739d159bf..cbbbd3f0b7 100644 --- a/lib/erl_interface/src/decode/decode_big.c +++ b/lib/erl_interface/src/decode/decode_big.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2002-2011. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/decode/decode_bignum.c b/lib/erl_interface/src/decode/decode_bignum.c index 9d09aefd76..70a86e29c9 100644 --- a/lib/erl_interface/src/decode/decode_bignum.c +++ b/lib/erl_interface/src/decode/decode_bignum.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2002-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/decode/decode_binary.c b/lib/erl_interface/src/decode/decode_binary.c index 66014181b5..5b8d234984 100644 --- a/lib/erl_interface/src/decode/decode_binary.c +++ b/lib/erl_interface/src/decode/decode_binary.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/decode/decode_boolean.c b/lib/erl_interface/src/decode/decode_boolean.c index edaf1486d4..23cfd16f77 100644 --- a/lib/erl_interface/src/decode/decode_boolean.c +++ b/lib/erl_interface/src/decode/decode_boolean.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2013. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/decode/decode_char.c b/lib/erl_interface/src/decode/decode_char.c index 0290c71988..babf34c90c 100644 --- a/lib/erl_interface/src/decode/decode_char.c +++ b/lib/erl_interface/src/decode/decode_char.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/decode/decode_double.c b/lib/erl_interface/src/decode/decode_double.c index 413d575b1a..1ce8b2a417 100644 --- a/lib/erl_interface/src/decode/decode_double.c +++ b/lib/erl_interface/src/decode/decode_double.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2010. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/decode/decode_fun.c b/lib/erl_interface/src/decode/decode_fun.c index c2e321c067..f944c028af 100644 --- a/lib/erl_interface/src/decode/decode_fun.c +++ b/lib/erl_interface/src/decode/decode_fun.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2013. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/decode/decode_intlist.c b/lib/erl_interface/src/decode/decode_intlist.c index 68f38075e2..494371d778 100644 --- a/lib/erl_interface/src/decode/decode_intlist.c +++ b/lib/erl_interface/src/decode/decode_intlist.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/decode/decode_list_header.c b/lib/erl_interface/src/decode/decode_list_header.c index e198f52d52..4c6ce3859e 100644 --- a/lib/erl_interface/src/decode/decode_list_header.c +++ b/lib/erl_interface/src/decode/decode_list_header.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/decode/decode_long.c b/lib/erl_interface/src/decode/decode_long.c index 15bfb28cf0..b5f36adbb6 100644 --- a/lib/erl_interface/src/decode/decode_long.c +++ b/lib/erl_interface/src/decode/decode_long.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/decode/decode_longlong.c b/lib/erl_interface/src/decode/decode_longlong.c index 22f2a63d2e..e052cb7164 100644 --- a/lib/erl_interface/src/decode/decode_longlong.c +++ b/lib/erl_interface/src/decode/decode_longlong.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2002-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/decode/decode_pid.c b/lib/erl_interface/src/decode/decode_pid.c index 7fbb818b31..e1055aa5c9 100644 --- a/lib/erl_interface/src/decode/decode_pid.c +++ b/lib/erl_interface/src/decode/decode_pid.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2013. All Rights Reserved. + * 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. @@ -27,18 +27,22 @@ int ei_decode_pid(const char *buf, int *index, erlang_pid *p) { const char *s = buf + *index; const char *s0 = s; + const char tag = get8(s); - if (get8(s) != ERL_PID_EXT) return -1; + if (tag != ERL_PID_EXT && tag != ERL_NEW_PID_EXT) return -1; if (p) { if (get_atom(&s, p->node, NULL) < 0) return -1; p->num = get32be(s) & 0x7fff; /* 15 bits */ p->serial = get32be(s) & 0x1fff; /* 13 bits */ - p->creation = get8(s) & 0x03; /* 2 bits */ + if (tag == ERL_PID_EXT) + p->creation = get8(s) & 0x03; /* 2 bits */ + else + p->creation = get32be(s); /* 32 bits */ } else { if (get_atom(&s, NULL, NULL) < 0) return -1; - s+= 9; + s+= (tag == ERL_PID_EXT ? 9 : 12); } *index += s-s0; diff --git a/lib/erl_interface/src/decode/decode_port.c b/lib/erl_interface/src/decode/decode_port.c index e039b5b845..337648d803 100644 --- a/lib/erl_interface/src/decode/decode_port.c +++ b/lib/erl_interface/src/decode/decode_port.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2013. All Rights Reserved. + * 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. @@ -26,17 +26,21 @@ int ei_decode_port(const char *buf, int *index, erlang_port *p) { const char *s = buf + *index; const char *s0 = s; + const char tag = get8(s); - if (get8(s) != ERL_PORT_EXT) return -1; + if (tag != ERL_PORT_EXT && tag != ERL_NEW_PORT_EXT) return -1; if (p) { if (get_atom(&s, p->node, NULL) < 0) return -1; p->id = get32be(s) & 0x0fffffff /* 28 bits */; - p->creation = get8(s) & 0x03; + if (tag == ERL_PORT_EXT) + p->creation = get8(s) & 0x03; + else + p->creation = get32be(s); } else { if (get_atom(&s, NULL, NULL) < 0) return -1; - s += 5; + s += (tag == ERL_PORT_EXT ? 5 : 8); } *index += s-s0; diff --git a/lib/erl_interface/src/decode/decode_ref.c b/lib/erl_interface/src/decode/decode_ref.c index a6b87e5a21..c9b38c1c3b 100644 --- a/lib/erl_interface/src/decode/decode_ref.c +++ b/lib/erl_interface/src/decode/decode_ref.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2013. All Rights Reserved. + * 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. @@ -28,8 +28,9 @@ int ei_decode_ref(const char *buf, int *index, erlang_ref *p) const char *s = buf + *index; const char *s0 = s; int count, i; + const char tag = get8(s); - switch (get8(s)) { + switch (tag) { case ERL_REFERENCE_EXT: if (p) { if (get_atom(&s, p->node, NULL) < 0) return -1; @@ -47,18 +48,23 @@ int ei_decode_ref(const char *buf, int *index, erlang_ref *p) return 0; break; - case ERL_NEW_REFERENCE_EXT: + case ERL_NEW_REFERENCE_EXT: + case ERL_NEWER_REFERENCE_EXT: + /* first the integer count */ count = get16be(s); if (p) { p->len = count; if (get_atom(&s, p->node, NULL) < 0) return -1; - p->creation = get8(s) & 0x03; + if (tag == ERL_NEW_REFERENCE_EXT) + p->creation = get8(s) & 0x03; + else + p->creation = get32be(s); } else { if (get_atom(&s, NULL, NULL) < 0) return -1; - s += 1; + s += (tag == ERL_NEW_REFERENCE_EXT ? 1 : 4); } /* finally the id integers */ diff --git a/lib/erl_interface/src/decode/decode_skip.c b/lib/erl_interface/src/decode/decode_skip.c index d49ae0007f..0db315f09b 100644 --- a/lib/erl_interface/src/decode/decode_skip.c +++ b/lib/erl_interface/src/decode/decode_skip.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2002-2014. All Rights Reserved. + * 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. @@ -35,12 +35,15 @@ int ei_skip_term(const char* buf, int* index) NULL, NULL) < 0) return -1; break; case ERL_PID_EXT: + case ERL_NEW_PID_EXT: if (ei_decode_pid(buf, index, NULL) < 0) return -1; break; case ERL_PORT_EXT: + case ERL_NEW_PORT_EXT: if (ei_decode_port(buf, index, NULL) < 0) return -1; break; case ERL_NEW_REFERENCE_EXT: + case ERL_NEWER_REFERENCE_EXT: case ERL_REFERENCE_EXT: if (ei_decode_ref(buf, index, NULL) < 0) return -1; break; diff --git a/lib/erl_interface/src/decode/decode_skip.h b/lib/erl_interface/src/decode/decode_skip.h index a0934fdf35..be497e8601 100644 --- a/lib/erl_interface/src/decode/decode_skip.h +++ b/lib/erl_interface/src/decode/decode_skip.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2002-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/decode/decode_string.c b/lib/erl_interface/src/decode/decode_string.c index 98b7384dc5..3fe4fdd02d 100644 --- a/lib/erl_interface/src/decode/decode_string.c +++ b/lib/erl_interface/src/decode/decode_string.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/decode/decode_trace.c b/lib/erl_interface/src/decode/decode_trace.c index bcc53bce96..738d6f0885 100644 --- a/lib/erl_interface/src/decode/decode_trace.c +++ b/lib/erl_interface/src/decode/decode_trace.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2013. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/decode/decode_tuple_header.c b/lib/erl_interface/src/decode/decode_tuple_header.c index ea60a03ddc..4507edbc8e 100644 --- a/lib/erl_interface/src/decode/decode_tuple_header.c +++ b/lib/erl_interface/src/decode/decode_tuple_header.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2014. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/decode/decode_ulong.c b/lib/erl_interface/src/decode/decode_ulong.c index dbd86f5022..8675ae257f 100644 --- a/lib/erl_interface/src/decode/decode_ulong.c +++ b/lib/erl_interface/src/decode/decode_ulong.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/decode/decode_ulonglong.c b/lib/erl_interface/src/decode/decode_ulonglong.c index e579df41aa..0f0eaeb5da 100644 --- a/lib/erl_interface/src/decode/decode_ulonglong.c +++ b/lib/erl_interface/src/decode/decode_ulonglong.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2002-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/decode/decode_version.c b/lib/erl_interface/src/decode/decode_version.c index b2146d3280..00a85bea35 100644 --- a/lib/erl_interface/src/decode/decode_version.c +++ b/lib/erl_interface/src/decode/decode_version.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/eidefs.mk.in b/lib/erl_interface/src/eidefs.mk.in index 4f6c4e5a3c..dc34ad478a 100644 --- a/lib/erl_interface/src/eidefs.mk.in +++ b/lib/erl_interface/src/eidefs.mk.in @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2004-2009. All Rights Reserved. +# Copyright Ericsson AB 2004-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. diff --git a/lib/erl_interface/src/encode/eicode.h b/lib/erl_interface/src/encode/eicode.h index 351e88cf2b..1db9a0b65a 100644 --- a/lib/erl_interface/src/encode/eicode.h +++ b/lib/erl_interface/src/encode/eicode.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/encode/encode_atom.c b/lib/erl_interface/src/encode/encode_atom.c index 372122f3eb..c1817628e5 100644 --- a/lib/erl_interface/src/encode/encode_atom.c +++ b/lib/erl_interface/src/encode/encode_atom.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2013. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/encode/encode_big.c b/lib/erl_interface/src/encode/encode_big.c index f758070d8c..cf542a5557 100644 --- a/lib/erl_interface/src/encode/encode_big.c +++ b/lib/erl_interface/src/encode/encode_big.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2009. All Rights Reserved. + * Copyright Ericsson AB 2009-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. diff --git a/lib/erl_interface/src/encode/encode_bignum.c b/lib/erl_interface/src/encode/encode_bignum.c index ebd1853b21..6e418df0c7 100644 --- a/lib/erl_interface/src/encode/encode_bignum.c +++ b/lib/erl_interface/src/encode/encode_bignum.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2002-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/encode/encode_binary.c b/lib/erl_interface/src/encode/encode_binary.c index 91dab32c29..4471c51769 100644 --- a/lib/erl_interface/src/encode/encode_binary.c +++ b/lib/erl_interface/src/encode/encode_binary.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/encode/encode_boolean.c b/lib/erl_interface/src/encode/encode_boolean.c index d98cb5ad09..61e7e5e6e7 100644 --- a/lib/erl_interface/src/encode/encode_boolean.c +++ b/lib/erl_interface/src/encode/encode_boolean.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/encode/encode_char.c b/lib/erl_interface/src/encode/encode_char.c index 87fdef7bdd..fab56469aa 100644 --- a/lib/erl_interface/src/encode/encode_char.c +++ b/lib/erl_interface/src/encode/encode_char.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/encode/encode_double.c b/lib/erl_interface/src/encode/encode_double.c index 8943cefa11..cff220639a 100644 --- a/lib/erl_interface/src/encode/encode_double.c +++ b/lib/erl_interface/src/encode/encode_double.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2010. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/encode/encode_fun.c b/lib/erl_interface/src/encode/encode_fun.c index 14f66dcde1..3bfc7530d1 100644 --- a/lib/erl_interface/src/encode/encode_fun.c +++ b/lib/erl_interface/src/encode/encode_fun.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2013. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/encode/encode_list_header.c b/lib/erl_interface/src/encode/encode_list_header.c index 0ddca107d7..409bd98ea0 100644 --- a/lib/erl_interface/src/encode/encode_list_header.c +++ b/lib/erl_interface/src/encode/encode_list_header.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/encode/encode_long.c b/lib/erl_interface/src/encode/encode_long.c index cf99a7488c..ef3b92cd9e 100644 --- a/lib/erl_interface/src/encode/encode_long.c +++ b/lib/erl_interface/src/encode/encode_long.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/encode/encode_longlong.c b/lib/erl_interface/src/encode/encode_longlong.c index fff170c32d..2a1cbedce1 100644 --- a/lib/erl_interface/src/encode/encode_longlong.c +++ b/lib/erl_interface/src/encode/encode_longlong.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2002-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/encode/encode_pid.c b/lib/erl_interface/src/encode/encode_pid.c index 7b01b7045f..d14746b40f 100644 --- a/lib/erl_interface/src/encode/encode_pid.c +++ b/lib/erl_interface/src/encode/encode_pid.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2013. All Rights Reserved. + * 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. @@ -24,7 +24,8 @@ int ei_encode_pid(char *buf, int *index, const erlang_pid *p) { - char *s = buf + *index; + 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), @@ -32,17 +33,21 @@ int ei_encode_pid(char *buf, int *index, const erlang_pid *p) return -1; if (buf) { - put8(s,ERL_PID_EXT); + put8(s, tag); s = buf + *index; /* now the integers */ put32be(s,p->num & 0x7fff); /* 15 bits */ put32be(s,p->serial & 0x1fff); /* 13 bits */ - put8(s,(p->creation & 0x03)); /* 2 bits */ + if (tag == ERL_PID_EXT) { + put8(s,(p->creation & 0x03)); /* 2 bits */ + } else { + put32be(s, p->creation); /* 32 bits */ + } } - *index += 4 + 4 + 1; + *index += 4 + 4 + (tag == ERL_PID_EXT ? 1 : 4); return 0; } diff --git a/lib/erl_interface/src/encode/encode_port.c b/lib/erl_interface/src/encode/encode_port.c index a7468e5917..eb464380c0 100644 --- a/lib/erl_interface/src/encode/encode_port.c +++ b/lib/erl_interface/src/encode/encode_port.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2013. All Rights Reserved. + * 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. @@ -25,6 +25,7 @@ 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, @@ -32,16 +33,19 @@ int ei_encode_port(char *buf, int *index, const erlang_port *p) return -1; } if (buf) { - put8(s,ERL_PORT_EXT); + put8(s, tag); s = buf + *index; /* now the integers */ put32be(s,p->id & 0x0fffffff /* 28 bits */); - put8(s,(p->creation & 0x03)); + if (tag == ERL_PORT_EXT) { + put8(s,(p->creation & 0x03)); + } else { + put32be(s, p->creation); + } } - - *index += 4 + 1; + *index += 4 + (tag == ERL_PORT_EXT ? 1 : 4); return 0; } diff --git a/lib/erl_interface/src/encode/encode_ref.c b/lib/erl_interface/src/encode/encode_ref.c index 0f27a086f0..5ccfc32c6d 100644 --- a/lib/erl_interface/src/encode/encode_ref.c +++ b/lib/erl_interface/src/encode/encode_ref.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2013. All Rights Reserved. + * 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. @@ -24,6 +24,7 @@ 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; @@ -36,7 +37,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,ERL_NEW_REFERENCE_EXT); + put8(s, tag); /* first, number of integers */ put16be(s, p->len); @@ -45,12 +46,15 @@ int ei_encode_ref(char *buf, int *index, const erlang_ref *p) s = buf + *index; /* now the integers */ - put8(s,(p->creation & 0x03)); + if (tag == ERL_NEW_REFERENCE_EXT) + put8(s,(p->creation & 0x03)); + else + put32be(s, p->creation); for (i = 0; i < p->len; i++) put32be(s,p->n[i]); } - *index += p->len*4 + 1; + *index += p->len*4 + (tag == ERL_NEW_REFERENCE_EXT ? 1 : 4); return 0; } diff --git a/lib/erl_interface/src/encode/encode_string.c b/lib/erl_interface/src/encode/encode_string.c index 180fe3f1da..a45eae934d 100644 --- a/lib/erl_interface/src/encode/encode_string.c +++ b/lib/erl_interface/src/encode/encode_string.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2011. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/encode/encode_trace.c b/lib/erl_interface/src/encode/encode_trace.c index 95b49a04e6..d0e6aec474 100644 --- a/lib/erl_interface/src/encode/encode_trace.c +++ b/lib/erl_interface/src/encode/encode_trace.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/encode/encode_tuple_header.c b/lib/erl_interface/src/encode/encode_tuple_header.c index 254840a3d1..e75df57bed 100644 --- a/lib/erl_interface/src/encode/encode_tuple_header.c +++ b/lib/erl_interface/src/encode/encode_tuple_header.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2014. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/encode/encode_ulong.c b/lib/erl_interface/src/encode/encode_ulong.c index 98b26fed40..94b45b2dd4 100644 --- a/lib/erl_interface/src/encode/encode_ulong.c +++ b/lib/erl_interface/src/encode/encode_ulong.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/encode/encode_ulonglong.c b/lib/erl_interface/src/encode/encode_ulonglong.c index 069138a458..e16acc10ef 100644 --- a/lib/erl_interface/src/encode/encode_ulonglong.c +++ b/lib/erl_interface/src/encode/encode_ulonglong.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2002-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/encode/encode_version.c b/lib/erl_interface/src/encode/encode_version.c index 1694697260..41a2deda12 100644 --- a/lib/erl_interface/src/encode/encode_version.c +++ b/lib/erl_interface/src/encode/encode_version.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/epmd/ei_epmd.h b/lib/erl_interface/src/epmd/ei_epmd.h index 50974b89c5..ac153b6e66 100644 --- a/lib/erl_interface/src/epmd/ei_epmd.h +++ b/lib/erl_interface/src/epmd/ei_epmd.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2010. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/epmd/epmd_port.c b/lib/erl_interface/src/epmd/epmd_port.c index dedc21e679..2ec418b24a 100644 --- a/lib/erl_interface/src/epmd/epmd_port.c +++ b/lib/erl_interface/src/epmd/epmd_port.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2011. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/epmd/epmd_publish.c b/lib/erl_interface/src/epmd/epmd_publish.c index 6370a5ab37..47d68a6db0 100644 --- a/lib/erl_interface/src/epmd/epmd_publish.c +++ b/lib/erl_interface/src/epmd/epmd_publish.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2010. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/epmd/epmd_unpublish.c b/lib/erl_interface/src/epmd/epmd_unpublish.c index ef84938e5b..255d0ffb59 100644 --- a/lib/erl_interface/src/epmd/epmd_unpublish.c +++ b/lib/erl_interface/src/epmd/epmd_unpublish.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2011. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/erl_interface.app.src b/lib/erl_interface/src/erl_interface.app.src index 8ab3e1012f..f00cdfba88 100644 --- a/lib/erl_interface/src/erl_interface.app.src +++ b/lib/erl_interface/src/erl_interface.app.src @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2014. All Rights Reserved. +%% Copyright Ericsson AB 2014-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. diff --git a/lib/erl_interface/src/erl_interface.appup.src b/lib/erl_interface/src/erl_interface.appup.src index eee7be1540..eb9854d22d 100644 --- a/lib/erl_interface/src/erl_interface.appup.src +++ b/lib/erl_interface/src/erl_interface.appup.src @@ -1,7 +1,7 @@ %% -*- erlang -*- %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2014. All Rights Reserved. +%% Copyright Ericsson AB 2014-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. diff --git a/lib/erl_interface/src/legacy/decode_term.c b/lib/erl_interface/src/legacy/decode_term.c index fabbee19a9..72bacc3123 100644 --- a/lib/erl_interface/src/legacy/decode_term.c +++ b/lib/erl_interface/src/legacy/decode_term.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2010. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/legacy/encode_term.c b/lib/erl_interface/src/legacy/encode_term.c index 47837214e8..df740ab487 100644 --- a/lib/erl_interface/src/legacy/encode_term.c +++ b/lib/erl_interface/src/legacy/encode_term.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/legacy/erl_config.h b/lib/erl_interface/src/legacy/erl_config.h index 1da150bdbd..fb72169f23 100644 --- a/lib/erl_interface/src/legacy/erl_config.h +++ b/lib/erl_interface/src/legacy/erl_config.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/legacy/erl_connect.c b/lib/erl_interface/src/legacy/erl_connect.c index 4b1004ae2b..7ffd545d3e 100644 --- a/lib/erl_interface/src/legacy/erl_connect.c +++ b/lib/erl_interface/src/legacy/erl_connect.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2013. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/legacy/erl_connect.h b/lib/erl_interface/src/legacy/erl_connect.h index eb3292b679..6cb5d5cd1b 100644 --- a/lib/erl_interface/src/legacy/erl_connect.h +++ b/lib/erl_interface/src/legacy/erl_connect.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/legacy/erl_error.c b/lib/erl_interface/src/legacy/erl_error.c index d3309d2863..a3bbfbc58f 100644 --- a/lib/erl_interface/src/legacy/erl_error.c +++ b/lib/erl_interface/src/legacy/erl_error.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/legacy/erl_error.h b/lib/erl_interface/src/legacy/erl_error.h index 27a8d13d0f..0cce083ae7 100644 --- a/lib/erl_interface/src/legacy/erl_error.h +++ b/lib/erl_interface/src/legacy/erl_error.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/legacy/erl_eterm.c b/lib/erl_interface/src/legacy/erl_eterm.c index f2f35ab693..e4b3b49c7d 100644 --- a/lib/erl_interface/src/legacy/erl_eterm.c +++ b/lib/erl_interface/src/legacy/erl_eterm.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2013. All Rights Reserved. + * 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. @@ -285,12 +285,12 @@ ETERM *erl_mk_pid(const char *node, erl_errno = ENOMEM; return NULL; } - erl_mk_pid_helper(ep, number, serial, creation); + 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 char creation) + unsigned int serial, unsigned int creation) { ERL_PID_NUMBER(ep) = number & 0x7fff; /* 15 bits */ if (ei_internal_use_r9_pids_ports()) { @@ -299,7 +299,7 @@ void erl_mk_pid_helper(ETERM *ep, unsigned int number, else { ERL_PID_SERIAL(ep) = serial & 0x1fff; /* 13 bits */ } - ERL_PID_CREATION(ep) = creation & 0x03; /* 2 bits */ + ERL_PID_CREATION(ep) = creation; /* 32 bits */ } /* @@ -326,7 +326,7 @@ ETERM *erl_mk_port(const char *node, return ep; } -void erl_mk_port_helper(ETERM* ep, unsigned number, unsigned char creation) +void erl_mk_port_helper(ETERM* ep, unsigned number, unsigned int creation) { if (ei_internal_use_r9_pids_ports()) { ERL_PORT_NUMBER(ep) = number & 0x3ffff; /* 18 bits */ @@ -334,7 +334,7 @@ void erl_mk_port_helper(ETERM* ep, unsigned number, unsigned char creation) else { ERL_PORT_NUMBER(ep) = number & 0x0fffffff; /* 18 bits */ } - ERL_PORT_CREATION(ep) = creation & 0x03; /* 2 bits */ + ERL_PORT_CREATION(ep) = creation; /* 32 bits */ } /* @@ -344,7 +344,7 @@ ETERM *__erl_mk_reference (ETERM* t, const char *node, size_t len, unsigned int n[], - unsigned char creation) + unsigned int creation) { if (t == NULL) { if (node == NULL) return NULL; @@ -363,7 +363,7 @@ ETERM *__erl_mk_reference (ETERM* t, 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 & 0x03; /* 2 bits */ + ERL_REF_CREATION(t) = creation; /* 32 bits */ return t; } diff --git a/lib/erl_interface/src/legacy/erl_eterm.h b/lib/erl_interface/src/legacy/erl_eterm.h index d9a26b2541..e2f3a90531 100644 --- a/lib/erl_interface/src/legacy/erl_eterm.h +++ b/lib/erl_interface/src/legacy/erl_eterm.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2013. All Rights Reserved. + * 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. @@ -56,9 +56,9 @@ typedef struct _heapmark { } Erl_HeapMark; -void erl_mk_port_helper(ETERM* ep, unsigned number, unsigned char creation); -void erl_mk_pid_helper(ETERM*, unsigned,unsigned, unsigned char); -ETERM * __erl_mk_reference(ETERM*, const char *, size_t, unsigned int n[], unsigned char); +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 index 70d592bfe1..890a9ce291 100644 --- a/lib/erl_interface/src/legacy/erl_fix_alloc.c +++ b/lib/erl_interface/src/legacy/erl_fix_alloc.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2011. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/legacy/erl_fix_alloc.h b/lib/erl_interface/src/legacy/erl_fix_alloc.h index af86202ae7..50d1368e34 100644 --- a/lib/erl_interface/src/legacy/erl_fix_alloc.h +++ b/lib/erl_interface/src/legacy/erl_fix_alloc.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/legacy/erl_format.c b/lib/erl_interface/src/legacy/erl_format.c index c5ef47236d..45f5489e54 100644 --- a/lib/erl_interface/src/legacy/erl_format.c +++ b/lib/erl_interface/src/legacy/erl_format.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2013. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/legacy/erl_format.h b/lib/erl_interface/src/legacy/erl_format.h index 388267f859..92fa068206 100644 --- a/lib/erl_interface/src/legacy/erl_format.h +++ b/lib/erl_interface/src/legacy/erl_format.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/legacy/erl_global.h b/lib/erl_interface/src/legacy/erl_global.h index 3c99b2fe40..d2eec08b35 100644 --- a/lib/erl_interface/src/legacy/erl_global.h +++ b/lib/erl_interface/src/legacy/erl_global.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/legacy/erl_internal.h b/lib/erl_interface/src/legacy/erl_internal.h index 22160d8911..25cf3e4f42 100644 --- a/lib/erl_interface/src/legacy/erl_internal.h +++ b/lib/erl_interface/src/legacy/erl_internal.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/legacy/erl_malloc.c b/lib/erl_interface/src/legacy/erl_malloc.c index cad7f75261..27ef8c4b32 100644 --- a/lib/erl_interface/src/legacy/erl_malloc.c +++ b/lib/erl_interface/src/legacy/erl_malloc.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2013. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/legacy/erl_malloc.h b/lib/erl_interface/src/legacy/erl_malloc.h index cfbd190b61..6cbc01faba 100644 --- a/lib/erl_interface/src/legacy/erl_malloc.h +++ b/lib/erl_interface/src/legacy/erl_malloc.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/legacy/erl_marshal.c b/lib/erl_interface/src/legacy/erl_marshal.c index a4216c9541..2bdf5f2134 100644 --- a/lib/erl_interface/src/legacy/erl_marshal.c +++ b/lib/erl_interface/src/legacy/erl_marshal.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2013. All Rights Reserved. + * 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. @@ -120,10 +120,13 @@ void erl_init_marshal(void) 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; @@ -304,8 +307,8 @@ int erl_encode_it(ETERM *ep, unsigned char **ext, int dist) *(*ext)++ = ul & 0xff; return 0; - case ERL_PID: - *(*ext)++ = ERL_PID_EXT; + 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 */ @@ -319,17 +322,29 @@ int erl_encode_it(ETERM *ep, unsigned char **ext, int dist) *(*ext)++ = (i >> 16) &0xff; *(*ext)++ = (i >> 8) &0xff; *(*ext)++ = i &0xff; - *(*ext)++ = ERL_PID_CREATION(ep); + + 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. */ - *(*ext)++ = ERL_NEW_REFERENCE_EXT; - i = strlen((char *)ERL_REF_NODE(ep)); len = ERL_REF_LEN(ep); *(*ext)++ = (len >> 8) &0xff; @@ -337,7 +352,18 @@ int erl_encode_it(ETERM *ep, unsigned char **ext, int dist) encode_atom(&ep->uval.refval.node, ext); - *(*ext)++ = ERL_REF_CREATION(ep); + 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]; @@ -348,8 +374,8 @@ int erl_encode_it(ETERM *ep, unsigned char **ext, int dist) } } return 0; - case ERL_PORT: - *(*ext)++ = ERL_PORT_EXT; + 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 */ @@ -358,8 +384,20 @@ int erl_encode_it(ETERM *ep, unsigned char **ext, int dist) *(*ext)++ = (i >> 16) &0xff; *(*ext)++ = (i >> 8) &0xff; *(*ext)++ = i &0xff; - *(*ext)++ = ERL_PORT_CREATION(ep); + + 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; @@ -698,12 +736,14 @@ static ETERM *erl_decode_it(unsigned char **ext) 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; - switch (*(*ext)++) + tag = *(*ext)++; + switch (tag) { case ERL_INTEGER_EXT: i = (int) (**ext << 24) | ((*ext)[1] << 16) | @@ -727,6 +767,13 @@ static ETERM *erl_decode_it(unsigned char **ext) ((*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; @@ -763,23 +810,28 @@ static ETERM *erl_decode_it(unsigned char **ext) *ext += arity; return ep; } else { - /* Fits in a long long */ - int x; - long long l = 0LL; - - for(x = 0 ; x < arity ; x++) { - l |= ((long long)(*ext)[x]) << ((long long)(8*x)); - } - if (sign) { - l = -l; - if (l > 0) goto big_truncate; - } - - ERL_TYPE(ep) = ERL_LONGLONG; - ep->uval.llval.i = l; - *ext += arity; - return ep; + /* 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 @@ -801,9 +853,10 @@ static ETERM *erl_decode_it(unsigned char **ext) return ep; case ERL_PID_EXT: + case ERL_NEW_PID_EXT: { unsigned int number, serial; - unsigned char creation; + unsigned int creation; ERL_TYPE(ep) = ERL_PID; if (read_atom(ext, &ep->uval.pidval.node) < 0) return NULL; @@ -815,7 +868,13 @@ static ETERM *erl_decode_it(unsigned char **ext) serial = ((*ext)[0] << 24) | ((*ext)[1]) << 16 | ((*ext)[2]) << 8 | ((*ext)[3]); *ext += 4; - creation = *(*ext)++; + 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; } @@ -836,11 +895,12 @@ static ETERM *erl_decode_it(unsigned char **ext) return ep; } - case ERL_NEW_REFERENCE_EXT: + case ERL_NEW_REFERENCE_EXT: + case ERL_NEWER_REFERENCE_EXT: { size_t cnt, i; unsigned int n[3]; - unsigned char creation; + unsigned int creation; ERL_TYPE(ep) = ERL_REF; cnt = ((*ext)[0] << 8) | (*ext)[1]; @@ -849,7 +909,13 @@ static ETERM *erl_decode_it(unsigned char **ext) if (read_atom(ext, &ep->uval.refval.node) < 0) return NULL; /* get the integers */ - creation = *(*ext)++; + 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 | @@ -861,9 +927,10 @@ static ETERM *erl_decode_it(unsigned char **ext) } case ERL_PORT_EXT: + case ERL_NEW_PORT_EXT: { unsigned int number; - unsigned char creation; + unsigned int creation; ERL_TYPE(ep) = ERL_PORT; if (read_atom(ext, &ep->uval.portval.node) < 0) return NULL; @@ -872,7 +939,13 @@ static ETERM *erl_decode_it(unsigned char **ext) number = ((*ext)[0] << 24) | ((*ext)[1]) << 16 | ((*ext)[2]) << 8 | ((*ext)[3]); *ext += 4; - creation = *(*ext)++; + 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; } @@ -1114,11 +1187,14 @@ unsigned char erl_ext_type(unsigned char *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; @@ -1167,9 +1243,12 @@ int erl_ext_size(unsigned char *t) 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: @@ -1240,8 +1319,9 @@ static int jump(unsigned char **ext) { int j,k,i=0; int n; + const int tag = *(*ext)++; - switch (*(*ext)++) { + switch (tag) { case ERL_VERSION_MAGIC: return jump(ext); case ERL_INTEGER_EXT: @@ -1257,22 +1337,29 @@ static int jump(unsigned char **ext) jump_atom(ext); break; case ERL_PID_EXT: - /* eat first atom */ if (!jump_atom(ext)) return 0; - *ext += 9; /* Two int's and the creation field */ + *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: - /* first field is an atom */ if (!jump_atom(ext)) return 0; - *ext += 5; /* One int and the creation field */ + *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+1; + *ext += 4*n + (tag == ERL_NEW_REFERENCE_EXT ? 1 : 4); break; case ERL_NIL_EXT: /* We just passed it... */ @@ -1605,7 +1692,6 @@ static int cmp_exe2(unsigned char **e1, unsigned char **e2) { int min, ret,i,j,k; double ff1, ff2; - unsigned char *tmp1, *tmp2; unsigned char tag1, tag2; if ( ((*e1)[0] == ERL_STRING_EXT) && ((*e2)[0] == ERL_LIST_EXT) ) { @@ -1649,47 +1735,68 @@ static int cmp_exe2(unsigned char **e1, unsigned char **e2) *e1 += i; *e2 += j; return ret; - case ERL_PID_EXT: { - unsigned char *n1 = *e1; - unsigned char *n2 = *e2; - CMP_EXT_SKIP_ATOM(*e1); CMP_EXT_SKIP_ATOM(*e2); - *e1 += 9; *e2 += 9; + 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 ... */ - tmp1 = *e1 - 5; tmp2 = *e2 - 5; - CMP_EXT_INT32_BE(tmp1, tmp2); + if (pid1.serial < pid2.serial) return -1; + else if (pid1.serial > pid2.serial) return 1; /* ... then ids ... */ - tmp1 -= 4; tmp2 -= 4; - CMP_EXT_INT32_BE(tmp1, tmp2); + if (pid1.num < pid2.num) return -1; + else if (pid1.num > pid2.num) return 1; /* ... then node names ... */ - ret = cmp_exe2(&n1, &n2); - if (ret != 0) - return ret; + j = strcmp(pid1.node, pid2.node); + if (j < 0) return -1; + else if (j > 0) return 1; /* ... and then finaly creations. */ - tmp1 += 8; tmp2 += 8; - if (*tmp1 != *tmp2) - return *tmp1 < *tmp2 ? -1 : 1; + if (pid1.creation < pid2.creation) return -1; + else if (pid1.creation > pid2.creation) return 1; + return 0; } case ERL_PORT_EXT: - /* First compare node names ... */ - if (!IS_ERL_ATOM(**e1) || !IS_ERL_ATOM(**e2)) - return CMP_EXT_ERROR_CODE; - ret = cmp_exe2(e1, e2); - *e1 += 5; *e2 += 5; - if (ret != 0) - return ret; + 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 ... */ - tmp1 = *e1 - 1; tmp2 = *e2 - 1; - if (*tmp1 != *tmp2) - return *tmp1 < *tmp2 ? -1 : 1; + if (port1.creation < port2.creation) return -1; + else if (port1.creation > port2.creation) return 1; + /* ... and then finaly ids. */ - tmp1 -= 4; tmp2 -= 4; - CMP_EXT_INT32_BE(tmp1, tmp2); - return 0; + 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]; diff --git a/lib/erl_interface/src/legacy/erl_marshal.h b/lib/erl_interface/src/legacy/erl_marshal.h index c7fe2139a6..c1963b832d 100644 --- a/lib/erl_interface/src/legacy/erl_marshal.h +++ b/lib/erl_interface/src/legacy/erl_marshal.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/legacy/erl_resolve.c b/lib/erl_interface/src/legacy/erl_resolve.c index cc6558471a..bb09caec85 100644 --- a/lib/erl_interface/src/legacy/erl_resolve.c +++ b/lib/erl_interface/src/legacy/erl_resolve.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2003-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/legacy/erl_timeout.c b/lib/erl_interface/src/legacy/erl_timeout.c index 1651131dff..e36ea0e250 100644 --- a/lib/erl_interface/src/legacy/erl_timeout.c +++ b/lib/erl_interface/src/legacy/erl_timeout.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1997-2011. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/legacy/erl_timeout.h b/lib/erl_interface/src/legacy/erl_timeout.h index 17d45915f5..6bcfa5ecbb 100644 --- a/lib/erl_interface/src/legacy/erl_timeout.h +++ b/lib/erl_interface/src/legacy/erl_timeout.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1997-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/legacy/global_names.c b/lib/erl_interface/src/legacy/global_names.c index bf717bb32b..ee808620fb 100644 --- a/lib/erl_interface/src/legacy/global_names.c +++ b/lib/erl_interface/src/legacy/global_names.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2011. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/legacy/global_register.c b/lib/erl_interface/src/legacy/global_register.c index 9905977514..4cb6d8071f 100644 --- a/lib/erl_interface/src/legacy/global_register.c +++ b/lib/erl_interface/src/legacy/global_register.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2011. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/legacy/global_unregister.c b/lib/erl_interface/src/legacy/global_unregister.c index ace7343503..27f68670ca 100644 --- a/lib/erl_interface/src/legacy/global_unregister.c +++ b/lib/erl_interface/src/legacy/global_unregister.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2011. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/legacy/global_whereis.c b/lib/erl_interface/src/legacy/global_whereis.c index 23be4a1055..13c4c93ca7 100644 --- a/lib/erl_interface/src/legacy/global_whereis.c +++ b/lib/erl_interface/src/legacy/global_whereis.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2013. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/legacy/portability.h b/lib/erl_interface/src/legacy/portability.h index d544c63c99..42a78662d5 100644 --- a/lib/erl_interface/src/legacy/portability.h +++ b/lib/erl_interface/src/legacy/portability.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2000-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/misc/ei_compat.c b/lib/erl_interface/src/misc/ei_compat.c index ceb597e970..93d7dbfb83 100644 --- a/lib/erl_interface/src/misc/ei_compat.c +++ b/lib/erl_interface/src/misc/ei_compat.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2004-2009. All Rights Reserved. + * Copyright Ericsson AB 2004-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. diff --git a/lib/erl_interface/src/misc/ei_decode_term.c b/lib/erl_interface/src/misc/ei_decode_term.c index 0ec67dde09..63a7034508 100644 --- a/lib/erl_interface/src/misc/ei_decode_term.c +++ b/lib/erl_interface/src/misc/ei_decode_term.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2014. All Rights Reserved. + * 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. @@ -33,7 +33,7 @@ int ei_decode_ei_term(const char* buf, int* index, ei_term* term) { const char* s = buf + *index, * s0 = s; - int i, n, sign; + int n, sign; char c; if (term == NULL) return -1; @@ -47,47 +47,27 @@ int ei_decode_ei_term(const char* buf, int* index, ei_term* term) break; case ERL_FLOAT_EXT: case NEW_FLOAT_EXT: - return ei_decode_double(buf, index, &term->value.d_val); + return (ei_decode_double(buf, index, &term->value.d_val) < 0 + ? -1 : 1); case ERL_ATOM_EXT: case ERL_ATOM_UTF8_EXT: case ERL_SMALL_ATOM_EXT: case ERL_SMALL_ATOM_UTF8_EXT: - return ei_decode_atom(buf, index, term->value.atom_name); + return (ei_decode_atom(buf, index, term->value.atom_name) < 0 + ? -1 : 1); case ERL_REFERENCE_EXT: - /* first the nodename */ - if (get_atom(&s, term->value.ref.node, NULL) < 0) return -1; - /* now the numbers: num (4), creation (1) */ - term->value.ref.n[0] = get32be(s); - term->value.ref.len = 1; - term->value.ref.creation = get8(s) & 0x03; - break; case ERL_NEW_REFERENCE_EXT: - /* first the integer count */ - term->value.ref.len = get16be(s); - /* then the nodename */ - if (get_atom(&s, term->value.ref.node, NULL) < 0) return -1; - /* creation */ - term->value.ref.creation = get8(s) & 0x03; - /* finally the id integers */ - for (i = 0; (i<term->value.ref.len) && (i<3); i++) { - term->value.ref.n[i] = get32be(s); - } - if (term->value.ref.len > 3) { - s += 4 * (term->value.ref.len - 3); - } - break; + case ERL_NEWER_REFERENCE_EXT: + return (ei_decode_ref(buf, index, &term->value.ref) < 0 + ? -1 : 1); case ERL_PORT_EXT: - if (get_atom(&s, term->value.port.node, NULL) < 0) return -1; - term->value.port.id = get32be(s) & 0x0fffffff; /* 28 bits */; - term->value.port.creation = get8(s) & 0x03; - break; + case ERL_NEW_PORT_EXT: + return (ei_decode_port(buf, index, &term->value.port) < 0 + ? -1 : 1); case ERL_PID_EXT: - if (get_atom(&s, term->value.pid.node, NULL) < 0) return -1; - /* now the numbers: num (4), serial (4), creation (1) */ - term->value.pid.num = get32be(s) & 0x7fff; /* 15 bits */ - term->value.pid.serial = get32be(s) & 0x1fff; /* 13 bits */ - term->value.pid.creation = get8(s) & 0x03; /* 2 bits */ - break; + case ERL_NEW_PID_EXT: + return (ei_decode_pid(buf, index, &term->value.pid) < 0 + ? -1 : 1); case ERL_SMALL_TUPLE_EXT: term->arity = get8(s); break; diff --git a/lib/erl_interface/src/misc/ei_decode_term.h b/lib/erl_interface/src/misc/ei_decode_term.h index 1f7cedff02..cf2b8f7e86 100644 --- a/lib/erl_interface/src/misc/ei_decode_term.h +++ b/lib/erl_interface/src/misc/ei_decode_term.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/misc/ei_format.c b/lib/erl_interface/src/misc/ei_format.c index 191f4ec7b5..a188171f40 100644 --- a/lib/erl_interface/src/misc/ei_format.c +++ b/lib/erl_interface/src/misc/ei_format.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2013. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/misc/ei_format.h b/lib/erl_interface/src/misc/ei_format.h index 5fa3247d60..7a418008a1 100644 --- a/lib/erl_interface/src/misc/ei_format.h +++ b/lib/erl_interface/src/misc/ei_format.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/misc/ei_internal.h b/lib/erl_interface/src/misc/ei_internal.h index 56cdb53fbf..aa6aacd703 100644 --- a/lib/erl_interface/src/misc/ei_internal.h +++ b/lib/erl_interface/src/misc/ei_internal.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2002-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/misc/ei_locking.c b/lib/erl_interface/src/misc/ei_locking.c index c4c4a8e735..85b2a5fd8b 100644 --- a/lib/erl_interface/src/misc/ei_locking.c +++ b/lib/erl_interface/src/misc/ei_locking.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1997-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/misc/ei_locking.h b/lib/erl_interface/src/misc/ei_locking.h index 99b88ead3b..1bbee2d499 100644 --- a/lib/erl_interface/src/misc/ei_locking.h +++ b/lib/erl_interface/src/misc/ei_locking.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1997-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/misc/ei_malloc.c b/lib/erl_interface/src/misc/ei_malloc.c index 347973bbd6..a8921bc5b5 100644 --- a/lib/erl_interface/src/misc/ei_malloc.c +++ b/lib/erl_interface/src/misc/ei_malloc.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/misc/ei_malloc.h b/lib/erl_interface/src/misc/ei_malloc.h index b02811101b..b62a3cf4d7 100644 --- a/lib/erl_interface/src/misc/ei_malloc.h +++ b/lib/erl_interface/src/misc/ei_malloc.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2002-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/misc/ei_portio.c b/lib/erl_interface/src/misc/ei_portio.c index d4fa2c30e7..8cd35bf2e5 100644 --- a/lib/erl_interface/src/misc/ei_portio.c +++ b/lib/erl_interface/src/misc/ei_portio.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2011. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/misc/ei_portio.h b/lib/erl_interface/src/misc/ei_portio.h index 24dcee4780..bded811a35 100644 --- a/lib/erl_interface/src/misc/ei_portio.h +++ b/lib/erl_interface/src/misc/ei_portio.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2009. All Rights Reserved. + * 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. @@ -21,6 +21,12 @@ */ #ifndef _EI_PORTIO_H #define _EI_PORTIO_H +#if !defined(__WIN32__) && !defined(VXWORKS) +#ifdef HAVE_WRITEV +/* Declaration of struct iovec *iov should be visible in this scope. */ +#include <sys/uio.h> +#endif +#endif int ei_accept_t(int fd, void *addr, void *addrlen, unsigned ms); int ei_connect_t(int fd, void *sinp, int sin_siz, unsigned ms); @@ -29,8 +35,7 @@ int ei_write_fill(int fd, const char *buf, int len); int ei_read_fill_t(int fd, char* buf, int len, unsigned ms); int ei_write_fill_t(int fd, const char *buf, int len, unsigned ms); #ifdef HAVE_WRITEV -int ei_writev_fill_t(int fd, const struct iovec *iov, int iovcnt, - unsigned ms); +int ei_writev_fill_t(int fd, const struct iovec *iov, int iovcnt, unsigned ms); #endif #endif /* _EI_PORTIO_H */ diff --git a/lib/erl_interface/src/misc/ei_printterm.c b/lib/erl_interface/src/misc/ei_printterm.c index 702ee9566d..058de00de5 100644 --- a/lib/erl_interface/src/misc/ei_printterm.c +++ b/lib/erl_interface/src/misc/ei_printterm.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2013. All Rights Reserved. + * 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. @@ -151,15 +151,18 @@ static int print_term(FILE* fp, ei_x_buff* x, } break; case ERL_PID_EXT: + case ERL_NEW_PID_EXT: if (ei_decode_pid(buf, index, &pid) < 0) goto err; ch_written += xprintf(fp, x, "<%s.%d.%d>", pid.node, pid.num, pid.serial); break; case ERL_PORT_EXT: + case ERL_NEW_PORT_EXT: if (ei_decode_port(buf, index, &port) < 0) goto err; ch_written += xprintf(fp, x, "#Port<%d.%d>", port.id, port.creation); break; case ERL_NEW_REFERENCE_EXT: + case ERL_NEWER_REFERENCE_EXT: case ERL_REFERENCE_EXT: if (ei_decode_ref(buf, index, &ref) < 0) goto err; ch_written += xprintf(fp, x, "#Ref<"); diff --git a/lib/erl_interface/src/misc/ei_printterm.h b/lib/erl_interface/src/misc/ei_printterm.h index cb9e12c2dd..953ea00744 100644 --- a/lib/erl_interface/src/misc/ei_printterm.h +++ b/lib/erl_interface/src/misc/ei_printterm.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/misc/ei_pthreads.c b/lib/erl_interface/src/misc/ei_pthreads.c index 1d86fdb736..25608edeec 100644 --- a/lib/erl_interface/src/misc/ei_pthreads.c +++ b/lib/erl_interface/src/misc/ei_pthreads.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/misc/ei_trace.c b/lib/erl_interface/src/misc/ei_trace.c index b341f38105..53d90a9c51 100644 --- a/lib/erl_interface/src/misc/ei_trace.c +++ b/lib/erl_interface/src/misc/ei_trace.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/misc/ei_trace.h b/lib/erl_interface/src/misc/ei_trace.h index 0105a0c1f1..a0988ca8ae 100644 --- a/lib/erl_interface/src/misc/ei_trace.h +++ b/lib/erl_interface/src/misc/ei_trace.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2002-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/misc/ei_x_encode.c b/lib/erl_interface/src/misc/ei_x_encode.c index 4cd882235f..4ff5974663 100644 --- a/lib/erl_interface/src/misc/ei_x_encode.c +++ b/lib/erl_interface/src/misc/ei_x_encode.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2014. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/misc/ei_x_encode.h b/lib/erl_interface/src/misc/ei_x_encode.h index f11d750b28..2c8e362caa 100644 --- a/lib/erl_interface/src/misc/ei_x_encode.h +++ b/lib/erl_interface/src/misc/ei_x_encode.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/misc/eidef.h b/lib/erl_interface/src/misc/eidef.h index 9ac49434e6..f38824d826 100644 --- a/lib/erl_interface/src/misc/eidef.h +++ b/lib/erl_interface/src/misc/eidef.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2002-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/misc/eiext.h b/lib/erl_interface/src/misc/eiext.h index caf98c8e70..ac60d73821 100644 --- a/lib/erl_interface/src/misc/eiext.h +++ b/lib/erl_interface/src/misc/eiext.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/misc/get_type.c b/lib/erl_interface/src/misc/get_type.c index 6b95c1f470..aa69cd4d60 100644 --- a/lib/erl_interface/src/misc/get_type.c +++ b/lib/erl_interface/src/misc/get_type.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2013. All Rights Reserved. + * 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. @@ -76,6 +76,15 @@ int ei_get_type_internal(const char *buf, const int *index, *len = get32be(s); /* #digit_bytes */ break; + case ERL_NEW_PID_EXT: + *type = ERL_PID_EXT; + break; + case ERL_NEW_PORT_EXT: + *type = ERL_PORT_EXT; + break; + case ERL_NEWER_REFERENCE_EXT: + *type = ERL_NEW_REFERENCE_EXT; + break; default: *len = 0; break; diff --git a/lib/erl_interface/src/misc/putget.h b/lib/erl_interface/src/misc/putget.h index f7b42b6efa..afc04e32f9 100644 --- a/lib/erl_interface/src/misc/putget.h +++ b/lib/erl_interface/src/misc/putget.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2013. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/misc/show_msg.c b/lib/erl_interface/src/misc/show_msg.c index b08b17aea4..5868cccba6 100644 --- a/lib/erl_interface/src/misc/show_msg.c +++ b/lib/erl_interface/src/misc/show_msg.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2013. All Rights Reserved. + * 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. @@ -40,6 +40,8 @@ # include <time.h> # endif # endif +#else +# include <time.h> #endif #include "eiext.h" @@ -398,6 +400,7 @@ static void show_term(const char *termbuf, int *index, FILE *stream) break; case ERL_PID_EXT: + case ERL_NEW_PID_EXT: ei_decode_pid(termbuf,index,&pid); show_pid(stream,&pid); break; @@ -432,6 +435,7 @@ static void show_term(const char *termbuf, int *index, FILE *stream) case ERL_REFERENCE_EXT: case ERL_NEW_REFERENCE_EXT: + case ERL_NEWER_REFERENCE_EXT: ei_decode_ref(termbuf,index,&ref); fprintf(stream,"#Ref<%s",ref.node); for (i = 0; i < ref.len; i++) { @@ -441,6 +445,7 @@ static void show_term(const char *termbuf, int *index, FILE *stream) break; case ERL_PORT_EXT: + case ERL_NEW_PORT_EXT: ei_decode_port(termbuf,index,&port); fprintf(stream,"#Port<%s.%u.%u>",port.node,port.id,port.creation); break; diff --git a/lib/erl_interface/src/misc/show_msg.h b/lib/erl_interface/src/misc/show_msg.h index 1f1bd9cb17..de0f8fcdcd 100644 --- a/lib/erl_interface/src/misc/show_msg.h +++ b/lib/erl_interface/src/misc/show_msg.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2002-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/not_used/ei_send.c b/lib/erl_interface/src/not_used/ei_send.c index 437b62cc5d..8071876677 100644 --- a/lib/erl_interface/src/not_used/ei_send.c +++ b/lib/erl_interface/src/not_used/ei_send.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/not_used/ei_send_reg.c b/lib/erl_interface/src/not_used/ei_send_reg.c index f6b66e155c..ba9c7348f9 100644 --- a/lib/erl_interface/src/not_used/ei_send_reg.c +++ b/lib/erl_interface/src/not_used/ei_send_reg.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/not_used/send_link.c b/lib/erl_interface/src/not_used/send_link.c index 3c907897e0..7be476fd93 100644 --- a/lib/erl_interface/src/not_used/send_link.c +++ b/lib/erl_interface/src/not_used/send_link.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/not_used/whereis.c b/lib/erl_interface/src/not_used/whereis.c index 3b7cfb0ee7..4072fa7b33 100644 --- a/lib/erl_interface/src/not_used/whereis.c +++ b/lib/erl_interface/src/not_used/whereis.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/prog/ei_fake_prog.c b/lib/erl_interface/src/prog/ei_fake_prog.c index 2d149aec0c..c7a16dc7c4 100644 --- a/lib/erl_interface/src/prog/ei_fake_prog.c +++ b/lib/erl_interface/src/prog/ei_fake_prog.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2002-2013. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/prog/erl_call.c b/lib/erl_interface/src/prog/erl_call.c index d36742c4f6..d233ed26a2 100644 --- a/lib/erl_interface/src/prog/erl_call.c +++ b/lib/erl_interface/src/prog/erl_call.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2011. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/prog/erl_fake_prog.c b/lib/erl_interface/src/prog/erl_fake_prog.c index 80d72eb933..093bad8d7c 100644 --- a/lib/erl_interface/src/prog/erl_fake_prog.c +++ b/lib/erl_interface/src/prog/erl_fake_prog.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2002-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/prog/erl_start.c b/lib/erl_interface/src/prog/erl_start.c index b7816f3ad4..670a5900c9 100644 --- a/lib/erl_interface/src/prog/erl_start.c +++ b/lib/erl_interface/src/prog/erl_start.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1997-2009. All Rights Reserved. + * 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. @@ -17,7 +17,6 @@ * * %CopyrightEnd% * - */ /* An exception from using eidef.h, use config.h directly */ @@ -45,7 +44,7 @@ #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> -#include <netinet/tcp.h> +#include <netinet/tcp.h> #include <symLib.h> #include <sysSymTbl.h> #include <sysLib.h> @@ -117,9 +116,9 @@ static int unique_id(void); static unsigned long spawn_erlang_epmd(ei_cnode *ec, char *alive, Erl_IpAddr adr, - int flags, - char *erl_or_epmd, - char *args[], + int flags, + char *erl_or_epmd, + char *args[], int port, int is_erlang); #else @@ -161,10 +160,10 @@ int erl_start_sys(ei_cnode *ec, char *alive, Erl_IpAddr adr, int flags, r = ERL_SYS_ERROR; goto done; } - + memset(&addr,0,sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = htonl(INADDR_ANY); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = 0; if (bind(sockd,(struct sockaddr *)&addr,sizeof(addr))<0) { @@ -179,12 +178,12 @@ int erl_start_sys(ei_cnode *ec, char *alive, Erl_IpAddr adr, int flags, listen(sockd,5); #if defined(VXWORKS) || defined(__WIN32__) - if((pid = spawn_erlang_epmd(ec,alive,adr,flags,erl,args,port,1)) + if((pid = spawn_erlang_epmd(ec,alive,adr,flags,erl,args,port,1)) == 0) return ERL_SYS_ERROR; timeout.tv_usec = 0; timeout.tv_sec = 10; /* ignoring ERL_START_TIME */ - if((r = wait_for_erlang(sockd,unique_id(),&timeout)) + if((r = wait_for_erlang(sockd,unique_id(),&timeout)) == ERL_TIMEOUT) { #if defined(VXWORKS) taskDelete((int) pid); @@ -262,7 +261,7 @@ done: static int unique_id(void){ #if defined(VXWORKS) return taskIdSelf(); -#else +#else return (int) GetCurrentThreadId(); #endif } @@ -285,7 +284,7 @@ static int enquote_args(char **oargs, char ***qargs){ for(len=0;oargs[len] != NULL; ++len) ; args = malloc(sizeof(char *) * (len + 1)); - + for(i = 0; i < len; ++i){ qwhole = strchr(oargs[i],' ') != NULL; extra = qwhole * 2; @@ -337,16 +336,16 @@ static FUNCPTR lookup_function(char *symname){ static unsigned long spawn_erlang_epmd(ei_cnode *ec, char *alive, Erl_IpAddr adr, - int flags, - char *erl_or_epmd, - char *args[], + int flags, + char *erl_or_epmd, + char *args[], int port, int is_erlang) { #if defined(VXWORKS) FUNCPTR erlfunc; #else /* Windows */ - STARTUPINFO sinfo; + STARTUPINFO sinfo; SECURITY_ATTRIBUTES sa; PROCESS_INFORMATION pinfo; #endif @@ -364,7 +363,7 @@ 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); + inet_ntoa_b(myaddr, iaddrbuf); #else /* Windows */ if((ptr = inet_ntoa(myaddr)) == NULL) return 0; @@ -372,7 +371,7 @@ static unsigned long spawn_erlang_epmd(ei_cnode *ec, strcpy(iaddrbuf,ptr); #endif } - if ((flags & ERL_START_REMOTE) || + if ((flags & ERL_START_REMOTE) || (is_erlang && (hisaddr->s_addr != myaddr.s_addr))) { return 0; } else { @@ -382,19 +381,17 @@ static unsigned long spawn_erlang_epmd(ei_cnode *ec, #if !defined(VXWORKS) /* On VxWorks, we dont actually run a command, we call start_erl() */ - if(!erl_or_epmd) + if(!erl_or_epmd) #endif erl_or_epmd = (is_erlang) ? DEF_ERL_COMMAND : DEF_EPMD_COMMAND; if(is_erlang){ name_format = (flags & ERL_START_LONG) ? ERL_NAME_FMT : ERL_SNAME_FMT; - cmdlen += + cmdlen += strlen(erl_or_epmd) + (*erl_or_epmd != '\0') + strlen(name_format) + 1 + strlen(alive) + - strlen(ERL_REPLY_FMT) + 1 + strlen(iaddrbuf) + - 2 * FORMATTED_INT_LEN + - 1; + strlen(ERL_REPLY_FMT) + 1 + strlen(iaddrbuf) + 2 * FORMATTED_INT_LEN + 1; ptr = cmdbuf = malloc(cmdlen); if(*erl_or_epmd != '\0') ptr += sprintf(ptr,"%s ",erl_or_epmd); @@ -484,11 +481,11 @@ static unsigned long spawn_erlang_epmd(ei_cnode *ec, * arguments we use here. */ static int exec_erlang(ei_cnode *ec, - char *alive, + char *alive, Erl_IpAddr adr, - int flags, - char *erl, - char *args[], + int flags, + char *erl, + char *args[], int port) { #if !defined(__WIN32__) && !defined(VXWORKS) @@ -498,8 +495,11 @@ static int exec_erlang(ei_cnode *ec, char argbuf[BUFSIZ]; struct in_addr myaddr; struct in_addr *hisaddr = (struct in_addr *)adr; - - get_addr(ei_thishostname(ec), &myaddr); + + if (!get_addr(ei_thishostname(ec), &myaddr)) { + fprintf(stderr,"erl_call: failed to find hostname\r\n"); + return ERL_SYS_ERROR; + } /* on this host? */ /* compare ip addresses, unless forced by flag setting to use rsh */ @@ -525,8 +525,8 @@ static int exec_erlang(ei_cnode *ec, /* *must* be noinput or node (seems to) hang... */ /* long or short names? */ - sprintf(&argbuf[len], "-noinput %s %s ", - ((flags & ERL_START_LONG) ? "-name" : "-sname"), + sprintf(&argbuf[len], "-noinput %s %s ", + ((flags & ERL_START_LONG) ? "-name" : "-sname"), alive); len = strlen(argbuf); @@ -572,7 +572,7 @@ static int exec_erlang(ei_cnode *ec, fprintf(stderr,"\n\n===== Log started ======\n%s \n",ctime(&t)); fprintf(stderr,"erl_call: %s %s %s\n",argv[0],argv[1],argv[2]); } - } + } /* start the system */ execvp(argv[0], argv); @@ -609,7 +609,7 @@ static void gettimeofday(struct timeval *now, void *dummy){ now->tv_usec = ((ctick - (now->tv_sec * rate))*1000000)/rate; } #endif - + /* wait for the remote system to reply */ /* @@ -648,7 +648,7 @@ static int wait_for_erlang(int sockd, int magic, struct timeval *timeout) "will timeout at %ld.%06ld\n", now.tv_sec,now.tv_usec,stop_time.tv_sec,stop_time.tv_usec); #endif - + while (1) { FD_ZERO(&rdset); FD_SET(sockd,&rdset); @@ -662,7 +662,7 @@ static int wait_for_erlang(int sockd, int magic, struct timeval *timeout) to.tv_sec--; } if (to.tv_sec < 0) return ERL_TIMEOUT; - + #ifdef DEBUG fprintf(stderr,"erl_call: debug remaining to timeout: %ld.%06ld\n", to.tv_sec,to.tv_usec); @@ -690,7 +690,7 @@ static int wait_for_erlang(int sockd, int magic, struct timeval *timeout) if (FD_ISSET(sockd,&rdset)) { if ((fd = accept(sockd,(struct sockaddr *)&peer,&len)) < 0) return ERL_SYS_ERROR; - + /* now get sign-on message and terminate it */ #if defined(__WIN32__) if ((n=recv(fd,buf,16,0)) >= 0) buf[n]=0x0; @@ -703,7 +703,6 @@ static int wait_for_erlang(int sockd, int magic, struct timeval *timeout) fprintf(stderr,"erl_call: debug got %d, expected %d\n", atoi(buf),magic); #endif - if (atoi(buf) == magic) return 0; /* success */ } /* if FD_SET */ } /* switch */ diff --git a/lib/erl_interface/src/prog/erl_start.h b/lib/erl_interface/src/prog/erl_start.h index a78dd16edb..1d0d584c45 100644 --- a/lib/erl_interface/src/prog/erl_start.h +++ b/lib/erl_interface/src/prog/erl_start.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1997-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/hash.h b/lib/erl_interface/src/registry/hash.h index 69882a79d9..7fcaced319 100644 --- a/lib/erl_interface/src/registry/hash.h +++ b/lib/erl_interface/src/registry/hash.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/hash_dohash.c b/lib/erl_interface/src/registry/hash_dohash.c index 0be54e0d3d..6f859cef2e 100644 --- a/lib/erl_interface/src/registry/hash_dohash.c +++ b/lib/erl_interface/src/registry/hash_dohash.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/hash_foreach.c b/lib/erl_interface/src/registry/hash_foreach.c index 2fe8eebfbc..b58df27e8e 100644 --- a/lib/erl_interface/src/registry/hash_foreach.c +++ b/lib/erl_interface/src/registry/hash_foreach.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/hash_freetab.c b/lib/erl_interface/src/registry/hash_freetab.c index e509af4a69..0a2c0dcfe6 100644 --- a/lib/erl_interface/src/registry/hash_freetab.c +++ b/lib/erl_interface/src/registry/hash_freetab.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/hash_insert.c b/lib/erl_interface/src/registry/hash_insert.c index d1b27ee6fe..0002cb64df 100644 --- a/lib/erl_interface/src/registry/hash_insert.c +++ b/lib/erl_interface/src/registry/hash_insert.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/hash_isprime.c b/lib/erl_interface/src/registry/hash_isprime.c index 18fd74fbc7..58166c6957 100644 --- a/lib/erl_interface/src/registry/hash_isprime.c +++ b/lib/erl_interface/src/registry/hash_isprime.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/hash_lookup.c b/lib/erl_interface/src/registry/hash_lookup.c index 3a6643ad69..31c30179df 100644 --- a/lib/erl_interface/src/registry/hash_lookup.c +++ b/lib/erl_interface/src/registry/hash_lookup.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/hash_newtab.c b/lib/erl_interface/src/registry/hash_newtab.c index 08ecc60f8a..4baa5a7b41 100644 --- a/lib/erl_interface/src/registry/hash_newtab.c +++ b/lib/erl_interface/src/registry/hash_newtab.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/hash_remove.c b/lib/erl_interface/src/registry/hash_remove.c index 63484daff6..080f15889e 100644 --- a/lib/erl_interface/src/registry/hash_remove.c +++ b/lib/erl_interface/src/registry/hash_remove.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/hash_resize.c b/lib/erl_interface/src/registry/hash_resize.c index c556ab7b68..031d8bfbf6 100644 --- a/lib/erl_interface/src/registry/hash_resize.c +++ b/lib/erl_interface/src/registry/hash_resize.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/hash_rlookup.c b/lib/erl_interface/src/registry/hash_rlookup.c index d774089e36..b0a948673a 100644 --- a/lib/erl_interface/src/registry/hash_rlookup.c +++ b/lib/erl_interface/src/registry/hash_rlookup.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/reg.h b/lib/erl_interface/src/registry/reg.h index 92798f02c8..261e36ac06 100644 --- a/lib/erl_interface/src/registry/reg.h +++ b/lib/erl_interface/src/registry/reg.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/reg_close.c b/lib/erl_interface/src/registry/reg_close.c index 1ac9e623a7..c1475383e1 100644 --- a/lib/erl_interface/src/registry/reg_close.c +++ b/lib/erl_interface/src/registry/reg_close.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/reg_delete.c b/lib/erl_interface/src/registry/reg_delete.c index b1fb7a1fac..8882f611bc 100644 --- a/lib/erl_interface/src/registry/reg_delete.c +++ b/lib/erl_interface/src/registry/reg_delete.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/reg_dirty.c b/lib/erl_interface/src/registry/reg_dirty.c index a128136054..00f19482c2 100644 --- a/lib/erl_interface/src/registry/reg_dirty.c +++ b/lib/erl_interface/src/registry/reg_dirty.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/reg_dump.c b/lib/erl_interface/src/registry/reg_dump.c index d1347491e5..43c9824433 100644 --- a/lib/erl_interface/src/registry/reg_dump.c +++ b/lib/erl_interface/src/registry/reg_dump.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2011. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/reg_free.c b/lib/erl_interface/src/registry/reg_free.c index aff6782925..d835520e76 100644 --- a/lib/erl_interface/src/registry/reg_free.c +++ b/lib/erl_interface/src/registry/reg_free.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/reg_get.c b/lib/erl_interface/src/registry/reg_get.c index e3f111e746..67d99e231e 100644 --- a/lib/erl_interface/src/registry/reg_get.c +++ b/lib/erl_interface/src/registry/reg_get.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/reg_getf.c b/lib/erl_interface/src/registry/reg_getf.c index 20071d6d95..35956c3d79 100644 --- a/lib/erl_interface/src/registry/reg_getf.c +++ b/lib/erl_interface/src/registry/reg_getf.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/reg_geti.c b/lib/erl_interface/src/registry/reg_geti.c index 14c8a17b51..09709fdf3d 100644 --- a/lib/erl_interface/src/registry/reg_geti.c +++ b/lib/erl_interface/src/registry/reg_geti.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/reg_getp.c b/lib/erl_interface/src/registry/reg_getp.c index b60aa9d37f..faff00bcb0 100644 --- a/lib/erl_interface/src/registry/reg_getp.c +++ b/lib/erl_interface/src/registry/reg_getp.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/reg_gets.c b/lib/erl_interface/src/registry/reg_gets.c index 32d34197c2..27fd83ac03 100644 --- a/lib/erl_interface/src/registry/reg_gets.c +++ b/lib/erl_interface/src/registry/reg_gets.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/reg_make.c b/lib/erl_interface/src/registry/reg_make.c index 11373afab9..ed77a740b6 100644 --- a/lib/erl_interface/src/registry/reg_make.c +++ b/lib/erl_interface/src/registry/reg_make.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/reg_open.c b/lib/erl_interface/src/registry/reg_open.c index 9965416599..73c2140145 100644 --- a/lib/erl_interface/src/registry/reg_open.c +++ b/lib/erl_interface/src/registry/reg_open.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/reg_purge.c b/lib/erl_interface/src/registry/reg_purge.c index b585a43a64..08483e32f5 100644 --- a/lib/erl_interface/src/registry/reg_purge.c +++ b/lib/erl_interface/src/registry/reg_purge.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/reg_resize.c b/lib/erl_interface/src/registry/reg_resize.c index 18a2c2670e..b451a28348 100644 --- a/lib/erl_interface/src/registry/reg_resize.c +++ b/lib/erl_interface/src/registry/reg_resize.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/reg_restore.c b/lib/erl_interface/src/registry/reg_restore.c index 49e8f2740d..75d073303f 100644 --- a/lib/erl_interface/src/registry/reg_restore.c +++ b/lib/erl_interface/src/registry/reg_restore.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2011. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/reg_set.c b/lib/erl_interface/src/registry/reg_set.c index 0519246a7f..95b90adb87 100644 --- a/lib/erl_interface/src/registry/reg_set.c +++ b/lib/erl_interface/src/registry/reg_set.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/reg_setf.c b/lib/erl_interface/src/registry/reg_setf.c index abbe409f10..e0879cb3d5 100644 --- a/lib/erl_interface/src/registry/reg_setf.c +++ b/lib/erl_interface/src/registry/reg_setf.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/reg_seti.c b/lib/erl_interface/src/registry/reg_seti.c index afb3b1fee7..507ed9907e 100644 --- a/lib/erl_interface/src/registry/reg_seti.c +++ b/lib/erl_interface/src/registry/reg_seti.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/reg_setp.c b/lib/erl_interface/src/registry/reg_setp.c index dd8038a811..1dd158778a 100644 --- a/lib/erl_interface/src/registry/reg_setp.c +++ b/lib/erl_interface/src/registry/reg_setp.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/reg_sets.c b/lib/erl_interface/src/registry/reg_sets.c index 7f0e64162f..d281d732b7 100644 --- a/lib/erl_interface/src/registry/reg_sets.c +++ b/lib/erl_interface/src/registry/reg_sets.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/reg_stat.c b/lib/erl_interface/src/registry/reg_stat.c index e876aa566c..e946199f4a 100644 --- a/lib/erl_interface/src/registry/reg_stat.c +++ b/lib/erl_interface/src/registry/reg_stat.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/src/registry/reg_tabstat.c b/lib/erl_interface/src/registry/reg_tabstat.c index 2c5d185ec1..1a3e654090 100644 --- a/lib/erl_interface/src/registry/reg_tabstat.c +++ b/lib/erl_interface/src/registry/reg_tabstat.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/test/Makefile b/lib/erl_interface/test/Makefile index 800573e8e4..94f4b422d6 100644 --- a/lib/erl_interface/test/Makefile +++ b/lib/erl_interface/test/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1997-2012. All Rights Reserved. +# 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. diff --git a/lib/erl_interface/test/Makefile.src b/lib/erl_interface/test/Makefile.src index f105a1a3d1..8cf2ea0933 100644 --- a/lib/erl_interface/test/Makefile.src +++ b/lib/erl_interface/test/Makefile.src @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1997-2009. All Rights Reserved. +# 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. diff --git a/lib/erl_interface/test/all_SUITE_data/Makefile.first b/lib/erl_interface/test/all_SUITE_data/Makefile.first index fe295b5e5c..b83fa6ff5c 100644 --- a/lib/erl_interface/test/all_SUITE_data/Makefile.first +++ b/lib/erl_interface/test/all_SUITE_data/Makefile.first @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2003-2009. All Rights Reserved. +# 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. diff --git a/lib/erl_interface/test/all_SUITE_data/Makefile.src b/lib/erl_interface/test/all_SUITE_data/Makefile.src index 476784230b..4f27b097c8 100644 --- a/lib/erl_interface/test/all_SUITE_data/Makefile.src +++ b/lib/erl_interface/test/all_SUITE_data/Makefile.src @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2003-2012. All Rights Reserved. +# 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. diff --git a/lib/erl_interface/test/all_SUITE_data/ei_runner.c b/lib/erl_interface/test/all_SUITE_data/ei_runner.c index 3a0de22df4..cd7a67c57c 100644 --- a/lib/erl_interface/test/all_SUITE_data/ei_runner.c +++ b/lib/erl_interface/test/all_SUITE_data/ei_runner.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2014. All Rights Reserved. + * 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. @@ -198,8 +198,8 @@ void free_packet(char* packet) * ----- ---------------------------- * [$b|Bytes] {bytes, Bytes} * [$e] eot - * [$f] test_server:fail() - * [$f|Reason] test_server:fail(Reason) + * [$f] ct:fail() + * [$f|Reason] ct:fail(Reason) * [$t|EncodedTerm] {term, Term} * [$N] 'NULL' * [$m|Message] io:format("~s", [Message]) (otherwise ignored) @@ -211,7 +211,7 @@ void free_packet(char* packet) * 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 test_server:fail() to be called); otherwise, + * 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. @@ -251,16 +251,21 @@ do_report(file, line, ok) /* - * This function causes a call to test_server:fail(Reason) on the + * This function causes a call to ct:fail(Reason) on the * Erlang side. */ -void do_fail(char* file, int line, char* reason) +void do_fail(const char* file, int line, const char* reason, ...) { + va_list ap; char sbuf[2048]; + char* sp = sbuf; - sbuf[0] = 'f'; - sprintf(sbuf+1, "%s, line %d: %s", file, line, reason); + *sp++ = 'f'; + sp += sprintf(sp, "%s, line %d: ", file, line); + va_start(ap, reason); + sp += vsprintf(sp, reason, ap); + va_end(ap); reply(sbuf, 1+strlen(sbuf+1)); } diff --git a/lib/erl_interface/test/all_SUITE_data/ei_runner.h b/lib/erl_interface/test/all_SUITE_data/ei_runner.h index 62997d00a0..2608661303 100644 --- a/lib/erl_interface/test/all_SUITE_data/ei_runner.h +++ b/lib/erl_interface/test/all_SUITE_data/ei_runner.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2014. All Rights Reserved. + * 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. @@ -52,10 +52,11 @@ void free_packet(char*); */ #define fail(reason) do_fail(__FILE__, __LINE__, reason) +#define fail1(reason, a1) do_fail(__FILE__, __LINE__, reason, a1) #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 do_fail(const char* file, int line, const char* reason, ...); void send_buffer(char* buf, int size); void message(char* format, ...); diff --git a/lib/erl_interface/test/all_SUITE_data/gccifier.c b/lib/erl_interface/test/all_SUITE_data/gccifier.c index ca022eb390..0c3ef915fb 100644 --- a/lib/erl_interface/test/all_SUITE_data/gccifier.c +++ b/lib/erl_interface/test/all_SUITE_data/gccifier.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2004-2012. All Rights Reserved. + * Copyright Ericsson AB 2004-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. diff --git a/lib/erl_interface/test/all_SUITE_data/gccifier.sh b/lib/erl_interface/test/all_SUITE_data/gccifier.sh index 594608df9f..179394bb4e 100755 --- a/lib/erl_interface/test/all_SUITE_data/gccifier.sh +++ b/lib/erl_interface/test/all_SUITE_data/gccifier.sh @@ -2,7 +2,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2005-2009. All Rights Reserved. +# Copyright Ericsson AB 2005-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. 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 74d32d9ea4..d9ad291f3d 100644 --- a/lib/erl_interface/test/all_SUITE_data/init_tc.erl +++ b/lib/erl_interface/test/all_SUITE_data/init_tc.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2013. All Rights Reserved. +%% 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. diff --git a/lib/erl_interface/test/all_SUITE_data/reclaim.h b/lib/erl_interface/test/all_SUITE_data/reclaim.h index eb0f7ce9fa..fe99bb0afc 100644 --- a/lib/erl_interface/test/all_SUITE_data/reclaim.h +++ b/lib/erl_interface/test/all_SUITE_data/reclaim.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/test/all_SUITE_data/runner.c b/lib/erl_interface/test/all_SUITE_data/runner.c index 47d918308d..42e8bb03e5 100644 --- a/lib/erl_interface/test/all_SUITE_data/runner.c +++ b/lib/erl_interface/test/all_SUITE_data/runner.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1997-2013. All Rights Reserved. + * 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. @@ -200,8 +200,8 @@ char *read_packet(int *len) * ----- ---------------------------- * [$b|Bytes] {bytes, Bytes} * [$e] eot - * [$f] test_server:fail() - * [$f|Reason] test_server:fail(Reason) + * [$f] ct:fail() + * [$f|Reason] ct:fail(Reason) * [$t|EncodedTerm] {term, Term} * [$N] 'NULL' * [$m|Message] io:format("~s", [Message]) (otherwise ignored) @@ -213,7 +213,7 @@ char *read_packet(int *len) * 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 test_server:fail() to be called); otherwise, + * 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. @@ -253,7 +253,7 @@ do_report(file, line, ok) /* - * This function causes a call to test_server:fail(Reason) on the + * This function causes a call to ct:fail(Reason) on the * Erlang side. */ diff --git a/lib/erl_interface/test/all_SUITE_data/runner.h b/lib/erl_interface/test/all_SUITE_data/runner.h index 2af267ecb9..493602869f 100644 --- a/lib/erl_interface/test/all_SUITE_data/runner.h +++ b/lib/erl_interface/test/all_SUITE_data/runner.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1997-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/test/ei_accept_SUITE.erl b/lib/erl_interface/test/ei_accept_SUITE.erl index 144ec99e0a..e06ee762d7 100644 --- a/lib/erl_interface/test/ei_accept_SUITE.erl +++ b/lib/erl_interface/test/ei_accept_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2001-2011. All Rights Reserved. +%% 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. @@ -21,97 +21,70 @@ %% -module(ei_accept_SUITE). --include_lib("test_server/include/test_server.hrl"). +-include_lib("common_test/include/ct.hrl"). -include("ei_accept_SUITE_data/ei_accept_test_cases.hrl"). --export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, - init_per_group/2,end_per_group/2, - init_per_testcase/2, end_per_testcase/2, - ei_accept/1, ei_threaded_accept/1]). +-export([all/0, suite/0, + ei_accept/1, ei_threaded_accept/1]). -import(runner, [get_term/1,send_term/2]). -suite() -> [{ct_hooks,[ts_install_cth]}]. +suite() -> + [{ct_hooks,[ts_install_cth]}, + {timetrap, {seconds, 30}}]. all() -> [ei_accept, ei_threaded_accept]. -groups() -> - []. - -init_per_suite(Config) -> - Config. - -end_per_suite(Config) -> - ok. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - -init_per_testcase(_Case, Config) -> - Dog = ?t:timetrap(?t:seconds(30)), - [{watchdog, Dog}|Config]. - -end_per_testcase(_Case, Config) -> - Dog = ?config(watchdog, Config), - test_server:timetrap_cancel(Dog), - ok. - ei_accept(Config) when is_list(Config) -> - ?line P = runner:start(?interpret), - ?line 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0), - - ?line Myname= hd(tl(string:tokens(atom_to_list(node()), "@"))), - ?line io:format("Myname ~p ~n", [Myname]), - ?line EINode= list_to_atom("c42@"++Myname), - ?line io:format("EINode ~p ~n", [EINode]), - ?line Self= self(), - ?line TermToSend= {call, Self, "Test"}, - ?line F= fun() -> - case waitfornode("c42",20) of - true -> - {any, EINode} ! TermToSend, - Self ! sent_ok; - false -> - Self ! never_published - end, - ok - end, - - ?line spawn(F), - ?line Port = 6543, - ?line {ok, Fd, _Node} = ei_accept(P, Port), - ?line TermReceived= ei_receive(P, Fd), - ?line io:format("Sent ~p received ~p ~n", [TermToSend, TermReceived]), - ?line TermToSend= TermReceived, - ?line receive - sent_ok -> - ok; - Unknown -> - io:format("~p ~n", [Unknown]) - after 1000 -> - io:format("timeout ~n") - end, - ?line runner:finish(P), + P = runner:start(?interpret), + 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0), + + Myname = hd(tl(string:tokens(atom_to_list(node()), "@"))), + io:format("Myname ~p ~n", [Myname]), + EINode = list_to_atom("c42@"++Myname), + io:format("EINode ~p ~n", [EINode]), + Self = self(), + TermToSend= {call, Self, "Test"}, + F= fun() -> + case waitfornode("c42",20) of + true -> + {any, EINode} ! TermToSend, + Self ! sent_ok; + false -> + Self ! never_published + end, + ok + end, + + spawn(F), + Port = 6543, + {ok, Fd, _Node} = ei_accept(P, Port), + TermReceived= ei_receive(P, Fd), + io:format("Sent ~p received ~p ~n", [TermToSend, TermReceived]), + TermToSend= TermReceived, + receive + sent_ok -> + ok; + Unknown -> + io:format("~p ~n", [Unknown]) + after 1000 -> + io:format("timeout ~n") + end, + runner:finish(P), ok. ei_threaded_accept(Config) when is_list(Config) -> - ?line Einode = filename:join(?config(data_dir, Config), "eiaccnode"), - ?line N = 1, % 3, - ?line Host = atom_to_list(node()), - ?line Port = 6767, - ?line start_einode(Einode, N, Host, Port), - ?line io:format("started eiaccnode"), - %%?line spawn_link(fun() -> start_einode(Einode, N, Host, Port) end), - ?line TestServerPid = self(), - ?line [ spawn_link(fun() -> send_rec_einode(I, TestServerPid) end) - || I <- lists:seq(0, N-1) ], - ?line [ receive I -> ok end - || I <- lists:seq(0, N-1) ], + Einode = filename:join(proplists:get_value(data_dir, Config), "eiaccnode"), + N = 1, % 3, + Host = atom_to_list(node()), + Port = 6767, + start_einode(Einode, N, Host, Port), + io:format("started eiaccnode"), + %%spawn_link(fun() -> start_einode(Einode, N, Host, Port) end), + TestServerPid = self(), + [spawn_link(fun() -> send_rec_einode(I, TestServerPid) end) || I <- lists:seq(0, N-1)], + [receive I -> ok end || I <- lists:seq(0, N-1) ], ok. waitfornode(String,0) -> @@ -120,66 +93,61 @@ waitfornode(String,0) -> waitfornode(String,N) -> Registered = [X || {X,_} <- element(2,erl_epmd:names())], case lists:member(String,Registered) of - true -> - true; - false -> - timer:sleep(1000), - waitfornode(String,N-1) + true -> + true; + false -> + timer:sleep(1000), + waitfornode(String,N-1) end. send_rec_einode(N, TestServerPid) -> - ?line Myname= hd(tl(string:tokens(atom_to_list(node()), "@"))), - ?line FirstPart = "eiacc" ++ integer_to_list(N), - ?line EINode= list_to_atom(FirstPart ++ "@" ++ Myname), - ?line io:format("EINode ~p ~n", [EINode]), - ?line Self= self(), - ?line case waitfornode(FirstPart,20) of - true -> ok; - false -> test_server:fail({never_published,EINode}) - end, - ?line {any, EINode} ! Self, - ?line receive - {N,_}=X -> - ?line io:format("Received by ~s ~p~n", [EINode, X]), - ?line TestServerPid ! N, - ?line X - after 10000 -> - ?line test_server:fail(EINode) - end. + Myname= hd(tl(string:tokens(atom_to_list(node()), "@"))), + FirstPart = "eiacc" ++ integer_to_list(N), + EINode= list_to_atom(FirstPart ++ "@" ++ Myname), + io:format("EINode ~p ~n", [EINode]), + Self= self(), + case waitfornode(FirstPart,20) of + true -> ok; + false -> ct:fail({never_published,EINode}) + end, + {any, EINode} ! Self, + receive + {N,_}=X -> + io:format("Received by ~s ~p~n", [EINode, X]), + TestServerPid ! N, + X + after 10000 -> + ct:fail(EINode) + end. start_einode(Einode, N, Host, Port) -> Einodecmd = Einode ++ " " ++ atom_to_list(erlang:get_cookie()) - ++ " " ++ integer_to_list(N) ++ " " ++ Host ++ " " - ++ integer_to_list(Port) ++ " nothreads", + ++ " " ++ integer_to_list(N) ++ " " ++ Host ++ " " + ++ integer_to_list(Port) ++ " nothreads", io:format("Einodecmd ~p ~n", [Einodecmd]), - ?line open_port({spawn, Einodecmd}, []), + open_port({spawn, Einodecmd}, []), ok. - %%% Interface functions for ei (erl_interface) functions. ei_connect_init(P, Num, Cookie, Creation) -> send_command(P, ei_connect_init, [Num,Cookie,Creation]), case get_term(P) of - {term,Int} when is_integer(Int) -> Int + {term,Int} when is_integer(Int) -> Int end. ei_accept(P, PortNo) -> send_command(P, ei_accept, [PortNo]), case get_term(P) of - {term,{Fd, _, Node}} when Fd >= 0 -> {ok, Fd, Node}; - {term,{_Fd, Errno, _Node}} -> {error,Errno} + {term,{Fd, _, Node}} when Fd >= 0 -> {ok, Fd, Node}; + {term,{_Fd, Errno, _Node}} -> {error,Errno} end. ei_receive(P, Fd) -> send_command(P, ei_receive, [Fd]), - {term, T}= get_term(P), + {term, T} = get_term(P), T. send_command(P, Name, Args) -> runner:send_term(P, {Name,list_to_tuple(Args)}). - - - - diff --git a/lib/erl_interface/test/ei_accept_SUITE_data/Makefile.first b/lib/erl_interface/test/ei_accept_SUITE_data/Makefile.first index 8153368870..6e89cc5a78 100644 --- a/lib/erl_interface/test/ei_accept_SUITE_data/Makefile.first +++ b/lib/erl_interface/test/ei_accept_SUITE_data/Makefile.first @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2001-2009. All Rights Reserved. +# 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. 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 d900b4aa8f..10ef437f8b 100644 --- a/lib/erl_interface/test/ei_accept_SUITE_data/Makefile.src +++ b/lib/erl_interface/test/ei_accept_SUITE_data/Makefile.src @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2001-2009. All Rights Reserved. +# 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. 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 ad68ba9bb5..7b81ee5491 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 @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2009. All Rights Reserved. + * 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. 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 6a3d2bc157..308f843530 100644 --- a/lib/erl_interface/test/ei_accept_SUITE_data/eiaccnode.c +++ b/lib/erl_interface/test/ei_accept_SUITE_data/eiaccnode.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/test/ei_connect_SUITE.erl b/lib/erl_interface/test/ei_connect_SUITE.erl index 3385d1eb6c..66498deadc 100644 --- a/lib/erl_interface/test/ei_connect_SUITE.erl +++ b/lib/erl_interface/test/ei_connect_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2001-2011. All Rights Reserved. +%% 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. @@ -21,176 +21,148 @@ %% -module(ei_connect_SUITE). --include_lib("test_server/include/test_server.hrl"). +-include_lib("common_test/include/ct.hrl"). -include("ei_connect_SUITE_data/ei_connect_test_cases.hrl"). --export([ - all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, - init_per_group/2,end_per_group/2, - init_per_testcase/2, - end_per_testcase/2, - - ei_send/1, - ei_reg_send/1, - ei_format_pid/1, - ei_rpc/1, - rpc_test/1, - ei_send_funs/1, - ei_threaded_send/1, - ei_set_get_tracelevel/1 - ]). +-export([all/0, suite/0, + ei_send/1, + ei_reg_send/1, + ei_format_pid/1, + ei_rpc/1, + rpc_test/1, + ei_send_funs/1, + ei_threaded_send/1, + ei_set_get_tracelevel/1]). -import(runner, [get_term/1,send_term/2]). -suite() -> [{ct_hooks,[ts_install_cth]}]. +suite() -> + [{ct_hooks,[ts_install_cth]}, + {timetrap, {seconds, 30}}]. all() -> [ei_send, ei_reg_send, ei_rpc, ei_format_pid, ei_send_funs, ei_threaded_send, ei_set_get_tracelevel]. -groups() -> - []. - -init_per_suite(Config) -> - Config. - -end_per_suite(_Config) -> - ok. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - -init_per_testcase(_Case, Config) -> - Dog = ?t:timetrap(?t:minutes(0.25)), - [{watchdog, Dog}|Config]. - -end_per_testcase(_Case, Config) -> - Dog = ?config(watchdog, Config), - test_server:timetrap_cancel(Dog), - ok. - ei_send(Config) when is_list(Config) -> - ?line P = runner:start(?interpret), - ?line 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0), - ?line {ok,Fd} = ei_connect(P, node()), + P = runner:start(?interpret), + 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0), + {ok,Fd} = ei_connect(P, node()), - ?line ok = ei_send(P, Fd, self(), AMsg={a,message}), - ?line receive AMsg -> ok end, + ok = ei_send(P, Fd, self(), AMsg={a,message}), + receive AMsg -> ok end, - ?line runner:send_eot(P), - ?line runner:recv_eot(P), + runner:send_eot(P), + runner:recv_eot(P), ok. ei_format_pid(Config) when is_list(Config) -> - ?line S = self(), - ?line P = runner:start(?interpret), - ?line 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0), - ?line {ok,Fd} = ei_connect(P, node()), + S = self(), + P = runner:start(?interpret), + 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0), + {ok,Fd} = ei_connect(P, node()), - ?line ok = ei_format_pid(P, Fd, S), - ?line receive S -> ok end, + ok = ei_format_pid(P, Fd, S), + receive S -> ok end, - ?line runner:send_eot(P), - ?line runner:recv_eot(P), + runner:send_eot(P), + runner:recv_eot(P), ok. ei_send_funs(Config) when is_list(Config) -> - ?line P = runner:start(?interpret), - ?line 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0), - ?line {ok,Fd} = ei_connect(P, node()), - - ?line Fun1 = fun ei_send/1, - ?line Fun2 = fun(X) -> P, X, Fd, Fun1 end, - - ?line AMsg={Fun1,Fun2}, + P = runner:start(?interpret), + 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0), + {ok,Fd} = ei_connect(P, node()), + + Fun1 = fun ei_send/1, + Fun2 = fun(X) -> P, X, Fd, Fun1 end, + + AMsg={Fun1,Fun2}, %%AMsg={wait_with_funs, new_dist_format}, - ?line ok = ei_send_funs(P, Fd, self(), AMsg), - ?line EIMsg = receive M -> M end, - ?line EIMsg = AMsg, + ok = ei_send_funs(P, Fd, self(), AMsg), + EIMsg = receive M -> M end, + EIMsg = AMsg, - ?line runner:send_eot(P), - ?line runner:recv_eot(P), + runner:send_eot(P), + runner:recv_eot(P), ok. ei_reg_send(Config) when is_list(Config) -> - ?line P = runner:start(?interpret), - ?line 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0), - ?line {ok,Fd} = ei_connect(P, node()), + P = runner:start(?interpret), + 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0), + {ok,Fd} = ei_connect(P, node()), ARegName = a_strange_registred_name, - ?line register(ARegName, self()), - ?line ok = ei_reg_send(P, Fd, ARegName, AMsg={another,[strange],message}), - ?line receive AMsg -> ok end, + register(ARegName, self()), + ok = ei_reg_send(P, Fd, ARegName, AMsg={another,[strange],message}), + receive AMsg -> ok end, - ?line runner:send_eot(P), - ?line runner:recv_eot(P), + runner:send_eot(P), + runner:recv_eot(P), ok. ei_threaded_send(Config) when is_list(Config) -> - ?line Einode = filename:join(?config(data_dir, Config), "einode"), - ?line N = 15, - ?line Host = atom_to_list(node()), - ?line TestServerPid = self(), - ?line [ spawn_link(fun() -> rec_einode(I, TestServerPid) end) - || I <- lists:seq(0, N-1) ], - ?line [ receive {I,registered} -> ok end - || I <- lists:seq(0, N-1) ], - ?line spawn_link(fun() -> start_einode(Einode, N, Host) end), - ?line [ receive I -> ok end - || I <- lists:seq(0, N-1) ], + Einode = filename:join(proplists:get_value(data_dir, Config), "einode"), + N = 15, + Host = atom_to_list(node()), + TestServerPid = self(), + [ spawn_link(fun() -> rec_einode(I, TestServerPid) end) + || I <- lists:seq(0, N-1) ], + [ receive {I,registered} -> ok end + || I <- lists:seq(0, N-1) ], + spawn_link(fun() -> start_einode(Einode, N, Host) end), + [ receive I -> ok end + || I <- lists:seq(0, N-1) ], ok. rec_einode(N, TestServerPid) -> - ?line Regname = list_to_atom("mth"++integer_to_list(N)), - ?line register(Regname, self()), - ?line TestServerPid ! {N, registered}, - ?line io:format("~p waiting~n", [Regname]), - ?line receive - X -> - ?line io:format("Received by ~s ~p~n", [Regname, X]), - ?line TestServerPid ! N, - ?line X - after 10000 -> - ?line test_server:fail(Regname) - end. + Regname = list_to_atom("mth"++integer_to_list(N)), + register(Regname, self()), + TestServerPid ! {N, registered}, + io:format("~p waiting~n", [Regname]), + receive + X -> + io:format("Received by ~s ~p~n", [Regname, X]), + TestServerPid ! N, + X + after 10000 -> + ct:fail(Regname) + end. start_einode(Einode, N, Host) -> Einodecmd = Einode ++ " " ++ atom_to_list(erlang:get_cookie()) - ++ " " ++ integer_to_list(N) ++ " " ++ Host, + ++ " " ++ integer_to_list(N) ++ " " ++ Host, io:format("Einodecmd ~p ~n", [Einodecmd]), - ?line open_port({spawn, Einodecmd}, []), + open_port({spawn, Einodecmd}, []), ok. ei_rpc(Config) when is_list(Config) -> - ?line P = runner:start(?interpret), - ?line 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0), - ?line {ok,Fd} = ei_connect(P, node()), + P = runner:start(?interpret), + 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0), + {ok,Fd} = ei_connect(P, node()), - ?line S= "Hej du glade!", SRev = lists:reverse(S), - ?line X = ei_rpc(P, Fd, self(), {?MODULE, rpc_test}, [SRev]), - ?line {term, S}= X, + S= "Hej du glade!", SRev = lists:reverse(S), + X = ei_rpc(P, Fd, self(), {?MODULE, rpc_test}, [SRev]), + {term, S}= X, - ?line runner:send_eot(P), - ?line runner:recv_eot(P), + runner:send_eot(P), + runner:recv_eot(P), ok. ei_set_get_tracelevel(Config) when is_list(Config) -> - ?line P = runner:start(?interpret), - ?line 5 = ei_set_get_tracelevel(P, 5), - ?line 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0), - ?line {ok,Fd} = ei_connect(P, node()), + P = runner:start(?interpret), + 5 = ei_set_get_tracelevel(P, 5), + 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0), + {ok,Fd} = ei_connect(P, node()), - ?line S= "Hej du glade!", SRev = lists:reverse(S), - ?line X = ei_rpc(P, Fd, self(), {?MODULE, rpc_test}, [SRev]), - ?line {term, S}= X, + S= "Hej du glade!", SRev = lists:reverse(S), + X = ei_rpc(P, Fd, self(), {?MODULE, rpc_test}, [SRev]), + {term, S}= X, - ?line 0 = ei_set_get_tracelevel(P, 0), + 0 = ei_set_get_tracelevel(P, 0), - ?line runner:send_eot(P), - ?line runner:recv_eot(P), + runner:send_eot(P), + runner:recv_eot(P), ok. @@ -199,20 +171,20 @@ ei_set_get_tracelevel(Config) when is_list(Config) -> ei_connect_init(P, Num, Cookie, Creation) -> send_command(P, ei_connect_init, [Num,Cookie,Creation]), case get_term(P) of - {term,Int} when is_integer(Int) -> Int + {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} + {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 - {term,{tracelevel, Level}} when is_integer(Level) -> Level + {term,{tracelevel, Level}} when is_integer(Level) -> Level end. ei_send(P, Fd, To, Msg) -> @@ -238,12 +210,12 @@ ei_rpc(P, Fd, To, Func, Msg) -> get_send_result(P) -> case get_term(P) of - {term,{0,_}} -> ok; - {term,{1,_}} -> ok; - {term,{-1,Errno}} -> {error,Errno}; - {term,{Res,Errno}}-> - io:format("Return value: ~p\nerl_errno: ~p", [Res,Errno]), - ?t:fail(bad_return_value) + {term,{0,_}} -> ok; + {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) -> diff --git a/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.first b/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.first index feee049795..1a9b4dbcea 100644 --- a/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.first +++ b/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.first @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2001-2009. All Rights Reserved. +# 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. 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 49e5e8f8e2..c2d8261dd8 100644 --- a/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.src +++ b/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.src @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2001-2009. All Rights Reserved. +# 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. @@ -23,9 +23,10 @@ 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@ \ - $(LIBEI) @LIBS@ @erl_interface_sock_libs@ \ + $(LIBERL) $(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@ 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 cfad73fd07..6a3796dd24 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 @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2011. All Rights Reserved. + * 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. 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 f151f6d2d6..bb71575740 100644 --- a/lib/erl_interface/test/ei_connect_SUITE_data/einode.c +++ b/lib/erl_interface/test/ei_connect_SUITE_data/einode.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2009. All Rights Reserved. + * 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. @@ -35,6 +35,7 @@ #endif #include "ei.h" +#include "erl_interface.h" #ifdef VXWORKS #define MAIN cnode @@ -115,6 +116,8 @@ MAIN(int argc, char *argv[]) if (argc < 3) exit(1); + erl_init(NULL, 0); + cookie = argv[1]; n = atoi(argv[2]); if (n > 100) diff --git a/lib/erl_interface/test/ei_decode_SUITE.erl b/lib/erl_interface/test/ei_decode_SUITE.erl index 0abcf50fb5..1495a0d5d9 100644 --- a/lib/erl_interface/test/ei_decode_SUITE.erl +++ b/lib/erl_interface/test/ei_decode_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2013. All Rights Reserved. +%% Copyright Ericsson AB 2004-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. @@ -21,23 +21,18 @@ %% -module(ei_decode_SUITE). --include_lib("test_server/include/test_server.hrl"). +-include_lib("common_test/include/ct.hrl"). -include("ei_decode_SUITE_data/ei_decode_test_cases.hrl"). --export( - [ - all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, - init_per_group/2,end_per_group/2, init_per_testcase/2, - end_per_testcase/2, - test_ei_decode_long/1, - test_ei_decode_ulong/1, - test_ei_decode_longlong/1, - test_ei_decode_ulonglong/1, - test_ei_decode_char/1, - test_ei_decode_nonoptimal/1, - test_ei_decode_misc/1, - test_ei_decode_utf8_atom/1 - ]). +-export([all/0, suite/0, + test_ei_decode_long/1, + test_ei_decode_ulong/1, + test_ei_decode_longlong/1, + test_ei_decode_ulonglong/1, + test_ei_decode_char/1, + test_ei_decode_nonoptimal/1, + test_ei_decode_misc/1, + test_ei_decode_utf8_atom/1]). suite() -> [{ct_hooks,[ts_install_cth]}]. @@ -47,27 +42,6 @@ all() -> test_ei_decode_char, test_ei_decode_nonoptimal, test_ei_decode_misc, test_ei_decode_utf8_atom]. -groups() -> - []. - -init_per_suite(Config) -> - Config. - -end_per_suite(_Config) -> - ok. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - -init_per_testcase(_TC, Config) -> - Config. - -end_per_testcase(_RC, Config) -> - Config. - %% --------------------------------------------------------------------------- % NOTE: for historical reasons we don't pach as tight as we can, @@ -76,55 +50,51 @@ end_per_testcase(_RC, Config) -> %% ######################################################################## %% -test_ei_decode_long(suite) -> []; test_ei_decode_long(Config) when is_list(Config) -> - ?line P = runner:start(?test_ei_decode_long), + P = runner:start(?test_ei_decode_long), send_integers(P), - ?line runner:recv_eot(P), + runner:recv_eot(P), ok. %% ######################################################################## %% -test_ei_decode_ulong(suite) -> []; test_ei_decode_ulong(Config) when is_list(Config) -> - ?line P = runner:start(?test_ei_decode_ulong), + P = runner:start(?test_ei_decode_ulong), send_integers(P), - ?line runner:recv_eot(P), + runner:recv_eot(P), ok. % (*) In practical terms, other values may fit into the ext format % i32 is signed 32 bit on C side % u32 is unsigned 32 bit on C side - + %% ######################################################################## %% -test_ei_decode_longlong(suite) -> []; test_ei_decode_longlong(Config) when is_list(Config) -> case os:type() of - vxworks -> - {skip,"Skipped on VxWorks"}; - _ -> - ?line P = runner:start(?test_ei_decode_longlong), - send_integers2(P), - ?line runner:recv_eot(P), - ok + vxworks -> + {skip,"Skipped on VxWorks"}; + _ -> + P = runner:start(?test_ei_decode_longlong), + send_integers2(P), + runner:recv_eot(P), + ok end. %% ######################################################################## %% -test_ei_decode_ulonglong(suite) -> []; test_ei_decode_ulonglong(Config) when is_list(Config) -> case os:type() of - vxworks -> - {skip,"Skipped on VxWorks"}; - _ -> - ?line P = runner:start(?test_ei_decode_ulonglong), - send_integers2(P), - ?line runner:recv_eot(P), - ok + vxworks -> + {skip,"Skipped on VxWorks"}; + _ -> + P = runner:start(?test_ei_decode_ulonglong), + send_integers2(P), + runner:recv_eot(P), + ok end. @@ -133,38 +103,36 @@ test_ei_decode_ulonglong(Config) when is_list(Config) -> %% it is unsigned. %% FIXME maybe the API should change to use "unsigned char" to be clear?! -test_ei_decode_char(suite) -> []; test_ei_decode_char(Config) when is_list(Config) -> - ?line P = runner:start(?test_ei_decode_char), + P = runner:start(?test_ei_decode_char), - ?line send_term_as_binary(P,0), - ?line send_term_as_binary(P,16#7f), - ?line send_term_as_binary(P,16#ff), + send_term_as_binary(P,0), + send_term_as_binary(P,16#7f), + send_term_as_binary(P,16#ff), - ?line send_term_as_binary(P, []), % illegal type + send_term_as_binary(P, []), % illegal type - ?line runner:recv_eot(P), + runner:recv_eot(P), ok. %% ######################################################################## %% -test_ei_decode_nonoptimal(suite) -> []; test_ei_decode_nonoptimal(Config) when is_list(Config) -> - ?line P = runner:start(?test_ei_decode_nonoptimal), + P = runner:start(?test_ei_decode_nonoptimal), 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 + vxworks -> + ok; + _ -> + send_non_optimal(P), % decode_longlong + send_non_optimal_pos(P) % decode_ulonglong end, - ?line runner:recv_eot(P), + runner:recv_eot(P), ok. @@ -173,82 +141,81 @@ send_non_optimal(P) -> send_non_optimal_neg(P). send_non_optimal_pos(P) -> - ?line send_raw(P, <<131,97,42>>), - ?line send_raw(P, <<131,98,42:32>>), - ?line send_raw(P, <<131,110,1,0,42>>), - ?line send_raw(P, <<131,110,2,0,42,0>>), - ?line send_raw(P, <<131,110,4,0,42,0,0,0>>), - ?line send_raw(P, <<131,111,0,0,0,1,0,42>>), - ?line send_raw(P, <<131,111,0,0,0,2,0,42,0>>), - ?line send_raw(P, <<131,111,0,0,0,3,0,42,0,0>>), - ?line send_raw(P, <<131,111,0,0,0,6,0,42,0,0,0,0,0>>), + send_raw(P, <<131,97,42>>), + send_raw(P, <<131,98,42:32>>), + send_raw(P, <<131,110,1,0,42>>), + send_raw(P, <<131,110,2,0,42,0>>), + send_raw(P, <<131,110,4,0,42,0,0,0>>), + send_raw(P, <<131,111,0,0,0,1,0,42>>), + send_raw(P, <<131,111,0,0,0,2,0,42,0>>), + send_raw(P, <<131,111,0,0,0,3,0,42,0,0>>), + send_raw(P, <<131,111,0,0,0,6,0,42,0,0,0,0,0>>), ok. send_non_optimal_neg(P) -> -% ?line send_raw(P, <<131,97,-42>>), - ?line send_raw(P, <<131,98,-42:32>>), - ?line send_raw(P, <<131,110,1,1,42>>), - ?line send_raw(P, <<131,110,2,1,42,0>>), - ?line send_raw(P, <<131,110,4,1,42,0,0,0>>), - ?line send_raw(P, <<131,111,0,0,0,1,1,42>>), - ?line send_raw(P, <<131,111,0,0,0,2,1,42,0>>), - ?line send_raw(P, <<131,111,0,0,0,3,1,42,0,0>>), - ?line send_raw(P, <<131,111,0,0,0,6,1,42,0,0,0,0,0>>), + % send_raw(P, <<131,97,-42>>), + send_raw(P, <<131,98,-42:32>>), + send_raw(P, <<131,110,1,1,42>>), + send_raw(P, <<131,110,2,1,42,0>>), + send_raw(P, <<131,110,4,1,42,0,0,0>>), + send_raw(P, <<131,111,0,0,0,1,1,42>>), + send_raw(P, <<131,111,0,0,0,2,1,42,0>>), + send_raw(P, <<131,111,0,0,0,3,1,42,0,0>>), + send_raw(P, <<131,111,0,0,0,6,1,42,0,0,0,0,0>>), ok. %% ######################################################################## %% -test_ei_decode_misc(suite) -> []; test_ei_decode_misc(Config) when is_list(Config) -> - ?line P = runner:start(?test_ei_decode_misc), + P = runner:start(?test_ei_decode_misc), - ?line send_term_as_binary(P,0.0), - ?line send_term_as_binary(P,-1.0), - ?line send_term_as_binary(P,1.0), + send_term_as_binary(P,0.0), + send_term_as_binary(P,-1.0), + send_term_as_binary(P,1.0), - ?line send_term_as_binary(P,false), - ?line send_term_as_binary(P,true), + send_term_as_binary(P,false), + send_term_as_binary(P,true), - ?line send_term_as_binary(P,foo), - ?line send_term_as_binary(P,''), - ?line send_term_as_binary(P,'ÅÄÖåäö'), + send_term_as_binary(P,foo), + send_term_as_binary(P,''), + send_term_as_binary(P,'ÅÄÖåäö'), - ?line send_term_as_binary(P,"foo"), - ?line send_term_as_binary(P,""), - ?line send_term_as_binary(P,"ÅÄÖåäö"), + send_term_as_binary(P,"foo"), + send_term_as_binary(P,""), + send_term_as_binary(P,"ÅÄÖåäö"), - ?line send_term_as_binary(P,<<"foo">>), - ?line send_term_as_binary(P,<<>>), - ?line send_term_as_binary(P,<<"ÅÄÖåäö">>), + send_term_as_binary(P,<<"foo">>), + send_term_as_binary(P,<<>>), + send_term_as_binary(P,<<"ÅÄÖåäö">>), -% ?line send_term_as_binary(P,{}), -% ?line send_term_as_binary(P,[]), + % send_term_as_binary(P,{}), + % send_term_as_binary(P,[]), - ?line runner:recv_eot(P), + runner:recv_eot(P), ok. %% ######################################################################## %% test_ei_decode_utf8_atom(Config) -> - ?line P = runner:start(?test_ei_decode_utf8_atom), + P = runner:start(?test_ei_decode_utf8_atom), send_utf8_atom_as_binary(P,"Ã¥"), send_utf8_atom_as_binary(P,"ä"), send_term_as_binary(P,'ö'), send_term_as_binary(P,'õ'), - - ?line send_utf8_atom_as_binary(P,[1758]), - ?line send_utf8_atom_as_binary(P,[1758,1758]), - ?line send_utf8_atom_as_binary(P,[1758,1758,1758]), - ?line send_utf8_atom_as_binary(P,[1758,1758,1758,1758]), + + send_utf8_atom_as_binary(P,[1758]), + send_utf8_atom_as_binary(P,[1758,1758]), + send_utf8_atom_as_binary(P,[1758,1758,1758]), + send_utf8_atom_as_binary(P,[1758,1758,1758,1758]), send_utf8_atom_as_binary(P,"a"), send_utf8_atom_as_binary(P,"b"), send_term_as_binary(P,'c'), send_term_as_binary(P,'d'), - ?line runner:recv_eot(P), + runner:recv_eot(P), ok. @@ -264,77 +231,77 @@ send_utf8_atom_as_binary(Port, String) -> Port ! {self(), {command, term_to_binary(uc_atup(String))}}. send_integers(P) -> - ?line send_term_as_binary(P,0), % SMALL_INTEGER_EXT smallest - ?line send_term_as_binary(P,255), % SMALL_INTEGER_EXT largest - ?line send_term_as_binary(P,256), % INTEGER_EXT smallest pos (*) - ?line send_term_as_binary(P,-1), % INTEGER_EXT largest neg - - ?line send_term_as_binary(P, 16#07ffffff), % INTEGER_EXT old largest (28 bits) - ?line send_term_as_binary(P,-16#08000000), % INTEGER_EXT old smallest - ?line send_term_as_binary(P, 16#08000000), % SMALL_BIG_EXT old smallest pos(*) - ?line send_term_as_binary(P,-16#08000001), % SMALL_BIG_EXT old largest neg (*) - - ?line send_term_as_binary(P, 16#7fffffff), % INTEGER_EXT new largest (32 bits) - ?line send_term_as_binary(P,-16#80000000), % INTEGER_EXT new smallest (32 bis) - ?line send_term_as_binary(P, 16#80000000), % SMALL_BIG_EXT new smallest pos(*) - ?line send_term_as_binary(P,-16#80000001), % SMALL_BIG_EXT new largest neg (*) - + send_term_as_binary(P,0), % SMALL_INTEGER_EXT smallest + send_term_as_binary(P,255), % SMALL_INTEGER_EXT largest + send_term_as_binary(P,256), % INTEGER_EXT smallest pos (*) + send_term_as_binary(P,-1), % INTEGER_EXT largest neg + + send_term_as_binary(P, 16#07ffffff), % INTEGER_EXT old largest (28 bits) + send_term_as_binary(P,-16#08000000), % INTEGER_EXT old smallest + send_term_as_binary(P, 16#08000000), % SMALL_BIG_EXT old smallest pos(*) + send_term_as_binary(P,-16#08000001), % SMALL_BIG_EXT old largest neg (*) + + send_term_as_binary(P, 16#7fffffff), % INTEGER_EXT new largest (32 bits) + send_term_as_binary(P,-16#80000000), % INTEGER_EXT new smallest (32 bis) + send_term_as_binary(P, 16#80000000), % SMALL_BIG_EXT new smallest pos(*) + send_term_as_binary(P,-16#80000001), % SMALL_BIG_EXT new largest neg (*) + case erlang:system_info({wordsize,external}) of - 4 -> - ?line send_term_as_binary(P, 16#80000000),% SMALL_BIG_EXT u32 - ?line send_term_as_binary(P, 16#ffffffff),% SMALL_BIG_EXT largest u32 - - ?line send_term_as_binary(P, 16#7fffffffffff), % largest i48 - ?line send_term_as_binary(P,-16#800000000000), % smallest i48 - ?line send_term_as_binary(P, 16#ffffffffffff), % largest u48 - ?line send_term_as_binary(P, 16#7fffffffffffffff), % largest i64 - ?line send_term_as_binary(P,-16#8000000000000000), % smallest i64 - ?line send_term_as_binary(P, 16#ffffffffffffffff); % largest u64 - 8 -> - ?line send_term_as_binary(P, 16#8000000000000000),% SMALL_BIG_EXT u64 - % SMALL_BIG_EXT largest u64 - ?line send_term_as_binary(P, 16#ffffffffffffffff), - % largest i96 - ?line send_term_as_binary(P, 16#7fffffffffffffffffffffff), - % smallest i96 - ?line send_term_as_binary(P,-16#800000000000000000000000), - % largest u96 - ?line send_term_as_binary(P, 16#ffffffffffffffffffffffff), - % largest i128 - ?line send_term_as_binary(P, 16#7fffffffffffffffffffffffffffffff), - % smallest i128 - ?line send_term_as_binary(P,-16#80000000000000000000000000000000), - % largest u128 - ?line send_term_as_binary(P, 16#ffffffffffffffffffffffffffffffff) + 4 -> + send_term_as_binary(P, 16#80000000),% SMALL_BIG_EXT u32 + send_term_as_binary(P, 16#ffffffff),% SMALL_BIG_EXT largest u32 + + send_term_as_binary(P, 16#7fffffffffff), % largest i48 + send_term_as_binary(P,-16#800000000000), % smallest i48 + send_term_as_binary(P, 16#ffffffffffff), % largest u48 + send_term_as_binary(P, 16#7fffffffffffffff), % largest i64 + send_term_as_binary(P,-16#8000000000000000), % smallest i64 + send_term_as_binary(P, 16#ffffffffffffffff); % largest u64 + 8 -> + send_term_as_binary(P, 16#8000000000000000),% SMALL_BIG_EXT u64 + % SMALL_BIG_EXT largest u64 + send_term_as_binary(P, 16#ffffffffffffffff), + % largest i96 + send_term_as_binary(P, 16#7fffffffffffffffffffffff), + % smallest i96 + send_term_as_binary(P,-16#800000000000000000000000), + % largest u96 + send_term_as_binary(P, 16#ffffffffffffffffffffffff), + % largest i128 + send_term_as_binary(P, 16#7fffffffffffffffffffffffffffffff), + % smallest i128 + send_term_as_binary(P,-16#80000000000000000000000000000000), + % largest u128 + send_term_as_binary(P, 16#ffffffffffffffffffffffffffffffff) end, - ?line send_term_as_binary(P, []), % illegal type + send_term_as_binary(P, []), % illegal type ok. send_integers2(P) -> - ?line send_term_as_binary(P,0), % SMALL_INTEGER_EXT smallest - ?line send_term_as_binary(P,255), % SMALL_INTEGER_EXT largest - ?line send_term_as_binary(P,256), % INTEGER_EXT smallest pos (*) - ?line send_term_as_binary(P,-1), % INTEGER_EXT largest neg - - ?line send_term_as_binary(P, 16#07ffffff), % INTEGER_EXT old largest (28 bits) - ?line send_term_as_binary(P,-16#08000000), % INTEGER_EXT old smallest - ?line send_term_as_binary(P, 16#08000000), % SMALL_BIG_EXT old smallest pos(*) - ?line send_term_as_binary(P,-16#08000001), % SMALL_BIG_EXT old largest neg (*) - - ?line send_term_as_binary(P, 16#7fffffff), % INTEGER_EXT new largest (32 bits) - ?line send_term_as_binary(P,-16#80000000), % INTEGER_EXT new smallest - ?line send_term_as_binary(P, 16#80000000), % SMALL_BIG_EXT new smallest pos(*) - ?line send_term_as_binary(P,-16#80000001), % SMALL_BIG_EXT new largest neg (*) - - ?line send_term_as_binary(P, 16#ffffffff),% SMALL_BIG_EXT largest u32 - - ?line send_term_as_binary(P, 16#7fffffffffff), % largest i48 - ?line send_term_as_binary(P,-16#800000000000), % smallest i48 - ?line send_term_as_binary(P, 16#ffffffffffff), % largest u48 - ?line send_term_as_binary(P, 16#7fffffffffffffff), % largest i64 - ?line send_term_as_binary(P,-16#8000000000000000), % smallest i64 - ?line send_term_as_binary(P, 16#ffffffffffffffff), % largest u64 - ?line send_term_as_binary(P, []), % illegal type + send_term_as_binary(P,0), % SMALL_INTEGER_EXT smallest + send_term_as_binary(P,255), % SMALL_INTEGER_EXT largest + send_term_as_binary(P,256), % INTEGER_EXT smallest pos (*) + send_term_as_binary(P,-1), % INTEGER_EXT largest neg + + send_term_as_binary(P, 16#07ffffff), % INTEGER_EXT old largest (28 bits) + send_term_as_binary(P,-16#08000000), % INTEGER_EXT old smallest + send_term_as_binary(P, 16#08000000), % SMALL_BIG_EXT old smallest pos(*) + send_term_as_binary(P,-16#08000001), % SMALL_BIG_EXT old largest neg (*) + + send_term_as_binary(P, 16#7fffffff), % INTEGER_EXT new largest (32 bits) + send_term_as_binary(P,-16#80000000), % INTEGER_EXT new smallest + send_term_as_binary(P, 16#80000000), % SMALL_BIG_EXT new smallest pos(*) + send_term_as_binary(P,-16#80000001), % SMALL_BIG_EXT new largest neg (*) + + send_term_as_binary(P, 16#ffffffff), % SMALL_BIG_EXT largest u32 + + send_term_as_binary(P, 16#7fffffffffff), % largest i48 + send_term_as_binary(P,-16#800000000000), % smallest i48 + send_term_as_binary(P, 16#ffffffffffff), % largest u48 + send_term_as_binary(P, 16#7fffffffffffffff), % largest i64 + send_term_as_binary(P,-16#8000000000000000), % smallest i64 + send_term_as_binary(P, 16#ffffffffffffffff), % largest u64 + send_term_as_binary(P, []), % illegal type ok. uc_atup(ATxt) -> @@ -344,35 +311,32 @@ string_to_atom(String) -> Utf8List = string_to_utf8_list(String), Len = length(Utf8List), TagLen = case Len < 256 of - true -> [119, Len]; - false -> [118, Len bsr 8, Len band 16#ff] - end, + true -> [119, Len]; + false -> [118, Len bsr 8, Len band 16#ff] + end, binary_to_term(list_to_binary([131, TagLen, Utf8List])). string_to_utf8_list([]) -> []; string_to_utf8_list([CP|CPs]) when is_integer(CP), - 0 =< CP, - CP =< 16#7F -> + 0 =< CP, + CP =< 16#7F -> [CP | string_to_utf8_list(CPs)]; string_to_utf8_list([CP|CPs]) when is_integer(CP), - 16#80 =< CP, - CP =< 16#7FF -> + 16#80 =< CP, + CP =< 16#7FF -> [16#C0 bor (CP bsr 6), - 16#80 bor (16#3F band CP) - | string_to_utf8_list(CPs)]; + 16#80 bor (16#3F band CP) | string_to_utf8_list(CPs)]; string_to_utf8_list([CP|CPs]) when is_integer(CP), - 16#800 =< CP, - CP =< 16#FFFF -> + 16#800 =< CP, + CP =< 16#FFFF -> [16#E0 bor (CP bsr 12), 16#80 bor (16#3F band (CP bsr 6)), - 16#80 bor (16#3F band CP) - | string_to_utf8_list(CPs)]; + 16#80 bor (16#3F band CP) | string_to_utf8_list(CPs)]; string_to_utf8_list([CP|CPs]) when is_integer(CP), - 16#10000 =< CP, - CP =< 16#10FFFF -> + 16#10000 =< CP, + CP =< 16#10FFFF -> [16#F0 bor (CP bsr 18), 16#80 bor (16#3F band (CP bsr 12)), 16#80 bor (16#3F band (CP bsr 6)), - 16#80 bor (16#3F band CP) - | string_to_utf8_list(CPs)]. + 16#80 bor (16#3F band CP) | string_to_utf8_list(CPs)]. diff --git a/lib/erl_interface/test/ei_decode_SUITE_data/Makefile.first b/lib/erl_interface/test/ei_decode_SUITE_data/Makefile.first index 74a49dbdab..6e4f0bc37e 100644 --- a/lib/erl_interface/test/ei_decode_SUITE_data/Makefile.first +++ b/lib/erl_interface/test/ei_decode_SUITE_data/Makefile.first @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2004-2009. All Rights Reserved. +# Copyright Ericsson AB 2004-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. diff --git a/lib/erl_interface/test/ei_decode_SUITE_data/Makefile.src b/lib/erl_interface/test/ei_decode_SUITE_data/Makefile.src index 54c40e52a4..e678914a40 100644 --- a/lib/erl_interface/test/ei_decode_SUITE_data/Makefile.src +++ b/lib/erl_interface/test/ei_decode_SUITE_data/Makefile.src @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2004-2009. All Rights Reserved. +# Copyright Ericsson AB 2004-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. 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 a0bafe543d..cfe9083065 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 @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2004-2013. All Rights Reserved. + * Copyright Ericsson AB 2004-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. @@ -377,8 +377,14 @@ TESTCASE(test_ei_decode_ulong) EI_DECODE_2 (decode_ulong, 11, unsigned long, ll(0x8000000000000000)); EI_DECODE_2 (decode_ulong, 11, unsigned long, ll(0xffffffffffffffff)); } else { - EI_DECODE_2 (decode_ulong, 7, unsigned long, 0x80000000); - EI_DECODE_2 (decode_ulong, 7, unsigned long, 0xffffffff); + if (sizeof(void*) > 4) { + /* Windows */ + EI_DECODE_2_FAIL(decode_ulong, 11, unsigned long, ll(0x8000000000000000)); + EI_DECODE_2_FAIL(decode_ulong, 11, unsigned long, ll(0xffffffffffffffff)); + } else { + EI_DECODE_2 (decode_ulong, 7, unsigned long, 0x80000000); + EI_DECODE_2 (decode_ulong, 7, unsigned long, 0xffffffff); + } } EI_DECODE_2_FAIL(decode_ulong, 9, unsigned long, ll(0x7fffffffffff)); diff --git a/lib/erl_interface/test/ei_decode_encode_SUITE.erl b/lib/erl_interface/test/ei_decode_encode_SUITE.erl index 3c7e4bf70d..570a91e2da 100644 --- a/lib/erl_interface/test/ei_decode_encode_SUITE.erl +++ b/lib/erl_interface/test/ei_decode_encode_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2014. All Rights Reserved. +%% Copyright Ericsson AB 2004-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. @@ -21,37 +21,18 @@ %% -module(ei_decode_encode_SUITE). --include_lib("test_server/include/test_server.hrl"). +-include_lib("common_test/include/ct.hrl"). -include("ei_decode_encode_SUITE_data/ei_decode_encode_test_cases.hrl"). --export( - [ - all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, - init_per_group/2,end_per_group/2, - test_ei_decode_encode/1 - ]). +-export([all/0, suite/0, + test_ei_decode_encode/1]). -suite() -> [{ct_hooks,[ts_install_cth]}]. +suite() -> + [{ct_hooks,[ts_install_cth]}]. all() -> [test_ei_decode_encode]. -groups() -> - []. - -init_per_suite(Config) -> - Config. - -end_per_suite(_Config) -> - ok. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - %% --------------------------------------------------------------------------- % NOTE: these types have no meaning on the C side so we pass them @@ -60,20 +41,19 @@ end_per_group(_GroupName, Config) -> %% ######################################################################## %% -test_ei_decode_encode(suite) -> []; test_ei_decode_encode(Config) when is_list(Config) -> - ?line P = runner:start(?test_ei_decode_encode), + P = runner:start(?test_ei_decode_encode), Fun = fun (X) -> {X,true} end, Pid = self(), Port = case os:type() of - {win32,_} -> - open_port({spawn,"sort"},[]); - {unix, darwin} -> - open_port({spawn,"/usr/bin/true"},[]); - _ -> - open_port({spawn,"/bin/true"},[]) - end, + {win32,_} -> + open_port({spawn,"sort"},[]); + {unix, darwin} -> + open_port({spawn,"/usr/bin/true"},[]); + _ -> + open_port({spawn,"/bin/true"},[]) + end, Ref = make_ref(), Trace = {1,2,3,self(),4}, % FIXME how to construct?! @@ -86,47 +66,46 @@ test_ei_decode_encode(Config) when is_list(Config) -> BigLargeB = 1 bsl 11112 + BigSmallB, BigLargeC = BigSmallA * BigSmallB * BigSmallC * BigSmallA, - ?line send_rec(P, Fun), - ?line send_rec(P, Pid), - ?line send_rec(P, Port), - ?line send_rec(P, Ref), - ?line send_rec(P, Trace), + send_rec(P, Fun), + send_rec(P, Pid), + send_rec(P, Port), + send_rec(P, Ref), + send_rec(P, Trace), % bigs - ?line send_rec(P, BigSmallA), - ?line send_rec(P, BigSmallB), - ?line send_rec(P, BigSmallC), - - ?line send_rec(P, BigLargeA), - ?line send_rec(P, BigLargeB), - ?line send_rec(P, BigLargeC), + send_rec(P, BigSmallA), + send_rec(P, BigSmallB), + send_rec(P, BigSmallC), + + send_rec(P, BigLargeA), + send_rec(P, BigLargeB), + send_rec(P, BigLargeC), %% Test large node containers... - ?line ThisNode = {node(), erlang:system_info(creation)}, - ?line TXPid = mk_pid(ThisNode, 32767, 8191), - ?line TXPort = mk_port(ThisNode, 268435455), - ?line TXRef = mk_ref(ThisNode, [262143, 4294967295, 4294967295]), + ThisNode = {node(), erlang:system_info(creation)}, + TXPid = mk_pid(ThisNode, 32767, 8191), + TXPort = mk_port(ThisNode, 268435455), + TXRef = mk_ref(ThisNode, [262143, 4294967295, 4294967295]), - ?line OtherNode = {gurka@sallad, 2}, - ?line OXPid = mk_pid(OtherNode, 32767, 8191), - ?line OXPort = mk_port(OtherNode, 268435455), - ?line OXRef = mk_ref(OtherNode, [262143, 4294967295, 4294967295]), + send_rec(P, TXPid), + send_rec(P, TXPort), + send_rec(P, TXRef), - ?line send_rec(P, TXPid), - ?line send_rec(P, TXPort), - ?line send_rec(P, TXRef), - ?line send_rec(P, OXPid), - ?line send_rec(P, OXPort), - ?line send_rec(P, OXRef), + [begin OtherNode = {gurka@sallad, Creation}, + send_rec(P, mk_pid(OtherNode, 32767, 8191)), + send_rec(P, mk_port(OtherNode, 268435455)), + send_rec(P, mk_ref(OtherNode, [262143, 4294967295, 4294967295])), + void + end || Creation <- [1, 2, 3, 4, 16#adec0ded]], %% Unicode atoms [begin send_rec(P, Atom), - send_rec(P, mk_pid({Atom,1}, 23434, 3434)), - send_rec(P, mk_port({Atom,1}, 2343434)), - send_rec(P, mk_ref({Atom,1}, [262143, 8723648, 24097245])), - void + send_rec(P, mk_pid({Atom,1}, 23434, 3434)), + send_rec(P, mk_port({Atom,1}, 2343434)), + send_rec(P, mk_ref({Atom,1}, [262143, 8723648, 24097245])), + void end || Atom <- unicode_atom_data()], send_rec(P, {}), @@ -137,7 +116,7 @@ test_ei_decode_encode(Config) when is_list(Config) -> send_rec(P, #{key => value}), send_rec(P, maps:put(Port, Ref, #{key => value, key2 => Pid})), - ?line runner:recv_eot(P), + runner:recv_eot(P), ok. @@ -146,29 +125,27 @@ test_ei_decode_encode(Config) when is_list(Config) -> % We read two packets for each test, the ei_decode_encode and ei_x_decode_encode version.... send_rec(P, Term) when is_port(P) -> - %%?t:format("Testing: ~p~n", [Term]), P ! {self(), {command, term_to_binary(Term)}}, {_B,Term} = get_buf_and_term(P). - get_buf_and_term(P) -> B = get_binaries(P), case B of - <<131>> -> - io:format("(got single magic, no content)\n",[]), - {B,'$$magic$$'}; - <<131,_>> -> - T = binary_to_term(B), - io:format("~w\n~w\n(got magic)\n",[B,T]), - {B,T}; - _ -> - B1 = list_to_binary([131,B]), % No magic, add - T = binary_to_term(B1), - %io:format("~w\n~w\n(got no magic)\n",[B,T]), - {B,T} + <<131>> -> + io:format("(got single magic, no content)\n",[]), + {B,'$$magic$$'}; + <<131,_>> -> + T = binary_to_term(B), + io:format("~w\n~w\n(got magic)\n",[B,T]), + {B,T}; + _ -> + B1 = list_to_binary([131,B]), % No magic, add + T = binary_to_term(B1), + %io:format("~w\n~w\n(got no magic)\n",[B,T]), + {B,T} end. - + get_binaries(P) -> B1 = get_binary(P), @@ -177,40 +154,17 @@ get_binaries(P) -> get_binary(P) -> case runner:get_term(P) of - {bytes,L} -> - B = list_to_binary(L), - %%io:format("~w\n",[L]), -% For strange reasons <<131>> show up as <>.... -% io:format("~w\n",[B]), - B; - Other -> - Other + {bytes,L} -> + B = list_to_binary(L), + %%io:format("~w\n",[L]), + % For strange reasons <<131>> show up as <>.... + % io:format("~w\n",[B]), + B; + Other -> + Other end. %% - -% We use our own get_term() - -get_term(P) -> - case runner:get_term(P) of - {bytes,[131]} -> - io:format("(got single magic, no content)\n",[]), - '$$magic$$'; - {bytes,[131,L]} -> - B = list_to_binary(L), - T = binary_to_term(B), - io:format("~w\n~w\n(got magic)\n",[L,T]), - T; - {bytes,L} -> - B = list_to_binary([131,L]), - T = binary_to_term(B), - io:format("~w\n~w\n(got no magic)\n",[L,T]), - T; - Other -> - Other - end. - -%% %% Node container constructor functions %% @@ -221,6 +175,9 @@ get_term(P) -> -define(PORT_EXT, 102). -define(PID_EXT, 103). -define(NEW_REFERENCE_EXT, 114). +-define(NEW_PID_EXT, $X). +-define(NEW_PORT_EXT, $Y). +-define(NEWER_REFERENCE_EXT, $Z). uint32_be(Uint) when is_integer(Uint), 0 =< Uint, Uint < 1 bsl 32 -> [(Uint bsr 24) band 16#ff, @@ -242,18 +199,22 @@ uint8(Uint) when is_integer(Uint), 0 =< Uint, Uint < 1 bsl 8 -> uint8(Uint) -> exit({badarg, uint8, [Uint]}). +pid_tag(Creation) when Creation =< 3 -> ?PID_EXT; +pid_tag(_Creation) -> ?NEW_PID_EXT. +enc_creation(Creation) when Creation =< 3 -> uint8(Creation); +enc_creation(Creation) -> uint32_be(Creation). mk_pid({NodeName, Creation}, Number, Serial) when is_atom(NodeName) -> <<?VERSION_MAGIC, NodeNameExt/binary>> = term_to_binary(NodeName), mk_pid({NodeNameExt, Creation}, Number, Serial); mk_pid({NodeNameExt, Creation}, Number, Serial) -> case catch binary_to_term(list_to_binary([?VERSION_MAGIC, - ?PID_EXT, - NodeNameExt, - uint32_be(Number), - uint32_be(Serial), - uint8(Creation)])) of + pid_tag(Creation), + NodeNameExt, + uint32_be(Number), + uint32_be(Serial), + enc_creation(Creation)])) of Pid when is_pid(Pid) -> Pid; {'EXIT', {badarg, _}} -> @@ -262,15 +223,18 @@ mk_pid({NodeNameExt, Creation}, Number, Serial) -> exit({unexpected_binary_to_term_result, Other}) end. +port_tag(Creation) when Creation =< 3 -> ?PORT_EXT; +port_tag(_Creation) -> ?NEW_PORT_EXT. + mk_port({NodeName, Creation}, Number) when is_atom(NodeName) -> <<?VERSION_MAGIC, NodeNameExt/binary>> = term_to_binary(NodeName), mk_port({NodeNameExt, Creation}, Number); mk_port({NodeNameExt, Creation}, Number) -> case catch binary_to_term(list_to_binary([?VERSION_MAGIC, - ?PORT_EXT, + port_tag(Creation), NodeNameExt, uint32_be(Number), - uint8(Creation)])) of + enc_creation(Creation)])) of Port when is_port(Port) -> Port; {'EXIT', {badarg, _}} -> @@ -279,34 +243,38 @@ mk_port({NodeNameExt, Creation}, Number) -> exit({unexpected_binary_to_term_result, Other}) end. +ref_tag(Creation) when Creation =< 3 -> ?NEW_REFERENCE_EXT; +ref_tag(_Creation) -> ?NEWER_REFERENCE_EXT. + mk_ref({NodeName, Creation}, Numbers) when is_atom(NodeName), - is_integer(Creation), - is_list(Numbers) -> + is_integer(Creation), + is_list(Numbers) -> <<?VERSION_MAGIC, NodeNameExt/binary>> = term_to_binary(NodeName), mk_ref({NodeNameExt, Creation}, Numbers); mk_ref({NodeNameExt, Creation}, [Number]) when is_binary(NodeNameExt), is_integer(Creation), + Creation =< 3, is_integer(Number) -> case catch binary_to_term(list_to_binary([?VERSION_MAGIC, - ?REFERENCE_EXT, - NodeNameExt, - uint32_be(Number), - uint8(Creation)])) of - Ref when is_reference(Ref) -> - Ref; - {'EXIT', {badarg, _}} -> - exit({badarg, mk_ref, [{NodeNameExt, Creation}, [Number]]}); - Other -> - exit({unexpected_binary_to_term_result, Other}) + ?REFERENCE_EXT, + NodeNameExt, + uint32_be(Number), + uint8(Creation)])) of + Ref when is_reference(Ref) -> + Ref; + {'EXIT', {badarg, _}} -> + exit({badarg, mk_ref, [{NodeNameExt, Creation}, [Number]]}); + Other -> + exit({unexpected_binary_to_term_result, Other}) end; mk_ref({NodeNameExt, Creation}, Numbers) when is_binary(NodeNameExt), - is_integer(Creation), - is_list(Numbers) -> + is_integer(Creation), + is_list(Numbers) -> case catch binary_to_term(list_to_binary([?VERSION_MAGIC, - ?NEW_REFERENCE_EXT, + ref_tag(Creation), uint16_be(length(Numbers)), NodeNameExt, - uint8(Creation), + enc_creation(Creation), lists:map(fun (N) -> uint32_be(N) end, @@ -333,10 +301,10 @@ unicode_atom_data() -> uc_atup(lists:seq(65500, 65754)), uc_atup(lists:seq(65500, 65563)) | lists:map(fun (N) -> - Pow2 = (1 bsl N), - uc_atup(lists:seq(Pow2 - 127, Pow2 + 127)) - end, - lists:seq(7, 20)) + Pow2 = (1 bsl N), + uc_atup(lists:seq(Pow2 - 127, Pow2 + 127)) + end, + lists:seq(7, 20)) ]. uc_atup(ATxt) -> @@ -346,33 +314,33 @@ string_to_atom(String) -> Utf8List = string_to_utf8_list(String), Len = length(Utf8List), TagLen = case Len < 256 of - true -> [119, Len]; - false -> [118, Len bsr 8, Len band 16#ff] - end, + true -> [119, Len]; + false -> [118, Len bsr 8, Len band 16#ff] + end, binary_to_term(list_to_binary([131, TagLen, Utf8List])). string_to_utf8_list([]) -> []; string_to_utf8_list([CP|CPs]) when is_integer(CP), - 0 =< CP, - CP =< 16#7F -> + 0 =< CP, + CP =< 16#7F -> [CP | string_to_utf8_list(CPs)]; string_to_utf8_list([CP|CPs]) when is_integer(CP), - 16#80 =< CP, - CP =< 16#7FF -> + 16#80 =< CP, + CP =< 16#7FF -> [16#C0 bor (CP bsr 6), 16#80 bor (16#3F band CP) | string_to_utf8_list(CPs)]; string_to_utf8_list([CP|CPs]) when is_integer(CP), - 16#800 =< CP, - CP =< 16#FFFF -> + 16#800 =< CP, + CP =< 16#FFFF -> [16#E0 bor (CP bsr 12), 16#80 bor (16#3F band (CP bsr 6)), 16#80 bor (16#3F band CP) | string_to_utf8_list(CPs)]; string_to_utf8_list([CP|CPs]) when is_integer(CP), - 16#10000 =< CP, - CP =< 16#10FFFF -> + 16#10000 =< CP, + CP =< 16#10FFFF -> [16#F0 bor (CP bsr 18), 16#80 bor (16#3F band (CP bsr 12)), 16#80 bor (16#3F band (CP bsr 6)), diff --git a/lib/erl_interface/test/ei_decode_encode_SUITE_data/Makefile.first b/lib/erl_interface/test/ei_decode_encode_SUITE_data/Makefile.first index 6edcc0c5ed..ee9e25adbc 100644 --- a/lib/erl_interface/test/ei_decode_encode_SUITE_data/Makefile.first +++ b/lib/erl_interface/test/ei_decode_encode_SUITE_data/Makefile.first @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2004-2009. All Rights Reserved. +# Copyright Ericsson AB 2004-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. diff --git a/lib/erl_interface/test/ei_decode_encode_SUITE_data/Makefile.src b/lib/erl_interface/test/ei_decode_encode_SUITE_data/Makefile.src index 03db2ae9f2..853fe9ddeb 100644 --- a/lib/erl_interface/test/ei_decode_encode_SUITE_data/Makefile.src +++ b/lib/erl_interface/test/ei_decode_encode_SUITE_data/Makefile.src @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2004-2009. All Rights Reserved. +# Copyright Ericsson AB 2004-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. 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 4b0201ca0b..467f789fdb 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 @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2004-2014. All Rights Reserved. + * Copyright Ericsson AB 2004-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. @@ -240,7 +240,7 @@ void decode_encode(struct Type** tv, int nobj) if (err != -1) { fail("decode returned non zero but not -1"); } else { - fail("decode returned non zero"); + fail1("decode '%s' returned non zero", t->name); } return; } @@ -491,12 +491,11 @@ TESTCASE(test_ei_decode_encode) decode_encode_big(&big_type); /* Test large node containers... */ - decode_encode_one(&pid_type); - decode_encode_one(&port_type); - decode_encode_one(&ref_type); - decode_encode_one(&pid_type); - decode_encode_one(&port_type); - decode_encode_one(&ref_type); + for (i=0; i<6; i++) { + decode_encode_one(&pid_type); + decode_encode_one(&port_type); + decode_encode_one(&ref_type); + } /* Unicode atoms */ for (i=0; i<24; i++) { diff --git a/lib/erl_interface/test/ei_encode_SUITE.erl b/lib/erl_interface/test/ei_encode_SUITE.erl index 6213916314..ac6ec9cf4e 100644 --- a/lib/erl_interface/test/ei_encode_SUITE.erl +++ b/lib/erl_interface/test/ei_encode_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2013. All Rights Reserved. +%% Copyright Ericsson AB 2004-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. @@ -21,25 +21,22 @@ %% -module(ei_encode_SUITE). --include_lib("test_server/include/test_server.hrl"). +-include_lib("common_test/include/ct.hrl"). -include("ei_encode_SUITE_data/ei_encode_test_cases.hrl"). --export( - [ - all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, - init_per_group/2,end_per_group/2, - test_ei_encode_long/1, - test_ei_encode_ulong/1, - test_ei_encode_longlong/1, - test_ei_encode_ulonglong/1, - test_ei_encode_char/1, - test_ei_encode_misc/1, - test_ei_encode_fails/1, - test_ei_encode_utf8_atom/1, - test_ei_encode_utf8_atom_len/1 - ]). - -suite() -> [{ct_hooks,[ts_install_cth]}]. +-export([all/0, suite/0, + test_ei_encode_long/1, + test_ei_encode_ulong/1, + test_ei_encode_longlong/1, + test_ei_encode_ulonglong/1, + test_ei_encode_char/1, + test_ei_encode_misc/1, + test_ei_encode_fails/1, + test_ei_encode_utf8_atom/1, + test_ei_encode_utf8_atom_len/1]). + +suite() -> + [{ct_hooks,[ts_install_cth]}]. all() -> [test_ei_encode_long, test_ei_encode_ulong, @@ -48,21 +45,6 @@ all() -> test_ei_encode_fails, test_ei_encode_utf8_atom, test_ei_encode_utf8_atom_len]. -groups() -> - []. - -init_per_suite(Config) -> - Config. - -end_per_suite(_Config) -> - ok. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - %% --------------------------------------------------------------------------- @@ -72,105 +54,101 @@ end_per_group(_GroupName, Config) -> %% ######################################################################## %% -test_ei_encode_long(suite) -> []; test_ei_encode_long(Config) when is_list(Config) -> - ?line P = runner:start(?test_ei_encode_long), + P = runner:start(?test_ei_encode_long), - ?line {<<97,0>> ,0} = get_buf_and_term(P), - ?line {<<97,255>> ,255} = get_buf_and_term(P), - ?line {<<98,256:32/big-signed-integer>>,256} = get_buf_and_term(P), - ?line {<<98,-1:32/big-signed-integer>> ,-1} = get_buf_and_term(P), + {<<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), - ?line {<<98, 16#07ffffff:32/big-signed-integer>>, 16#07ffffff} = get_buf_and_term(P), - ?line {<<98,-16#08000000:32/big-signed-integer>>,-16#08000000} = get_buf_and_term(P), - ?line {<<110,4,0, 0,0,0,8>> , 16#08000000} = get_buf_and_term(P), - ?line {<<110,4,1, 1,0,0,8>> ,-16#08000001} = 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), - ?line {<<110,4,0, 255,255,255,127>> , 16#7fffffff} = get_buf_and_term(P), - ?line {<<110,4,1, 0,0,0,128>> ,-16#80000000} = 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), - ?line runner:recv_eot(P), + runner:recv_eot(P), ok. %% ######################################################################## %% -test_ei_encode_ulong(suite) -> []; test_ei_encode_ulong(Config) when is_list(Config) -> - ?line P = runner:start(?test_ei_encode_ulong), + P = runner:start(?test_ei_encode_ulong), - ?line {<<97,0>> ,0} = get_buf_and_term(P), - ?line {<<97,255>> ,255} = get_buf_and_term(P), - ?line {<<98,256:32/big-unsigned-integer>>,256} = get_buf_and_term(P), + {<<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), - ?line {<<98, 16#07ffffff:32/big-signed-integer>>,16#07ffffff} = get_buf_and_term(P), - ?line {<<110,4,0, 0,0,0,8>> ,16#08000000} = 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), - ?line {<<110,4,0, 255,255,255,127>> ,16#7fffffff} = get_buf_and_term(P), - ?line {<<110,4,0, 0,0,0,128>> ,16#80000000} = get_buf_and_term(P), - ?line {<<110,4,0, 255,255,255,255>> ,16#ffffffff} = 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), - ?line runner:recv_eot(P), + runner:recv_eot(P), ok. %% ######################################################################## %% -test_ei_encode_longlong(suite) -> []; test_ei_encode_longlong(Config) when is_list(Config) -> case os:type() of - vxworks -> - {skip,"Skipped on VxWorks"}; - _ -> - ?line P = runner:start(?test_ei_encode_longlong), - - ?line {<<97,0>> ,0} = get_buf_and_term(P), - ?line {<<97,255>> ,255} = get_buf_and_term(P), - ?line {<<98,256:32/big-signed-integer>>,256} = get_buf_and_term(P), - ?line {<<98,-1:32/big-signed-integer>> ,-1} = get_buf_and_term(P), - - ?line {<<98, 16#07ffffff:32/big-signed-integer>>, 16#07ffffff} = get_buf_and_term(P), - ?line {<<98,-16#08000000:32/big-signed-integer>>,-16#08000000} = get_buf_and_term(P), - ?line {<<110,4,0, 0,0,0,8>> , 16#08000000} = get_buf_and_term(P), - ?line {<<110,4,1, 1,0,0,8>> ,-16#08000001} = get_buf_and_term(P), - - ?line {<<110,4,0, 255,255,255,127>> , 16#7fffffff} = get_buf_and_term(P), - ?line {<<110,4,1, 0,0,0,128>> ,-16#80000000} = get_buf_and_term(P), - ?line {<<110,6,0, 255,255,255,255,255,127>> , 16#7fffffffffff} = get_buf_and_term(P), - ?line {<<110,6,1, 0,0,0,0,0,128>> ,-16#800000000000} = get_buf_and_term(P), - ?line {<<110,8,0, 255,255,255,255,255,255,255,127>>,16#7fffffffffffffff} = get_buf_and_term(P), - ?line {<<110,8,1, 0,0,0,0,0,0,0,128>> ,-16#8000000000000000} = get_buf_and_term(P), - - ?line runner:recv_eot(P), - ok + vxworks -> + {skip,"Skipped on VxWorks"}; + _ -> + P = runner:start(?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. %% ######################################################################## %% -test_ei_encode_ulonglong(suite) -> []; test_ei_encode_ulonglong(Config) when is_list(Config) -> case os:type() of - vxworks -> - {skip,"Skipped on VxWorks"}; - _ -> - ?line P = runner:start(?test_ei_encode_ulonglong), - - ?line {<<97,0>> ,0} = get_buf_and_term(P), - ?line {<<97,255>> ,255} = get_buf_and_term(P), - ?line {<<98,256:32/big-unsigned-integer>>,256} = get_buf_and_term(P), - - ?line {<<98, 16#07ffffff:32/big-signed-integer>>,16#07ffffff} = get_buf_and_term(P), - ?line {<<110,4,0, 0,0,0,8>> ,16#08000000} = get_buf_and_term(P), - - ?line {<<110,4,0, 255,255,255,127>> ,16#7fffffff} = get_buf_and_term(P), - ?line {<<110,4,0, 0,0,0,128>> ,16#80000000} = get_buf_and_term(P), - ?line {<<110,4,0, 255,255,255,255>> ,16#ffffffff} = get_buf_and_term(P), - ?line {<<110,6,0, 255,255,255,255,255,255>>,16#ffffffffffff} = get_buf_and_term(P), - ?line {<<110,8,0, 255,255,255,255,255,255,255,255>>,16#ffffffffffffffff} = get_buf_and_term(P), - - ?line runner:recv_eot(P), - ok + vxworks -> + {skip,"Skipped on VxWorks"}; + _ -> + P = runner:start(?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), + + runner:recv_eot(P), + ok end. @@ -179,115 +157,112 @@ test_ei_encode_ulonglong(Config) when is_list(Config) -> %% it is unsigned. %% FIXME maybe the API should change to use "unsigned char" to be clear?! -test_ei_encode_char(suite) -> []; test_ei_encode_char(Config) when is_list(Config) -> - ?line P = runner:start(?test_ei_encode_char), + P = runner:start(?test_ei_encode_char), - ?line {<<97, 0>>,0} = get_buf_and_term(P), - ?line {<<97,127>>,16#7f} = get_buf_and_term(P), - ?line {<<97,255>>,16#ff} = get_buf_and_term(P), + {<<97, 0>>,0} = get_buf_and_term(P), + {<<97,127>>,16#7f} = get_buf_and_term(P), + {<<97,255>>,16#ff} = get_buf_and_term(P), - ?line runner:recv_eot(P), + runner:recv_eot(P), ok. %% ######################################################################## %% -test_ei_encode_misc(suite) -> []; test_ei_encode_misc(Config) when is_list(Config) -> - ?line P = runner:start(?test_ei_encode_misc), + P = runner:start(?test_ei_encode_misc), - ?line <<131>> = get_binaries(P), + <<131>> = get_binaries(P), - ?line {<<70,_:8/binary>>,F0} = get_buf_and_term(P), - ?line true = match_float(F0, 0.0), + {<<70,_:8/binary>>,F0} = get_buf_and_term(P), + true = match_float(F0, 0.0), - ?line {<<70,_:8/binary>>,Fn1} = get_buf_and_term(P), - ?line true = match_float(Fn1, -1.0), + {<<70,_:8/binary>>,Fn1} = get_buf_and_term(P), + true = match_float(Fn1, -1.0), - ?line {<<70,_:8/binary>>,Fp1} = get_buf_and_term(P), - ?line true = match_float(Fp1, 1.0), + {<<70,_:8/binary>>,Fp1} = get_buf_and_term(P), + true = match_float(Fp1, 1.0), - ?line {<<100,0,5,"false">>,false} = get_buf_and_term(P), - ?line {<<100,0,4,"true">> ,true} = get_buf_and_term(P), - ?line {<<100,0,4,"true">> ,true} = get_buf_and_term(P), - ?line {<<100,0,4,"true">> ,true} = get_buf_and_term(P), + {<<100,0,5,"false">>,false} = get_buf_and_term(P), + {<<100,0,4,"true">> ,true} = get_buf_and_term(P), + {<<100,0,4,"true">> ,true} = get_buf_and_term(P), + {<<100,0,4,"true">> ,true} = get_buf_and_term(P), - ?line {<<100,0,3,"foo">>,foo} = get_buf_and_term(P), - ?line {<<100,0,3,"foo">>,foo} = get_buf_and_term(P), - ?line {<<100,0,0,"">>,''} = get_buf_and_term(P), - ?line {<<100,0,0,"">>,''} = get_buf_and_term(P), - ?line {<<100,0,6,"ÅÄÖåäö">>,'ÅÄÖåäö'} = get_buf_and_term(P), - ?line {<<100,0,6,"ÅÄÖåäö">>,'ÅÄÖåäö'} = get_buf_and_term(P), + {<<100,0,3,"foo">>,foo} = get_buf_and_term(P), + {<<100,0,3,"foo">>,foo} = get_buf_and_term(P), + {<<100,0,0,"">>,''} = get_buf_and_term(P), + {<<100,0,0,"">>,''} = get_buf_and_term(P), + {<<100,0,6,"ÅÄÖåäö">>,'ÅÄÖåäö'} = get_buf_and_term(P), + {<<100,0,6,"ÅÄÖåäö">>,'ÅÄÖåäö'} = get_buf_and_term(P), - ?line {<<107,0,3,"foo">>,"foo"} = get_buf_and_term(P), - ?line {<<107,0,3,"foo">>,"foo"} = get_buf_and_term(P), - ?line {<<106>>,""} = get_buf_and_term(P), - ?line {<<106>>,""} = get_buf_and_term(P), - ?line {<<107,0,6,"ÅÄÖåäö">>,"ÅÄÖåäö"} = get_buf_and_term(P), - ?line {<<107,0,6,"ÅÄÖåäö">>,"ÅÄÖåäö"} = get_buf_and_term(P), + {<<107,0,3,"foo">>,"foo"} = get_buf_and_term(P), + {<<107,0,3,"foo">>,"foo"} = get_buf_and_term(P), + {<<106>>,""} = get_buf_and_term(P), + {<<106>>,""} = get_buf_and_term(P), + {<<107,0,6,"ÅÄÖåäö">>,"ÅÄÖåäö"} = get_buf_and_term(P), + {<<107,0,6,"ÅÄÖåäö">>,"ÅÄÖåäö"} = get_buf_and_term(P), - ?line {<<109,0,0,0,3,"foo">>,<<"foo">>} = get_buf_and_term(P), - ?line {<<109,0,0,0,0,"">>,<<>>} = get_buf_and_term(P), - ?line {<<109,0,0,0,6,"ÅÄÖåäö">>,<<"ÅÄÖåäö">>} = get_buf_and_term(P), + {<<109,0,0,0,3,"foo">>,<<"foo">>} = get_buf_and_term(P), + {<<109,0,0,0,0,"">>,<<>>} = get_buf_and_term(P), + {<<109,0,0,0,6,"ÅÄÖåäö">>,<<"ÅÄÖåäö">>} = get_buf_and_term(P), - ?line {<<104,0>>,{}} = get_buf_and_term(P), % Tuple header for {} - ?line {<<106>>,[]} = get_buf_and_term(P), % Empty list [] + {<<104,0>>,{}} = get_buf_and_term(P), % Tuple header for {} + {<<106>>,[]} = get_buf_and_term(P), % Empty list [] - ?line runner:recv_eot(P), + runner:recv_eot(P), ok. %% ######################################################################## %% -test_ei_encode_fails(suite) -> []; test_ei_encode_fails(Config) when is_list(Config) -> - ?line P = runner:start(?test_ei_encode_fails), + P = runner:start(?test_ei_encode_fails), - ?line XAtom = list_to_atom(lists:duplicate(255, $x)), - ?line YAtom = list_to_atom(lists:duplicate(255, $y)), + XAtom = list_to_atom(lists:duplicate(255, $x)), + YAtom = list_to_atom(lists:duplicate(255, $y)), - ?line XAtom = get_term(P), - ?line XAtom = get_term(P), - ?line YAtom = get_term(P), - ?line YAtom = get_term(P), + XAtom = get_term(P), + XAtom = get_term(P), + YAtom = get_term(P), + YAtom = get_term(P), - ?line {{{{}}}} = get_term(P), + {{{{}}}} = get_term(P), - ?line runner:recv_eot(P), + runner:recv_eot(P), ok. %% ######################################################################## %% test_ei_encode_utf8_atom(Config) -> - ?line P = runner:start(?test_ei_encode_utf8_atom), - - ?line {<<119,2,195,133>>,'Ã…'} = get_buf_and_term(P), - ?line {<<100,0,1,197>>,'Ã…'} = get_buf_and_term(P), - ?line {<<100,0,1,197>>,'Ã…'} = get_buf_and_term(P), - ?line {<<119,2,195,133>>,'Ã…'} = get_buf_and_term(P), + P = runner:start(?test_ei_encode_utf8_atom), - ?line {<<119,1,$A>>,'A'} = get_buf_and_term(P), - ?line {<<100,0,1,$A>>,'A'} = get_buf_and_term(P), + {<<119,2,195,133>>,'Ã…'} = get_buf_and_term(P), + {<<100,0,1,197>>,'Ã…'} = get_buf_and_term(P), + {<<100,0,1,197>>,'Ã…'} = get_buf_and_term(P), + {<<119,2,195,133>>,'Ã…'} = get_buf_and_term(P), - ?line runner:recv_eot(P), + {<<119,1,$A>>,'A'} = get_buf_and_term(P), + {<<100,0,1,$A>>,'A'} = get_buf_and_term(P), + + runner:recv_eot(P), ok. %% ######################################################################## %% test_ei_encode_utf8_atom_len(Config) -> - ?line P = runner:start(?test_ei_encode_utf8_atom_len), - - ?line {<<119,2,195,133>>,'Ã…'} = get_buf_and_term(P), - ?line {<<100,0,2,197,196>>,'ÅÄ'} = get_buf_and_term(P), - ?line {<<100,0,1,197>>,'Ã…'} = get_buf_and_term(P), - ?line {<<119,4,195,133,195,132>>,'ÅÄ'} = get_buf_and_term(P), - - ?line {<<119,1,$A>>,'A'} = get_buf_and_term(P), - ?line {<<100,0,2,$A,$B>>,'AB'} = get_buf_and_term(P), - ?line {<<100,0,255,_:(255*8)>>,_} = get_buf_and_term(P), - - ?line runner:recv_eot(P), + P = runner:start(?test_ei_encode_utf8_atom_len), + + {<<119,2,195,133>>,'Ã…'} = get_buf_and_term(P), + {<<100,0,2,197,196>>,'ÅÄ'} = get_buf_and_term(P), + {<<100,0,1,197>>,'Ã…'} = get_buf_and_term(P), + {<<119,4,195,133,195,132>>,'ÅÄ'} = get_buf_and_term(P), + + {<<119,1,$A>>,'A'} = get_buf_and_term(P), + {<<100,0,2,$A,$B>>,'AB'} = get_buf_and_term(P), + {<<100,0,255,_:(255*8)>>,_} = get_buf_and_term(P), + + runner:recv_eot(P), ok. %% ######################################################################## %% @@ -297,20 +272,20 @@ test_ei_encode_utf8_atom_len(Config) -> get_buf_and_term(P) -> B = get_binaries(P), case B of - <<131>> -> - io:format("(got single magic, no content)\n",[]), - {B,'$$magic$$'}; - <<131,_>> -> - T = binary_to_term(B), - io:format("~w\n~w\n(got magic)\n",[B,T]), - {B,T}; - _ -> - B1 = list_to_binary([131,B]), % No magic, add - T = binary_to_term(B1), - io:format("~w\n~w\n(got no magic)\n",[B,T]), - {B,T} + <<131>> -> + io:format("(got single magic, no content)\n",[]), + {B,'$$magic$$'}; + <<131,_>> -> + T = binary_to_term(B), + io:format("~w\n~w\n(got magic)\n",[B,T]), + {B,T}; + _ -> + B1 = list_to_binary([131,B]), % No magic, add + T = binary_to_term(B1), + io:format("~w\n~w\n(got no magic)\n",[B,T]), + {B,T} end. - + get_binaries(P) -> B1 = get_binary(P), @@ -319,14 +294,14 @@ get_binaries(P) -> get_binary(P) -> case runner:get_term(P) of - {bytes,L} -> - B = list_to_binary(L), - io:format("~w\n",[L]), -% For strange reasons <<131>> show up as <>.... -% io:format("~w\n",[B]), - B; - Other -> - Other + {bytes,L} -> + B = list_to_binary(L), + io:format("~w\n",[L]), + % For strange reasons <<131>> show up as <>.... + % io:format("~w\n",[B]), + B; + Other -> + Other end. %% @@ -335,27 +310,26 @@ get_binary(P) -> get_term(P) -> case runner:get_term(P) of - {bytes,[131]} -> - io:format("(got single magic, no content)\n",[]), - '$$magic$$'; - {bytes,[131,L]} -> - B = list_to_binary(L), - T = binary_to_term(B), - io:format("~w\n~w\n(got magic)\n",[L,T]), - T; - {bytes,L} -> - B = list_to_binary([131,L]), - T = binary_to_term(B), - io:format("~w\n~w\n(got no magic)\n",[L,T]), - T; - Other -> - Other + {bytes,[131]} -> + io:format("(got single magic, no content)\n",[]), + '$$magic$$'; + {bytes,[131,L]} -> + B = list_to_binary(L), + T = binary_to_term(B), + io:format("~w\n~w\n(got magic)\n",[L,T]), + T; + {bytes,L} -> + B = list_to_binary([131,L]), + T = binary_to_term(B), + io:format("~w\n~w\n(got no magic)\n",[L,T]), + T; + Other -> + Other end. - + %% match_float(F, Match) when is_float(F), is_float(Match), F == Match -> true; match_float(F, Match) when is_float(F), F > Match*0.99, F < Match*1.01 -> true. - diff --git a/lib/erl_interface/test/ei_encode_SUITE_data/Makefile.first b/lib/erl_interface/test/ei_encode_SUITE_data/Makefile.first index 26ba7f475e..0d2d3510a7 100644 --- a/lib/erl_interface/test/ei_encode_SUITE_data/Makefile.first +++ b/lib/erl_interface/test/ei_encode_SUITE_data/Makefile.first @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2004-2009. All Rights Reserved. +# Copyright Ericsson AB 2004-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. diff --git a/lib/erl_interface/test/ei_encode_SUITE_data/Makefile.src b/lib/erl_interface/test/ei_encode_SUITE_data/Makefile.src index 753700d7e2..3b2cab7af4 100644 --- a/lib/erl_interface/test/ei_encode_SUITE_data/Makefile.src +++ b/lib/erl_interface/test/ei_encode_SUITE_data/Makefile.src @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2004-2009. All Rights Reserved. +# Copyright Ericsson AB 2004-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. 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 ace368f8e6..32811fdf22 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 @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2004-2013. All Rights Reserved. + * Copyright Ericsson AB 2004-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. diff --git a/lib/erl_interface/test/ei_format_SUITE.erl b/lib/erl_interface/test/ei_format_SUITE.erl index 11cbae31db..07ee479b1f 100644 --- a/lib/erl_interface/test/ei_format_SUITE.erl +++ b/lib/erl_interface/test/ei_format_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2001-2011. All Rights Reserved. +%% 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. @@ -21,158 +21,134 @@ %% -module(ei_format_SUITE). --include_lib("test_server/include/test_server.hrl"). +-include_lib("common_test/include/ct.hrl"). -include("ei_format_SUITE_data/ei_format_test_cases.hrl"). --export([ - format_wo_ver/1, - all/0, suite/0,groups/0, - init_per_suite/1, end_per_suite/1, - init_per_group/2,end_per_group/2, - atoms/1, - tuples/1, - lists/1 - ]). +-export([format_wo_ver/1, + all/0, suite/0, + atoms/1, + tuples/1, + lists/1]). -import(runner, [get_term/1]). %% This test suite test the erl_format() function. %% It uses the port program "ei_format_test". -suite() -> [{ct_hooks,[ts_install_cth]}]. +suite() -> + [{ct_hooks,[ts_install_cth]}]. all() -> [format_wo_ver, atoms, tuples, lists]. -groups() -> - []. - -init_per_suite(Config) -> - Config. - -end_per_suite(_Config) -> - ok. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - %% Tests formatting various atoms. -atoms(suite) -> []; atoms(Config) when is_list(Config) -> - ?line P = runner:start(?atoms), - - ?line {term, ''} = get_term(P), - ?line {term, 'a'} = get_term(P), - ?line {term, 'A'} = get_term(P), - ?line {term, 'abc'} = get_term(P), - ?line {term, 'Abc'} = get_term(P), - ?line {term, 'ab@c'} = get_term(P), - ?line {term, 'The rain in Spain stays mainly in the plains'} = - get_term(P), - - ?line {term, a} = get_term(P), - ?line {term, ab} = get_term(P), - ?line {term, abc} = get_term(P), - ?line {term, ab@c} = get_term(P), - ?line {term, abcdefghijklmnopq} = get_term(P), - - ?line {term, ''} = get_term(P), - ?line {term, 'a'} = get_term(P), - ?line {term, 'A'} = get_term(P), - ?line {term, 'abc'} = get_term(P), - ?line {term, 'Abc'} = get_term(P), - ?line {term, 'ab@c'} = get_term(P), - ?line {term, 'The rain in Spain stays mainly in the plains'} = - get_term(P), - - ?line {term, a} = get_term(P), - ?line {term, ab} = get_term(P), - ?line {term, abc} = get_term(P), - ?line {term, ab@c} = get_term(P), - ?line {term, ' abcdefghijklmnopq '} = get_term(P), - - ?line runner:recv_eot(P), + P = runner:start(?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(suite) -> []; tuples(Config) when is_list(Config) -> - ?line P = runner:start(?tuples), - - ?line {term, {}} = get_term(P), - ?line {term, {a}} = get_term(P), - ?line {term, {a, b}} = get_term(P), - ?line {term, {a, b, c}} = get_term(P), - ?line {term, {1}} = get_term(P), - ?line {term, {[]}} = get_term(P), - ?line {term, {[], []}} = get_term(P), - ?line {term, {[], a, b, c}} = get_term(P), - ?line {term, {[], a, [], b, c}} = get_term(P), - ?line {term, {[], a, '', b, c}} = get_term(P), - - ?line runner:recv_eot(P), + P = runner:start(?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(suite) -> []; lists(Config) when is_list(Config) -> - ?line P = runner:start(?lists), - - ?line {term, []} = get_term(P), - ?line {term, [a]} = get_term(P), - ?line {term, [a, b]} = get_term(P), - ?line {term, [a, b, c]} = get_term(P), - ?line {term, [1]} = get_term(P), - ?line {term, [[]]} = get_term(P), - ?line {term, [[], []]} = get_term(P), - ?line {term, [[], a, b, c]} = get_term(P), - ?line {term, [[], a, [], b, c]} = get_term(P), - ?line {term, [[], a, '', b, c]} = get_term(P), - ?line {term, [[x, 2], [y, 3], [z, 4]]}= get_term(P), - ?line {term, [{a,b},{c,d}]}= get_term(P), -%% ?line {term, [{name, 'Madonna'}, {age, 21}, {data, [{addr, "E-street", 42}]}]} = -%% get_term(P), - - ?line {term, [{pi, F1}, {'cos(70)', F2}]} = get_term(P), + P = runner:start(?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, [[x, 2], [y, 3], [z, 4]]}= get_term(P), + {term, [{a,b},{c,d}]} = get_term(P), + %% {term, [{name, 'Madonna'}, {age, 21}, {data, [{addr, "E-street", 42}]}]} = get_term(P), + + {term, [{pi, F1}, {'cos(70)', F2}]} = get_term(P), %% don't match floats directly true= abs(3.1415-F1) < 0.01, true= abs(0.34202-F2) < 0.01, - ?line {term, [[pi, F3], ['cos(70)', F4]]} = get_term(P), + {term, [[pi, F3], ['cos(70)', F4]]} = get_term(P), true= abs(3.1415-F3) < 0.01, true= abs(0.34202-F4) < 0.01, -%% ?line {term, [[pi, 3.1415], [], ["cos(70)", 0.34202]]} = get_term(P), - ?line {term, [-1]} = get_term(P), - ?line {term, "hejsan"} = get_term(P), + %% {term, [[pi, 3.1415], [], ["cos(70)", 0.34202]]} = get_term(P), + {term, [-1]} = get_term(P), + {term, "hejsan"} = get_term(P), - ?line Str1 = lists:duplicate(65535,$A), - ?line Str2 = lists:duplicate(65536,$A), - ?line {term,Str1} = get_term(P), - ?line {term,Str2} = get_term(P), + Str1 = lists:duplicate(65535,$A), + Str2 = lists:duplicate(65536,$A), + {term,Str1} = get_term(P), + {term,Str2} = get_term(P), - ?line runner:recv_eot(P), + runner:recv_eot(P), ok. -format_wo_ver(suite) -> []; format_wo_ver(Config) when is_list(Config) -> - ?line P = runner:start(?format_wo_ver), + P = runner:start(?format_wo_ver), - ?line {term, [-1, 2, $c, {a, "b"}, {c, 10}]} = get_term(P), + {term, [-1, 2, $c, {a, "b"}, {c, 10}]} = get_term(P), - ?line runner:recv_eot(P), + runner:recv_eot(P), ok. diff --git a/lib/erl_interface/test/ei_format_SUITE_data/Makefile.first b/lib/erl_interface/test/ei_format_SUITE_data/Makefile.first index d655cd13e6..7bf2d761ac 100644 --- a/lib/erl_interface/test/ei_format_SUITE_data/Makefile.first +++ b/lib/erl_interface/test/ei_format_SUITE_data/Makefile.first @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2001-2009. All Rights Reserved. +# 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. diff --git a/lib/erl_interface/test/ei_format_SUITE_data/Makefile.src b/lib/erl_interface/test/ei_format_SUITE_data/Makefile.src index bfcb8ae840..b89dcae45a 100644 --- a/lib/erl_interface/test/ei_format_SUITE_data/Makefile.src +++ b/lib/erl_interface/test/ei_format_SUITE_data/Makefile.src @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2001-2009. All Rights Reserved. +# 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. 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 d3ca91db5a..8450332b28 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 @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2013. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/test/ei_print_SUITE.erl b/lib/erl_interface/test/ei_print_SUITE.erl index 4309b883bb..6d5c341eae 100644 --- a/lib/erl_interface/test/ei_print_SUITE.erl +++ b/lib/erl_interface/test/ei_print_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2001-2012. All Rights Reserved. +%% 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. @@ -21,144 +21,120 @@ %% -module(ei_print_SUITE). --include_lib("test_server/include/test_server.hrl"). +-include_lib("common_test/include/ct.hrl"). -include("ei_print_SUITE_data/ei_print_test_cases.hrl"). --export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, - init_per_group/2,end_per_group/2, - atoms/1, tuples/1, lists/1, strings/1]). +-export([all/0, suite/0, + atoms/1, tuples/1, lists/1, strings/1]). -import(runner, [get_term/1]). %% This test suite test the ei_print() function. %% It uses the port program "ei_format_test". -suite() -> [{ct_hooks,[ts_install_cth]}]. +suite() -> + [{ct_hooks,[ts_install_cth]}]. all() -> [atoms, tuples, lists, strings]. -groups() -> - []. - -init_per_suite(Config) -> - Config. - -end_per_suite(_Config) -> - ok. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - %% Tests formatting various atoms. -atoms(suite) -> []; atoms(Config) when is_list(Config) -> - ?line P = runner:start(?atoms), - - ?line {term, "''"} = get_term(P), - ?line {term, "a"} = get_term(P), - ?line {term, "'A'"} = get_term(P), - ?line {term, "abc"} = get_term(P), - ?line {term, "'Abc'"} = get_term(P), - ?line {term, "ab@c"} = get_term(P), - ?line {term, "'The rain in Spain stays mainly in the plains'"} = - get_term(P), - - ?line {term, "a"} = get_term(P), - ?line {term, "ab"} = get_term(P), - ?line {term, "abc"} = get_term(P), - ?line {term, "ab@c"} = get_term(P), - ?line {term, "abcdefghijklmnopq"} = get_term(P), - - ?line {term, "''"} = get_term(P), - ?line {term, "a"} = get_term(P), - ?line {term, "'A'"} = get_term(P), - ?line {term, "abc"} = get_term(P), - ?line {term, "'Abc'"} = get_term(P), - ?line {term, "ab@c"} = get_term(P), - ?line {term, "'The rain in Spain stays mainly in the plains'"} = - get_term(P), - - ?line {term, "a"} = get_term(P), - ?line {term, "ab"} = get_term(P), - ?line {term, "abc"} = get_term(P), - ?line {term, "ab@c"} = get_term(P), - ?line {term, "' abcdefghijklmnopq '"} = get_term(P), - - ?line runner:recv_eot(P), + P = runner:start(?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(suite) -> []; tuples(Config) when is_list(Config) -> - ?line P = runner:start(?tuples), - - ?line {term, "{}"} = get_term(P), - ?line {term, "{a}"} = get_term(P), - ?line {term, "{a, b}"} = get_term(P), - ?line {term, "{a, b, c}"} = get_term(P), - ?line {term, "{1}"} = get_term(P), - ?line {term, "{[]}"} = get_term(P), - ?line {term, "{[], []}"} = get_term(P), - ?line {term, "{[], a, b, c}"} = get_term(P), - ?line {term, "{[], a, [], b, c}"} = get_term(P), - ?line {term, "{[], a, '', b, c}"} = get_term(P), - - ?line runner:recv_eot(P), + P = runner:start(?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(suite) -> []; lists(Config) when is_list(Config) -> - ?line P = runner:start(?lists), - - ?line {term, "[]"} = get_term(P), - ?line {term, "[a]"} = get_term(P), - ?line {term, "[a, b]"} = get_term(P), - ?line {term, "[a, b, c]"} = get_term(P), - ?line {term, "[1]"} = get_term(P), - ?line {term, "[[]]"} = get_term(P), - ?line {term, "[[], []]"} = get_term(P), - ?line {term, "[[], a, b, c]"} = get_term(P), - ?line {term, "[[], a, [], b, c]"} = get_term(P), - ?line {term, "[[], a, '', b, c]"} = get_term(P), - ?line {term, "[[x, 2], [y, 3], [z, 4]]"}= get_term(P), - -%% ?line {term, "[{name, 'Madonna'}, {age, 21}, {data, [{addr, "E-street", 42}]}]"} = -%% get_term(P), + P = runner:start(?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, "[[x, 2], [y, 3], [z, 4]]"}= get_term(P), + + %% {term, "[{name, 'Madonna'}, {age, 21}, {data, [{addr, "E-street", 42}]}]"} = get_term(P), %% maybe regexp instead? - ?line {term, "[{pi, 3.141500}, {'cos(70)', 0.342020}]"} = get_term(P), - ?line {term, "[[pi, 3.141500], ['cos(70)', 0.342020]]"} = get_term(P), + {term, "[{pi, 3.141500}, {'cos(70)', 0.342020}]"} = get_term(P), + {term, "[[pi, 3.141500], ['cos(70)', 0.342020]]"} = get_term(P), - ?line {term, "[-1]"} = get_term(P), + {term, "[-1]"} = get_term(P), - ?line runner:recv_eot(P), + runner:recv_eot(P), ok. -strings(suite) -> []; strings(Config) when is_list(Config) -> - ?line P = runner:start(?strings), - - ?line {term, "\"\\n\""} = get_term(P), - ?line {term, "\"\\r\\n\""} = get_term(P), - ?line {term, "\"a\""} = get_term(P), - ?line {term, "\"A\""} = get_term(P), - ?line {term, "\"0\""} = get_term(P), - ?line {term, "\"9\""} = get_term(P), - ?line {term, "\"The rain in Spain stays mainly in the plains\""} = get_term(P), - ?line {term, "\" abcdefghijklmnopq \""} = get_term(P), - - ?line runner:recv_eot(P), + P = runner:start(?strings), + + {term, "\"\\n\""} = get_term(P), + {term, "\"\\r\\n\""} = get_term(P), + {term, "\"a\""} = get_term(P), + {term, "\"A\""} = get_term(P), + {term, "\"0\""} = get_term(P), + {term, "\"9\""} = get_term(P), + {term, "\"The rain in Spain stays mainly in the plains\""} = get_term(P), + {term, "\" abcdefghijklmnopq \""} = get_term(P), + + runner:recv_eot(P), ok. - diff --git a/lib/erl_interface/test/ei_print_SUITE_data/Makefile.first b/lib/erl_interface/test/ei_print_SUITE_data/Makefile.first index 987dbc27a9..3d2395a2c2 100644 --- a/lib/erl_interface/test/ei_print_SUITE_data/Makefile.first +++ b/lib/erl_interface/test/ei_print_SUITE_data/Makefile.first @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2001-2009. All Rights Reserved. +# 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. diff --git a/lib/erl_interface/test/ei_print_SUITE_data/Makefile.src b/lib/erl_interface/test/ei_print_SUITE_data/Makefile.src index 266fcfcb10..150c11b99c 100644 --- a/lib/erl_interface/test/ei_print_SUITE_data/Makefile.src +++ b/lib/erl_interface/test/ei_print_SUITE_data/Makefile.src @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2001-2009. All Rights Reserved. +# 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. 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 2db5450b77..15cfbcae34 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 @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2013. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/test/ei_tmo_SUITE.erl b/lib/erl_interface/test/ei_tmo_SUITE.erl index 689499f42f..003fe20594 100644 --- a/lib/erl_interface/test/ei_tmo_SUITE.erl +++ b/lib/erl_interface/test/ei_tmo_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2012. All Rights Reserved. +%% 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. @@ -21,337 +21,304 @@ %% -module(ei_tmo_SUITE). --include_lib("test_server/include/test_server.hrl"). +-include_lib("common_test/include/ct.hrl"). -include_lib("kernel/include/inet.hrl"). -include("ei_tmo_SUITE_data/ei_tmo_test_cases.hrl"). --define(dummy_host,test01). +-export([all/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, + ei_recv_tmo/1]). --export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, - init_per_group/2,end_per_group/2, - init_per_testcase/2, end_per_testcase/2, - framework_check/1, ei_accept_tmo/1, ei_connect_tmo/1, ei_send_tmo/1, - ei_recv_tmo/1]). - -suite() -> [{ct_hooks,[ts_install_cth]}]. +suite() -> + [{ct_hooks,[ts_install_cth]}, + {timetrap, {minutes, 1}}]. all() -> [framework_check, ei_accept_tmo, ei_connect_tmo, ei_send_tmo, ei_recv_tmo]. -groups() -> - []. - -init_per_suite(Config) -> - Config. - -end_per_suite(_Config) -> - ok. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - init_per_testcase(_Case, Config) -> - Dog = ?t:timetrap(?t:minutes(1)), % test if platform is vxworks_simso - ?line {_,Host} = split(node()), + {_,Host} = split(node()), Bool = case atom_to_list(Host) of - [$v,$x,$s,$i,$m | _] -> true; - _ -> false - end, - [{vxsim,Bool},{watchdog, Dog}|Config]. - -end_per_testcase(_Case, Config) -> - Dog = ?config(watchdog, Config), - test_server:timetrap_cancel(Dog), + [$v,$x,$s,$i,$m | _] -> true; + _ -> false + end, + [{vxsim,Bool}|Config]. + +end_per_testcase(_Case, _Config) -> ok. -framework_check(doc) -> - ["Check the framework."]; -framework_check(suite) -> - []; +%% Check the framework. framework_check(Config) when is_list(Config) -> %%dbg:tracer(), %%dbg:p(self()), - ?line P = runner:start(?framework_check), - ?line runner:send_term(P,{hello,world}), - ?line {term, {hello,world}} = runner:get_term(P), - ?line runner:recv_eot(P), + P = runner:start(?framework_check), + runner:send_term(P,{hello,world}), + {term, {hello,world}} = runner:get_term(P), + runner:recv_eot(P), ok. -ei_recv_tmo(doc) -> - ["Check recv with timeouts."]; -ei_recv_tmo(suite) -> - []; +%% Check recv with timeouts. ei_recv_tmo(Config) when is_list(Config) -> - ?line do_one_recv(Config,c_node_recv_tmo_1), - ?line do_one_recv_failure(Config,c_node_recv_tmo_2), + do_one_recv(Config,c_node_recv_tmo_1), + do_one_recv_failure(Config,c_node_recv_tmo_2), ok. do_one_recv(Config,CNode) -> - ?line {_,Host} = split(node()), - ?line P1 = runner:start(?recv_tmo), - ?line runner:send_term(P1,{CNode, - erlang:get_cookie(), - node()}), - ?line {term, X} = runner:get_term(P1, 10000), - ?line true = is_integer(X), - ?line CNode1 = join(CNode,Host), - ?line Term1 = {hej,[hopp,{i,[lingon,"skogen"]}]}, - ?line {test,CNode1} ! Term1, - ?line {term, Term1} = runner:get_term(P1, 10000), - ?line runner:recv_eot(P1). - + {_,Host} = split(node()), + P1 = runner:start(?recv_tmo), + runner:send_term(P1,{CNode, + erlang:get_cookie(), + node()}), + {term, X} = runner:get_term(P1, 10000), + true = is_integer(X), + CNode1 = join(CNode,Host), + Term1 = {hej,[hopp,{i,[lingon,"skogen"]}]}, + {test,CNode1} ! Term1, + {term, Term1} = runner:get_term(P1, 10000), + runner:recv_eot(P1). + do_one_recv_failure(Config,CNode) -> - ?line P1 = runner:start(?recv_tmo), - ?line runner:send_term(P1,{CNode, - erlang:get_cookie(), - node()}), - ?line {term, X} = runner:get_term(P1, 10000), - ?line true = is_integer(X), - ?line {term, {Ret,ETimedout,ETimedout}} = runner:get_term(P1, 10000), - ?line true = (Ret < 0), - ?line runner:recv_eot(P1). - - -ei_send_tmo(doc) -> - ["Check send with timeouts."]; -ei_send_tmo(suite) -> - []; + P1 = runner:start(?recv_tmo), + runner:send_term(P1,{CNode, + erlang:get_cookie(), + node()}), + {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). + + +%% Check send with timeouts. ei_send_tmo(Config) when is_list(Config) -> %dbg:tracer(), %dbg:p(self()), - VxSim = ?config(vxsim, Config), - ?line register(ei_send_tmo_1,self()), - ?line do_one_send(Config,self(),c_node_send_tmo_1), - ?line do_one_send(Config,ei_send_tmo_1,c_node_send_tmo_2), - ?line do_one_send_failure(Config,self(),cccc1,c_nod_send_tmo_3,VxSim), - ?line do_one_send_failure(Config,ei_send_tmo_1,cccc2,c_nod_send_tmo_4,VxSim), + 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. - + do_one_send(Config,From,CNode) -> - ?line {_,Host} = split(node()), - ?line P1 = runner:start(?send_tmo), - ?line runner:send_term(P1,{CNode, - erlang:get_cookie(), - node()}), - ?line {term, X} = runner:get_term(P1, 10000), - ?line true = is_integer(X), - ?line CNode1 = join(CNode,Host), - ?line Term1 = {hej,[hopp,{i,[lingon,"skogen"]}]}, - ?line {test,CNode1} ! {From,1,Term1}, - ?line ok = receive - Term1 -> - ok - after 2000 -> - error - end, - ?line {term, 0} = runner:get_term(P1, 10000), - ?line runner:recv_eot(P1). + {_,Host} = split(node()), + P1 = runner:start(?send_tmo), + runner:send_term(P1,{CNode, + erlang:get_cookie(), + node()}), + {term, X} = runner:get_term(P1, 10000), + true = is_integer(X), + CNode1 = join(CNode,Host), + Term1 = {hej,[hopp,{i,[lingon,"skogen"]}]}, + {test,CNode1} ! {From,1,Term1}, + ok = receive + Term1 -> + ok + after 2000 -> + error + end, + {term, 0} = runner:get_term(P1, 10000), + runner:recv_eot(P1). do_one_send_failure(Config,From,FakeName,CName,VxSim) -> - ?line {_,Host} = split(node()), - ?line OurName = join(FakeName,Host), - ?line Node = join(CName,Host), - ?line LSocket = case gen_tcp:listen(0, [{active, false}, {packet,2}]) of - {ok, Socket} -> - ?line Socket; - Else -> - ?line exit(Else) - end, - ?line EpmdSocket = register(OurName, LSocket, 1, 5), - ?line P3 = runner:start(?send_tmo), - ?line Cookie = kaksmula_som_ingen_bryr_sig_om, - ?line runner:send_term(P3,{CName, - Cookie, - OurName}), - ?line SocketB = case gen_tcp:accept(LSocket) of - {ok, Socket1} -> - ?line Socket1; - Else2 -> - ?line exit(Else2) - end, - ?line {hidden,Node,5} = recv_name(SocketB), % See 1) - ?line send_status(SocketB, ok), - ?line MyChallengeB = gen_challenge(), - ?line send_challenge(SocketB, OurName, MyChallengeB, 5), - ?line HisChallengeB = recv_challenge_reply( - SocketB, - MyChallengeB, - Cookie), - ?line DigestB = gen_digest(HisChallengeB,Cookie), - ?line send_challenge_ack(SocketB, DigestB), - ?line inet:setopts(SocketB, [{active, false}, - {packet, 4}]), - ?line {term, X} = runner:get_term(P3, 10000), - ?line true = is_integer(X), - ?line Message = [112,term_to_binary({6,self(),'',test}), - term_to_binary({From,10000, - {app,["lapp",{sa,["att",du,{slapp, - sitta}]}]}})], - ?line gen_tcp:send(SocketB,Message), - - %% At this point the test program starts sending messages (max 10000). Since + {_,Host} = split(node()), + OurName = join(FakeName,Host), + Node = join(CName,Host), + LSocket = case gen_tcp:listen(0, [{active, false}, {packet,2}]) of + {ok, Socket} -> + Socket; + Else -> + exit(Else) + end, + EpmdSocket = register(OurName, LSocket, 1, 5), + P3 = runner:start(?send_tmo), + Cookie = kaksmula_som_ingen_bryr_sig_om, + runner:send_term(P3,{CName, + Cookie, + OurName}), + SocketB = case gen_tcp:accept(LSocket) of + {ok, Socket1} -> + Socket1; + Else2 -> + exit(Else2) + end, + {hidden,Node,5} = recv_name(SocketB), % See 1) + send_status(SocketB, ok), + MyChallengeB = gen_challenge(), + send_challenge(SocketB, OurName, MyChallengeB, 5), + HisChallengeB = recv_challenge_reply(SocketB, + MyChallengeB, + Cookie), + DigestB = gen_digest(HisChallengeB,Cookie), + send_challenge_ack(SocketB, DigestB), + inet:setopts(SocketB, [{active, false}, + {packet, 4}]), + {term, X} = runner:get_term(P3, 10000), + true = is_integer(X), + Message = [112,term_to_binary({6,self(),'',test}), + term_to_binary({From,50000, + {app,["lapp",{sa,["att",du,{slapp, + sitta}]}]}})], + gen_tcp:send(SocketB,Message), + + %% At this point the test program starts sending messages (max 50000). Since %% we're not receiving, eventually the send buffer fills up. Then no more %% sending is possible and select() times out. The number of messages sent %% before this happens is returned in Iters. The timeout value for get_term/2 %% 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 -> - ?line {term,{Res,ETO,Iters,ETO}} = runner:get_term(P3, 20000), - Res; - true -> % relax the test for vxsim - ?line case runner:get_term(P3, 20000) of - {term,{Res,ETO,Iters,ETO}} -> - Res; - {term,{Res,_,Iters,ETO}} -> % EIO? - Res - end - end, - ?line runner:recv_eot(P3), - ?line true = ((Res0 < 0) and (Iters > 0)), - ?line gen_tcp:close(SocketB), - ?line gen_tcp:close(EpmdSocket), + + 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, + runner:recv_eot(P3), + true = ((Res0 < 0) and (Iters > 0)), + gen_tcp:close(SocketB), + gen_tcp:close(EpmdSocket), ok. - -ei_connect_tmo(doc) -> - ["Check accept with timeouts."]; -ei_connect_tmo(suite) -> - []; + +%% Check accept with timeouts. +ei_connect_tmo() -> [{require, test_host_not_reachable}]. + ei_connect_tmo(Config) when is_list(Config) -> %dbg:tracer(), %dbg:p(self()), - VxSim = ?config(vxsim, Config), + VxSim = proplists:get_value(vxsim, Config), DummyNode = make_and_check_dummy(), - ?line P = runner:start(?connect_tmo), - ?line runner:send_term(P,{c_nod_connect_tmo_1, - kaksmula_som_ingen_bryr_sig_om, - DummyNode}), + P = runner:start(?connect_tmo), + runner:send_term(P,{c_nod_connect_tmo_1, + kaksmula_som_ingen_bryr_sig_om, + DummyNode}), ETimedout = - if VxSim == false -> - ?line {term,{-3,ETO,ETO}} = runner:get_term(P, 10000), - ?line ETO; - true -> % relax the test for vxsim - ?line case runner:get_term(P, 10000) of - {term,{-3,ETO,ETO}} -> - ?line ETO; - {term,{-1,_,ETO}} -> % EHOSTUNREACH = ok - ?line ETO - end - end, - ?line runner:recv_eot(P), - ?line P2 = runner:start(?connect_tmo), - ?line runner:send_term(P2,{c_nod_connect_tmo_2, - erlang:get_cookie(), - node()}), - ?line {term, X} = runner:get_term(P2, 10000), - ?line runner:recv_eot(P2), - ?line true = is_integer(X), + 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, + runner:recv_eot(P), + P2 = runner:start(?connect_tmo), + runner:send_term(P2,{c_nod_connect_tmo_2, + erlang:get_cookie(), + node()}), + {term, X} = runner:get_term(P2, 10000), + runner:recv_eot(P2), + true = is_integer(X), %% Aborted handshake test... - ?line {_,Host} = split(node()), - ?line OurName = join(cccc,Host), - ?line Node = join(c_nod_connect_tmo_3,Host), - ?line LSocket = case gen_tcp:listen(0, [{active, false}, {packet,2}]) of - {ok, Socket} -> - ?line Socket; - Else -> - ?line exit(Else) - end, - ?line EpmdSocket = register(OurName, LSocket, 1, 5), - ?line P3 = runner:start(?connect_tmo), - ?line Cookie = kaksmula_som_ingen_bryr_sig_om, - ?line runner:send_term(P3,{c_nod_connect_tmo_3, - Cookie, - OurName}), - ?line SocketB = case gen_tcp:accept(LSocket) of - {ok, Socket1} -> - ?line Socket1; - Else2 -> - ?line exit(Else2) - end, - ?line {hidden,Node,5} = recv_name(SocketB), % See 1) - ?line send_status(SocketB, ok), - ?line MyChallengeB = gen_challenge(), - ?line send_challenge(SocketB, OurName, MyChallengeB, 5), - ?line HisChallengeB = recv_challenge_reply( - SocketB, - MyChallengeB, - Cookie), - ?line {term,{-1,ETimedout,ETimedout}} = runner:get_term(P3, 10000), - ?line runner:recv_eot(P3), - ?line gen_tcp:close(SocketB), - ?line gen_tcp:close(EpmdSocket), + {_,Host} = split(node()), + OurName = join(cccc,Host), + Node = join(c_nod_connect_tmo_3,Host), + LSocket = case gen_tcp:listen(0, [{active, false}, {packet,2}]) of + {ok, Socket} -> + Socket; + Else -> + exit(Else) + end, + EpmdSocket = register(OurName, LSocket, 1, 5), + P3 = runner:start(?connect_tmo), + Cookie = kaksmula_som_ingen_bryr_sig_om, + runner:send_term(P3,{c_nod_connect_tmo_3, + Cookie, + OurName}), + SocketB = case gen_tcp:accept(LSocket) of + {ok, Socket1} -> + Socket1; + Else2 -> + exit(Else2) + end, + {hidden,Node,5} = recv_name(SocketB), % See 1) + send_status(SocketB, ok), + MyChallengeB = gen_challenge(), + send_challenge(SocketB, OurName, MyChallengeB, 5), + _HisChallengeB = recv_challenge_reply(SocketB, + MyChallengeB, + Cookie), + {term,{-1,ETimedout,ETimedout}} = runner:get_term(P3, 10000), + runner:recv_eot(P3), + gen_tcp:close(SocketB), + gen_tcp:close(EpmdSocket), ok. - -ei_accept_tmo(doc) -> - ["Check accept with timeouts."]; -ei_accept_tmo(suite) -> - []; + +%% Check accept with timeouts. ei_accept_tmo(Config) when is_list(Config) -> %%dbg:tracer(), %%dbg:p(self()), - ?line P = runner:start(?accept_tmo), - ?line runner:send_term(P,{c_nod_som_ingen_kontaktar_1, - kaksmula_som_ingen_bryr_sig_om}), - ?line {term,{-1,ETimedout,ETimedout}} = runner:get_term(P, 10000), - ?line runner:recv_eot(P), - ?line P2 = runner:start(?accept_tmo), - ?line runner:send_term(P2,{c_nod_som_vi_kontaktar_1, - erlang:get_cookie()}), - ?line receive after 1000 -> ok end, - ?line CNode1 = make_node(c_nod_som_vi_kontaktar_1), - ?line {ignored,CNode1} ! tjenare, - ?line {term, X} = runner:get_term(P2, 10000), - ?line runner:recv_eot(P2), - ?line true = is_integer(X), - ?line P3 = runner:start(?accept_tmo), - ?line runner:send_term(P3,{c_nod_som_vi_kontaktar_2, - erlang:get_cookie()}), - ?line receive after 1000 -> ok end, - ?line CNode2 = make_node(c_nod_som_vi_kontaktar_2), - ?line {NA,NB} = split(CNode2), - ?line {_,Host} = split(node()), - ?line OurName = join(ccc,Host), - ?line {port,PortNo,_} = erl_epmd:port_please(NA,NB), - ?line {ok, SocketA} = gen_tcp:connect(atom_to_list(NB),PortNo, - [{active,false}, - {packet,2}]), - ?line send_name(SocketA,OurName,5), - ?line ok = recv_status(SocketA), - ?line {hidden,Node,5,HisChallengeA} = recv_challenge(SocketA), % See 1) - ?line OurChallengeA = gen_challenge(), - ?line OurDigestA = gen_digest(HisChallengeA, erlang:get_cookie()), + P = runner:start(?accept_tmo), + runner:send_term(P,{c_nod_som_ingen_kontaktar_1, + kaksmula_som_ingen_bryr_sig_om}), + {term,{-1,ETimedout,ETimedout}} = runner:get_term(P, 10000), + runner:recv_eot(P), + P2 = runner:start(?accept_tmo), + runner:send_term(P2,{c_nod_som_vi_kontaktar_1, + erlang:get_cookie()}), + receive after 1000 -> ok end, + CNode1 = make_node(c_nod_som_vi_kontaktar_1), + {ignored,CNode1} ! tjenare, + {term, X} = runner:get_term(P2, 10000), + runner:recv_eot(P2), + true = is_integer(X), + P3 = runner:start(?accept_tmo), + runner:send_term(P3,{c_nod_som_vi_kontaktar_2, + erlang:get_cookie()}), + 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), + {ok, SocketA} = gen_tcp:connect(atom_to_list(NB),PortNo, + [{active,false}, + {packet,2}]), + send_name(SocketA,OurName,5), + ok = recv_status(SocketA), + {hidden,_Node,5,HisChallengeA} = recv_challenge(SocketA), % See 1) + _OurChallengeA = gen_challenge(), + _OurDigestA = gen_digest(HisChallengeA, erlang:get_cookie()), %% Dont do the last two steps of the connection setup... %% send_challenge_reply(SocketA, OurChallengeA, OurDigestA), %% ok = recv_challenge_ack(SocketA, OurChallengeA, erlang:get_cookie()), - ?line {term, {-1,ETimedout,ETimedout}} = runner:get_term(P3, 10000), - ?line runner:recv_eot(P3), - ?line gen_tcp:close(SocketA), + {term, {-1,ETimedout,ETimedout}} = runner:get_term(P3, 10000), + runner:recv_eot(P3), + gen_tcp:close(SocketA), ok. make_node(X) -> list_to_atom(atom_to_list(X) ++ "@" ++ - hd(tl(string:tokens(atom_to_list(node()),"@")))). + hd(tl(string:tokens(atom_to_list(node()),"@")))). make_and_check_dummy() -> % First check that the host has an ip and is *not* reachable - ?line case gen_tcp:connect(?dummy_host,23,[{active,false}],5000) of - {error,timeout} -> ok; - {error,ehostunreach} -> ok - end, + HostNotReachable = ct:get_config(test_host_not_reachable), + case gen_tcp:connect(HostNotReachable, 23, [{active,false}],5000) of + {error,timeout} -> ok; + {error,ehostunreach} -> ok + end, - list_to_atom("dummy@"++atom_to_list(?dummy_host)). + list_to_atom("dummy@"++HostNotReachable). %% %% Stolen from the erl_distribution_wb_test in kernel @@ -359,12 +326,12 @@ make_and_check_dummy() -> %% -define(to_port(Socket, Data), - case inet_tcp:send(Socket, Data) of - {error, closed} -> - self() ! {tcp_closed, Socket}, - {error, closed}; - R -> - R + case inet_tcp:send(Socket, Data) of + {error, closed} -> + self() ! {tcp_closed, Socket}, + {error, closed}; + R -> + R end). -define(DFLAG_PUBLISHED,1). @@ -382,8 +349,8 @@ make_and_check_dummy() -> -define(int16(X), [((X) bsr 8) band 16#ff, (X) band 16#ff]). -define(int32(X), - [((X) bsr 24) band 16#ff, ((X) bsr 16) band 16#ff, - ((X) bsr 8) band 16#ff, (X) band 16#ff]). + [((X) bsr 24) band 16#ff, ((X) bsr 16) band 16#ff, + ((X) bsr 8) band 16#ff, (X) band 16#ff]). -define(i16(X1,X0), (?u16(X1,X0) - @@ -406,9 +373,9 @@ make_and_check_dummy() -> %% This is no proper random number, but that is not really important in %% this test gen_challenge() -> - {_,_,N} = erlang:now(), + {_,_,N} = os:timestamp(), N. - + %% Generate a message digest from Challenge number and Cookie gen_digest(Challenge, Cookie) when is_integer(Challenge), is_atom(Cookie) -> C0 = erlang:md5_init(), @@ -423,95 +390,93 @@ gen_digest(Challenge, Cookie) when is_integer(Challenge), is_atom(Cookie) -> send_status(Socket, Stat) -> case gen_tcp:send(Socket, [$s | atom_to_list(Stat)]) of - {error, _} -> - ?shutdown(could_not_send_status); - _ -> - true + {error, _} -> ?shutdown(could_not_send_status); + _ -> true end. recv_status(Socket) -> case gen_tcp:recv(Socket, 0) of - {ok, [$s|StrStat]} -> - list_to_atom(StrStat); - Bad -> - exit(Bad) + {ok, [$s|StrStat]} -> + list_to_atom(StrStat); + Bad -> + 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), + {ok, {{_Ip1,_Ip2,_Ip3,_Ip4}, _}} = inet:sockname(Socket), ?to_port(Socket, [$n,?int16(Version),?int32(Flags), - ?int32(Challenge), atom_to_list(Node)]). + ?int32(Challenge), atom_to_list(Node)]). recv_challenge(Socket) -> case gen_tcp:recv(Socket, 0) of - {ok,[$n,V1,V0,Fl1,Fl2,Fl3,Fl4,CA3,CA2,CA1,CA0 | Ns]} -> - Flags = ?u32(Fl1,Fl2,Fl3,Fl4), - Type = case Flags band ?DFLAG_PUBLISHED of - 0 -> - hidden; - _ -> - normal - end, - Node =list_to_atom(Ns), - Version = ?u16(V1,V0), - Challenge = ?u32(CA3,CA2,CA1,CA0), - {Type,Node,Version,Challenge}; - _ -> - ?shutdown(no_node) + {ok,[$n,V1,V0,Fl1,Fl2,Fl3,Fl4,CA3,CA2,CA1,CA0 | Ns]} -> + Flags = ?u32(Fl1,Fl2,Fl3,Fl4), + Type = case Flags band ?DFLAG_PUBLISHED of + 0 -> + hidden; + _ -> + normal + end, + Node =list_to_atom(Ns), + Version = ?u16(V1,V0), + Challenge = ?u32(CA3,CA2,CA1,CA0), + {Type,Node,Version,Challenge}; + _ -> + ?shutdown(no_node) end. -send_challenge_reply(Socket, Challenge, Digest) -> - ?to_port(Socket, [$r,?int32(Challenge),Digest]). +%send_challenge_reply(Socket, Challenge, Digest) -> +% ?to_port(Socket, [$r,?int32(Challenge),Digest]). recv_challenge_reply(Socket, ChallengeA, Cookie) -> case gen_tcp:recv(Socket, 0) of - {ok,[$r,CB3,CB2,CB1,CB0 | SumB]} when length(SumB) == 16 -> - SumA = gen_digest(ChallengeA, Cookie), - ChallengeB = ?u32(CB3,CB2,CB1,CB0), - if SumB == SumA -> - ChallengeB; - true -> - ?shutdown(bad_challenge_reply) - end; - _ -> - ?shutdown(no_node) + {ok,[$r,CB3,CB2,CB1,CB0 | SumB]} when length(SumB) == 16 -> + SumA = gen_digest(ChallengeA, Cookie), + ChallengeB = ?u32(CB3,CB2,CB1,CB0), + if SumB == SumA -> + ChallengeB; + true -> + ?shutdown(bad_challenge_reply) + end; + _ -> + ?shutdown(no_node) end. send_challenge_ack(Socket, Digest) -> ?to_port(Socket, [$a,Digest]). -recv_challenge_ack(Socket, ChallengeB, CookieA) -> - case gen_tcp:recv(Socket, 0) of - {ok,[$a | SumB]} when length(SumB) == 16 -> - SumA = gen_digest(ChallengeB, CookieA), - if SumB == SumA -> - ok; - true -> - ?shutdown(bad_challenge_ack) - end; - _ -> - ?shutdown(bad_challenge_ack) - end. +%recv_challenge_ack(Socket, ChallengeB, CookieA) -> +% case gen_tcp:recv(Socket, 0) of +% {ok,[$a | SumB]} when length(SumB) == 16 -> +% SumA = gen_digest(ChallengeB, CookieA), +% if SumB == SumA -> +% ok; +% true -> +% ?shutdown(bad_challenge_ack) +% end; +% _ -> +% ?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). + MyNode). %% %% recv_name is common for both old and new handshake. %% recv_name(Socket) -> case gen_tcp:recv(Socket, 0) of - {ok,Data} -> - get_name(Data); - Res -> - ?shutdown({no_node,Res}) + {ok,Data} -> + get_name(Data); + Res -> + ?shutdown({no_node,Res}) end. get_name([$m,VersionA,VersionB,_Ip1,_Ip2,_Ip3,_Ip4|OtherNode]) -> @@ -520,11 +485,9 @@ 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, + 0 -> hidden; + _ -> normal + end, {Type, list_to_atom(OtherNode), ?u16(VersionA,VersionB)}; get_name(Data) -> @@ -533,74 +496,73 @@ get_name(Data) -> %% %% tell_name is for old handshake %% -tell_name(Socket, MyNode0, Version) -> - MyNode = atom_to_list(MyNode0), - {ok, {{Ip1,Ip2,Ip3,Ip4}, _}} = inet:sockname(Socket), - ?to_port(Socket, [$h,?int16(Version),Ip1,Ip2,Ip3,Ip4] ++ - MyNode). +%tell_name(Socket, MyNode0, Version) -> +% MyNode = atom_to_list(MyNode0), +% {ok, {{Ip1,Ip2,Ip3,Ip4}, _}} = inet:sockname(Socket), +% ?to_port(Socket, [$h,?int16(Version),Ip1,Ip2,Ip3,Ip4] ++ MyNode). %% %% The communication with EPMD follows %% do_register_node(NodeName, TcpPort, VLow, VHigh) -> case gen_tcp:connect({127,0,0,1}, get_epmd_port(), []) of - {ok, Socket} -> - {N0,_} = split(NodeName), - Name = atom_to_list(N0), - Extra = "", - Elen = length(Extra), - Len = 1+2+1+1+2+2+2+length(Name)+2+Elen, - gen_tcp:send(Socket, [?int16(Len), $x, - ?int16(TcpPort), - $M, - 0, - ?int16(VHigh), - ?int16(VLow), - ?int16(length(Name)), - Name, - ?int16(Elen), - Extra]), - case wait_for_reg_reply(Socket, []) of - {error, epmd_close} -> - exit(epmd_broken); - Other -> - Other - end; - Error -> - Error + {ok, Socket} -> + {N0,_} = split(NodeName), + Name = atom_to_list(N0), + Extra = "", + Elen = length(Extra), + Len = 1+2+1+1+2+2+2+length(Name)+2+Elen, + gen_tcp:send(Socket, [?int16(Len), $x, + ?int16(TcpPort), + $M, + 0, + ?int16(VHigh), + ?int16(VLow), + ?int16(length(Name)), + Name, + ?int16(Elen), + Extra]), + case wait_for_reg_reply(Socket, []) of + {error, epmd_close} -> + exit(epmd_broken); + Other -> + Other + end; + Error -> + Error end. 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; - Data when length(Data) < 4 -> - wait_for_reg_reply(Socket, Data); - Garbage -> - {error, {garbage_from_epmd, Garbage}} - end; - {tcp_closed, Socket} -> - {error, epmd_close} + {tcp, Socket, Data0} -> + case SoFar ++ Data0 of + [$y, Result, A, B] -> + case Result of + 0 -> + {alive, Socket, ?u16(A, B)}; + _ -> + {error, duplicate_name} + end; + Data when length(Data) < 4 -> + wait_for_reg_reply(Socket, Data); + Garbage -> + {error, {garbage_from_epmd, Garbage}} + end; + {tcp_closed, Socket} -> + {error, epmd_close} after 10000 -> - gen_tcp:close(Socket), - {error, no_reg_reply_from_epmd} + gen_tcp:close(Socket), + {error, no_reg_reply_from_epmd} end. register(NodeName, ListenSocket, VLow, VHigh) -> {ok,{_,TcpPort}} = inet:sockname(ListenSocket), case do_register_node(NodeName, TcpPort, VLow, VHigh) of - {alive, Socket, Creation} -> - Socket; - Other -> - exit(Other) + {alive, Socket, _Creation} -> + Socket; + Other -> + exit(Other) end. @@ -618,69 +580,10 @@ split(Atom) -> {A,B} = split(atom_to_list(Atom),[]), {list_to_atom(A),list_to_atom(B)}. -%% Build a simple distribution message -build_message(Cookie) -> - [$?,term_to_binary({6,self(),Cookie,rex}),term_to_binary(plupp)]. - -%% Build a distribution message that will make rex answer -build_rex_message(Cookie,OurName) -> - [$?,term_to_binary({6,self(),Cookie,rex}), - term_to_binary({'$gen_cast', - {cast, - rpc, - cast, - [OurName, hello, world, []], - self()} })]. - -%% Receive a distribution message -recv_message(Socket) -> - case gen_tcp:recv(Socket, 0) of - {ok,Data} -> - B0 = list_to_binary(Data), - {_,B1} = erlang:split_binary(B0,1), - Header = erlang:binary_to_term(B1), - Siz = size(term_to_binary(Header)), - {_,B2} = erlang:split_binary(B1,Siz), - Message = case (catch erlang:binary_to_term(B2)) of - {'EXIT', _} -> - could_not_digest_message; - Other -> - Other - end, - {Header, Message}; - Res -> - exit({no_message,Res}) - end. - %% Build a nodename join(Name,Host) -> list_to_atom(atom_to_list(Name) ++ "@" ++ atom_to_list(Host)). -%% start/stop slave. -start_node(Name, Param) -> - ?t:start_node(Name, slave, [{args, Param}]). - -stop_node(Node) -> - ?t:stop_node(Node). - - -get_nodenames(N, T) -> - get_nodenames(N, T, []). - -get_nodenames(0, _, Acc) -> - Acc; -get_nodenames(N, T, Acc) -> - {A, B, C} = now(), - get_nodenames(N-1, T, [list_to_atom(atom_to_list(?MODULE) - ++ "-" - ++ atom_to_list(T) - ++ "-" - ++ integer_to_list(A) - ++ "-" - ++ integer_to_list(B) - ++ "-" - ++ integer_to_list(C)) | Acc]). - get_epmd_port() -> case init:get_argument(epmd_port) of {ok, [[PortStr|_]|_]} when is_list(PortStr) -> diff --git a/lib/erl_interface/test/ei_tmo_SUITE_data/Makefile.first b/lib/erl_interface/test/ei_tmo_SUITE_data/Makefile.first index a19eabb64a..884221d9d7 100644 --- a/lib/erl_interface/test/ei_tmo_SUITE_data/Makefile.first +++ b/lib/erl_interface/test/ei_tmo_SUITE_data/Makefile.first @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2003-2009. All Rights Reserved. +# 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. 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 c6798a6644..b4ee361939 100644 --- a/lib/erl_interface/test/ei_tmo_SUITE_data/Makefile.src +++ b/lib/erl_interface/test/ei_tmo_SUITE_data/Makefile.src @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2003-2009. All Rights Reserved. +# 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. 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 1104f642a2..0079ef8c86 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 @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2003-2010. All Rights Reserved. + * 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. @@ -512,18 +512,21 @@ TESTCASE(send_tmo) for (i=0;i < iterations; ++i) { res = ei_send_tmo(com_sock, &pid, send_buffer.buff, send_buffer.index, 5000); - DEBUGF(("Sent bindata (%d):\n",res)); + if (res < 0) { + DEBUGF(("Sent bindata failed (%d) after %d iterations:\n", res, i)); + break; + } #ifdef DEBUG + if (i < 10 || (i % 100 == 0)) /* don't flood the log */ { int ndx = 0; int v; + DEBUGF(("%d: Sent bindata (%d): ", i, res)); ei_decode_version(send_buffer.buff,&ndx,&v); ei_print_term(debugfile, send_buffer.buff, &ndx); + DEBUGF(("\n")); } #endif - DEBUGF(("\n")); - if (res < 0) - break; } if (res < 0) { DEBUGF(("ei_send_tmo failure at line %d\n",__LINE__)); diff --git a/lib/erl_interface/test/erl_connect_SUITE.erl b/lib/erl_interface/test/erl_connect_SUITE.erl index f621310a1c..cd73f07b8f 100644 --- a/lib/erl_interface/test/erl_connect_SUITE.erl +++ b/lib/erl_interface/test/erl_connect_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2000-2011. All Rights Reserved. +%% 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. @@ -21,90 +21,67 @@ %% -module(erl_connect_SUITE). --include_lib("test_server/include/test_server.hrl"). +-include_lib("common_test/include/ct.hrl"). -include("erl_connect_SUITE_data/erl_connect_test_cases.hrl"). --export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, - init_per_group/2,end_per_group/2, - init_per_testcase/2,end_per_testcase/2, - erl_send/1,erl_reg_send/1, erl_send_cookie_file/1]). +-export([all/0, suite/0, + 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]}]. +suite() -> + [{ct_hooks,[ts_install_cth]}, + {timetrap, {seconds, 30}}]. all() -> [erl_send, erl_reg_send, erl_send_cookie_file]. -groups() -> - []. - -init_per_suite(Config) -> - Config. - -end_per_suite(_Config) -> - ok. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - -init_per_testcase(_Case, Config) -> - Dog = ?t:timetrap(?t:minutes(0.25)), - [{watchdog, Dog}|Config]. - -end_per_testcase(_Case, Config) -> - Dog = ?config(watchdog, Config), - test_server:timetrap_cancel(Dog), - ok. erl_send(Config) when is_list(Config) -> - ?line P = runner:start(?interpret), - ?line 1 = erl_connect_init(P, 42, erlang:get_cookie(), 0), - ?line {ok,Fd} = erl_connect(P, node()), + P = runner:start(?interpret), + 1 = erl_connect_init(P, 42, erlang:get_cookie(), 0), + {ok,Fd} = erl_connect(P, node()), - ?line ok = erl_send(P, Fd, self(), AMsg={a,message}), - ?line receive AMsg -> ok end, + ok = erl_send(P, Fd, self(), AMsg={a,message}), + receive AMsg -> ok end, - ?line 0 = erl_close_connection(P,Fd), - ?line runner:send_eot(P), - ?line runner:recv_eot(P), + 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"}; - _ -> - ?line P = runner:start(?interpret), - ?line 1 = erl_connect_init(P, 42, '', 0), - ?line {ok,Fd} = erl_connect(P, node()), - - ?line ok = erl_send(P, Fd, self(), AMsg={a,message}), - ?line receive AMsg -> ok end, - - ?line 0 = erl_close_connection(P,Fd), - ?line runner:send_eot(P), - ?line runner:recv_eot(P), - ok + vxworks -> + {skip,"Skipped on VxWorks"}; + _ -> + P = runner:start(?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) -> - ?line P = runner:start(?interpret), - ?line 1 = erl_connect_init(P, 42, erlang:get_cookie(), 0), - ?line {ok,Fd} = erl_connect(P, node()), + P = runner:start(?interpret), + 1 = erl_connect_init(P, 42, erlang:get_cookie(), 0), + {ok,Fd} = erl_connect(P, node()), ARegName = a_strange_registred_name, - ?line register(ARegName, self()), - ?line ok = erl_reg_send(P, Fd, ARegName, AMsg={another,[strange],message}), - ?line receive AMsg -> ok end, + register(ARegName, self()), + ok = erl_reg_send(P, Fd, ARegName, AMsg={another,[strange],message}), + receive AMsg -> ok end, - ?line 0 = erl_close_connection(P,Fd), - ?line runner:send_eot(P), - ?line runner:recv_eot(P), + 0 = erl_close_connection(P,Fd), + runner:send_eot(P), + runner:recv_eot(P), ok. @@ -113,20 +90,20 @@ erl_reg_send(Config) when is_list(Config) -> 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 + {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} + {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 + {term,Int} when is_integer(Int) -> Int end. erl_send(P, Fd, To, Msg) -> @@ -139,17 +116,12 @@ erl_reg_send(P, Fd, To, Msg) -> 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]), - ?t:fail(bad_return_value) + {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 index f0b8eef6bd..21a7aac0b0 100644 --- a/lib/erl_interface/test/erl_connect_SUITE_data/Makefile.first +++ b/lib/erl_interface/test/erl_connect_SUITE_data/Makefile.first @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2001-2009. All Rights Reserved. +# 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. diff --git a/lib/erl_interface/test/erl_connect_SUITE_data/Makefile.src b/lib/erl_interface/test/erl_connect_SUITE_data/Makefile.src index 57db6f6024..ff4c382c97 100644 --- a/lib/erl_interface/test/erl_connect_SUITE_data/Makefile.src +++ b/lib/erl_interface/test/erl_connect_SUITE_data/Makefile.src @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2000-2009. All Rights Reserved. +# 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. 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 index 11c0daa4c5..0adaa79a33 100644 --- 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 @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2000-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/test/erl_eterm_SUITE.erl b/lib/erl_interface/test/erl_eterm_SUITE.erl index 8fbef35309..0e51a50c19 100644 --- a/lib/erl_interface/test/erl_eterm_SUITE.erl +++ b/lib/erl_interface/test/erl_eterm_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2011. All Rights Reserved. +%% 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. @@ -21,7 +21,7 @@ %% -module(erl_eterm_SUITE). --include_lib("test_server/include/test_server.hrl"). +-include_lib("common_test/include/ct.hrl"). -include("erl_eterm_SUITE_data/eterm_test_cases.hrl"). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -34,40 +34,39 @@ %%% 5. Miscellanous functions. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, - init_per_group/2,end_per_group/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([all/0, suite/0, + 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]). @@ -76,7 +75,8 @@ %% 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]}]. +suite() -> + [{ct_hooks,[ts_install_cth]}]. all() -> [build_terms, round_trip_conversion, decode_terms, @@ -93,22 +93,6 @@ all() -> erl_print_term, print_string, t_erl_free_compound, high_chaparal, broken_data, cnode_1]. -groups() -> - []. - -init_per_suite(Config) -> - Config. - -end_per_suite(_Config) -> - ok. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% @@ -119,82 +103,77 @@ end_per_group(_GroupName, Config) -> %% This test asks the C function to construct all data types in %% a list and verifies that the result is as expected. -build_terms(suite) -> []; build_terms(Config) when is_list(Config) -> - ?line P = runner:start(?build_terms), - ?line {term, Term} = get_term(P), - ?line io:format("Received: ~p", [Term]), - ?line [ARefLN, ARef, APortLN, APort, APidLN, APid, - {element1, 42, 767}, "A string", - 1, -1, 0, 3.0, ABin, 'I am an atom'] = Term, - ?line "A binary" = binary_to_list(ABin), - ?line case ARef of - R when is_reference(R), node(R) == kalle@localhost -> ok - end, - ?line case ARefLN of - R1 when is_reference(R1), node(R1) == abcdefghijabcdefghij@localhost -> ok - end, - ?line case APort of - Port when is_port(Port), node(Port) == kalle@localhost -> ok - end, - ?line case APortLN of - Port1 when is_port(Port1), node(Port1) == abcdefghijabcdefghij@localhost -> ok - end, - ?line case APid of - Pid when is_pid(Pid), node(Pid) == kalle@localhost -> ok - end, - ?line case APidLN of - Pid1 when is_pid(Pid1), node(Pid1) == abcdefghijabcdefghij@localhost -> ok - end, - - ?line runner:recv_eot(P), + P = runner:start(?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(suite) -> []; round_trip_conversion(Config) when is_list(Config) -> - ?line runner:test(?round_trip_conversion), + runner:test(?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(suite) -> []; decode_terms(Config) when is_list(Config) -> - ?line Dummy1 = list_to_atom(filename:join(?config(priv_dir, Config), - dummy_file1)), - ?line Dummy2 = list_to_atom(filename:join(?config(priv_dir, Config), - dummy_file2)), - ?line Port1 = open_port(Dummy1, [out]), - ?line Port2 = open_port(Dummy2, [out]), - ?line ABinary = list_to_binary("A binary"), - ?line Terms = [make_ref(), make_ref(), - Port1, Port2, - self(), self(), - {element1, 42, 767}, "A string", - 1, -1, 0, 3.0, ABinary, 'I am an atom'], - - ?line P = runner:start(?decode_terms), - ?line runner:send_term(P, Terms), - ?line runner:recv_eot(P), + 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(?decode_terms), + runner:send_term(P, Terms), + runner:recv_eot(P), ok. %% Decodes the floating point number 3.1415. -decode_float(suite) -> []; decode_float(Config) when is_list(Config) -> - ?line P = runner:start(?decode_float), - ?line runner:send_term(P, 3.1415), - ?line runner:recv_eot(P), + P = runner:start(?decode_float), + runner:send_term(P, 3.1415), + runner:recv_eot(P), ok. %% Tests the erl_free_compound() function. -t_erl_free_compound(suite) -> []; t_erl_free_compound(Config) when is_list(Config) -> - ?line runner:test(?t_erl_free_compound), + runner:test(?t_erl_free_compound), ok. @@ -206,317 +185,296 @@ t_erl_free_compound(Config) when is_list(Config) -> %% This tests the erl_mk_list() function. -t_erl_mk_list(suite) -> []; t_erl_mk_list(Config) when is_list(Config) -> - ?line P = runner:start(?t_erl_mk_list), + P = runner:start(?t_erl_mk_list), - ?line {term, []} = get_term(P), - ?line {term, [abc]} = get_term(P), - ?line {term, [abcdef, 42]} = get_term(P), - ?line {term, [0.0, 23, [], 3.1415]} = get_term(P), + {term, []} = get_term(P), + {term, [abc]} = get_term(P), + {term, [abcdef, 42]} = get_term(P), + {term, [0.0, 23, [], 3.1415]} = get_term(P), - ?line runner:recv_eot(P), + runner:recv_eot(P), ok. %% This tests the erl_mk_int() function. -t_erl_mk_int(suite) -> []; t_erl_mk_int(Config) when is_list(Config) -> - ?line P = runner:start(?t_erl_mk_int), - - ?line {term, 0} = get_term(P), - ?line {term, 127} = get_term(P), - ?line {term, 128} = get_term(P), - ?line {term, 255} = get_term(P), - ?line {term, 256} = get_term(P), - - ?line {term, 16#FFFF} = get_term(P), - ?line {term, 16#10000} = get_term(P), - - ?line {term, 16#07FFFFFF} = get_term(P), - ?line {term, 16#0FFFFFFF} = get_term(P), - ?line {term, 16#1FFFFFFF} = get_term(P), - ?line {term, 16#3FFFFFFF} = get_term(P), - ?line {term, 16#7FFFFFFF} = get_term(P), - - ?line {term, 16#08000000} = get_term(P), - ?line {term, 16#10000000} = get_term(P), - ?line {term, 16#20000000} = get_term(P), - ?line {term, 16#40000000} = get_term(P), - - - ?line {term, -16#07FFFFFF} = get_term(P), - ?line {term, -16#0FFFFFFF} = get_term(P), - ?line {term, -16#1FFFFFFF} = get_term(P), - ?line {term, -16#3FFFFFFF} = get_term(P), - ?line {term, -16#7FFFFFFF} = get_term(P), - - ?line {term, -16#08000000} = get_term(P), - ?line {term, -16#10000000} = get_term(P), - ?line {term, -16#20000000} = get_term(P), - ?line {term, -16#40000000} = get_term(P), - - ?line {term, -16#08000001} = get_term(P), - ?line {term, -16#10000001} = get_term(P), - ?line {term, -16#20000001} = get_term(P), - ?line {term, -16#40000001} = get_term(P), - - ?line {term, -16#08000002} = get_term(P), - ?line {term, -16#10000002} = get_term(P), - ?line {term, -16#20000002} = get_term(P), - ?line {term, -16#40000002} = get_term(P), - - ?line {term, -1999999999} = get_term(P), - ?line {term, -2000000000} = get_term(P), - ?line {term, -2000000001} = get_term(P), - - ?line runner:recv_eot(P), + P = runner:start(?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(suite) -> []; basic_copy(Config) when is_list(Config) -> - ?line runner:test(?basic_copy), + runner:test(?basic_copy), ok. %% This tests the erl_mk_tuple() function. -t_erl_mk_tuple(suite) -> []; t_erl_mk_tuple(Config) when is_list(Config) -> - ?line P = runner:start(?t_erl_mk_tuple), + P = runner:start(?t_erl_mk_tuple), - ?line {term, {madonna, 21, 'mad donna', 12}} = get_term(P), - ?line {term, {'Madonna',21,{children,{"Isabella",2}}, - {'home page',"http://www.madonna.com/"}}} = get_term(P), + {term, {madonna, 21, 'mad donna', 12}} = get_term(P), + {term, {'Madonna',21,{children,{"Isabella",2}}, + {'home page',"http://www.madonna.com/"}}} = get_term(P), - ?line runner:recv_eot(P), + runner:recv_eot(P), ok. %% This tests the erl_mk_atom() function. -t_erl_mk_atom(suite) -> []; t_erl_mk_atom(Config) when is_list(Config) -> - ?line P = runner:start(?t_erl_mk_atom), - - ?line {term, madonna} = (get_term(P)), - ?line {term, 'Madonna'} = (get_term(P)), - ?line {term, 'mad donna'} = (get_term(P)), - ?line {term, '_madonna_'} = (get_term(P)), - ?line {term, '/home/madonna/tour_plan'} = (get_term(P)), - ?line {term, 'http://www.madonna.com/tour_plan'} = (get_term(P)), - ?line {term, '\'madonna\''} = (get_term(P)), - ?line {term, '\"madonna\"'} = (get_term(P)), - ?line {term, '\\madonna\\'} = (get_term(P)), - ?line {term, '{madonna,21,\'mad donna\',12}'} = (get_term(P)), - - ?line runner:recv_eot(P), + P = runner:start(?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(suite) -> []; t_erl_mk_binary(Config) when is_list(Config) -> - ?line P = runner:start(?t_erl_mk_binary), + P = runner:start(?t_erl_mk_binary), - ?line {term, Bin} = (get_term(P)), - ?line "{madonna,21,'mad donna',1234.567.890, !#$%&/()=?+-@, \" \\}" = - binary_to_list(Bin), + {term, Bin} = (get_term(P)), + "{madonna,21,'mad donna',1234.567.890, !#$%&/()=?+-@, \" \\}" = binary_to_list(Bin), - ?line runner:recv_eot(P), + runner:recv_eot(P), ok. %% This tests the erl_mk_empty_list() function. -t_erl_mk_empty_list(suite) -> []; t_erl_mk_empty_list(Config) when is_list(Config) -> - ?line P = runner:start(?t_erl_mk_empty_list), + P = runner:start(?t_erl_mk_empty_list), - ?line {term, []} = get_term(P), + {term, []} = get_term(P), - ?line runner:recv_eot(P), + runner:recv_eot(P), ok. %% This tests the erl_mk_float() function. -t_erl_mk_float(suite) -> []; t_erl_mk_float(Config) when is_list(Config) -> case os:type() of - vxworks -> - {skipped, "Floating point numbers never compare equal on PPC"}; - _ -> - ?line P = runner:start(?t_erl_mk_float), - ?line {term, {3.1415, 1.999999, 2.000000, 2.000001, - 2.000002, 12345.67890}} = - get_term(P), - ?line runner:recv_eot(P), - ok + vxworks -> + {skipped, "Floating point numbers never compare equal on PPC"}; + _ -> + P = runner:start(?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(suite) -> []; t_erl_mk_pid(Config) when is_list(Config) -> - ?line P = runner:start(?t_erl_mk_pid), + P = runner:start(?t_erl_mk_pid), - ?line {term, A_pid} = (get_term(P)), - ?line {pid, kalle@localhost, 3, 2} = nc2vinfo(A_pid), + {term, A_pid} = (get_term(P)), + {pid, kalle@localhost, 3, 2} = nc2vinfo(A_pid), - ?line runner:recv_eot(P), + runner:recv_eot(P), ok. -t_erl_mk_xpid(suite) -> []; t_erl_mk_xpid(Config) when is_list(Config) -> - ?line P = runner:start(?t_erl_mk_xpid), + P = runner:start(?t_erl_mk_xpid), - ?line {term, A_pid} = (get_term(P)), - ?line {pid, kalle@localhost, 32767, 8191} = nc2vinfo(A_pid), + {term, A_pid} = (get_term(P)), + {pid, kalle@localhost, 32767, 8191} = nc2vinfo(A_pid), - ?line runner:recv_eot(P), + runner:recv_eot(P), ok. %% This tests the erl_mk_port() function. -t_erl_mk_port(suite) -> []; t_erl_mk_port(Config) when is_list(Config) -> - ?line P = runner:start(?t_erl_mk_port), + P = runner:start(?t_erl_mk_port), - ?line {term, A_port} = (get_term(P)), - ?line {port, kalle@localhost, 4} = nc2vinfo(A_port), + {term, A_port} = (get_term(P)), + {port, kalle@localhost, 4} = nc2vinfo(A_port), - ?line runner:recv_eot(P), + runner:recv_eot(P), ok. -t_erl_mk_xport(suite) -> []; t_erl_mk_xport(Config) when is_list(Config) -> - ?line P = runner:start(?t_erl_mk_xport), + P = runner:start(?t_erl_mk_xport), - ?line {term, A_port} = (get_term(P)), - ?line {port, kalle@localhost, 268435455} = nc2vinfo(A_port), + {term, A_port} = (get_term(P)), + {port, kalle@localhost, 268435455} = nc2vinfo(A_port), - ?line runner:recv_eot(P), + runner:recv_eot(P), ok. %% This tests the erl_mk_ref() function. -t_erl_mk_ref(suite) -> []; t_erl_mk_ref(Config) when is_list(Config) -> - ?line P = runner:start(?t_erl_mk_ref), + P = runner:start(?t_erl_mk_ref), - ?line {term, A_ref} = (get_term(P)), - ?line {ref, kalle@localhost, _Length, [6]} = nc2vinfo(A_ref), + {term, A_ref} = (get_term(P)), + {ref, kalle@localhost, _Length, [6]} = nc2vinfo(A_ref), - ?line runner:recv_eot(P), + runner:recv_eot(P), ok. -t_erl_mk_long_ref(suite) -> []; t_erl_mk_long_ref(Config) when is_list(Config) -> - ?line P = runner:start(?t_erl_mk_long_ref), + P = runner:start(?t_erl_mk_long_ref), - ?line {term, A_ref} = (get_term(P)), - ?line {ref, kalle@localhost, _Length, [4294967295,4294967295,262143]} - = nc2vinfo(A_ref), + {term, A_ref} = (get_term(P)), + {ref, kalle@localhost, _Length, [4294967295,4294967295,262143]} + = nc2vinfo(A_ref), - ?line runner:recv_eot(P), + runner:recv_eot(P), ok. %% This tests the erl_mk_string() function. -t_erl_mk_string(suite) -> []; t_erl_mk_string(Config) when is_list(Config) -> - ?line P = runner:start(?t_erl_mk_string), - - ?line {term, "madonna"} = (get_term(P)), - ?line {term, "Madonna"} = (get_term(P)), - ?line {term, "mad donna"} = (get_term(P)), - ?line {term, "_madonna_"} = (get_term(P)), - ?line {term, "/home/madonna/tour_plan"} = (get_term(P)), - ?line {term, "http://www.madonna.com/tour_plan"} = (get_term(P)), - ?line {term, "\'madonna\'"} = (get_term(P)), - ?line {term, "\"madonna\""} = (get_term(P)), - ?line {term, "\\madonna\\"} = (get_term(P)), - ?line {term, "{madonna,21,'mad donna',12}"} = (get_term(P)), - - ?line runner:recv_eot(P), + P = runner:start(?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(suite) -> []; t_erl_mk_estring(Config) when is_list(Config) -> - ?line P = runner:start(?t_erl_mk_estring), - - ?line {term, "madonna"} = (get_term(P)), - ?line {term, "Madonna"} = (get_term(P)), - ?line {term, "mad donna"} = (get_term(P)), - ?line {term, "_madonna_"} = (get_term(P)), - ?line {term, "/home/madonna/tour_plan"} = (get_term(P)), - ?line {term, "http://www.madonna.com/tour_plan"} = (get_term(P)), - ?line {term, "\'madonna\'"} = (get_term(P)), - ?line {term, "\"madonna\""} = (get_term(P)), - ?line {term, "\\madonna\\"} = (get_term(P)), - ?line {term, "{madonna,21,'mad donna',12}"} = (get_term(P)), - - ?line runner:recv_eot(P), + P = runner:start(?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(suite) -> []; t_erl_mk_uint(Config) when is_list(Config) -> - ?line P = runner:start(?t_erl_mk_uint), + P = runner:start(?t_erl_mk_uint), - ?line {term, 54321} = (get_term(P)), - ?line {term, 2147483647} = (get_term(P)), - ?line {term, 2147483648} = (get_term(P)), - ?line {term, 2147483649} = (get_term(P)), - ?line {term, 2147483650} = (get_term(P)), - ?line {term, 4294967295} = (get_term(P)), + {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)), - ?line runner:recv_eot(P), + runner:recv_eot(P), ok. %% This tests the erl_mk_var() function. -t_erl_mk_var(suite) -> []; t_erl_mk_var(Config) when is_list(Config) -> - ?line P = runner:start(?t_erl_mk_var), + P = runner:start(?t_erl_mk_var), - ?line {term, 1} = (get_term(P)), - ?line {term, 0} = (get_term(P)), - ?line {term, 1} = (get_term(P)), - ?line {term, 0} = (get_term(P)), - ?line {term, 1} = (get_term(P)), - ?line {term, 0} = (get_term(P)), - ?line {term, 1} = (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)), + {term, 0} = (get_term(P)), + {term, 1} = (get_term(P)), - ?line runner:recv_eot(P), + runner:recv_eot(P), ok. %% This tests the erl_cons() function. -t_erl_cons(suite) -> []; t_erl_cons(Config) when is_list(Config) -> - ?line P = runner:start(?t_erl_cons), + P = runner:start(?t_erl_cons), - ?line {term, [madonna, 21]} = get_term(P), + {term, [madonna, 21]} = get_term(P), - ?line runner:recv_eot(P), + runner:recv_eot(P), ok. @@ -531,21 +489,20 @@ t_erl_cons(Config) when is_list(Config) -> %% Tests the erl_length() function. -t_erl_length(suite) -> []; t_erl_length(Config) when is_list(Config) -> - ?line P = runner:start(?t_erl_length), + P = runner:start(?t_erl_length), - ?line 0 = erl_length(P, []), - ?line 1 = erl_length(P, [a]), - ?line 2 = erl_length(P, [a, b]), - ?line 3 = erl_length(P, [a, b, c]), + 0 = erl_length(P, []), + 1 = erl_length(P, [a]), + 2 = erl_length(P, [a, b]), + 3 = erl_length(P, [a, b, c]), - ?line 4 = erl_length(P, [a, [x, y], c, []]), + 4 = erl_length(P, [a, [x, y], c, []]), - ?line -1 = erl_length(P, [a|b]), - ?line -1 = erl_length(P, a), + -1 = erl_length(P, [a|b]), + -1 = erl_length(P, a), - ?line runner:finish(P), + runner:finish(P), ok. %% Invokes the erl_length() function. @@ -555,22 +512,21 @@ erl_length(Port, List) -> %% Tests the erl_hd() function. -t_erl_hd(suite) -> []; t_erl_hd(Config) when is_list(Config) -> - ?line P = runner:start(?t_erl_hd), - - ?line 'NULL' = erl_hd(P, 42), - ?line 'NULL' = erl_hd(P, abc), - ?line 'NULL' = erl_hd(P, []), - - ?line [] = erl_hd(P, [[], a]), - ?line a = erl_hd(P, [a]), - ?line a = erl_hd(P, [a, b]), - ?line a = erl_hd(P, [a, b, c]), - ?line a = erl_hd(P, [a|b]), - - ?line runner:send_eot(P), - ?line runner:recv_eot(P), + P = runner:start(?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. @@ -580,22 +536,21 @@ erl_hd(Port, List) -> %% Tests the erl_tail() function. -t_erl_tl(suite) -> []; t_erl_tl(Config) when is_list(Config) -> - ?line P = runner:start(?t_erl_tl), + P = runner:start(?t_erl_tl), - ?line 'NULL' = erl_tl(P, 42), - ?line 'NULL' = erl_tl(P, abc), - ?line 'NULL' = erl_tl(P, []), + 'NULL' = erl_tl(P, 42), + 'NULL' = erl_tl(P, abc), + 'NULL' = erl_tl(P, []), - ?line [] = erl_tl(P, [a]), - ?line [b] = erl_tl(P, [a, b]), - ?line [b, c] = erl_tl(P, [a, b, c]), + [] = erl_tl(P, [a]), + [b] = erl_tl(P, [a, b]), + [b, c] = erl_tl(P, [a, b, c]), - ?line b = erl_tl(P, [a|b]), + b = erl_tl(P, [a|b]), - ?line runner:send_eot(P), - ?line runner:recv_eot(P), + runner:send_eot(P), + runner:recv_eot(P), ok. %% Invokes the erl_tail() function in erl_interface. @@ -605,68 +560,63 @@ erl_tl(Port, List) -> %% Tests the type checking macros (done in the C program). -type_checks(suite) -> []; type_checks(Config) when is_list(Config) -> - ?line runner:test(?type_checks), + runner:test(?type_checks), ok. %% Tests the extractor macros (done in the C program). -extractor_macros(suite) -> []; extractor_macros(Config) when is_list(Config) -> - ?line runner:test(?extractor_macros), + runner:test(?extractor_macros), ok. %% This tests the erl_size() function. -t_erl_size(suite) -> []; t_erl_size(Config) when is_list(Config) -> - ?line P = runner:start(?t_erl_size), + P = runner:start(?t_erl_size), - ?line {term, 0} = (get_term(P)), - ?line {term, 4} = (get_term(P)), + {term, 0} = (get_term(P)), + {term, 4} = (get_term(P)), - ?line {term, 0} = (get_term(P)), - ?line {term, 27} = (get_term(P)), + {term, 0} = (get_term(P)), + {term, 27} = (get_term(P)), - ?line runner:recv_eot(P), + runner:recv_eot(P), ok. %% This tests the erl_var_content() function. -t_erl_var_content(suite) -> []; t_erl_var_content(Config) when is_list(Config) -> - ?line P = runner:start(?t_erl_var_content), + P = runner:start(?t_erl_var_content), - ?line {term, 17} = (get_term(P)), - ?line {term, "http://www.madonna.com"} = (get_term(P)), - ?line {term, 2} = (get_term(P)), - ?line {term, "http://www.madonna.com"} = (get_term(P)), - ?line {term, 2} = (get_term(P)), + {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)), - ?line runner:recv_eot(P), + runner:recv_eot(P), ok. %% This tests the erl_element() function. -t_erl_element(suite) -> []; t_erl_element(Config) when is_list(Config) -> - ?line P = runner:start(?t_erl_element), + P = runner:start(?t_erl_element), - ?line {term, madonna} = get_term(P), - ?line {term, 21} = get_term(P), - ?line {term, 'mad donna'} = get_term(P), - ?line {term, 12} = get_term(P), + {term, madonna} = get_term(P), + {term, 21} = get_term(P), + {term, 'mad donna'} = get_term(P), + {term, 12} = get_term(P), - ?line {term, 'Madonna'} = get_term(P), - ?line {term, 21} = get_term(P), - ?line {term, {children,{"Isabella",2}}} = get_term(P), - ?line {term, {'home page',"http://www.madonna.com/"}} = 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), - ?line runner:recv_eot(P), + runner:recv_eot(P), ok. @@ -679,65 +629,64 @@ t_erl_element(Config) when is_list(Config) -> %% Tests the erl_iolist_length() function. -t_erl_iolist_length(suite) -> []; t_erl_iolist_length(Config) when is_list(Config) -> - ?line P = runner:start(?t_erl_iolist_length), + P = runner:start(?t_erl_iolist_length), %% Flat lists. - ?line 0 = erl_iolist_length(P, []), - ?line 1 = erl_iolist_length(P, [10]), - ?line 2 = erl_iolist_length(P, [10, 20]), - ?line 3 = erl_iolist_length(P, [10, 20, 30]), - ?line 256 = erl_iolist_length(P, lists:seq(0, 255)), + 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. - ?line 0 = erl_iolist_length(P, [[]]), - ?line 1 = erl_iolist_length(P, [[], 42]), - ?line 1 = erl_iolist_length(P, [42, []]), - ?line 2 = erl_iolist_length(P, [42, [], 45]), + 0 = erl_iolist_length(P, [[]]), + 1 = erl_iolist_length(P, [[], 42]), + 1 = erl_iolist_length(P, [42, []]), + 2 = erl_iolist_length(P, [42, [], 45]), - ?line 3 = erl_iolist_length(P, [42, [90], 45]), - ?line 3 = erl_iolist_length(P, [[42, [90]], 45]), - ?line 3 = erl_iolist_length(P, [[42, [90]], 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. - ?line 0 = erl_iolist_length(P, [list_to_binary([])]), - ?line 0 = erl_iolist_length(P, [[], list_to_binary([])]), - ?line 1 = erl_iolist_length(P, [[1], list_to_binary([])]), - ?line 1 = erl_iolist_length(P, [[], list_to_binary([2])]), - ?line 2 = erl_iolist_length(P, [[42], list_to_binary([2])]), - ?line 4 = erl_iolist_length(P, [[42], list_to_binary([2, 3, 4])]), + 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. - ?line 0 = erl_iolist_length(P, [[]| list_to_binary([])]), - ?line 1 = erl_iolist_length(P, [[1]| list_to_binary([])]), - ?line 1 = erl_iolist_length(P, [[]| list_to_binary([2])]), - ?line 2 = erl_iolist_length(P, [[42]| list_to_binary([2])]), + 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. - ?line 0 = erl_iolist_length(P, list_to_binary("")), - ?line 1 = erl_iolist_length(P, list_to_binary([1])), - ?line 2 = erl_iolist_length(P, list_to_binary([1, 2])), + 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. - ?line -1 = erl_iolist_length(P, [42|43]), - ?line -1 = erl_iolist_length(P, a), + -1 = erl_iolist_length(P, [42|43]), + -1 = erl_iolist_length(P, a), - ?line -1 = erl_iolist_length(P, [a]), - ?line -1 = erl_iolist_length(P, [256]), - ?line -1 = erl_iolist_length(P, [257]), - ?line -1 = erl_iolist_length(P, [-1]), - ?line -1 = erl_iolist_length(P, [-2]), - ?line -1 = erl_iolist_length(P, [-127]), - ?line -1 = erl_iolist_length(P, [-128]), + -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]), - ?line runner:finish(P), + runner:finish(P), ok. %% Invokes the erl_iolist_length() function. @@ -747,143 +696,141 @@ erl_iolist_length(Port, List) -> %% Tests the erl_iolist_to_binary() function. -t_erl_iolist_to_binary(suite) -> []; t_erl_iolist_to_binary(Config) when is_list(Config) -> - ?line P = runner:start(?t_erl_iolist_to_binary), + P = runner:start(?t_erl_iolist_to_binary), %% Flat lists. - ?line [] = iolist_to_list(P, []), - ?line [10] = iolist_to_list(P, [10]), - ?line [10, 20] = iolist_to_list(P, [10, 20]), - ?line [10, 20, 30] = iolist_to_list(P, [10, 20, 30]), - ?line AllBytes = lists:seq(0, 255), - ?line AllBytes = iolist_to_list(P, AllBytes), + [] = 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. - ?line [] = iolist_to_list(P, [[]]), - ?line [42] = iolist_to_list(P, [[], 42]), - ?line [42] = iolist_to_list(P, [42, []]), - ?line [42, 45] = iolist_to_list(P, [42, [], 45]), + [] = iolist_to_list(P, [[]]), + [42] = iolist_to_list(P, [[], 42]), + [42] = iolist_to_list(P, [42, []]), + [42, 45] = iolist_to_list(P, [42, [], 45]), - ?line [42, 90, 45] = iolist_to_list(P, [42, [90], 45]), - ?line [42, 90, 45] = iolist_to_list(P, [[42, [90]], 45]), - ?line [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]), + [42, 90, 45] = iolist_to_list(P, [[42, [90]], 45]), %% List with binaries. - ?line [] = iolist_to_list(P, [list_to_binary([])]), - ?line [] = iolist_to_list(P, [[], list_to_binary([])]), - ?line [1] = iolist_to_list(P, [[1], list_to_binary([])]), - ?line [2] = iolist_to_list(P, [[], list_to_binary([2])]), - ?line [42, 2] = iolist_to_list(P, [[42], list_to_binary([2])]), - ?line [42, 2, 3, 4] = iolist_to_list(P, [[42], list_to_binary([2, 3, 4])]), + [] = 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. - ?line [] = iolist_to_list(P, [[]| list_to_binary([])]), - ?line [1] = iolist_to_list(P, [[1]| list_to_binary([])]), - ?line [2] = iolist_to_list(P, [[]| list_to_binary([2])]), - ?line [42, 2] = iolist_to_list(P, [[42]| list_to_binary([2])]), + [] = 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. - ?line [] = iolist_to_list(P, list_to_binary("")), - ?line [1] = iolist_to_list(P, list_to_binary([1])), - ?line [1, 2] = iolist_to_list(P, list_to_binary([1, 2])), + [] = 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. - ?line 'NULL' = iolist_to_list(P, [42|43]), - ?line 'NULL' = iolist_to_list(P, a), + 'NULL' = iolist_to_list(P, [42|43]), + 'NULL' = iolist_to_list(P, a), - ?line 'NULL' = iolist_to_list(P, [a]), - ?line 'NULL' = iolist_to_list(P, [256]), - ?line 'NULL' = iolist_to_list(P, [257]), - ?line 'NULL' = iolist_to_list(P, [-1]), - ?line 'NULL' = iolist_to_list(P, [-2]), - ?line 'NULL' = iolist_to_list(P, [-127]), - ?line 'NULL' = iolist_to_list(P, [-128]), + '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]), - ?line runner:finish(P), + 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) + 'NULL' -> + 'NULL'; + Bin when is_binary(Bin) -> + binary_to_list(Bin) end. %% Tests the erl_iolist_to_string() function. -t_erl_iolist_to_string(suite) -> []; t_erl_iolist_to_string(Config) when is_list(Config) -> - ?line P = runner:start(?t_erl_iolist_to_string), + P = runner:start(?t_erl_iolist_to_string), %% Flat lists. - ?line [0] = iolist_to_string(P, []), - ?line [10, 0] = iolist_to_string(P, [10]), - ?line [10, 20, 0] = iolist_to_string(P, [10, 20]), - ?line [10, 20, 30, 0] = iolist_to_string(P, [10, 20, 30]), - ?line AllBytes = lists:seq(1, 255)++[0], - ?line AllBytes = iolist_to_string(P, lists:seq(1, 255)), + [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. - ?line [0] = iolist_to_string(P, [[]]), - ?line [42, 0] = iolist_to_string(P, [[], 42]), - ?line [42, 0] = iolist_to_string(P, [42, []]), - ?line [42, 45, 0] = iolist_to_string(P, [42, [], 45]), + [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]), - ?line [42, 90, 45, 0] = iolist_to_string(P, [42, [90], 45]), - ?line [42, 90, 45, 0] = iolist_to_string(P, [[42, [90]], 45]), - ?line [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]), + [42, 90, 45, 0] = iolist_to_string(P, [[42, [90]], 45]), %% List with binaries. - ?line [0] = iolist_to_string(P, [list_to_binary([])]), - ?line [0] = iolist_to_string(P, [[], list_to_binary([])]), - ?line [1, 0] = iolist_to_string(P, [[1], list_to_binary([])]), - ?line [2, 0] = iolist_to_string(P, [[], list_to_binary([2])]), - ?line [42, 2, 0] = iolist_to_string(P, [[42], list_to_binary([2])]), - ?line [42, 2, 3, 4, 0] = iolist_to_string(P, [[42], - list_to_binary([2, 3, 4])]), + [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. - ?line [0] = iolist_to_string(P, [[]| list_to_binary([])]), - ?line [1, 0] = iolist_to_string(P, [[1]| list_to_binary([])]), - ?line [2, 0] = iolist_to_string(P, [[]| list_to_binary([2])]), - ?line [42, 2, 0] = iolist_to_string(P, [[42]| list_to_binary([2])]), + [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. - ?line [0] = iolist_to_string(P, list_to_binary("")), - ?line [1, 0] = iolist_to_string(P, list_to_binary([1])), - ?line [1, 2, 0] = iolist_to_string(P, list_to_binary([1, 2])), + [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. - ?line 'NULL' = iolist_to_string(P, [0]), - ?line 'NULL' = iolist_to_string(P, [65, 0, 66]), - ?line 'NULL' = iolist_to_string(P, [65, 66, 67, 0]), + 'NULL' = iolist_to_string(P, [0]), + 'NULL' = iolist_to_string(P, [65, 0, 66]), + 'NULL' = iolist_to_string(P, [65, 66, 67, 0]), - ?line 'NULL' = iolist_to_string(P, [42|43]), - ?line 'NULL' = iolist_to_string(P, a), + 'NULL' = iolist_to_string(P, [42|43]), + 'NULL' = iolist_to_string(P, a), - ?line 'NULL' = iolist_to_string(P, [a]), - ?line 'NULL' = iolist_to_string(P, [256]), - ?line 'NULL' = iolist_to_string(P, [257]), - ?line 'NULL' = iolist_to_string(P, [-1]), - ?line 'NULL' = iolist_to_string(P, [-2]), - ?line 'NULL' = iolist_to_string(P, [-127]), - ?line 'NULL' = iolist_to_string(P, [-128]), + '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]), - ?line runner:finish(P), + runner:finish(P), ok. %% Invokes the erl_iolist_to_string() function. @@ -891,8 +838,8 @@ t_erl_iolist_to_string(Config) when is_list(Config) -> iolist_to_string(Port, Term) -> runner:send_term(Port, Term), case get_term(Port) of - {bytes, Result} -> Result; - 'NULL' -> 'NULL' + {bytes, Result} -> Result; + 'NULL' -> 'NULL' end. @@ -902,38 +849,37 @@ iolist_to_string(Port, Term) -> %%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -erl_print_term(suite) -> []; -erl_print_term(doc) -> "Tests the erl_print_term() function"; +%% Tests the erl_print_term() function erl_print_term(Config) when is_list(Config) -> - ?line PrintTerm = print_term(Config), - ?line P = open_port({spawn, PrintTerm}, [stream]), + PrintTerm = print_term(Config), + P = open_port({spawn, PrintTerm}, [stream]), %% Lists. - ?line print(P, "[]", []), - ?line print(P, "[a]", [a]), - ?line print(P, "[[a]]", [[a]]), - ?line print(P, "[[]]", [[]]), - ?line print(P, "[a,b,c]", [a,b,c]), - ?line print(P, "[a,b|c]", [a,b|c]), - ?line print(P, "[a,[],c]", [a,[],c]), - ?line print(P, "[a,[1000,1],c]", [a,[1000,1],c]), + 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. - ?line print(P, "{}", {}), - ?line print(P, "{ok}", {ok}), - ?line print(P, "{1,2,3}", {1, 2, 3}), + print(P, "{}", {}), + print(P, "{ok}", {ok}), + print(P, "{1,2,3}", {1, 2, 3}), %% Pids. - ?line {_X, Y, Z} = split_pid(self()), - ?line PidString = lists:flatten(io_lib:format("<~s.~w.~w>", - [node(), Y, Z])), - ?line print(P, PidString, self()), + {_X, Y, Z} = split_pid(self()), + PidString = lists:flatten(io_lib:format("<~s.~w.~w>", + [node(), Y, Z])), + print(P, PidString, self()), - ?line unlink(P), - ?line exit(P, die), + unlink(P), + exit(P, die), ok. split_pid(Pid) when is_pid(Pid) -> @@ -948,23 +894,22 @@ split_pid([$.|Rest], Cur, Result) -> split_pid([$>], Cur, Result) -> list_to_tuple(Result++[Cur]). -print_string(suite) -> []; -print_string(doc) -> "Test printing a string with erl_print_term()"; +%% Test printing a string with erl_print_term() print_string(Config) when is_list(Config) -> - ?line PrintTerm = print_term(Config), - ?line P = open_port({spawn, PrintTerm}, [stream]), + PrintTerm = print_term(Config), + P = open_port({spawn, PrintTerm}, [stream]), %% Strings. - ?line print(P, "\"ABC\"", "ABC"), - ?line {11, "\"\\tABC\\r\\n\""} = print(P, "\tABC\r\n"), + print(P, "\"ABC\"", "ABC"), + {11, "\"\\tABC\\r\\n\""} = print(P, "\tABC\r\n"), %% Not strings. - ?line print(P, "[65,66,67,0]", "ABC\000"), + print(P, "[65,66,67,0]", "ABC\000"), - ?line unlink(P), - ?line exit(P, die), + unlink(P), + exit(P, die), ok. print(Port, TermString, Term) -> @@ -983,15 +928,15 @@ print(Port, Term) -> 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 test_server:seconds(5) -> - test_server:fail("No response from C program") + {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) -> @@ -1001,18 +946,16 @@ collect_line1([C|Rest], Result) -> %% Test case submitted by Per Lundgren, ERV. -high_chaparal(suite) -> []; high_chaparal(Config) when is_list(Config) -> - ?line P = runner:start(?high_chaparal), - ?line {term, [hello, world]} = get_term(P), - ?line runner:recv_eot(P), + P = runner:start(?high_chaparal), + {term, [hello, world]} = get_term(P), + runner:recv_eot(P), ok. %% OTP-7448 -broken_data(suite) -> []; broken_data(Config) when is_list(Config) -> - ?line P = runner:start(?broken_data), - ?line runner:recv_eot(P), + P = runner:start(?broken_data), + runner:recv_eot(P), ok. %% This calls a C function with one parameter and returns the result. @@ -1020,12 +963,12 @@ broken_data(Config) when is_list(Config) -> call_erl_function(Port, Term) -> runner:send_term(Port, Term), case get_term(Port) of - {term, Result} -> Result; - 'NULL' -> 'NULL' + {term, Result} -> Result; + 'NULL' -> 'NULL' end. print_term(Config) when is_list(Config) -> - filename:join(?config(data_dir, Config), "print_term"). + filename:join(proplists:get_value(data_dir, Config), "print_term"). @@ -1034,57 +977,57 @@ print_term(Config) when is_list(Config) -> %%% 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. -cnode_1(suite) -> []; -cnode_1(doc) -> "Tests involving cnode: sends a long ref from a cnode to us"; + +%% Tests involving cnode: sends a long ref from a cnode to us cnode_1(Config) when is_list(Config) -> - ?line Cnode = filename:join(?config(data_dir, Config), "cnode"), - ?line register(mip, self()), - ?line spawn_link(?MODULE, start_cnode, [Cnode]), - ?line Ref1 = get_ref(), + 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]), - ?line check_ref(Ref1), - ?line Ref2 = make_ref(), - ?line receive - Pid -> Pid - end, - ?line Fun1 = fun(X) -> {Pid, X} end, % sneak in a fun test here - %?line Fun1 = {wait_with_funs, new_dist_format}, - ?line Term = {Ref2, Fun1, {1,2,3,4,5,6,7,8,9,10}}, + 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'. - ?line Pid ! Term, - ?line receive - Term2 -> - io:format("received ~p~n", [Term2]), - case Term2 of - Term -> - {Ref22,_,_} = Term2, - ?line check_ref(Ref22); - X -> - test_server:fail({receive1,X}) - end - after 5000 -> - test_server:fail(receive1) - end, - ?line receive - Pid -> - ok; - Y -> - test_server:fail({receive1,Y}) - after 5000 -> - test_server:fail(receive2) - end, - ?line io:format("ref = ~p~n", [Ref1]), - ?line check_ref(Ref1), + 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 -> - test_server:fail(oldref); - 114 -> - ok; - Type -> - test_server:fail({type, Type}) + 101 -> + ct:fail(oldref); + 114 -> + ok; + Type -> + ct:fail({type, Type}) end. bin_ext_type(T) -> @@ -1093,10 +1036,10 @@ bin_ext_type(T) -> get_ref() -> receive - X when is_reference(X) -> - X + X when is_reference(X) -> + X after 5000 -> - test_server:fail({cnode, timeout}) + ct:fail({cnode, timeout}) end. start_cnode(Cnode) -> @@ -1105,35 +1048,33 @@ start_cnode(Cnode) -> rec_cnode() -> receive - X -> - io:format("from cnode: ~p~n", [X]), - rec_cnode() + X -> + io:format("from cnode: ~p~n", [X]), + rec_cnode() end. nc2vinfo(Pid) when is_pid(Pid) -> - ?line [_NodeStr, NumberStr, SerialStr] - = string:tokens(pid_to_list(Pid), "<.>"), - ?line Number = list_to_integer(NumberStr), - ?line Serial = list_to_integer(SerialStr), - ?line {pid, node(Pid), Number, Serial}; + [_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) -> - ?line ["#Port", _NodeStr, NumberStr] - = string:tokens(erlang:port_to_list(Port), "<.>"), - ?line Number = list_to_integer(NumberStr), - ?line {port, node(Port), Number}; + ["#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) -> - ?line ["#Ref", _NodeStr | NumStrList] - = string:tokens(erlang:ref_to_list(Ref), "<.>"), - ?line {Len, RevNumList} = lists:foldl(fun ("0", {N, []}) -> - {N+1, []}; - (IStr, {N, Is}) -> - {N+1, - [list_to_integer(IStr)|Is]} - end, - {0, []}, - NumStrList), - ?line {ref, node(Ref), Len, lists:reverse(RevNumList)}; + ["#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) -> - ?line {badarg, 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 index 4a8664429e..0ea872ef49 100644 --- a/lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.first +++ b/lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.first @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2000-2009. All Rights Reserved. +# 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. diff --git a/lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.src b/lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.src index 31584ff686..4b1ddf77b6 100644 --- a/lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.src +++ b/lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.src @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1997-2009. All Rights Reserved. +# 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. diff --git a/lib/erl_interface/test/erl_eterm_SUITE_data/cnode.c b/lib/erl_interface/test/erl_eterm_SUITE_data/cnode.c index df40a4414e..bead0f8413 100644 --- a/lib/erl_interface/test/erl_eterm_SUITE_data/cnode.c +++ b/lib/erl_interface/test/erl_eterm_SUITE_data/cnode.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1999-2009. All Rights Reserved. + * 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. 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 index 0a2ecf9dcc..d97f218a26 100644 --- a/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c +++ b/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1997-2010. All Rights Reserved. + * 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. @@ -149,7 +149,7 @@ TESTCASE(round_trip_conversion) { int v; - for (v = 8; v; v <<= 1) { + 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"); @@ -166,7 +166,7 @@ TESTCASE(round_trip_conversion) } { long long v; - for (v = 8; v; v <<= 1) { + 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"); 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 index e474e8f7ab..5b7cb1aec8 100644 --- a/lib/erl_interface/test/erl_eterm_SUITE_data/print_term.c +++ b/lib/erl_interface/test/erl_eterm_SUITE_data/print_term.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1997-2013. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/test/erl_ext_SUITE.erl b/lib/erl_interface/test/erl_ext_SUITE.erl index f73c15e15f..afaba1fd93 100644 --- a/lib/erl_interface/test/erl_ext_SUITE.erl +++ b/lib/erl_interface/test/erl_ext_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2011. All Rights Reserved. +%% 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. @@ -21,77 +21,47 @@ %% -module(erl_ext_SUITE). --include_lib("test_server/include/test_server.hrl"). +-include_lib("common_test/include/ct.hrl"). -include("erl_ext_SUITE_data/ext_test_cases.hrl"). --export([ - all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, - init_per_group/2,end_per_group/2, - compare_tuple/1, - compare_list/1, - compare_string/1, - compare_list_string/1, - compare_nc_ext/1 - ]). +-export([all/0, suite/0, + compare_tuple/1, + compare_list/1, + compare_string/1, + compare_list_string/1, + compare_nc_ext/1]). -import(runner, [get_term/1]). -suite() -> [{ct_hooks,[ts_install_cth]}]. +suite() -> + [{ct_hooks,[ts_install_cth]}]. all() -> [compare_tuple, compare_list, compare_string, compare_list_string, compare_nc_ext]. -groups() -> - []. -init_per_suite(Config) -> - Config. - -end_per_suite(_Config) -> - ok. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - -compare_tuple(suite) -> []; -compare_tuple(doc) -> []; compare_tuple(Config) when is_list(Config) -> - ?line P = runner:start(?compare_tuple), - ?line runner:recv_eot(P), + P = runner:start(?compare_tuple), + runner:recv_eot(P), ok. -compare_list(suite) -> []; -compare_list(doc) -> []; compare_list(Config) when is_list(Config) -> - ?line P = runner:start(?compare_list), - ?line runner:recv_eot(P), + P = runner:start(?compare_list), + runner:recv_eot(P), ok. -compare_string(suite) -> []; -compare_string(doc) -> []; compare_string(Config) when is_list(Config) -> - ?line P = runner:start(?compare_string), - ?line runner:recv_eot(P), + P = runner:start(?compare_string), + runner:recv_eot(P), ok. -compare_list_string(suite) -> []; -compare_list_string(doc) -> []; compare_list_string(Config) when is_list(Config) -> - ?line P = runner:start(?compare_list_string), - ?line runner:recv_eot(P), + P = runner:start(?compare_list_string), + runner:recv_eot(P), ok. -compare_nc_ext(suite) -> []; -compare_nc_ext(doc) -> []; compare_nc_ext(Config) when is_list(Config) -> - ?line P = runner:start(?compare_nc_ext), - ?line runner:recv_eot(P), + P = runner:start(?compare_nc_ext), + runner:recv_eot(P), ok. - - - diff --git a/lib/erl_interface/test/erl_ext_SUITE_data/Makefile.first b/lib/erl_interface/test/erl_ext_SUITE_data/Makefile.first index ddff1ba13f..9ca8f7f8a3 100644 --- a/lib/erl_interface/test/erl_ext_SUITE_data/Makefile.first +++ b/lib/erl_interface/test/erl_ext_SUITE_data/Makefile.first @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2002-2009. All Rights Reserved. +# 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. diff --git a/lib/erl_interface/test/erl_ext_SUITE_data/Makefile.src b/lib/erl_interface/test/erl_ext_SUITE_data/Makefile.src index 6f3fdec8a4..fe8caebbd6 100644 --- a/lib/erl_interface/test/erl_ext_SUITE_data/Makefile.src +++ b/lib/erl_interface/test/erl_ext_SUITE_data/Makefile.src @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2002-2009. All Rights Reserved. +# 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. diff --git a/lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c b/lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c index 65d5f0d2e0..36cf086ed2 100644 --- a/lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c +++ b/lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2002-2011. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/test/erl_format_SUITE.erl b/lib/erl_interface/test/erl_format_SUITE.erl index 8c01a9914f..c1a7d8377e 100644 --- a/lib/erl_interface/test/erl_format_SUITE.erl +++ b/lib/erl_interface/test/erl_format_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2011. All Rights Reserved. +%% 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. @@ -21,137 +21,111 @@ %% -module(erl_format_SUITE). --include_lib("test_server/include/test_server.hrl"). +-include_lib("common_test/include/ct.hrl"). -include("erl_format_SUITE_data/format_test_cases.hrl"). --export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, - init_per_group/2,end_per_group/2, atoms/1, tuples/1, lists/1]). +-export([all/0, suite/0, + 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]}]. +suite() -> + [{ct_hooks,[ts_install_cth]}]. all() -> [atoms, tuples, lists]. -groups() -> - []. - -init_per_suite(Config) -> - Config. - -end_per_suite(_Config) -> - ok. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - %% Tests formatting various atoms. -atoms(suite) -> []; atoms(Config) when is_list(Config) -> - ?line P = runner:start(?atoms), - - ?line {term, ''} = get_term(P), - ?line {term, 'a'} = get_term(P), - ?line {term, 'A'} = get_term(P), - ?line {term, 'abc'} = get_term(P), - ?line {term, 'Abc'} = get_term(P), - ?line {term, 'ab@c'} = get_term(P), - ?line {term, 'The rain in Spain stays mainly in the plains'} = - get_term(P), - - ?line {term, a} = get_term(P), - ?line {term, ab} = get_term(P), - ?line {term, abc} = get_term(P), - ?line {term, ab@c} = get_term(P), - ?line {term, abcdefghijklmnopq} = get_term(P), - - ?line {term, ''} = get_term(P), - ?line {term, 'a'} = get_term(P), - ?line {term, 'A'} = get_term(P), - ?line {term, 'abc'} = get_term(P), - ?line {term, 'Abc'} = get_term(P), - ?line {term, 'ab@c'} = get_term(P), - ?line {term, 'The rain in Spain stays mainly in the plains'} = - get_term(P), - - ?line {term, a} = get_term(P), - ?line {term, ab} = get_term(P), - ?line {term, abc} = get_term(P), - ?line {term, ab@c} = get_term(P), - ?line {term, ' abcdefghijklmnopq '} = get_term(P), - - ?line runner:recv_eot(P), + P = runner:start(?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(suite) -> []; tuples(Config) when is_list(Config) -> - ?line P = runner:start(?tuples), - - ?line {term, {}} = get_term(P), - ?line {term, {a}} = get_term(P), - ?line {term, {a, b}} = get_term(P), - ?line {term, {a, b, c}} = get_term(P), - ?line {term, {1}} = get_term(P), - ?line {term, {[]}} = get_term(P), - ?line {term, {[], []}} = get_term(P), - ?line {term, {[], a, b, c}} = get_term(P), - ?line {term, {[], a, [], b, c}} = get_term(P), - ?line {term, {[], a, '', b, c}} = get_term(P), - - ?line runner:recv_eot(P), + P = runner:start(?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(suite) -> []; lists(Config) when is_list(Config) -> - ?line P = runner:start(?lists), - - ?line {term, []} = get_term(P), - ?line {term, [a]} = get_term(P), - ?line {term, [a, b]} = get_term(P), - ?line {term, [a, b, c]} = get_term(P), - ?line {term, [1]} = get_term(P), - ?line {term, [[]]} = get_term(P), - ?line {term, [[], []]} = get_term(P), - ?line {term, [[], a, b, c]} = get_term(P), - ?line {term, [[], a, [], b, c]} = get_term(P), - ?line {term, [[], a, '', b, c]} = get_term(P), - - ?line {term, [{name, 'Madonna'}, {age, 21}, {data, [{addr, "E-street", 42}]}]} = - get_term(P), + P = runner:start(?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 -> - ?line {term, [{pi, _}, {'cos(70)', _}]} = get_term(P), - ?line {term, [[pi, _], ['cos(70)', _]]} = get_term(P), - ?line {term, [[pi, _], [], ["cos(70)", _]]} = - get_term(P); - _ -> - ?line {term, [{pi, 3.1415}, {'cos(70)', 0.34202}]} = get_term(P), - ?line {term, [[pi, 3.1415], ['cos(70)', 0.34202]]} = get_term(P), - ?line {term, [[pi, 3.1415], [], ["cos(70)", 0.34202]]} = - get_term(P) + 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, - ?line {term, [-1]} = get_term(P), + {term, [-1]} = get_term(P), - ?line runner:recv_eot(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 index 9fc4e742bd..acbb8c98bb 100644 --- a/lib/erl_interface/test/erl_format_SUITE_data/Makefile.first +++ b/lib/erl_interface/test/erl_format_SUITE_data/Makefile.first @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2000-2009. All Rights Reserved. +# 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. diff --git a/lib/erl_interface/test/erl_format_SUITE_data/Makefile.src b/lib/erl_interface/test/erl_format_SUITE_data/Makefile.src index 4f5f780f31..2ba59ab651 100644 --- a/lib/erl_interface/test/erl_format_SUITE_data/Makefile.src +++ b/lib/erl_interface/test/erl_format_SUITE_data/Makefile.src @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1997-2009. All Rights Reserved. +# 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. 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 index 179327ede0..258ae92e0f 100644 --- a/lib/erl_interface/test/erl_format_SUITE_data/format_test.c +++ b/lib/erl_interface/test/erl_format_SUITE_data/format_test.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1997-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/test/erl_global_SUITE.erl b/lib/erl_interface/test/erl_global_SUITE.erl index b719ad5c6a..ecc6753c7f 100644 --- a/lib/erl_interface/test/erl_global_SUITE.erl +++ b/lib/erl_interface/test/erl_global_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2000-2011. All Rights Reserved. +%% 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. @@ -21,12 +21,12 @@ %% -module(erl_global_SUITE). --include_lib("test_server/include/test_server.hrl"). +-include_lib("common_test/include/ct.hrl"). -include("erl_global_SUITE_data/erl_global_test_cases.hrl"). --export([all/0,suite/0,init_per_suite/1,end_per_suite/1, - init_per_testcase/2,end_per_testcase/2, - erl_global_registration/1, erl_global_whereis/1, erl_global_names/1]). +-export([all/0,suite/0, + erl_global_registration/1, + erl_global_whereis/1, erl_global_names/1]). -import(runner, [get_term/1,send_term/2]). @@ -35,62 +35,50 @@ all() -> [erl_global_registration, erl_global_whereis, erl_global_names]. -suite() -> [{ct_hooks,[ts_install_cth]}]. +suite() -> + [{ct_hooks,[ts_install_cth]}, + {timetrap, {seconds, 30}}]. -init_per_suite(Config) -> - Config. - -end_per_suite(_Config) -> - ok. - -init_per_testcase(_Case, Config) -> - Dog = ?t:timetrap(?t:minutes(0.25)), - [{watchdog, Dog}|Config]. - -end_per_testcase(_Case, Config) -> - Dog = ?config(watchdog, Config), - test_server:timetrap_cancel(Dog), - ok. erl_global_registration(Config) when is_list(Config) -> - ?line P = runner:start(?interpret), - ?line {ok, Fd} = erl_connect(P, node(), 42, erlang:get_cookie(), 0), + P = runner:start(?interpret), + {ok, Fd} = erl_connect(P, node(), 42, erlang:get_cookie(), 0), - ?line ok = erl_global_register(P, Fd, ?GLOBAL_NAME), - ?line ok = erl_global_unregister(P, Fd, ?GLOBAL_NAME), + ok = erl_global_register(P, Fd, ?GLOBAL_NAME), + ok = erl_global_unregister(P, Fd, ?GLOBAL_NAME), - ?line 0 = erl_close_connection(P,Fd), - ?line runner:send_eot(P), - ?line runner:recv_eot(P), + 0 = erl_close_connection(P,Fd), + runner:send_eot(P), + runner:recv_eot(P), ok. erl_global_whereis(Config) when is_list(Config) -> - ?line P = runner:start(?interpret), - ?line {ok, Fd} = erl_connect(P, node(), 42, erlang:get_cookie(), 0), - - ?line Self = self(), - ?line yes = global:register_name(?GLOBAL_NAME, Self), - ?line Self = erl_global_whereis(P, Fd, ?GLOBAL_NAME), - ?line global:unregister_name(?GLOBAL_NAME), - ?line 0 = erl_close_connection(P, Fd), - ?line runner:send_eot(P), - ?line runner:recv_eot(P), + P = runner:start(?interpret), + {ok, Fd} = erl_connect(P, node(), 42, erlang:get_cookie(), 0), + + Self = self(), + yes = global:register_name(?GLOBAL_NAME, Self), + Self = erl_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) -> - ?line P = runner:start(?interpret), - ?line {ok, Fd} = erl_connect(P, node(), 42, erlang:get_cookie(), 0), - - ?line Self = self(), - ?line global:register_name(?GLOBAL_NAME, Self), - ?line {Names1, _N1} = erl_global_names(P, Fd), - ?line true = lists:member(atom_to_list(?GLOBAL_NAME), Names1), - ?line global:unregister_name(?GLOBAL_NAME), - ?line {Names2, _N2} = erl_global_names(P, Fd), - ?line false = lists:member(atom_to_list(?GLOBAL_NAME), Names2), - ?line 0 = erl_close_connection(P, Fd), - ?line runner:send_eot(P), - ?line runner:recv_eot(P), + P = runner:start(?interpret), + {ok, Fd} = erl_connect(P, node(), 42, erlang:get_cookie(), 0), + + Self = self(), + global:register_name(?GLOBAL_NAME, Self), + {Names1, _N1} = erl_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), + 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. @@ -98,14 +86,14 @@ erl_global_names(Config) when is_list(Config) -> 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} + {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 + {term,Int} when is_integer(Int) -> Int end. erl_global_register(P, Fd, Name) -> @@ -115,15 +103,15 @@ erl_global_register(P, Fd, Name) -> erl_global_whereis(P, Fd, Name) -> send_command(P, erl_global_whereis, [Fd,Name]), case get_term(P) of - {term, What} -> - What + {term, What} -> + What end. erl_global_names(P, Fd) -> send_command(P, erl_global_names, [Fd]), case get_term(P) of - {term, What} -> - What + {term, What} -> + What end. erl_global_unregister(P, Fd, Name) -> @@ -132,11 +120,11 @@ erl_global_unregister(P, Fd, Name) -> get_send_result(P) -> case get_term(P) of - {term,{1,_}} -> ok; - {term,{0, 0}} -> ok; - {term,{-1, Errno}} -> {error,Errno}; - {term,{_,_}}-> - ?t:fail(bad_return_value) + {term,{1,_}} -> ok; + {term,{0, 0}} -> ok; + {term,{-1, Errno}} -> {error,Errno}; + {term,{_,_}}-> + ct:fail(bad_return_value) end. send_command(P, Name, Args) -> diff --git a/lib/erl_interface/test/erl_global_SUITE_data/Makefile.first b/lib/erl_interface/test/erl_global_SUITE_data/Makefile.first index ec77ef3dc2..b2c62be1f2 100644 --- a/lib/erl_interface/test/erl_global_SUITE_data/Makefile.first +++ b/lib/erl_interface/test/erl_global_SUITE_data/Makefile.first @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2001-2010. All Rights Reserved. +# 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. diff --git a/lib/erl_interface/test/erl_global_SUITE_data/Makefile.src b/lib/erl_interface/test/erl_global_SUITE_data/Makefile.src index 4cbf51713b..1c1530d1b6 100644 --- a/lib/erl_interface/test/erl_global_SUITE_data/Makefile.src +++ b/lib/erl_interface/test/erl_global_SUITE_data/Makefile.src @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2000-2010. All Rights Reserved. +# 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. 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 index 5a17069751..0f08727225 100644 --- 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 @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2000-2010. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/test/erl_match_SUITE.erl b/lib/erl_interface/test/erl_match_SUITE.erl index d8f7bd89b4..5566714092 100644 --- a/lib/erl_interface/test/erl_match_SUITE.erl +++ b/lib/erl_interface/test/erl_match_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2012. All Rights Reserved. +%% 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. @@ -21,249 +21,221 @@ %% -module(erl_match_SUITE). --include_lib("test_server/include/test_server.hrl"). +-include_lib("common_test/include/ct.hrl"). -include("erl_match_SUITE_data/match_test_cases.hrl"). --export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, - init_per_group/2,end_per_group/2, - atoms/1, lists/1, tuples/1, references/1, pids/1, ports/1, - bind/1, integers/1, floats/1, binaries/1, strings/1]). +-export([all/0, suite/0, + 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]}]. +suite() -> + [{ct_hooks,[ts_install_cth]}]. all() -> [atoms, lists, tuples, references, pids, ports, bind, integers, floats, binaries, strings]. -groups() -> - []. -init_per_suite(Config) -> - Config. - -end_per_suite(_Config) -> - ok. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. - - -atoms(suite) -> []; atoms(Config) when is_list(Config) -> - ?line P = start_matcher(Config), + P = start_matcher(Config), - ?line eq(P, '', ''), - ?line eq(P, a, a), - ?line ne(P, a, b), - ?line ne(P, a, aa), - ?line eq(P, kalle, kalle), - ?line ne(P, kalle, arne), + eq(P, '', ''), + eq(P, a, a), + ne(P, a, b), + ne(P, a, aa), + eq(P, kalle, kalle), + ne(P, kalle, arne), - ?line ne(P, kalle, 42), - ?line ne(P, 42, kalle), + ne(P, kalle, 42), + ne(P, 42, kalle), - ?line runner:finish(P), + runner:finish(P), ok. -lists(suite) -> []; lists(Config) when is_list(Config) -> - ?line P = start_matcher(Config), - ?line eq(P, [], []), + P = start_matcher(Config), + eq(P, [], []), - ?line ne(P, [], [a]), - ?line ne(P, [a], []), + ne(P, [], [a]), + ne(P, [a], []), - ?line eq(P, [a], [a]), - ?line ne(P, [a], [b]), + eq(P, [a], [a]), + ne(P, [a], [b]), - ?line eq(P, [a|b], [a|b]), - ?line ne(P, [a|b], [a|x]), + eq(P, [a|b], [a|b]), + ne(P, [a|b], [a|x]), - ?line eq(P, [a, b], [a, b]), - ?line ne(P, [a, b], [a, x]), + eq(P, [a, b], [a, b]), + ne(P, [a, b], [a, x]), - ?line eq(P, [a, b, c], [a, b, c]), - ?line ne(P, [a, b|c], [a, b|x]), - ?line ne(P, [a, b, c], [a, b, x]), - ?line ne(P, [a, b|c], [a, b|x]), - ?line ne(P, [a, x|c], [a, b|c]), - ?line ne(P, [a, b, c], [a, x, c]), + 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]), - ?line runner:finish(P), + runner:finish(P), ok. -tuples(suite) -> []; tuples(Config) when is_list(Config) -> - ?line P = start_matcher(Config), + P = start_matcher(Config), - ?line ne(P, {}, {a, b}), - ?line ne(P, {a, b}, {}), - ?line ne(P, {a}, {a, b}), - ?line ne(P, {a, b}, {a}), + ne(P, {}, {a, b}), + ne(P, {a, b}, {}), + ne(P, {a}, {a, b}), + ne(P, {a, b}, {a}), - ?line eq(P, {}, {}), + eq(P, {}, {}), - ?line eq(P, {a}, {a}), - ?line ne(P, {a}, {b}), + eq(P, {a}, {a}), + ne(P, {a}, {b}), - ?line eq(P, {1}, {1}), - ?line ne(P, {1}, {2}), + eq(P, {1}, {1}), + ne(P, {1}, {2}), - ?line eq(P, {a, b}, {a, b}), - ?line ne(P, {x, b}, {a, b}), + eq(P, {a, b}, {a, b}), + ne(P, {x, b}, {a, b}), - ?line ne(P, {error, x}, {error, y}), - ?line ne(P, {error, {undefined, {subscriber, last}}}, - {error, {undefined, {subscriber, name}}}), + ne(P, {error, x}, {error, y}), + ne(P, {error, {undefined, {subscriber, last}}}, + {error, {undefined, {subscriber, name}}}), - ?line runner:finish(P), + runner:finish(P), ok. -references(suite) -> []; references(Config) when is_list(Config) -> - ?line P = start_matcher(Config), - ?line Ref1 = make_ref(), - ?line Ref2 = make_ref(), - - ?line eq(P, Ref1, Ref1), - ?line eq(P, Ref2, Ref2), - ?line ne(P, Ref1, Ref2), - ?line ne(P, Ref2, Ref1), - - ?line runner:finish(P), + 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(suite) -> []; pids(Config) when is_list(Config) -> - ?line P = start_matcher(Config), - ?line Pid1 = c:pid(0,1,2), - ?line Pid2 = c:pid(0,1,3), - - ?line eq(P, self(), self()), - ?line eq(P, Pid1, Pid1), - ?line ne(P, Pid1, self()), - ?line ne(P, Pid2, Pid1), - - ?line runner:finish(P), + 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(suite) -> []; ports(Config) when is_list(Config) -> case os:type() of - vxworks -> - {skipped,"not on vxworks, pucko"}; - _ -> - ?line P = start_matcher(Config), - ?line P2 = start_matcher(Config), - - ?line eq(P, P, P), - ?line ne(P, P, P2), - - ?line runner:finish(P), - ?line runner:finish(P2), - ok + 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(suite) -> []; integers(Config) when is_list(Config) -> - ?line P = start_matcher(Config), - ?line I1 = 123, - ?line I2 = 12345, - ?line I3 = -123, - ?line I4 = 2234, - - ?line eq(P, I1, I1), - ?line eq(P, I2, I2), - ?line ne(P, I1, I2), - ?line ne(P, I1, I3), - ?line eq(P, I4, I4), - - ?line runner:finish(P), + 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(suite) -> []; floats(Config) when is_list(Config) -> - ?line P = start_matcher(Config), - ?line F1 = 3.1414, - ?line F2 = 3.1415, - ?line F3 = 3.1416, - - ?line S1 = "string", - ?line S2 = "string2", - - ?line eq(P, F1, F1), - ?line eq(P, F2, F2), - ?line ne(P, F1, F2), - ?line ne(P, F3, F2), - - ?line eq(P, S2, S2), - ?line ne(P, S1, S2), - - ?line runner:finish(P), + 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(suite) -> []; binaries(Config) when is_list(Config) -> - ?line P = start_matcher(Config), - ?line Bin1 = term_to_binary({kalle, 146015, {kungsgatan, 23}}), - ?line Bin2 = term_to_binary(sune), - ?line Bin3 = list_to_binary("sune"), - - ?line eq(P, Bin1, Bin1), - ?line eq(P, Bin2, Bin2), - ?line eq(P, Bin3, Bin3), - ?line ne(P, Bin1, Bin2), - ?line ne(P, Bin1, Bin3), - ?line ne(P, Bin2, Bin3), - - ?line runner:finish(P), + 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(suite) -> []; strings(Config) when is_list(Config) -> - ?line P = start_matcher(Config), + P = start_matcher(Config), - ?line S1 = "string", - ?line S2 = "streng", - ?line S3 = "String", - - ?line eq(P, S1, S1), - ?line ne(P, S1, S2), - ?line ne(P, S1, S3), + S1 = "string", + S2 = "streng", + S3 = "String", - ?line runner:finish(P), - ok. + eq(P, S1, S1), + ne(P, S1, S2), + ne(P, S1, S3), + runner:finish(P), + ok. -bind(suite) -> []; bind(Config) when is_list(Config) -> - ?line P = start_bind(Config), - ?line S = "[X,Y,Z]", - ?line L1 = [301,302,302], - ?line L2 = [65,66,67], - - ?line bind_ok(P, S, L1), - ?line bind_ok(P, S, L2), - - ?line runner:finish(P), + 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) -> @@ -279,15 +251,12 @@ 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 + {term, 0} -> false; + {term, 1} -> true end. - - - start_matcher(Config) -> runner:start(?erl_match_server). @@ -303,8 +272,6 @@ 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 + {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 index 867c59802f..459b5c14c2 100644 --- a/lib/erl_interface/test/erl_match_SUITE_data/Makefile.first +++ b/lib/erl_interface/test/erl_match_SUITE_data/Makefile.first @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2000-2009. All Rights Reserved. +# 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. diff --git a/lib/erl_interface/test/erl_match_SUITE_data/Makefile.src b/lib/erl_interface/test/erl_match_SUITE_data/Makefile.src index 5753a417fb..156214a269 100644 --- a/lib/erl_interface/test/erl_match_SUITE_data/Makefile.src +++ b/lib/erl_interface/test/erl_match_SUITE_data/Makefile.src @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1997-2009. All Rights Reserved. +# 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. 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 index c508786ba8..d577417f5b 100644 --- a/lib/erl_interface/test/erl_match_SUITE_data/match_test.c +++ b/lib/erl_interface/test/erl_match_SUITE_data/match_test.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1997-2009. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/test/port_call_SUITE.erl b/lib/erl_interface/test/port_call_SUITE.erl index b0f5ed4fe9..fb10bd895f 100644 --- a/lib/erl_interface/test/port_call_SUITE.erl +++ b/lib/erl_interface/test/port_call_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2001-2011. All Rights Reserved. +%% 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. @@ -32,96 +32,78 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2, basic/1]). -% Private exports --include_lib("test_server/include/test_server.hrl"). +-export([all/0, suite/0, basic/1]). +% Private exports +-include_lib("common_test/include/ct.hrl"). -suite() -> [{ct_hooks,[ts_install_cth]}]. +suite() -> + [{ct_hooks,[ts_install_cth]}, + {timetrap, {seconds, 10}}]. all() -> -[basic]. - -groups() -> - []. - -init_per_suite(Config) -> - Config. - -end_per_suite(_Config) -> - ok. - -init_per_group(_GroupName, Config) -> - Config. - -end_per_group(_GroupName, Config) -> - Config. + [basic]. -basic(suite) -> []; basic(Config) when is_list(Config) -> case os:type() of - {unix, linux} -> - do_basic(Config); - {unix, sunos} -> - do_basic(Config); - {win32,_} -> - do_basic(Config); - _ -> - {skipped, "Dynamic linking and erl_interface not fully examined" - " on this platform..."} + {unix, linux} -> + do_basic(Config); + {unix, sunos} -> + do_basic(Config); + {win32,_} -> + do_basic(Config); + _ -> + {skipped, "Dynamic linking and erl_interface not fully examined" + " on this platform..."} end. do_basic(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line Path = ?config(data_dir, Config), + Path = proplists:get_value(data_dir, Config), - ?line erl_ddll:start(), + erl_ddll:start(), %% Load the echo driver and verify that it was loaded. {ok,L1,L2}=load_port_call_driver(Path), %% Verify that the driver works. - ?line Port = open_port({spawn, port_call_drv}, [eof]), - ?line {hej, "hopp",4711,123445567436543653} = - erlang:port_call(Port,{hej, "hopp",4711,123445567436543653}), - ?line {hej, "hopp",4711,123445567436543653} = - erlang:port_call(Port,0,{hej, "hopp",4711,123445567436543653}), - ?line {[], a, [], b, c} = - erlang:port_call(Port,1,{hej, "hopp",4711,123445567436543653}), - ?line {return, {[], a, [], b, c}} = - erlang:port_call(Port,2,{[], a, [], b, c}), - ?line List = lists:duplicate(200,5), - ?line {return, List} = erlang:port_call(Port,2,List), - ?line {'EXIT',{badarg,_}} = (catch erlang:port_call(Port,4711,[])), - ?line {'EXIT',{badarg,_}} = (catch erlang:port_call(sune,2,[])), - ?line register(gunnar,Port), - ?line {return, List} = erlang:port_call(gunnar,2,List), - ?line {return, a} = erlang:port_call(gunnar,2,a), - ?line erlang:port_close(Port), + Port = open_port({spawn, port_call_drv}, [eof]), + {hej, "hopp",4711,123445567436543653} = + erlang:port_call(Port,{hej, "hopp",4711,123445567436543653}), + {hej, "hopp",4711,123445567436543653} = + erlang:port_call(Port,0,{hej, "hopp",4711,123445567436543653}), + {[], a, [], b, c} = + erlang:port_call(Port,1,{hej, "hopp",4711,123445567436543653}), + {return, {[], a, [], b, c}} = + erlang:port_call(Port,2,{[], a, [], b, c}), + List = lists:duplicate(200,5), + {return, List} = erlang:port_call(Port,2,List), + {'EXIT',{badarg,_}} = (catch erlang:port_call(Port,4711,[])), + {'EXIT',{badarg,_}} = (catch erlang:port_call(sune,2,[])), + register(gunnar,Port), + {return, List} = erlang:port_call(gunnar,2,List), + {return, a} = erlang:port_call(gunnar,2,a), + erlang:port_close(Port), %% Unload the driver and verify that it was unloaded. ok=unload_port_call_driver(L1,L2), - ?line {error, {already_started, _}} = erl_ddll:start(), - ?line ok = erl_ddll:stop(), - - ?line test_server:timetrap_cancel(Dog), + {error, {already_started, _}} = erl_ddll:start(), + ok = erl_ddll:stop(), ok. load_port_call_driver(Path) -> - ?line {ok, L1} = erl_ddll:loaded_drivers(), - ?line ok = erl_ddll:load_driver(Path, port_call_drv), - ?line {ok, L2} = erl_ddll:loaded_drivers(), - ?line ["port_call_drv"] = ordsets:to_list(ordsets:subtract(ordsets:from_list(L2), - ordsets:from_list(L1))), + {ok, L1} = erl_ddll:loaded_drivers(), + ok = erl_ddll:load_driver(Path, port_call_drv), + {ok, L2} = erl_ddll:loaded_drivers(), + ["port_call_drv"] = ordsets:to_list(ordsets:subtract(ordsets:from_list(L2), + ordsets:from_list(L1))), {ok,L1,L2}. unload_port_call_driver(L1,L2) -> - ?line {ok, L2} = erl_ddll:loaded_drivers(), - ?line ok = erl_ddll:unload_driver(port_call_drv), - ?line {ok, L3} = erl_ddll:loaded_drivers(), - ?line [] = ordsets:to_list(ordsets:subtract(ordsets:from_list(L3), - ordsets:from_list(L1))), + {ok, L2} = erl_ddll:loaded_drivers(), + ok = erl_ddll:unload_driver(port_call_drv), + {ok, L3} = erl_ddll:loaded_drivers(), + [] = ordsets:to_list(ordsets:subtract(ordsets:from_list(L3), + ordsets:from_list(L1))), ok. - 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 12b9fcae76..0f97ce9f70 100644 --- a/lib/erl_interface/test/port_call_SUITE_data/Makefile.src +++ b/lib/erl_interface/test/port_call_SUITE_data/Makefile.src @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2001-2011. All Rights Reserved. +# 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. 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 ac23a650c1..4617cb0316 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 @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2011. All Rights Reserved. + * 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. diff --git a/lib/erl_interface/test/runner.erl b/lib/erl_interface/test/runner.erl index ae2598abf8..1084eec2a3 100644 --- a/lib/erl_interface/test/runner.erl +++ b/lib/erl_interface/test/runner.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2010. All Rights Reserved. +%% 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. @@ -25,7 +25,7 @@ start/1, send_term/2, finish/1, send_eot/1, recv_eot/1, get_term/1, get_term/2]). --define(default_timeout, test_server:seconds(5)). +-define(default_timeout, 5000). %% Executes a test case in a C program. %% @@ -45,7 +45,7 @@ test(Tc, Timeout) -> io:format("In this test case, a success/failure result was"), io:format("expected from the C program.\n"), io:format("Received: ~p", [Other]), - test_server:fail() + ct:fail(badresult) end. %% Executes a test case in a C program. Returns the port. @@ -55,7 +55,7 @@ test(Tc, Timeout) -> %% Returns: {ok, Port} start({Prog, Tc}) when is_list(Prog), is_integer(Tc) -> - Port = open_port({spawn, Prog}, [{packet, 4}]), + Port = open_port({spawn, Prog}, [{packet, 4}, exit_status]), Command = [Tc div 256, Tc rem 256], Port ! {self(), {command, Command}}, Port. @@ -80,7 +80,7 @@ send_eot(Port) when is_port(Port) -> Port ! {self(), {command, [$e]}}. %% Waits for an 'eot' indication from the C program. -%% Either returns 'ok' or invokes test_server:fail(). +%% Either returns 'ok' or invokes ct:fail(badresult). recv_eot(Port) when is_port(Port) -> case get_term(Port) of @@ -90,12 +90,12 @@ recv_eot(Port) when is_port(Port) -> io:format("Error finishing test case. Expected eof from"), io:format("C program, but got:"), io:format("~p", [Other]), - test_server:fail() + ct:fail(badresult) end. %% Reads a term from the C program. %% -%% Returns: {term, Term}|eot|'NULL' or calls test_server:fail/1,2. +%% Returns: {term, Term}|eot|'NULL' or calls ct:fail/1,2. get_term(Port) -> get_term(Port, ?default_timeout). @@ -105,9 +105,9 @@ get_term(Port, Timeout) -> [$b|Bytes] -> {bytes, Bytes}; [$f] -> - test_server:fail(); + ct:fail(failure); [$f|Reason] -> - test_server:fail(Reason); + ct:fail(Reason); [$t|Term] -> {term, binary_to_term(list_to_binary(Term))}; [$N] -> @@ -119,13 +119,15 @@ get_term(Port, Timeout) -> get_term(Port, Timeout); Other -> io:format("Garbage received from C program: ~p", [Other]), - test_server:fail("Illegal response from C program") + ct:fail("Illegal response from C program") end. get_reply(Port, Timeout) when is_port(Port) -> receive {Port, {data, Reply}} -> - Reply + Reply; + Fail when element(1, Fail) == Port -> + ct:fail("Got unexpected message from port: ~p",[Fail]) after Timeout -> - test_server:fail("No response from C program") + ct:fail("No response from C program") end. diff --git a/lib/erl_interface/vsn.mk b/lib/erl_interface/vsn.mk index 56dbdbac9f..563694a0c1 100644 --- a/lib/erl_interface/vsn.mk +++ b/lib/erl_interface/vsn.mk @@ -1,2 +1,2 @@ -EI_VSN = 3.8.2 +EI_VSN = 3.9.3 ERL_INTERFACE_VSN = $(EI_VSN) |