diff options
Diffstat (limited to 'erts')
111 files changed, 11156 insertions, 4590 deletions
diff --git a/erts/doc/src/Makefile b/erts/doc/src/Makefile index bc01919da1..bb96293947 100644 --- a/erts/doc/src/Makefile +++ b/erts/doc/src/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1997-2018. All Rights Reserved. +# Copyright Ericsson AB 1997-2019. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -47,6 +47,20 @@ XML_REF1_FILES = epmd.xml \ run_erl.xml \ start.xml +ifeq ($(USE_ESOCK), yes) +XML_REF3_ESOCK_EFILES = socket.xml +XML_CHAPTER_ESOCK_EFILES = socket_usage.xml +ESOCK_USE_SOCKET_XML=<xi:include href="socket.xml"\/> +ESOCK_USE_SOCKET_SPECS_XML=<xi:include href="../specs/specs_socket.xml"/> +ESOCK_USE_SOCKET_USAGE_XML=<xi:include href="socket_usage.xml"/> +else +XML_REF3_ESOCK_EFILES = +XML_CHAPTER_ESOCK_EFILES = +ESOCK_USE_SOCKET_XML = +ESOCK_USE_SOCKET_SPECS_XML = +ESOCK_USE_SOCKET_USAGE_XML = +endif + XML_REF3_EFILES = \ erl_prim_loader.xml \ erlang.xml \ @@ -56,8 +70,7 @@ XML_REF3_EFILES = \ atomics.xml \ counters.xml \ zlib.xml \ - socket.xml \ - net.xml + $(XML_REF3_ESOCK_EFILES) XML_REF3_FILES = \ $(XML_REF3_EFILES) \ @@ -94,7 +107,7 @@ XML_CHAPTER_FILES = \ driver.xml \ absform.xml \ inet_cfg.xml \ - socket_usage.xml \ + $(XML_CHAPTER_ESOCK_EFILES) \ erl_ext_dist.xml \ erl_dist_protocol.xml \ communication.xml \ @@ -159,7 +172,7 @@ $(HTMLDIR)/%.gif: %.gif $(XML_FIGURE_DIR)/%.png: ../../emulator/internal_doc/figures/%.png $(INSTALL_DATA) $< $@ -docs: figures man pdf html $(INFO_FILE) +docs: part ref_man specs figures man pdf html $(INFO_FILE) $(TOP_PDF_FILE): $(XML_FILES) @@ -169,6 +182,10 @@ html: gifs $(HTML_REF_MAN_FILE) man: $(MAN1_FILES) $(MAN3_FILES) +ref_man: ref_man.xml +part: part.xml +specs: specs.xml + gifs: $(GIF_FILES:%=$(HTMLDIR)/%) $(INFO_FILE): $(INFO_FILE_SRC) $(ERL_TOP)/make/$(TARGET)/otp.mk @@ -196,6 +213,19 @@ $(SPECDIR)/specs_%.xml: $(XMLDIR)/%.xml: ../../emulator/internal_doc/%.md $(ERL_TOP)/make/emd2exml $(ERL_TOP)/make/emd2exml $< $@ +ref_man.xml: ref_man.xml.src + ($(PERL) -p -e 's?%ESOCK_USE_SOCKET_XML%?$(ESOCK_USE_SOCKET_XML)?' \ + $<) > $@ + +part.xml: part.xml.src + ($(PERL) -p -e 's?%ESOCK_USE_SOCKET_USAGE_XML%?$(ESOCK_USE_SOCKET_USAGE_XML)?' \ + $<) > $@ + +specs.xml: specs.xml.src + ($(PERL) -p -e 's?%ESOCK_USE_SOCKET_SPECS_XML%?$(ESOCK_USE_SOCKET_SPECS_XML)?' \ + $<) > $@ + + # ---------------------------------------------------- # Release Target # ---------------------------------------------------- diff --git a/erts/doc/src/erl_dist_protocol.xml b/erts/doc/src/erl_dist_protocol.xml index f924c8a70b..0c1100d394 100644 --- a/erts/doc/src/erl_dist_protocol.xml +++ b/erts/doc/src/erl_dist_protocol.xml @@ -109,7 +109,8 @@ <title>Register a Node in EPMD</title> <p>When a distributed node is started it registers itself in the EPMD. The message <c>ALIVE2_REQ</c> described below is sent from the node to - the EPMD. The response from the EPMD is <c>ALIVE2_RESP</c>.</p> + the EPMD. The response from the EPMD is <c>ALIVE2_X_RESP</c> (or + <c>ALIVE2_RESP</c>).</p> <table align="left"> <row> @@ -155,12 +156,12 @@ <tag><c>HighestVersion</c></tag> <item> <p>The highest distribution version that this node can handle. - The value in Erlang/OTP R6B and later is 5.</p> + The value in OTP 23 and later is 6.</p> </item> <tag><c>LowestVersion</c></tag> <item> <p>The lowest distribution version that this node can handle. - The value in Erlang/OTP R6B and later is 5.</p> + The value in OTP 23 and later is 5.</p> </item> <tag><c>Nlen</c></tag> <item> @@ -184,7 +185,24 @@ node is a distributed node. When the connection is closed, the node is automatically unregistered from the EPMD.</p> - <p>The response message <c>ALIVE2_RESP</c> is as follows:</p> + <p>The response message is either <c>ALIVE2_X_RESP</c> or + <c>ALIVE2_RESP</c> depending on distribution version. If both the node + and EPMD support distribution version 6 then response is + <c>ALIVE2_X_RESP</c> otherwise it is the older <c>ALIVE2_RESP</c>:</p> + + <table align="left"> + <row> + <cell align="center">1</cell> + <cell align="center">1</cell> + <cell align="center">4</cell> + </row> + <row> + <cell align="center"><c>118</c></cell> + <cell align="center"><c>Result</c></cell> + <cell align="center"><c>Creation</c></cell> + </row> + <tcaption>ALIVE2_X_RESP (118) with 32 bit creation</tcaption> + </table> <table align="left"> <row> @@ -197,7 +215,7 @@ <cell align="center"><c>Result</c></cell> <cell align="center"><c>Creation</c></cell> </row> - <tcaption>ALIVE2_RESP (121)</tcaption> + <tcaption>ALIVE2_RESP (121) with 16-bit creation</tcaption> </table> <p>Result = 0 -> ok, result > 0 -> error.</p> @@ -793,7 +811,8 @@ DiB == gen_digest(ChA, ICA)? </item> <tag><c>-define(DFLAG_NEW_FUN_TAGS,16#80).</c></tag> <item> - <p>The node understand new fun tags.</p> + <p>The node understands the <seealso marker="erl_ext_dist#NEW_FUN_EXT"> + <c>NEW_FUN_EXT</c></seealso> tag.</p> </item> <tag><c>-define(DFLAG_EXTENDED_PIDS_PORTS,16#100).</c></tag> <item> @@ -802,13 +821,18 @@ DiB == gen_digest(ChA, ICA)? </item> <tag><c>-define(DFLAG_EXPORT_PTR_TAG,16#200).</c></tag> <item> + <p>The node understands the <seealso marker="erl_ext_dist#EXPORT_EXT"> + <c>EXPORT_EXT</c></seealso> tag.</p> </item> <tag><c>-define(DFLAG_BIT_BINARIES,16#400).</c></tag> <item> + <p>The node understands the <seealso marker="erl_ext_dist#BIT_BINARY_EXT"> + <c>BIT_BINARY_EXT</c></seealso> tag.</p> </item> <tag><c>-define(DFLAG_NEW_FLOATS,16#800).</c></tag> <item> - <p>The node understands new float format.</p> + <p>The node understands the <seealso marker="erl_ext_dist#NEW_FLOAT_EXT"> + <c>NEW_FLOAT_EXT</c></seealso> tag.</p> </item> <tag><c>-define(DFLAG_UNICODE_IO,16#1000).</c></tag> <item> @@ -817,21 +841,34 @@ DiB == gen_digest(ChA, ICA)? <item> <p>The node implements atom cache in distribution header.</p> </item> + <marker id="DFLAG_SMALL_ATOM_TAGS"/> <tag><c>-define(DFLAG_SMALL_ATOM_TAGS, 16#4000).</c></tag> <item> - <p>The node understand the <c>SMALL_ATOM_EXT</c> tag.</p> + <p>The node understands the <seealso marker="erl_ext_dist#SMALL_ATOM_EXT"> + <c>SMALL_ATOM_EXT</c></seealso> tag.</p> </item> + <marker id="DFLAG_UTF8_ATOMS"/> <tag><c>-define(DFLAG_UTF8_ATOMS, 16#10000).</c></tag> <item> - <p>The node understand UTF-8 encoded atoms.</p> + <p>The node understands UTF-8 atoms encoded with + <seealso marker="erl_ext_dist#ATOM_UTF8_EXT"> + <c>ATOM_UTF8_EXT</c></seealso> and + <seealso marker="erl_ext_dist#SMALL_ATOM_UTF8_EXT"> + <c>SMALL ATOM_UTF8_EXT</c></seealso>.</p> </item> <tag><c>-define(DFLAG_MAP_TAG, 16#20000).</c></tag> <item> - <p>The node understand the map tag.</p> + <p>The node understands the map tag + <seealso marker="erl_ext_dist#MAP_EXT"><c>MAP_EXT</c></seealso>.</p> </item> + <marker id="DFLAG_BIG_CREATION"/> <tag><c>-define(DFLAG_BIG_CREATION, 16#40000).</c></tag> <item> - <p>The node understand big node creation.</p> + <p>The node understands big node creation tags + <seealso marker="erl_ext_dist#NEW_PID_EXT"><c>NEW_PID_EXT</c></seealso>, + <seealso marker="erl_ext_dist#NEW_PORT_EXT"><c>NEW_PORT_EXT</c></seealso> and + <seealso marker="erl_ext_dist#NEWER_REFERENCE_EXT"><c>NEWER_REFERENCE_EXT</c></seealso>. + </p> </item> <tag><c>-define(DFLAG_SEND_SENDER, 16#80000).</c></tag> <item> @@ -855,6 +892,7 @@ DiB == gen_digest(ChA, ICA)? <seealso marker="#control_message">control message</seealso>s instead of the non-PAYLOAD variants.</p> </item> + <marker id="DFLAG_FRAGMENTS"/> <tag><c>-define(DFLAG_FRAGMENTS, 16#800000).</c></tag> <item> <p>Use <seealso marker="erl_ext_dist#fragments">fragmented</seealso> diff --git a/erts/doc/src/erl_ext_dist.xml b/erts/doc/src/erl_ext_dist.xml index 2ba5994557..c5b2ce1a0a 100644 --- a/erts/doc/src/erl_ext_dist.xml +++ b/erts/doc/src/erl_ext_dist.xml @@ -264,7 +264,7 @@ consists of. Length is a 2 byte big-endian integer if flag <c>LongAtoms</c> has been set, otherwise a 1 byte integer. When distribution flag - <seealso marker="erl_dist_protocol#dflags"> + <seealso marker="erl_dist_protocol#DFLAG_UTF8_ATOMS"> <c>DFLAG_UTF8_ATOMS</c></seealso> has been exchanged between both nodes in the <seealso marker="erl_dist_protocol#distribution_handshake"> @@ -316,8 +316,8 @@ </p> <p>Fragmented distribution messages are only used if the receiving node signals that it supports them via the - <seealso marker="erl_dist_protocol#dflags">DFLAG_FRAGMENTS</seealso> distribution - flag.</p> + <seealso marker="erl_dist_protocol#DFLAG_FRAGMENTS">DFLAG_FRAGMENTS</seealso> + distribution flag.</p> <p>A process must complete the sending of a fragmented message before it can start sending any other message on the same distribution channel.</p> @@ -637,11 +637,14 @@ <seealso marker="#NEW_PID_EXT"><c>NEW_PID_EXT</c></seealso>. Port operations are not allowed across node boundaries. </p> - <p>Introduced in OTP 19, but only to be decoded and echoed back. Not - encoded for local ports. Planned to supersede <seealso marker="#PORT_EXT"> - <c>PORT_EXT</c></seealso> in OTP 23 when - <seealso marker="erl_dist_protocol#dflags"><c>DFLAG_BIG_CREATON</c></seealso> - becomes mandatory. + <p><c>NEW_PORT_EXT</c> was introduced in OTP 19, but only to be decoded + and echoed back. Not encoded for local ports. + </p> + <p>In OTP 23 distribution flag + <seealso marker="erl_dist_protocol#DFLAG_BIG_CREATION"><c>DFLAG_BIG_CREATION</c></seealso> + became mandatory. All ports are now + encoded using <c>NEW_PORT_EXT</c>, even external ports received as <seealso + marker="#PORT_EXT"><c>PORT_EXT</c></seealso> from older nodes. </p> </section> @@ -719,11 +722,14 @@ erlang:list_to_pid/1</seealso>).</p> </item> </taglist> - <p>Introduced in OTP 19, but only to be decoded and echoed back. Not - encoded for local processes. Planned to supersede <seealso marker="#PID_EXT"> - <c>PID_EXT</c></seealso> in OTP 23 when - <seealso marker="erl_dist_protocol#dflags"><c>DFLAG_BIG_CREATON</c></seealso> - becomes mandatory. + <p><c>NEW_PID_EXT</c> was introduced in OTP 19, but only to be decoded + and echoed back. Not encoded for local processes. + </p> + <p>In OTP 23 distribution flag + <seealso marker="erl_dist_protocol#DFLAG_BIG_CREATION"><c>DFLAG_BIG_CREATION</c></seealso> + became mandatory. All pids are now encoded using <c>NEW_PID_EXT</c>, + even external pids received as + <seealso marker="#PID_EXT"><c>PID_EXT</c></seealso> from older nodes. </p> </section> @@ -1047,11 +1053,15 @@ <seealso marker="#NEW_PID_EXT"><c>NEW_PID_EXT</c></seealso>.</p> </item> </taglist> - <p>Introduced in OTP 19, but only to be decoded and echoed back. Not - encoded for local references. Planned to supersede <seealso marker="#NEW_REFERENCE_EXT"> - <c>NEW_REFERENCE_EXT</c></seealso> in OTP 23 when - <seealso marker="erl_dist_protocol#dflags"><c>DFLAG_BIG_CREATON</c></seealso> - becomes mandatory. + <p><c>NEWER_REFERENCE_EXT</c> was introduced in OTP 19, but only to be decoded + and echoed back. Not encoded for local references. + </p> + <p>In OTP 23 distribution flag + <seealso marker="erl_dist_protocol#DFLAG_BIG_CREATION"><c>DFLAG_BIG_CREATION</c></seealso> + became mandatory. All references are now encoded using + <c>NEWER_REFERENCE_EXT</c>, even external references received as + <seealso marker="#NEW_REFERENCE_EXT"><c>NEW_REFERENCE_EXT</c></seealso> + from older nodes. </p> </section> @@ -1408,7 +1418,7 @@ <p> <c>SMALL_ATOM_EXT</c> was introduced in ERTS 5.7.2 and require an exchange of distribution flag - <seealso marker="erl_dist_protocol#dflags"> + <seealso marker="erl_dist_protocol#DFLAG_SMALL_ATOM_TAGS"> <c>DFLAG_SMALL_ATOM_TAGS</c></seealso> in the <seealso marker="erl_dist_protocol#distribution_handshake"> distribution handshake</seealso>. diff --git a/erts/doc/src/erl_ext_fig.gif b/erts/doc/src/erl_ext_fig.gif Binary files differindex 14d6bbc871..40dd17bd5e 100644 --- a/erts/doc/src/erl_ext_fig.gif +++ b/erts/doc/src/erl_ext_fig.gif diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml index 0e82ceba7d..2183f75487 100644 --- a/erts/doc/src/erlang.xml +++ b/erts/doc/src/erlang.xml @@ -2553,6 +2553,7 @@ os_prompt%</pre> true > is_map_key(value,Map). false</code> + <p>Allowed in guard tests.</p> </desc> </func> diff --git a/erts/doc/src/net.xml b/erts/doc/src/net.xml deleted file mode 100644 index 6fbc37076c..0000000000 --- a/erts/doc/src/net.xml +++ /dev/null @@ -1,129 +0,0 @@ -<?xml version="1.0" encoding="utf-8" ?> -<!DOCTYPE erlref SYSTEM "erlref.dtd"> - -<erlref> - <header> - <copyright> - <year>2018</year><year>2018</year> - <holder>Ericsson AB. All Rights Reserved.</holder> - </copyright> - <legalnotice> - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - </legalnotice> - - <title>net</title> - <prepared></prepared> - <docno></docno> - <date></date> - <rev></rev> - <file>net.xml</file> - </header> - <module since="OTP 22.0">net</module> - <modulesummary>Network interface.</modulesummary> - <description> - <p>This module provides an API for the network interface.</p> - <note> - <p>There is currently <em>no</em> support for Windows. </p> - </note> - </description> - - <datatypes> - <datatype> - <name name="address_info"/> - </datatype> - <datatype> - <name name="name_info"/> - </datatype> - <datatype> - <name name="name_info_flags"/> - </datatype> - <datatype> - <name name="name_info_flag"/> - </datatype> - <datatype> - <name name="name_info_flag_ext"/> - </datatype> - <datatype> - <name name="network_interface_name"/> - </datatype> - <datatype> - <name name="network_interface_index"/> - </datatype> - </datatypes> - - <funcs> - <func> - <name name="gethostname" arity="0"/> - <fsummary>Get hostname.</fsummary> - <desc> - <p>Returns the name of the current host.</p> - </desc> - </func> - - <func> - <name name="getnameinfo" arity="1" since="OTP 22.0"/> - <name name="getnameinfo" arity="2" since="OTP 22.0"/> - <fsummary>Address-to-name transaltion.</fsummary> - <desc> - <p>Address-to-name translation in a protocol-independant manner.</p> - <p>This function is the inverse of - <seealso marker="#getaddrinfo/1"><c>getaddrinfo</c></seealso>. - It converts a socket address to a corresponding host and service.</p> - </desc> - </func> - - <func> - <name name="getaddrinfo" arity="1" since="OTP 22.0"/> - <name name="getaddrinfo" arity="2" clause_i="1" since="OTP 22.0"/> - <name name="getaddrinfo" arity="2" clause_i="2" since="OTP 22.0"/> - <name name="getaddrinfo" arity="2" clause_i="3" since="OTP 22.0"/> - <fsummary>Network address and service transation.</fsummary> - <desc> - <p>Network address and service translation.</p> - <p>This function is the inverse of - <seealso marker="#getnameinfo/1"><c>getnameinfo</c></seealso>. - It converts host and service to a corresponding socket address.</p> - <p>One of the <c>Host</c> and <c>Service</c> may be <c>undefined</c> - but <em>not</em> both.</p> - </desc> - </func> - - <func> - <name name="if_name2index" arity="1" since="OTP 22.0"/> - <fsummary>Mappings between network interface names and indexes.</fsummary> - <desc> - <p>Mappings between network interface names and indexes.</p> - </desc> - </func> - - <func> - <name name="if_index2name" arity="1" since="OTP 22.0"/> - <fsummary>Mappings between network interface index and names.</fsummary> - <desc> - <p>Mappings between network interface index and names.</p> - </desc> - </func> - - <func> - <name name="if_names" arity="0" since="OTP 22.0"/> - <fsummary>Get network interface names and indexes.</fsummary> - <desc> - <p>Get network interface names and indexes.</p> - </desc> - </func> - - </funcs> - -</erlref> - diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml index cfa952f01c..5ca387ffd8 100644 --- a/erts/doc/src/notes.xml +++ b/erts/doc/src/notes.xml @@ -31,6 +31,54 @@ </header> <p>This document describes the changes made to the ERTS application.</p> +<section><title>Erts 10.4.4</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + An invalid value test caused the socket:setopt(Socket, + ip, add_membership, ip_mreq()) to fail with badarg. The + same for drop_membership.</p> + <p> + Own Id: OTP-15908 Aux Id: ERL-980 </p> + </item> + <item> + <p> + Fixed bug causing VM crash when doing textual dump of a + process containing an unhandled monitor down signal. + Textual process dumps can be done with + <c>erlang:system_info(procs)</c>, trace feature + <c>process_dump</c>, Erlang shell break menu and a + crashdump. Bug exist since OTP 21.0.</p> + <p> + Own Id: OTP-15909 Aux Id: ERL-979 </p> + </item> + <item> + <p><c>lists:subtract/2</c> would produce incorrect + results for some inputs on 64-bit platforms.</p> + <p> + Own Id: OTP-15938 Aux Id: ERL-986 </p> + </item> + <item> + <p>Fixed a bug in the loader that was similar to + <c>OTP-15938</c>, yielding incorrect code for some inputs + on 64-bit platforms.</p> + <p> + Own Id: OTP-15939</p> + </item> + <item> + <p> + Fixed bug causing scheduler threads in rare cases to + block spinnning indefinitely. Bug exists since OTP 21.0.</p> + <p> + Own Id: OTP-15941 Aux Id: PR-2313 </p> + </item> + </list> + </section> + +</section> + <section><title>Erts 10.4.3</title> <section><title>Fixed Bugs and Malfunctions</title> @@ -592,6 +640,46 @@ </section> +<section><title>Erts 10.3.5.4</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fixed bug causing VM crash when doing textual dump of a + process containing an unhandled monitor down signal. + Textual process dumps can be done with + <c>erlang:system_info(procs)</c>, trace feature + <c>process_dump</c>, Erlang shell break menu and a + crashdump. Bug exist since OTP 21.0.</p> + <p> + Own Id: OTP-15909 Aux Id: ERL-979 </p> + </item> + <item> + <p><c>lists:subtract/2</c> would produce incorrect + results for some inputs on 64-bit platforms.</p> + <p> + Own Id: OTP-15938 Aux Id: ERL-986 </p> + </item> + <item> + <p>Fixed a bug in the loader that was similar to + <c>OTP-15938</c>, yielding incorrect code for some inputs + on 64-bit platforms.</p> + <p> + Own Id: OTP-15939</p> + </item> + <item> + <p> + Fixed bug causing scheduler threads in rare cases to + block spinnning indefinitely. Bug exists since OTP 21.0.</p> + <p> + Own Id: OTP-15941 Aux Id: PR-2313 </p> + </item> + </list> + </section> + +</section> + <section><title>Erts 10.3.5.3</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/erts/doc/src/part.xml b/erts/doc/src/part.xml.src index f0b8a00b90..9b20beffad 100644 --- a/erts/doc/src/part.xml +++ b/erts/doc/src/part.xml.src @@ -4,7 +4,7 @@ <part xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>1996</year><year>2018</year> + <year>1996</year><year>2019</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -42,7 +42,7 @@ <xi:include href="tty.xml"/> <xi:include href="driver.xml"/> <xi:include href="inet_cfg.xml"/> - <xi:include href="socket_usage.xml"/> + %ESOCK_USE_SOCKET_USAGE_XML% <xi:include href="erl_ext_dist.xml"/> <xi:include href="erl_dist_protocol.xml"/> </part> diff --git a/erts/doc/src/ref_man.xml b/erts/doc/src/ref_man.xml.src index 80cdcf9145..7dd003763c 100644 --- a/erts/doc/src/ref_man.xml +++ b/erts/doc/src/ref_man.xml.src @@ -4,7 +4,7 @@ <application xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>1996</year><year>2018</year> + <year>1996</year><year>2019</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -46,10 +46,9 @@ <xi:include href="erts_alloc.xml"/> <xi:include href="escript.xml"/> <xi:include href="init.xml"/> - <xi:include href="net.xml"/> <xi:include href="persistent_term.xml"/> <xi:include href="run_erl.xml"/> - <xi:include href="socket.xml"/> + %ESOCK_USE_SOCKET_XML% <xi:include href="start.xml"/> <xi:include href="start_erl.xml"/> <xi:include href="werl.xml"/> diff --git a/erts/doc/src/socket.xml b/erts/doc/src/socket.xml index b4e22e86a8..2f7ff2fc07 100644 --- a/erts/doc/src/socket.xml +++ b/erts/doc/src/socket.xml @@ -47,14 +47,16 @@ <seealso marker="#recv_async"><c>recv/3</c></seealso> function with Timeout set to <c>nowait</c> (<c>recv(Sock, 0, nowait)</c>) when there is actually nothing to read, it will return with - <c>{ok, </c> - <seealso marker="#type-select_info"><c>SelectInfo</c></seealso><c>}</c>. + <c>{select, </c> + <seealso marker="#type-select_info"><c>SelectInfo</c></seealso><c>}</c> + (<c>SelectInfo</c> contains the + <seealso marker="socket#type-select_ref">SelectRef</seealso>). When data eventually arrives a 'select' message will be sent to the caller: </p> <taglist> <!-- NOTE THAT THE EMPTY TAG IS INTENTIONAL --> <tag></tag> - <item><c>{'$socket', socket(), select, select_ref()}</c></item> + <item><c>{'$socket', socket(), select, SelectRef}</c></item> </taglist> <p>The caller can now make another call to the recv function and now expect data.</p> @@ -70,7 +72,7 @@ <p>This message indicates that the (asynchronous) operation has been aborted. If, for instance, the socket has been closed (by another process), - <c>Info</c> will be <c>{select_ref(), closed}</c>. </p> + <c>Info</c> will be <c>{SelectRef, closed}</c>. </p> </note> <note> <p>There is currently <em>no</em> support for Windows. </p> @@ -112,6 +114,15 @@ <name name="select_info"/> </datatype> <datatype> + <name name="socket_counters"/> + </datatype> + <datatype> + <name name="socket_counter"/> + </datatype> + <datatype> + <name name="socket_info"/> + </datatype> + <datatype> <name name="ip4_address"/> </datatype> <datatype> @@ -329,7 +340,9 @@ <p>In the case when there is no connections waiting, the function will return with the <c>SelectInfo</c>. The caller can then await a select message, <c>{'$socket', Socket, select, Info}</c> (where - <c>Info</c> is the <c>select_ref()</c> from the <c>SelectInfo</c>), + <c>Info</c> is the + <seealso marker="socket#type-select_ref"><c>ref</c></seealso> + field from the <c>SelectInfo</c>), when a client connects (a subsequent call to accept will then return the socket). </p> </desc> @@ -401,7 +414,9 @@ <seealso marker="#type-select_info"><c>SelectInfo</c></seealso>. The caller can then await a select message, <c>{'$socket', Socket, select, Info}</c> (where - <c>Info</c> is the <c>select_ref()</c> from the <c>SelectInfo</c>, + <c>Info</c> is the + <seealso marker="socket#type-select_ref"><c>ref</c></seealso> + field from the <c>SelectInfo</c>, a subsequent call to connect will then establish the connection). </p> </desc> @@ -456,6 +471,20 @@ </func> <func> + <name name="info" arity="1" since="OTP @OTP-15818@"/> + <fsummary>Get miscellaneous socket info.</fsummary> + <desc> + <p>Get miscellaneous info about the socket.</p> + <p>The function returns a map with each info item as a key-value + binding. It reflects the "current" state of the socket. </p> + <note> + <p>In order to ensure data integrity, mutex'es are taken when + needed. So, do not call this function often. </p> + </note> + </desc> + </func> + + <func> <name name="listen" arity="1" since="OTP 22.0"/> <name name="listen" arity="2" since="OTP 22.0"/> <fsummary>Listen for connections on a socket.</fsummary> @@ -528,7 +557,9 @@ <p>In the case when there is no data waiting, the function will return with the <c>SelectInfo</c>. The caller can then await a select message, <c>{'$socket', Socket, select, Info}</c> (where - <c>Info</c> is the <c>select_ref()</c> from the <c>SelectInfo</c>), + <c>Info</c> is the + <seealso marker="socket#type-select_ref"><c>ref</c></seealso> + field from the <c>SelectInfo</c>), when data has arrived (a subsequent call to recv will then return the data). </p> <p>Note that if a length (<c>> 0</c>) is specified, and only part @@ -587,7 +618,9 @@ <p>In the case when there is no data waiting, the function will return with the <c>SelectInfo</c>. The caller can then await a select message, <c>{'$socket', Socket, select, Info}</c> (where - <c>Info</c> is the <c>select_ref()</c> from the <c>SelectInfo</c>), + <c>Info</c> is the + <seealso marker="socket#type-select_ref"><c>ref</c></seealso> + field from the <c>SelectInfo</c>), when data has arrived (a subsequent call to recvfrom will then return the data). </p> </desc> @@ -663,7 +696,9 @@ <p>In the case when there is no data waiting, the function will return with the <c>SelectInfo</c>. The caller can then await a select message, <c>{'$socket', Socket, select, Info}</c> (where - <c>Info</c> is the <c>select_ref()</c> from the <c>SelectInfo</c>), + <c>Info</c> is the + <seealso marker="socket#type-select_ref"><c>ref</c></seealso> + field from the <c>SelectInfo</c>), when data has arrived (a subsequent call to recvmsg will then return the data). </p> </desc> @@ -691,7 +726,9 @@ the function will return with the <c>SelectInfo</c>. The caller can then await a select message, <c>{'$socket', Socket, select, Info}</c> - (where <c>Info</c> is the <c>select_ref()</c> from the + (where <c>Info</c> is the + <seealso marker="socket#type-select_ref"><c>ref</c></seealso> + field from the <c>SelectInfo</c>), when there is room for more data (a subsequent call to send will then send the data). </p> <p>Note that if not all the data was sent, the function will return @@ -749,7 +786,9 @@ the function will return with the <c>SelectInfo</c>. The caller can then await a select message, <c>{'$socket', Socket, select, Info}</c> - (where <c>Info</c> is the <c>select_ref()</c> from the + (where <c>Info</c> is the + <seealso marker="socket#type-select_ref"><c>ref</c></seealso> + field from the <c>SelectInfo</c>), when there is room for more data (a subsequent call to sendmsg will then send the data). </p> </desc> @@ -777,7 +816,9 @@ the function will return with the <c>SelectInfo</c>. The caller can then await a select message, <c>{'$socket', Socket, select, Info}</c> - (where <c>Info</c> is the <c>select_ref()</c> from the + (where <c>Info</c> is the + <seealso marker="socket#type-select_ref"><c>ref</c></seealso> + field from the <c>SelectInfo</c>), when there is room for more data (a subsequent call to sendto will then send the data). </p> </desc> diff --git a/erts/doc/src/socket_usage.xml b/erts/doc/src/socket_usage.xml index 7e65bcbf70..c3cda9a615 100644 --- a/erts/doc/src/socket_usage.xml +++ b/erts/doc/src/socket_usage.xml @@ -56,23 +56,20 @@ function with Timeout set to <c>nowait</c> (i.e. <c>recv(Sock, 0, nowait)</c>) when there is actually nothing to read, it will return with - <c>{ok, </c> - <seealso marker="socket#type-select_info"><c>SelectInfo</c></seealso><c>}</c>. + <c>{select, </c> + <seealso marker="socket#type-select_info"><c>SelectInfo</c></seealso><c>}</c> + (<c>SelectInfo</c> contains the + <seealso marker="socket#type-select_ref">SelectRef</seealso>). When data eventually arrives a 'select message' will be sent to the caller:</p> <taglist> <!-- NOTE THAT THE EMPTY TAG IS INTENTIONAL --> <tag></tag> - <item><c>{'$socket', socket(), select, select_ref()}</c></item> + <item><c>{'$socket', socket(), select, SelectRef}</c></item> </taglist> <p>The caller can then make another call to the recv function and now expect data.</p> <p>The user must also be prepared to receive an abort message: </p> - <!-- - <list type="ordered"> - <item><c>{'$socket', Sock, abort, Info}</c></item> - </list> - --> <taglist> <!-- NOTE THAT THE EMPTY TAG IS INTENTIONAL --> <tag></tag> @@ -81,7 +78,7 @@ <p>If the operation is aborted for whatever reason (e.g. if the socket is closed "by someone else"). The <c>Info</c> part contains the abort reason (in this case that - the socket has been closed <c>Info = {select_ref(), closed}</c>). </p> + the socket has been closed <c>Info = {SelectRef, closed}</c>). </p> <p>Note that all other users are <em>locked out</em> until the 'current user' has called the function (recv in this case). So either immediately call the function or @@ -197,7 +194,7 @@ <cell><em>Other Requirements and comments</em></cell> </row> <row> - <cell>acceptcon</cell> + <cell>acceptconn</cell> <cell>boolean()</cell> <cell>no</cell> <cell>yes</cell> @@ -208,7 +205,9 @@ <cell>string()</cell> <cell>yes</cell> <cell>yes</cell> - <cell>none</cell> + <cell>Before Linux 3.8, this socket option could be set, but not get. + Only works for some socket types (e.g. <c>inet</c>). + If empty value is set, the binding is removed.</cell> </row> <row> <cell>broadcast</cell> @@ -222,7 +221,7 @@ <cell>integer()</cell> <cell>yes</cell> <cell>yes</cell> - <cell>requires admin capability</cell> + <cell>may require admin capability</cell> </row> <row> <cell>domain</cell> diff --git a/erts/doc/src/specs.xml b/erts/doc/src/specs.xml.src index 68fab5edf1..54224c15f5 100644 --- a/erts/doc/src/specs.xml +++ b/erts/doc/src/specs.xml.src @@ -5,8 +5,7 @@ <xi:include href="../specs/specs_erl_tracer.xml"/> <xi:include href="../specs/specs_init.xml"/> <xi:include href="../specs/specs_persistent_term.xml"/> - <xi:include href="../specs/specs_socket.xml"/> - <xi:include href="../specs/specs_net.xml"/> + %ESOCK_USE_SOCKET_SPECS_XML% <xi:include href="../specs/specs_zlib.xml"/> <xi:include href="../specs/specs_atomics.xml"/> <xi:include href="../specs/specs_counters.xml"/> diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in index 46df9b8bc3..a8b1728b90 100644 --- a/erts/emulator/Makefile.in +++ b/erts/emulator/Makefile.in @@ -636,10 +636,9 @@ GENERATE += $(TTF_DIR)/driver_tab.c ifeq ($(USE_ESOCK), yes) ESOCK_PRELOAD_BEAM = \ $(ERL_TOP)/erts/preloaded/ebin/socket.beam \ - $(ERL_TOP)/erts/preloaded/ebin/net.beam + $(ERL_TOP)/erts/preloaded/ebin/prim_net.beam else -ESOCK_PRELOAD_BEAM = \ - $(ERL_TOP)/erts/preloaded/ebin/net.beam +ESOCK_PRELOAD_BEAM = endif PRELOAD_BEAM = $(ERL_TOP)/erts/preloaded/ebin/erts_code_purger.beam \ @@ -850,7 +849,7 @@ ifeq ($(USE_ESOCK), yes) ESOCK_NIF_OBJS = \ $(OBJDIR)/socket_nif.o \ - $(OBJDIR)/net_nif.o + $(OBJDIR)/prim_net_nif.o ifneq ($(TARGET), win32) # These are *currently* only needed for non-win32, diff --git a/erts/emulator/beam/beam_bif_load.c b/erts/emulator/beam/beam_bif_load.c index bb1b2e5b27..4c8ee5178a 100644 --- a/erts/emulator/beam/beam_bif_load.c +++ b/erts/emulator/beam/beam_bif_load.c @@ -1799,6 +1799,78 @@ erts_queue_release_literals(Process* c_p, ErtsLiteralArea* literals) } } +struct debug_la_oh { + void (*func)(ErlOffHeap *, void *); + void *arg; +}; + +static void debug_later_cleanup_literal_area_off_heap(void *vfap, + ErtsThrPrgrVal val, + void *vlrlap) +{ + struct debug_la_oh *fap = vfap; + ErtsLaterReleasLiteralArea *lrlap = vlrlap; + ErtsLiteralArea *lap = lrlap->la; + if (!erts_debug_have_accessed_literal_area(lap)) { + ErlOffHeap oh; + ERTS_INIT_OFF_HEAP(&oh); + oh.first = lap->off_heap; + (*fap->func)(&oh, fap->arg); + erts_debug_save_accessed_literal_area(lap); + } +} + +static void debug_later_complete_literal_area_switch_off_heap(void *vfap, + ErtsThrPrgrVal val, + void *vlap) +{ + struct debug_la_oh *fap = vfap; + ErtsLiteralArea *lap = vlap; + if (lap && !erts_debug_have_accessed_literal_area(lap)) { + ErlOffHeap oh; + ERTS_INIT_OFF_HEAP(&oh); + oh.first = lap->off_heap; + (*fap->func)(&oh, fap->arg); + erts_debug_save_accessed_literal_area(lap); + } +} + + +void +erts_debug_foreach_release_literal_area_off_heap(void (*func)(ErlOffHeap *, void *), void *arg) +{ + ErtsLiteralArea *lap; + ErlOffHeap oh; + ErtsLiteralAreaRef *ref; + struct debug_la_oh fa; + erts_mtx_lock(&release_literal_areas.mtx); + for (ref = release_literal_areas.first; ref; ref = ref->next) { + lap = ref->literal_area; + if (!erts_debug_have_accessed_literal_area(lap)) { + ERTS_INIT_OFF_HEAP(&oh); + oh.first = lap->off_heap; + (*func)(&oh, arg); + erts_debug_save_accessed_literal_area(lap); + } + } + erts_mtx_unlock(&release_literal_areas.mtx); + lap = ERTS_COPY_LITERAL_AREA(); + if (lap && !erts_debug_have_accessed_literal_area(lap)) { + ERTS_INIT_OFF_HEAP(&oh); + oh.first = lap->off_heap; + (*func)(&oh, arg); + erts_debug_save_accessed_literal_area(lap); + } + fa.func = func; + fa.arg = arg; + erts_debug_later_op_foreach(later_release_literal_area, + debug_later_cleanup_literal_area_off_heap, + (void *) &fa); + erts_debug_later_op_foreach(complete_literal_area_switch, + debug_later_complete_literal_area_switch_off_heap, + (void *) &fa); +} + /* * Move code from current to old and null all export entries for the module */ diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index 9add87d944..3d5683f19f 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -4615,7 +4615,15 @@ typedef struct SortGenOpArg { static int genopargtermcompare(SortGenOpArg* a, SortGenOpArg* b) { - return CMP_TERM(a->term, b->term); + Sint res = CMP_TERM(a->term, b->term); + + if (res < 0) { + return -1; + } else if (res > 0) { + return 1; + } + + return 0; } static int diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c index dd04018ce6..9f67f46b31 100644 --- a/erts/emulator/beam/bif.c +++ b/erts/emulator/beam/bif.c @@ -1915,7 +1915,7 @@ do_send(Process *p, Eterm to, Eterm msg, Eterm return_term, Eterm *refp, erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf(); erts_dsprintf(dsbufp, "Discarding message %T from %T to %T in an old " - "incarnation (%d) of this node (%d)\n", + "incarnation (%u) of this node (%u)\n", msg, p->common.id, to, @@ -1959,7 +1959,7 @@ do_send(Process *p, Eterm to, Eterm msg, Eterm return_term, Eterm *refp, erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf(); erts_dsprintf(dsbufp, "Discarding message %T from %T to %T in an old " - "incarnation (%d) of this node (%d)\n", + "incarnation (%u) of this node (%u)\n", msg, p->common.id, to, diff --git a/erts/emulator/beam/big.c b/erts/emulator/beam/big.c index 522f50287a..7666f23a4f 100644 --- a/erts/emulator/beam/big.c +++ b/erts/emulator/beam/big.c @@ -2176,6 +2176,24 @@ term_to_Uint64(Eterm term, Uint64 *up) #endif } +int +term_to_Uint32(Eterm term, Uint32 *up) +{ +#if ERTS_SIZEOF_ETERM == 4 + return term_to_Uint(term,up); +#else + if (is_small(term)) { + Sint i = signed_val(term); + if (i >= 0) { + *up = (Uint32) i; + return 1; + } + } + *up = BADARG; + return 0; +#endif +} + int term_to_Sint(Eterm term, Sint *sp) { diff --git a/erts/emulator/beam/big.h b/erts/emulator/beam/big.h index ad19cce395..3fed076419 100644 --- a/erts/emulator/beam/big.h +++ b/erts/emulator/beam/big.h @@ -168,6 +168,8 @@ Eterm erts_uint64_array_to_big(Uint **, int, int, Uint64 *); int term_to_Uint64(Eterm, Uint64*); int term_to_Sint64(Eterm, Sint64*); #endif +int term_to_Uint32(Eterm, Uint32*); + Uint32 big_to_uint32(Eterm b); int term_equals_2pow32(Eterm); diff --git a/erts/emulator/beam/binary.c b/erts/emulator/beam/binary.c index a18228b84a..4ddf59092a 100644 --- a/erts/emulator/beam/binary.c +++ b/erts/emulator/beam/binary.c @@ -1153,51 +1153,47 @@ BIF_RETTYPE list_to_bitstring_1(BIF_ALIST_1) BIF_RETTYPE split_binary_2(BIF_ALIST_2) { - Uint pos; - ErlSubBin* sb1; - ErlSubBin* sb2; - size_t orig_size; - Eterm orig; - Uint offset; - Uint bit_offset; - Uint bit_size; - Eterm* hp; + size_t orig_size, left_size, right_size; + Uint byte_offset, bit_offset, bit_size; + Uint split_at; + + Eterm *hp, *hp_end; + Eterm left, right; + Eterm real_bin; + Eterm result; + byte *bptr; if (is_not_binary(BIF_ARG_1)) { - goto error; - } - if (!term_to_Uint(BIF_ARG_2, &pos)) { - goto error; - } - if ((orig_size = binary_size(BIF_ARG_1)) < pos) { - goto error; + BIF_ERROR(BIF_P, BADARG); + } else if (!term_to_Uint(BIF_ARG_2, &split_at)) { + BIF_ERROR(BIF_P, BADARG); + } else if ((orig_size = binary_size(BIF_ARG_1)) < split_at) { + BIF_ERROR(BIF_P, BADARG); } - hp = HAlloc(BIF_P, 2*ERL_SUB_BIN_SIZE+3); - ERTS_GET_REAL_BIN(BIF_ARG_1, orig, offset, bit_offset, bit_size); - sb1 = (ErlSubBin *) hp; - sb1->thing_word = HEADER_SUB_BIN; - sb1->size = pos; - sb1->offs = offset; - sb1->orig = orig; - sb1->bitoffs = bit_offset; - sb1->bitsize = 0; - sb1->is_writable = 0; - hp += ERL_SUB_BIN_SIZE; - - sb2 = (ErlSubBin *) hp; - sb2->thing_word = HEADER_SUB_BIN; - sb2->size = orig_size - pos; - sb2->offs = offset + pos; - sb2->orig = orig; - sb2->bitoffs = bit_offset; - sb2->bitsize = bit_size; /* The extra bits go into the second binary. */ - sb2->is_writable = 0; - hp += ERL_SUB_BIN_SIZE; - - return TUPLE2(hp, make_binary(sb1), make_binary(sb2)); - - error: - BIF_ERROR(BIF_P, BADARG); + + left_size = split_at; + right_size = orig_size - split_at; + + ERTS_GET_REAL_BIN(BIF_ARG_1, real_bin, byte_offset, bit_offset, bit_size); + bptr = binary_bytes(real_bin); + + hp = HAlloc(BIF_P, EXTRACT_SUB_BIN_HEAP_NEED * 2 + 3); + hp_end = hp + (EXTRACT_SUB_BIN_HEAP_NEED * 2 + 3); + + left = erts_extract_sub_binary(&hp, real_bin, bptr, + byte_offset * 8 + bit_offset, + left_size * 8); + + right = erts_extract_sub_binary(&hp, real_bin, bptr, + (byte_offset + split_at) * 8 + bit_offset, + right_size * 8 + bit_size); + + result = TUPLE2(hp, left, right); + hp += 3; + + HRelease(BIF_P, hp_end, hp); + + return result; } diff --git a/erts/emulator/beam/bs_instrs.tab b/erts/emulator/beam/bs_instrs.tab index bd1ad91e45..5f25bc2ad3 100644 --- a/erts/emulator/beam/bs_instrs.tab +++ b/erts/emulator/beam/bs_instrs.tab @@ -149,7 +149,7 @@ i_bs_get_binary_all2.execute(Fail, Live, Unit, Dst) { ErlBinMatchBuffer *_mb; Eterm _result; - $GC_TEST_PRESERVE(ERL_SUB_BIN_SIZE, $Live, context); + $GC_TEST_PRESERVE(EXTRACT_SUB_BIN_HEAP_NEED, $Live, context); _mb = ms_matchbuffer(context); if (((_mb->size - _mb->offset) % $Unit) == 0) { LIGHT_SWAPOUT; @@ -179,7 +179,7 @@ i_bs_get_binary2.execute(Fail, Live, Sz, Flags, Dst) { Eterm _result; Uint _size; $BS_GET_FIELD_SIZE($Sz, (($Flags) >> 3), $FAIL($Fail), _size); - $GC_TEST_PRESERVE(ERL_SUB_BIN_SIZE, $Live, context); + $GC_TEST_PRESERVE(EXTRACT_SUB_BIN_HEAP_NEED, $Live, context); _mb = ms_matchbuffer(context); LIGHT_SWAPOUT; _result = erts_bs_get_binary_2(c_p, _size, $Flags, _mb); @@ -206,8 +206,7 @@ i_bs_get_binary_imm2.fetch(Ctx) { i_bs_get_binary_imm2.execute(Fail, Live, Sz, Flags, Dst) { ErlBinMatchBuffer *_mb; Eterm _result; - $GC_TEST_PRESERVE(heap_bin_size(ERL_ONHEAP_BIN_LIMIT), - $Live, context); + $GC_TEST_PRESERVE(EXTRACT_SUB_BIN_HEAP_NEED, $Live, context); _mb = ms_matchbuffer(context); LIGHT_SWAPOUT; _result = erts_bs_get_binary_2(c_p, $Sz, $Flags, _mb); @@ -876,9 +875,7 @@ bs_start_match.execute(Fail, Live, Slots, Dst) { result = erts_bs_start_match_2(c_p, context, slots); HTOP = HEAP_TOP(c_p); HEAP_SPACE_VERIFIED(0); - if (is_non_value(result)) { - $FAIL($Fail); - } + $REFRESH_GEN_DEST(); $Dst = result; } else { @@ -1296,10 +1293,6 @@ i_bs_start_match3_gp.execute(Live, Fail, Dst, Pos) { HTOP = HEAP_TOP(c_p); HEAP_SPACE_VERIFIED(0); - if (ms == NULL) { - $FAIL($Fail); - } - $REFRESH_GEN_DEST(); $Dst = make_matchstate(ms); position = ms->mb.offset; @@ -1348,10 +1341,6 @@ i_bs_start_match3.execute(Live, Fail, Dst) { HTOP = HEAP_TOP(c_p); HEAP_SPACE_VERIFIED(0); - if (ms == NULL) { - $FAIL($Fail); - } - $REFRESH_GEN_DEST(); $Dst = make_matchstate(ms); } else { @@ -1523,10 +1512,6 @@ i_bs_start_match3.execute(Live, Fail, Dst) { HTOP = HEAP_TOP(c_p); HEAP_SPACE_VERIFIED(0); - if (is_non_value(result)) { - $FAIL($Fail); - } - $REFRESH_GEN_DEST(); $Dst = result; } else { diff --git a/erts/emulator/beam/copy.c b/erts/emulator/beam/copy.c index db74b06cc5..9bbcba6f3b 100644 --- a/erts/emulator/beam/copy.c +++ b/erts/emulator/beam/copy.c @@ -604,7 +604,12 @@ cleanup: /* * Copy a structure to a heap. */ -Eterm copy_struct_x(Eterm obj, Uint sz, Eterm** hpp, ErlOffHeap* off_heap, Uint *bsz, erts_literal_area_t *litopt) +Eterm copy_struct_x(Eterm obj, Uint sz, Eterm** hpp, ErlOffHeap* off_heap, + Uint *bsz, erts_literal_area_t *litopt +#ifdef ERTS_COPY_REGISTER_LOCATION + , char *file, int line +#endif + ) { char* hstart; Uint hsize; @@ -854,7 +859,11 @@ Eterm copy_struct_x(Eterm obj, Uint sz, Eterm** hpp, ErlOffHeap* off_heap, Uint case EXTERNAL_REF_SUBTAG: { ExternalThing *etp = (ExternalThing *) objp; +#if defined(ERTS_COPY_REGISTER_LOCATION) && defined(ERL_NODE_BOOKKEEP) + erts_ref_node_entry__(etp->node, 2, make_boxed(htop), file, line); +#else erts_ref_node_entry(etp->node, 2, make_boxed(htop)); +#endif } L_off_heap_node_container_common: { @@ -1326,8 +1335,13 @@ Uint copy_shared_calculate(Eterm obj, erts_shcopy_t *info) * Copy object "obj" preserving sharing. * Second half: copy and restore the object. */ -Uint copy_shared_perform(Eterm obj, Uint size, erts_shcopy_t *info, - Eterm** hpp, ErlOffHeap* off_heap) { +Uint copy_shared_perform_x(Eterm obj, Uint size, erts_shcopy_t *info, + Eterm** hpp, ErlOffHeap* off_heap +#ifdef ERTS_COPY_REGISTER_LOCATION + , char *file, int line +#endif + ) +{ Uint e; unsigned sz; Eterm* ptr; @@ -1393,7 +1407,11 @@ Uint copy_shared_perform(Eterm obj, Uint size, erts_shcopy_t *info, *resp = obj; } else { Uint bsz = 0; - *resp = copy_struct_x(obj, hbot - hp, &hp, off_heap, &bsz, NULL); /* copy literal */ + *resp = copy_struct_x(obj, hbot - hp, &hp, off_heap, &bsz, NULL +#ifdef ERTS_COPY_REGISTER_LOCATION + , file, line +#endif + ); /* copy literal */ hbot -= bsz; } goto cleanup_next; @@ -1461,7 +1479,11 @@ Uint copy_shared_perform(Eterm obj, Uint size, erts_shcopy_t *info, *resp = obj; } else { Uint bsz = 0; - *resp = copy_struct_x(obj, hbot - hp, &hp, off_heap, &bsz, NULL); /* copy literal */ + *resp = copy_struct_x(obj, hbot - hp, &hp, off_heap, &bsz, NULL +#ifdef ERTS_COPY_REGISTER_LOCATION + , file, line +#endif + ); /* copy literal */ hbot -= bsz; } goto cleanup_next; @@ -1660,7 +1682,12 @@ Uint copy_shared_perform(Eterm obj, Uint size, erts_shcopy_t *info, case EXTERNAL_REF_SUBTAG: { ExternalThing *etp = (ExternalThing *) ptr; + +#if defined(ERTS_COPY_REGISTER_LOCATION) && defined(ERL_NODE_BOOKKEEP) + erts_ref_node_entry__(etp->node, 2, make_boxed(hp), file, line); +#else erts_ref_node_entry(etp->node, 2, make_boxed(hp)); +#endif } off_heap_node_container_common: { @@ -1823,8 +1850,12 @@ all_clean: * * NOTE: Assumes that term is a tuple (ptr is an untagged tuple ptr). */ -Eterm copy_shallow(Eterm* ERTS_RESTRICT ptr, Uint sz, Eterm** hpp, - ErlOffHeap* off_heap) +Eterm +copy_shallow_x(Eterm* ERTS_RESTRICT ptr, Uint sz, Eterm** hpp, ErlOffHeap* off_heap +#ifdef ERTS_COPY_REGISTER_LOCATION + , char *file, int line +#endif + ) { Eterm* tp = ptr; Eterm* hp = *hpp; @@ -1866,7 +1897,11 @@ Eterm copy_shallow(Eterm* ERTS_RESTRICT ptr, Uint sz, Eterm** hpp, case EXTERNAL_REF_SUBTAG: { ExternalThing* etp = (ExternalThing *) (tp-1); +#if defined(ERTS_COPY_REGISTER_LOCATION) && defined(ERL_NODE_BOOKKEEP) + erts_ref_node_entry__(etp->node, 2, make_boxed(hp-1), file, line); +#else erts_ref_node_entry(etp->node, 2, make_boxed(hp-1)); +#endif } off_heap_common: { diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c index 6bf866eac9..dafe805a6f 100644 --- a/erts/emulator/beam/dist.c +++ b/erts/emulator/beam/dist.c @@ -1266,18 +1266,6 @@ erts_dsig_send_group_leader(ErtsDSigSendContext *ctx, Eterm leader, Eterm remote return dsig_send_ctl(ctx, ctl); } -struct dist_sequences { - ErlHeapFragment hfrag; - struct dist_sequences *parent; - struct dist_sequences *left; - struct dist_sequences *right; - char is_red; - - Uint64 seq_id; - int cnt; - Sint ctl_len; -}; - #define ERTS_RBT_PREFIX dist_seq #define ERTS_RBT_T DistSeqNode #define ERTS_RBT_KEY_T Uint @@ -1312,25 +1300,25 @@ struct dist_sequences { #include "erl_rbtree.h" -struct erts_dist_seq_tree_foreach_iter_arg { - int (*func)(ErtsDistExternal *, void *, Sint); +struct erts_debug_dist_seq_tree_foreach_iter_arg { + int (*func)(DistSeqNode *, void *, Sint); void *arg; }; static int -erts_dist_seq_tree_foreach_iter(DistSeqNode *seq, void *arg, Sint reds) +erts_debug_dist_seq_tree_foreach_iter(DistSeqNode *seq, void *arg, Sint reds) { - struct erts_dist_seq_tree_foreach_iter_arg *state = arg; - return state->func(erts_get_dist_ext(&seq->hfrag), state->arg, reds); + struct erts_debug_dist_seq_tree_foreach_iter_arg *state = arg; + return state->func(seq, state->arg, reds); } void -erts_dist_seq_tree_foreach(DistEntry *dep, int (*func)(ErtsDistExternal *, void *, Sint), void *arg) +erts_debug_dist_seq_tree_foreach(DistEntry *dep, int (*func)(DistSeqNode *, void *, Sint), void *arg) { - struct erts_dist_seq_tree_foreach_iter_arg state; + struct erts_debug_dist_seq_tree_foreach_iter_arg state; state.func = func; state.arg = arg; - dist_seq_rbt_foreach(dep->sequences, erts_dist_seq_tree_foreach_iter, &state); + dist_seq_rbt_foreach(dep->sequences, erts_debug_dist_seq_tree_foreach_iter, &state); } static int dist_seq_cleanup(DistSeqNode *seq, void *unused, Sint reds) @@ -3774,12 +3762,10 @@ int distribution_info(fmtfn_t to, void *arg) /* Called by break handler */ BIF_RETTYPE setnode_2(BIF_ALIST_2) { Process *net_kernel; - Uint creation; + Uint32 creation; /* valid creation ? */ - if(!term_to_Uint(BIF_ARG_2, &creation)) - goto error; - if(creation > 3) + if(!term_to_Uint32(BIF_ARG_2, &creation)) goto error; /* valid node name ? */ @@ -3823,7 +3809,7 @@ BIF_RETTYPE setnode_2(BIF_ALIST_2) erts_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN); erts_thr_progress_block(); inc_no_nodes(); - erts_set_this_node(BIF_ARG_1, (Uint32) creation); + erts_set_this_node(BIF_ARG_1, creation); erts_is_alive = 1; send_nodes_mon_msgs(NULL, am_nodeup, BIF_ARG_1, am_visible, NIL); erts_thr_progress_unblock(); diff --git a/erts/emulator/beam/dist.h b/erts/emulator/beam/dist.h index 067028634b..37ec88cc55 100644 --- a/erts/emulator/beam/dist.h +++ b/erts/emulator/beam/dist.h @@ -54,11 +54,12 @@ #define DFLAG_DIST_MANDATORY (DFLAG_EXTENDED_REFERENCES \ | DFLAG_EXTENDED_PIDS_PORTS \ | DFLAG_UTF8_ATOMS \ - | DFLAG_NEW_FUN_TAGS) + | DFLAG_NEW_FUN_TAGS \ + | DFLAG_BIG_CREATION) /* * Additional optimistic flags when encoding toward pending connection. - * If remote node (erl_interface) does not supporting these then we may need + * If remote node (erl_interface) does not support these then we may need * to transcode messages enqueued before connection setup was finished. */ #define DFLAG_DIST_HOPEFULLY (DFLAG_EXPORT_PTR_TAG \ @@ -75,7 +76,6 @@ | DFLAG_SMALL_ATOM_TAGS \ | DFLAG_UTF8_ATOMS \ | DFLAG_MAP_TAG \ - | DFLAG_BIG_CREATION \ | DFLAG_SEND_SENDER \ | DFLAG_BIG_SEQTRACE_LABELS \ | DFLAG_EXIT_PAYLOAD \ @@ -274,6 +274,18 @@ typedef struct erts_dsig_send_context { typedef struct dist_sequences DistSeqNode; +struct dist_sequences { + ErlHeapFragment hfrag; + struct dist_sequences *parent; + struct dist_sequences *left; + struct dist_sequences *right; + char is_red; + + Uint64 seq_id; + int cnt; + Sint ctl_len; +}; + /* * erts_dsig_send_* return values. */ @@ -306,9 +318,9 @@ extern Uint erts_dist_cache_size(void); extern Sint erts_abort_connection_rwunlock(DistEntry *dep); -extern void erts_dist_seq_tree_foreach( +extern void erts_debug_dist_seq_tree_foreach( DistEntry *dep, - int (*func)(ErtsDistExternal *, void*, Sint), void *args); + int (*func)(DistSeqNode *, void*, Sint), void *args); extern int erts_dsig_prepare(ErtsDSigSendContext *, DistEntry*, diff --git a/erts/emulator/beam/erl_alloc.types b/erts/emulator/beam/erl_alloc.types index 58d586453c..349977ebe7 100644 --- a/erts/emulator/beam/erl_alloc.types +++ b/erts/emulator/beam/erl_alloc.types @@ -149,6 +149,7 @@ type MODULE_TABLE LONG_LIVED CODE module_tab type TAINT LONG_LIVED CODE taint_list type MODULE_REFS STANDARD CODE module_refs type NC_TMP TEMPORARY SYSTEM nc_tmp +type NC_STD STANDARD SYSTEM nc_std type TMP TEMPORARY SYSTEM tmp type UNDEF SYSTEM SYSTEM undefined type DCACHE STANDARD SYSTEM dcache diff --git a/erts/emulator/beam/erl_alloc_util.c b/erts/emulator/beam/erl_alloc_util.c index 25ac3bc5af..bfc2f5992c 100644 --- a/erts/emulator/beam/erl_alloc_util.c +++ b/erts/emulator/beam/erl_alloc_util.c @@ -7112,12 +7112,21 @@ static int blockscan_cpool_yielding(blockscan_t *state) return 0; } -static int blockscan_yield_helper(blockscan_t *state, - int (*yielding_op)(blockscan_t*)) +/* */ + +static int blockscan_finish(blockscan_t *state) { - /* Note that we don't check whether to abort here; only yielding_op knows - * whether the carrier is still in the list/pool. */ + if (ERTS_PROC_IS_EXITING(state->process)) { + state->abort(state->user_data); + return 0; + } + state->current_op = blockscan_finish; + + return state->finish(state->user_data); +} + +static void blockscan_lock_helper(blockscan_t *state) { if ((state->allocator)->thread_safe) { /* Locked scans have to be as short as possible. */ state->reductions = 1; @@ -7126,34 +7135,18 @@ static int blockscan_yield_helper(blockscan_t *state, } else { state->reductions = BLOCKSCAN_REDUCTIONS; } +} - if (yielding_op(state)) { - state->next_op = state->current_op; - } - +static void blockscan_unlock_helper(blockscan_t *state) { if ((state->allocator)->thread_safe) { erts_mtx_unlock(&(state->allocator)->mutex); } - - return 1; -} - -/* */ - -static int blockscan_finish(blockscan_t *state) -{ - if (ERTS_PROC_IS_EXITING(state->process)) { - state->abort(state->user_data); - return 0; - } - - state->current_op = blockscan_finish; - - return state->finish(state->user_data); } static int blockscan_sweep_sbcs(blockscan_t *state) { + blockscan_lock_helper(state); + if (state->current_op != blockscan_sweep_sbcs) { SET_CARRIER_HDR(&state->dummy_carrier, 0, SCH_SBC, state->allocator); state->current_clist = &(state->allocator)->sbc_list; @@ -7163,11 +7156,19 @@ static int blockscan_sweep_sbcs(blockscan_t *state) state->current_op = blockscan_sweep_sbcs; state->next_op = blockscan_finish; - return blockscan_yield_helper(state, blockscan_clist_yielding); + if (blockscan_clist_yielding(state)) { + state->next_op = state->current_op; + } + + blockscan_unlock_helper(state); + + return 1; } static int blockscan_sweep_mbcs(blockscan_t *state) { + blockscan_lock_helper(state); + if (state->current_op != blockscan_sweep_mbcs) { SET_CARRIER_HDR(&state->dummy_carrier, 0, SCH_MBC, state->allocator); state->current_clist = &(state->allocator)->mbc_list; @@ -7177,11 +7178,19 @@ static int blockscan_sweep_mbcs(blockscan_t *state) state->current_op = blockscan_sweep_mbcs; state->next_op = blockscan_sweep_sbcs; - return blockscan_yield_helper(state, blockscan_clist_yielding); + if (blockscan_clist_yielding(state)) { + state->next_op = state->current_op; + } + + blockscan_unlock_helper(state); + + return 1; } static int blockscan_sweep_cpool(blockscan_t *state) { + blockscan_lock_helper(state); + if (state->current_op != blockscan_sweep_cpool) { SET_CARRIER_HDR(&state->dummy_carrier, 0, SCH_MBC, state->allocator); state->cpool_cursor = (state->allocator)->cpool.sentinel; @@ -7190,7 +7199,13 @@ static int blockscan_sweep_cpool(blockscan_t *state) state->current_op = blockscan_sweep_cpool; state->next_op = blockscan_sweep_mbcs; - return blockscan_yield_helper(state, blockscan_cpool_yielding); + if (blockscan_cpool_yielding(state)) { + state->next_op = state->current_op; + } + + blockscan_unlock_helper(state); + + return 1; } static int blockscan_get_specific_allocator(int allocator_num, diff --git a/erts/emulator/beam/erl_bif_binary.c b/erts/emulator/beam/erl_bif_binary.c index 4d6d31cd76..b8e56390c1 100644 --- a/erts/emulator/beam/erl_bif_binary.c +++ b/erts/emulator/beam/erl_bif_binary.c @@ -1750,9 +1750,8 @@ static Eterm do_split_single_result(Process *p, Eterm subject, BinaryFindContext Uint offset; Uint bit_offset; Uint bit_size; - ErlSubBin *sb1; - ErlSubBin *sb2; - Eterm *hp; + Uint hp_need; + Eterm *hp, *hp_end; Eterm ret; pos = ff->pos; @@ -1765,57 +1764,58 @@ static Eterm do_split_single_result(Process *p, Eterm subject, BinaryFindContext if (pos == 0) { ret = NIL; } else { - hp = HAlloc(p, (ERL_SUB_BIN_SIZE + 2)); + Eterm extracted; + + hp_need = EXTRACT_SUB_BIN_HEAP_NEED + 2; + + hp = HAlloc(p, hp_need); + hp_end = hp + hp_need; + ERTS_GET_REAL_BIN(subject, orig, offset, bit_offset, bit_size); - sb1 = (ErlSubBin *) hp; - sb1->thing_word = HEADER_SUB_BIN; - sb1->size = pos; - sb1->offs = offset; - sb1->orig = orig; - sb1->bitoffs = bit_offset; - sb1->bitsize = bit_size; - sb1->is_writable = 0; - hp += ERL_SUB_BIN_SIZE; - - ret = CONS(hp, make_binary(sb1), NIL); + extracted = erts_extract_sub_binary(&hp, orig, binary_bytes(orig), + offset * 8 + bit_offset, + pos * 8 + bit_size); + + ret = CONS(hp, extracted, NIL); hp += 2; + + HRelease(p, hp_end, hp); + + return ret; } } else { - if ((ctx->flags & BF_FLAG_SPLIT_TRIM_ALL) && (pos == 0)) { - hp = HAlloc(p, 1 * (ERL_SUB_BIN_SIZE + 2)); - ERTS_GET_REAL_BIN(subject, orig, offset, bit_offset, bit_size); - sb1 = NULL; - } else { - hp = HAlloc(p, 2 * (ERL_SUB_BIN_SIZE + 2)); - ERTS_GET_REAL_BIN(subject, orig, offset, bit_offset, bit_size); - sb1 = (ErlSubBin *) hp; - sb1->thing_word = HEADER_SUB_BIN; - sb1->size = pos; - sb1->offs = offset; - sb1->orig = orig; - sb1->bitoffs = bit_offset; - sb1->bitsize = 0; - sb1->is_writable = 0; - hp += ERL_SUB_BIN_SIZE; - } - - sb2 = (ErlSubBin *) hp; - sb2->thing_word = HEADER_SUB_BIN; - sb2->size = orig_size - pos - len; - sb2->offs = offset + pos + len; - sb2->orig = orig; - sb2->bitoffs = bit_offset; - sb2->bitsize = bit_size; - sb2->is_writable = 0; - hp += ERL_SUB_BIN_SIZE; - - ret = CONS(hp, make_binary(sb2), NIL); - hp += 2; - if (sb1 != NULL) { - ret = CONS(hp, make_binary(sb1), ret); - hp += 2; - } + Eterm first, rest; + + hp_need = (EXTRACT_SUB_BIN_HEAP_NEED + 2) * 2; + + hp = HAlloc(p, hp_need); + hp_end = hp + hp_need; + + ERTS_GET_REAL_BIN(subject, orig, offset, bit_offset, bit_size); + + if ((ctx->flags & BF_FLAG_SPLIT_TRIM_ALL) && (pos == 0)) { + first = NIL; + } else { + first = erts_extract_sub_binary(&hp, orig, binary_bytes(orig), + offset * 8 + bit_offset, + pos * 8); + } + + rest = erts_extract_sub_binary(&hp, orig, binary_bytes(orig), + (offset + pos + len) * 8 + bit_offset, + (orig_size - pos - len) * 8 + bit_size); + + ret = CONS(hp, rest, NIL); + hp += 2; + + if (first != NIL) { + ret = CONS(hp, first, ret); + hp += 2; + } + + HRelease(p, hp_end, hp); } + return ret; } @@ -1829,7 +1829,9 @@ static Eterm do_split_global_result(Process *p, Eterm subject, BinaryFindContext Uint offset; Uint bit_offset; Uint bit_size; - ErlSubBin *sb; + Uint extracted_offset; + Uint extracted_size; + Eterm extracted; Uint do_trim; Sint i; register Uint reds = ctx->reds; @@ -1852,7 +1854,8 @@ static Eterm do_split_global_result(Process *p, Eterm subject, BinaryFindContext *ctxp = ctx; fa = &(ctx->u.fa); } - erts_factory_proc_prealloc_init(&(fa->factory), p, (fa->size + 1) * (ERL_SUB_BIN_SIZE + 2)); + erts_factory_proc_prealloc_init(&(fa->factory), p, (fa->size + 1) * + (EXTRACT_SUB_BIN_HEAP_NEED + 2)); ctx->state = BFResult; } @@ -1871,39 +1874,39 @@ static Eterm do_split_global_result(Process *p, Eterm subject, BinaryFindContext } return THE_NON_VALUE; } - sb = (ErlSubBin *)(fa->factory.hp); - sb->size = fa->end_pos - (fad[i].pos + fad[i].len); - if (!(sb->size == 0 && do_trim)) { - sb->thing_word = HEADER_SUB_BIN; - sb->offs = offset + fad[i].pos + fad[i].len; - sb->orig = orig; - sb->bitoffs = bit_offset; - sb->bitsize = 0; - sb->is_writable = 0; - fa->factory.hp += ERL_SUB_BIN_SIZE; - fa->term = CONS(fa->factory.hp, make_binary(sb), fa->term); - fa->factory.hp += 2; - do_trim &= ~BF_FLAG_SPLIT_TRIM; - } - fa->end_pos = fad[i].pos; + + extracted_offset = (offset + fad[i].pos + fad[i].len) * 8 + bit_offset; + extracted_size = (fa->end_pos - (fad[i].pos + fad[i].len)) * 8; + + if (!(extracted_size == 0 && do_trim)) { + extracted = erts_extract_sub_binary(&fa->factory.hp, orig, + binary_bytes(orig), + extracted_offset, + extracted_size); + fa->term = CONS(fa->factory.hp, extracted, fa->term); + fa->factory.hp += 2; + + do_trim &= ~BF_FLAG_SPLIT_TRIM; + } + + fa->end_pos = fad[i].pos; } fa->head = i; ctx->reds = reds; - sb = (ErlSubBin *)(fa->factory.hp); - sb->size = fad[0].pos; - if (!(sb->size == 0 && do_trim)) { - sb->thing_word = HEADER_SUB_BIN; - sb->offs = offset; - sb->orig = orig; - sb->bitoffs = bit_offset; - sb->bitsize = 0; - sb->is_writable = 0; - fa->factory.hp += ERL_SUB_BIN_SIZE; - fa->term = CONS(fa->factory.hp, make_binary(sb), fa->term); - fa->factory.hp += 2; + extracted_offset = offset * 8 + bit_offset; + extracted_size = fad[0].pos * 8; + + if (!(extracted_size == 0 && do_trim)) { + extracted = erts_extract_sub_binary(&fa->factory.hp, orig, + binary_bytes(orig), + extracted_offset, + extracted_size); + fa->term = CONS(fa->factory.hp, extracted, fa->term); + fa->factory.hp += 2; } + erts_factory_close(&(fa->factory)); return fa->term; @@ -1937,8 +1940,8 @@ BIF_RETTYPE erts_binary_part(Process *p, Eterm binary, Eterm epos, Eterm elen) Uint offset; Uint bit_offset; Uint bit_size; - Eterm* hp; - ErlSubBin* sb; + Eterm *hp, *hp_end; + Eterm result; if (is_not_binary(binary)) { goto badarg; @@ -1970,19 +1973,18 @@ BIF_RETTYPE erts_binary_part(Process *p, Eterm binary, Eterm epos, Eterm elen) goto badarg; } - hp = HeapFragOnlyAlloc(p, ERL_SUB_BIN_SIZE); + hp = HeapFragOnlyAlloc(p, EXTRACT_SUB_BIN_HEAP_NEED); + hp_end = hp + EXTRACT_SUB_BIN_HEAP_NEED; ERTS_GET_REAL_BIN(binary, orig, offset, bit_offset, bit_size); - sb = (ErlSubBin *) hp; - sb->thing_word = HEADER_SUB_BIN; - sb->size = len; - sb->offs = offset + pos; - sb->orig = orig; - sb->bitoffs = bit_offset; - sb->bitsize = 0; - sb->is_writable = 0; - - BIF_RET(make_binary(sb)); + + result = erts_extract_sub_binary(&hp, orig, binary_bytes(orig), + (offset + pos) * 8 + bit_offset, + len * 8); + + HRelease(p, hp_end, hp); + + BIF_RET(result); badarg: BIF_ERROR(p, BADARG); diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c index 0339589b79..d1ceffd23c 100644 --- a/erts/emulator/beam/erl_bif_info.c +++ b/erts/emulator/beam/erl_bif_info.c @@ -162,10 +162,10 @@ static Eterm current_stacktrace(ErtsHeapFactory *hfact, Process* rp, Uint reserve_size); static Eterm -bld_bin_list(Uint **hpp, Uint *szp, ErlOffHeap* oh) +bld_bin_list(Uint **hpp, Uint *szp, ErlOffHeap* oh, Eterm tail) { struct erl_off_heap_header* ohh; - Eterm res = NIL; + Eterm res = tail; Eterm tuple; for (ohh = oh->first; ohh; ohh = ohh->next) { @@ -1864,11 +1864,25 @@ process_info_aux(Process *c_p, break; case ERTS_PI_IX_BINARY: { - Uint sz = 0; - (void) bld_bin_list(NULL, &sz, &MSO(rp)); + ErlHeapFragment *hfrag; + Uint sz; + + res = NIL; + sz = 0; + + (void)bld_bin_list(NULL, &sz, &MSO(rp), NIL); + for (hfrag = rp->mbuf; hfrag != NULL; hfrag = hfrag->next) { + (void)bld_bin_list(NULL, &sz, &hfrag->off_heap, NIL); + } + hp = erts_produce_heap(hfact, sz, reserve_size); - res = bld_bin_list(&hp, NULL, &MSO(rp)); - break; + + res = bld_bin_list(&hp, NULL, &MSO(rp), NIL); + for (hfrag = rp->mbuf; hfrag != NULL; hfrag = hfrag->next) { + res = bld_bin_list(&hp, NULL, &hfrag->off_heap, res); + } + + break; } case ERTS_PI_IX_SEQUENTIAL_TRACE_TOKEN: { @@ -2799,7 +2813,10 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1) } else if (BIF_ARG_1 == am_threads) { return am_true; } else if (BIF_ARG_1 == am_creation) { - return make_small(erts_this_node->creation); + Uint hsz = 0; + erts_bld_uint(NULL, &hsz, erts_this_node->creation); + hp = hsz ? HAlloc(BIF_P, hsz) : NULL; + BIF_RET(erts_bld_uint(&hp, NULL, erts_this_node->creation)); } else if (BIF_ARG_1 == am_break_ignored) { extern int ignore_break; if (ignore_break) diff --git a/erts/emulator/beam/erl_bif_lists.c b/erts/emulator/beam/erl_bif_lists.c index b23fa77f5f..fa2edfef1e 100644 --- a/erts/emulator/beam/erl_bif_lists.c +++ b/erts/emulator/beam/erl_bif_lists.c @@ -413,12 +413,25 @@ typedef struct { #define ERTS_RBT_GET_LEFT(T) ((T)->left) #define ERTS_RBT_SET_LEFT(T, L) ((T)->left = (L)) #define ERTS_RBT_GET_KEY(T) ((T)->key) -#define ERTS_RBT_CMP_KEYS(KX, KY) CMP_TERM(KX, KY) +#define ERTS_RBT_CMP_KEYS(KX, KY) subtract_term_cmp((KX), (KY)) #define ERTS_RBT_WANT_LOOKUP_INSERT #define ERTS_RBT_WANT_LOOKUP #define ERTS_RBT_WANT_DELETE #define ERTS_RBT_UNDEF +/* erl_rbtree expects comparisons to return an int */ +static int subtract_term_cmp(Eterm a, Eterm b) { + Sint res = CMP_TERM(a, b); + + if (res < 0) { + return -1; + } else if (res > 0) { + return 1; + } + + return 0; +} + #include "erl_rbtree.h" static int subtract_continue(Process *p, ErtsSubtractContext *context); diff --git a/erts/emulator/beam/erl_bif_persistent.c b/erts/emulator/beam/erl_bif_persistent.c index f38e0cc5cb..8662a9e33a 100644 --- a/erts/emulator/beam/erl_bif_persistent.c +++ b/erts/emulator/beam/erl_bif_persistent.c @@ -1234,3 +1234,102 @@ next_to_delete(void) erts_mtx_unlock(&delete_queue_mtx); return table; } + +/* + * test/debug functionality follow... + */ + +static Uint accessed_literal_areas_size; +static Uint accessed_no_literal_areas; +static ErtsLiteralArea **accessed_literal_areas; + +int +erts_debug_have_accessed_literal_area(ErtsLiteralArea *lap) +{ + Uint i; + for (i = 0; i < accessed_no_literal_areas; i++) { + if (accessed_literal_areas[i] == lap) + return !0; + } + return 0; +} + +void +erts_debug_save_accessed_literal_area(ErtsLiteralArea *lap) +{ + if (accessed_no_literal_areas == accessed_literal_areas_size) { + accessed_literal_areas_size += 10; + accessed_literal_areas = erts_realloc(ERTS_ALC_T_TMP, + accessed_literal_areas, + (sizeof(ErtsLiteralArea *) + *accessed_literal_areas_size)); + } + accessed_literal_areas[accessed_no_literal_areas++] = lap; +} + +static void debug_foreach_off_heap(HashTable *tbl, void (*func)(ErlOffHeap *, void *), void *arg) +{ + int i; + + for (i = 0; i < tbl->allocated; i++) { + Eterm term = tbl->term[i]; + if (is_tuple_arity(term, 2)) { + ErtsLiteralArea *lap = term_to_area(term); + ErlOffHeap oh; + if (!erts_debug_have_accessed_literal_area(lap)) { + ERTS_INIT_OFF_HEAP(&oh); + oh.first = lap->off_heap; + (*func)(&oh, arg); + erts_debug_save_accessed_literal_area(lap); + } + } + } +} + +struct debug_la_oh { + void (*func)(ErlOffHeap *, void *); + void *arg; +}; + +static void debug_handle_table(void *vfap, + ErtsThrPrgrVal val, + void *vtbl) +{ + struct debug_la_oh *fap = vfap; + HashTable *tbl = vtbl; + debug_foreach_off_heap(tbl, fap->func, fap->arg); +} + +void +erts_debug_foreach_persistent_term_off_heap(void (*func)(ErlOffHeap *, void *), void *arg) +{ + HashTable *tbl; + struct debug_la_oh fa; + accessed_no_literal_areas = 0; + accessed_literal_areas_size = 10; + accessed_literal_areas = erts_alloc(ERTS_ALC_T_TMP, + (sizeof(ErtsLiteralArea *) + * accessed_literal_areas_size)); + + tbl = (HashTable *) erts_atomic_read_nob(&the_hash_table); + debug_foreach_off_heap(tbl, func, arg); + erts_mtx_lock(&delete_queue_mtx); + for (tbl = delete_queue_head; tbl; tbl = tbl->delete_next) + debug_foreach_off_heap(tbl, func, arg); + erts_mtx_unlock(&delete_queue_mtx); + fa.func = func; + fa.arg = arg; + erts_debug_later_op_foreach(table_updater, + debug_handle_table, + (void *) &fa); + erts_debug_later_op_foreach(table_deleter, + debug_handle_table, + (void *) &fa); + erts_debug_foreach_release_literal_area_off_heap(func, arg); + + erts_free(ERTS_ALC_T_TMP, accessed_literal_areas); + accessed_no_literal_areas = 0; + accessed_literal_areas_size = 0; + accessed_literal_areas = NULL; +} + diff --git a/erts/emulator/beam/erl_binary.h b/erts/emulator/beam/erl_binary.h index c9c047255a..66b59ef1a3 100644 --- a/erts/emulator/beam/erl_binary.h +++ b/erts/emulator/beam/erl_binary.h @@ -351,6 +351,19 @@ erts_free_aligned_binary_bytes(byte* buf) erts_free_aligned_binary_bytes_extra(buf,ERTS_ALC_T_TMP); } +/* A binary's size in bits must fit into a word for matching to work. We used + * to allow creating larger binaries than this, but they acted really strangely + * in Erlang code and were pretty much only usable in drivers and NIFs. + * + * This check also ensures, indirectly, that there won't be an overflow when + * the size is bumped by CHICKEN_PAD and the binary struct itself. */ +#define BINARY_OVERFLOW_CHECK(BYTE_SIZE) \ + do { \ + if (ERTS_UNLIKELY(BYTE_SIZE > ERTS_UWORD_MAX / CHAR_BIT)) { \ + return NULL; \ + } \ + } while(0) + /* Explicit extra bytes allocated to counter buggy drivers. ** These extra bytes where earlier (< R13B04) added by an alignment-bug ** in this code. Do we dare remove this in some major release (R14?) maybe? @@ -364,86 +377,107 @@ erts_free_aligned_binary_bytes(byte* buf) ERTS_GLB_INLINE Binary * erts_bin_drv_alloc_fnf(Uint size) { - Uint bsize = ERTS_SIZEOF_Binary(size) + CHICKEN_PAD; Binary *res; + Uint bsize; + + BINARY_OVERFLOW_CHECK(size); + bsize = ERTS_SIZEOF_Binary(size) + CHICKEN_PAD; - if (bsize < size) /* overflow */ - return NULL; res = erts_alloc_fnf(ERTS_ALC_T_DRV_BINARY, bsize); ERTS_CHK_BIN_ALIGNMENT(res); + if (res) { - res->orig_size = size; - res->intern.flags = BIN_FLAG_DRV; + res->orig_size = size; + res->intern.flags = BIN_FLAG_DRV; erts_refc_init(&res->intern.refc, 1); } + return res; } ERTS_GLB_INLINE Binary * erts_bin_drv_alloc(Uint size) { - Uint bsize = ERTS_SIZEOF_Binary(size) + CHICKEN_PAD; + Binary *res = erts_bin_drv_alloc_fnf(size); + + if (res) { + return res; + } + + erts_alloc_enomem(ERTS_ALC_T_DRV_BINARY, size); +} + +ERTS_GLB_INLINE Binary * +erts_bin_nrml_alloc_fnf(Uint size) +{ Binary *res; + Uint bsize; - if (bsize < size) /* overflow */ - erts_alloc_enomem(ERTS_ALC_T_DRV_BINARY, size); - res = erts_alloc(ERTS_ALC_T_DRV_BINARY, bsize); + BINARY_OVERFLOW_CHECK(size); + bsize = ERTS_SIZEOF_Binary(size) + CHICKEN_PAD; + + res = erts_alloc_fnf(ERTS_ALC_T_BINARY, bsize); ERTS_CHK_BIN_ALIGNMENT(res); - res->orig_size = size; - res->intern.flags = BIN_FLAG_DRV; - erts_refc_init(&res->intern.refc, 1); + + if (res) { + res->orig_size = size; + res->intern.flags = 0; + erts_refc_init(&res->intern.refc, 1); + } + return res; } ERTS_GLB_INLINE Binary * erts_bin_nrml_alloc(Uint size) { - Uint bsize = ERTS_SIZEOF_Binary(size) + CHICKEN_PAD; - Binary *res; + Binary *res = erts_bin_drv_alloc_fnf(size); - if (bsize < size) /* overflow */ - erts_alloc_enomem(ERTS_ALC_T_BINARY, size); - res = erts_alloc(ERTS_ALC_T_BINARY, bsize); - ERTS_CHK_BIN_ALIGNMENT(res); - res->orig_size = size; - res->intern.flags = 0; - erts_refc_init(&res->intern.refc, 1); - return res; + if (res) { + return res; + } + + erts_alloc_enomem(ERTS_ALC_T_BINARY, size); } ERTS_GLB_INLINE Binary * erts_bin_realloc_fnf(Binary *bp, Uint size) { + ErtsAlcType_t type; Binary *nbp; - Uint bsize = ERTS_SIZEOF_Binary(size) + CHICKEN_PAD; - ErtsAlcType_t type = (bp->intern.flags & BIN_FLAG_DRV) ? ERTS_ALC_T_DRV_BINARY - : ERTS_ALC_T_BINARY; + Uint bsize; + + type = (bp->intern.flags & BIN_FLAG_DRV) ? ERTS_ALC_T_DRV_BINARY + : ERTS_ALC_T_BINARY; ASSERT((bp->intern.flags & BIN_FLAG_MAGIC) == 0); - if (bsize < size) /* overflow */ - return NULL; + + BINARY_OVERFLOW_CHECK(size); + bsize = ERTS_SIZEOF_Binary(size) + CHICKEN_PAD; + nbp = erts_realloc_fnf(type, (void *) bp, bsize); ERTS_CHK_BIN_ALIGNMENT(nbp); - if (nbp) - nbp->orig_size = size; + + if (nbp) { + nbp->orig_size = size; + } + return nbp; } ERTS_GLB_INLINE Binary * erts_bin_realloc(Binary *bp, Uint size) { - Binary *nbp; - Uint bsize = ERTS_SIZEOF_Binary(size) + CHICKEN_PAD; - ErtsAlcType_t type = (bp->intern.flags & BIN_FLAG_DRV) ? ERTS_ALC_T_DRV_BINARY - : ERTS_ALC_T_BINARY; - ASSERT((bp->intern.flags & BIN_FLAG_MAGIC) == 0); - if (bsize < size) /* overflow */ - erts_realloc_enomem(type, bp, size); - nbp = erts_realloc_fnf(type, (void *) bp, bsize); - if (!nbp) - erts_realloc_enomem(type, bp, bsize); - ERTS_CHK_BIN_ALIGNMENT(nbp); - nbp->orig_size = size; - return nbp; + Binary *nbp = erts_bin_realloc_fnf(bp, size); + + if (nbp) { + return nbp; + } + + if (bp->intern.flags & BIN_FLAG_DRV) { + erts_realloc_enomem(ERTS_ALC_T_DRV_BINARY, bp, size); + } else { + erts_realloc_enomem(ERTS_ALC_T_BINARY, bp, size); + } } ERTS_GLB_INLINE void diff --git a/erts/emulator/beam/erl_bits.c b/erts/emulator/beam/erl_bits.c index f5807d25d7..a0edbc81a4 100644 --- a/erts/emulator/beam/erl_bits.c +++ b/erts/emulator/beam/erl_bits.c @@ -124,10 +124,10 @@ erts_bs_start_match_2(Process *p, Eterm Binary, Uint Max) ProcBin* pb; ASSERT(is_binary(Binary)); + total_bin_size = binary_size(Binary); - if ((total_bin_size >> (8*sizeof(Uint)-3)) != 0) { - return THE_NON_VALUE; - } + ASSERT(total_bin_size <= ERTS_UWORD_MAX / CHAR_BIT); + NeededSize = ERL_BIN_MATCHSTATE_SIZE(Max); hp = HeapOnlyAlloc(p, NeededSize); ms = (ErlBinMatchState *) hp; @@ -157,10 +157,9 @@ ErlBinMatchState *erts_bs_start_match_3(Process *p, Eterm Binary) ProcBin* pb; ASSERT(is_binary(Binary)); + total_bin_size = binary_size(Binary); - if ((total_bin_size >> (8*sizeof(Uint)-3)) != 0) { - return NULL; - } + ASSERT(total_bin_size <= ERTS_UWORD_MAX / CHAR_BIT); NeededSize = ERL_BIN_MATCHSTATE_SIZE(0); hp = HeapOnlyAlloc(p, NeededSize); @@ -459,29 +458,25 @@ erts_bs_get_integer_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuff Eterm erts_bs_get_binary_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuffer* mb) { - ErlSubBin* sb; + Eterm result; CHECK_MATCH_BUFFER(mb); - if (mb->size - mb->offset < num_bits) { /* Asked for too many bits. */ - return THE_NON_VALUE; + if (mb->size - mb->offset < num_bits) { + /* Asked for too many bits. */ + return THE_NON_VALUE; } /* * From now on, we can't fail. */ - sb = (ErlSubBin *) HeapOnlyAlloc(p, ERL_SUB_BIN_SIZE); - - sb->thing_word = HEADER_SUB_BIN; - sb->orig = mb->orig; - sb->size = BYTE_OFFSET(num_bits); - sb->bitsize = BIT_OFFSET(num_bits); - sb->offs = BYTE_OFFSET(mb->offset); - sb->bitoffs = BIT_OFFSET(mb->offset); - sb->is_writable = 0; + result = erts_extract_sub_binary(&HEAP_TOP(p), + mb->orig, mb->base, + mb->offset, num_bits); + mb->offset += num_bits; - - return make_binary(sb); + + return result; } Eterm @@ -545,21 +540,19 @@ erts_bs_get_float_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuffer Eterm erts_bs_get_binary_all_2(Process *p, ErlBinMatchBuffer* mb) { - ErlSubBin* sb; - Uint size; + Uint bit_size; + Eterm result; CHECK_MATCH_BUFFER(mb); - size = mb->size-mb->offset; - sb = (ErlSubBin *) HeapOnlyAlloc(p, ERL_SUB_BIN_SIZE); - sb->thing_word = HEADER_SUB_BIN; - sb->size = BYTE_OFFSET(size); - sb->bitsize = BIT_OFFSET(size); - sb->offs = BYTE_OFFSET(mb->offset); - sb->bitoffs = BIT_OFFSET(mb->offset); - sb->is_writable = 0; - sb->orig = mb->orig; - mb->offset = mb->size; - return make_binary(sb); + bit_size = mb->size - mb->offset; + + result = erts_extract_sub_binary(&HEAP_TOP(p), + mb->orig, mb->base, + mb->offset, bit_size); + + mb->offset = mb->size; + + return result; } /**************************************************************** @@ -2097,3 +2090,39 @@ erts_copy_bits(byte* src, /* Base pointer to source. */ } } +Eterm erts_extract_sub_binary(Eterm **hp, Eterm base_bin, byte *base_data, + Uint bit_offset, Uint bit_size) +{ + Uint byte_offset, byte_size; + + ERTS_CT_ASSERT(ERL_SUB_BIN_SIZE <= ERL_ONHEAP_BIN_LIMIT); + + byte_offset = BYTE_OFFSET(bit_offset); + byte_size = BYTE_OFFSET(bit_size); + + if (BIT_OFFSET(bit_size) == 0 && byte_size <= ERL_ONHEAP_BIN_LIMIT) { + ErlHeapBin *hb = (ErlHeapBin*)*hp; + *hp += heap_bin_size(byte_size); + + hb->thing_word = header_heap_bin(byte_size); + hb->size = byte_size; + + copy_binary_to_buffer(hb->data, 0, base_data, bit_offset, bit_size); + + return make_binary(hb); + } else { + ErlSubBin *sb = (ErlSubBin*)*hp; + *hp += ERL_SUB_BIN_SIZE; + + sb->thing_word = HEADER_SUB_BIN; + sb->size = byte_size; + sb->offs = byte_offset; + sb->orig = base_bin; + sb->bitoffs = BIT_OFFSET(bit_offset); + sb->bitsize = BIT_OFFSET(bit_size); + sb->is_writable = 0; + + return make_binary(sb); + } +} + diff --git a/erts/emulator/beam/erl_bits.h b/erts/emulator/beam/erl_bits.h index 50d353e1fa..0b2a6f3760 100644 --- a/erts/emulator/beam/erl_bits.h +++ b/erts/emulator/beam/erl_bits.h @@ -116,7 +116,7 @@ typedef struct erl_bin_match_struct{ do { \ if (BIT_OFFSET(DstBufOffset) == 0 && (SrcBufferOffset == 0) && \ (BIT_OFFSET(NumBits)==0) && (NumBits != 0)) { \ - sys_memcpy(DstBuffer+BYTE_OFFSET(DstBufOffset), \ + sys_memcpy(((byte*)DstBuffer)+BYTE_OFFSET(DstBufOffset), \ SrcBuffer, NBYTES(NumBits)); \ } else { \ erts_copy_bits(SrcBuffer, SrcBufferOffset, 1, \ @@ -150,8 +150,11 @@ void erts_bits_destroy_state(ERL_BITS_PROTO_0); Eterm erts_bs_start_match_2(Process *p, Eterm Bin, Uint Max); ErlBinMatchState *erts_bs_start_match_3(Process *p, Eterm Bin); Eterm erts_bs_get_integer_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuffer* mb); -Eterm erts_bs_get_binary_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuffer* mb); Eterm erts_bs_get_float_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuffer* mb); + +/* These will create heap binaries when appropriate, so they require free space + * up to EXTRACT_SUB_BIN_HEAP_NEED. */ +Eterm erts_bs_get_binary_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuffer* mb); Eterm erts_bs_get_binary_all_2(Process *p, ErlBinMatchBuffer* mb); /* @@ -182,6 +185,17 @@ void erts_copy_bits(byte* src, size_t soffs, int sdir, byte* dst, size_t doffs,int ddir, size_t n); int erts_cmp_bits(byte* a_ptr, size_t a_offs, byte* b_ptr, size_t b_offs, size_t size); + +/* Extracts a region from base_bin as a sub-binary or heap binary, whichever + * is the most appropriate. + * + * The caller must ensure that there's enough free space at *hp */ +Eterm erts_extract_sub_binary(Eterm **hp, Eterm base_bin, byte *base_data, + Uint bit_offset, Uint num_bits); + +/* Pessimistic estimate of the words required for erts_extract_sub_binary */ +#define EXTRACT_SUB_BIN_HEAP_NEED (heap_bin_size(ERL_ONHEAP_BIN_LIMIT)) + /* * Flags for bs_get_* / bs_put_* / bs_init* instructions. */ diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c index d24f30f126..3c74ef493b 100644 --- a/erts/emulator/beam/erl_db.c +++ b/erts/emulator/beam/erl_db.c @@ -4415,7 +4415,7 @@ void db_info(fmtfn_t to, void *to_arg, int show) /* Called by break handler * pdbi.to_arg = to_arg; pdbi.show = show; - erts_db_foreach_table(db_info_print, &pdbi); + erts_db_foreach_table(db_info_print, &pdbi, !0); } Uint @@ -4428,7 +4428,7 @@ erts_get_ets_misc_mem_size(void) /* SMP Note: May only be used when system is locked */ void -erts_db_foreach_table(void (*func)(DbTable *, void *), void *arg) +erts_db_foreach_table(void (*func)(DbTable *, void *), void *arg, int alive_only) { int ix; @@ -4440,7 +4440,7 @@ erts_db_foreach_table(void (*func)(DbTable *, void *), void *arg) if (first) { DbTable *tb = first; do { - if (is_table_alive(tb)) + if (!alive_only || is_table_alive(tb)) (*func)(tb, arg); tb = tb->common.all.next; } while (tb != first); @@ -4457,6 +4457,15 @@ erts_db_foreach_offheap(DbTable *tb, tb->common.meth->db_foreach_offheap(tb, func, arg); } +void +erts_db_foreach_thr_prgr_offheap(void (*func)(ErlOffHeap *, void *), + void *arg) +{ + erts_db_foreach_thr_prgr_offheap_hash(func, arg); + erts_db_foreach_thr_prgr_offheap_tree(func, arg); + erts_db_foreach_thr_prgr_offheap_catree(func, arg); +} + /* retrieve max number of ets tables */ Uint erts_db_get_max_tabs() diff --git a/erts/emulator/beam/erl_db.h b/erts/emulator/beam/erl_db.h index b3dc1b9ba3..c604744687 100644 --- a/erts/emulator/beam/erl_db.h +++ b/erts/emulator/beam/erl_db.h @@ -114,10 +114,12 @@ void init_db(ErtsDbSpinCount); int erts_db_process_exiting(Process *, ErtsProcLocks, void **); int erts_db_execute_free_fixation(Process*, DbFixation*); void db_info(fmtfn_t, void *, int); -void erts_db_foreach_table(void (*)(DbTable *, void *), void *); +void erts_db_foreach_table(void (*)(DbTable *, void *), void *, int); void erts_db_foreach_offheap(DbTable *, void (*func)(ErlOffHeap *, void *), void *); +void erts_db_foreach_thr_prgr_offheap(void (*func)(ErlOffHeap *, void *), + void *); extern int erts_ets_rwmtx_spin_count; extern int user_requested_db_max_tabs; /* set in erl_init */ diff --git a/erts/emulator/beam/erl_db_catree.c b/erts/emulator/beam/erl_db_catree.c index fed4b44a9b..8a89eb72df 100644 --- a/erts/emulator/beam/erl_db_catree.c +++ b/erts/emulator/beam/erl_db_catree.c @@ -2395,6 +2395,34 @@ void db_calc_stats_catree(DbTableCATree* tb, DbCATreeStats* stats) } while (depth > 0); } +struct debug_catree_fa { + void (*func)(ErlOffHeap *, void *); + void *arg; +}; + +static void debug_free_route_node(void *vfap, ErtsThrPrgrVal val, void *vnp) +{ + DbTableCATreeNode *np = vnp; + if (np->u.route.key.oh) { + struct debug_catree_fa *fap = vfap; + ErlOffHeap oh; + ERTS_INIT_OFF_HEAP(&oh); + oh.first = np->u.route.key.oh; + (*fap->func)(&oh, fap->arg); + } +} + +void +erts_db_foreach_thr_prgr_offheap_catree(void (*func)(ErlOffHeap *, void *), + void *arg) +{ + struct debug_catree_fa fa; + fa.func = func; + fa.arg = arg; + erts_debug_later_op_foreach(do_free_route_node, debug_free_route_node, &fa); +} + + #ifdef HARDDEBUG /* diff --git a/erts/emulator/beam/erl_db_catree.h b/erts/emulator/beam/erl_db_catree.h index c2c884eee3..2ede85e04e 100644 --- a/erts/emulator/beam/erl_db_catree.h +++ b/erts/emulator/beam/erl_db_catree.h @@ -132,6 +132,9 @@ typedef struct { Uint max_depth; } DbCATreeStats; void db_calc_stats_catree(DbTableCATree*, DbCATreeStats*); +void +erts_db_foreach_thr_prgr_offheap_catree(void (*func)(ErlOffHeap *, void *), + void *arg); #endif /* _DB_CATREE_H */ diff --git a/erts/emulator/beam/erl_db_hash.c b/erts/emulator/beam/erl_db_hash.c index ceaccf7e44..44ecf7cce5 100644 --- a/erts/emulator/beam/erl_db_hash.c +++ b/erts/emulator/beam/erl_db_hash.c @@ -93,11 +93,9 @@ erts_flxctr_dec_read_centralized(&(DB)->common.counters, ERTS_DB_TABLE_NITEMS_COUNTER_ID) #define RESET_NITEMS(DB) \ erts_flxctr_reset(&(DB)->common.counters, ERTS_DB_TABLE_NITEMS_COUNTER_ID) -/* - * The following symbols can be manipulated to "tune" the linear hash array - */ + #define GROW_LIMIT(NACTIVE) ((NACTIVE)*1) -#define SHRINK_LIMIT(NACTIVE) ((NACTIVE) / 2) +#define SHRINK_LIMIT(TB) erts_atomic_read_nob(&(TB)->shrink_limit) /* ** We want the first mandatory segment to be small (to reduce minimal footprint) @@ -137,6 +135,11 @@ #define BUCKET(tb, i) SEGTAB(tb)[SLOT_IX_TO_SEG_IX(i)]->buckets[(i) & EXT_SEGSZ_MASK] +#ifdef DEBUG +# define DBG_BUCKET_INACTIVE ((HashDbTerm*)0xdead5107) +#endif + + /* * When deleting a table, the number of records to delete. * Approximate number, because we must delete entire buckets. @@ -377,7 +380,7 @@ typedef int (*extra_match_validator_t)(int keypos, Eterm match, Eterm guard, Ete */ static struct ext_segtab* alloc_ext_segtab(DbTableHash* tb, unsigned seg_ix); static void alloc_seg(DbTableHash *tb); -static int free_seg(DbTableHash *tb, int free_records); +static int free_seg(DbTableHash *tb); static HashDbTerm* next_live(DbTableHash *tb, Uint *iptr, erts_rwmtx_t** lck_ptr, HashDbTerm *list); static HashDbTerm* search_list(DbTableHash* tb, Eterm key, @@ -471,10 +474,8 @@ db_finalize_dbterm_hash(int cret, DbUpdateHandle* handle); static ERTS_INLINE void try_shrink(DbTableHash* tb) { - int nactive = NACTIVE(tb); int nitems = NITEMS(tb); - if (nactive > FIRST_SEGSZ && nitems < SHRINK_LIMIT(nactive) - && !IS_FIXED(tb)) { + if (nitems < SHRINK_LIMIT(tb) && !IS_FIXED(tb)) { shrink(tb, nitems); } } @@ -685,6 +686,7 @@ int db_create_hash(Process *p, DbTable *tbl) erts_atomic_init_nob(&tb->szm, FIRST_SEGSZ_MASK); erts_atomic_init_nob(&tb->nactive, FIRST_SEGSZ); + erts_atomic_init_nob(&tb->shrink_limit, 0); erts_atomic_init_nob(&tb->fixdel, (erts_aint_t)NULL); erts_atomic_init_nob(&tb->segtab, (erts_aint_t)NULL); SET_SEGTAB(tb, tb->first_segtab); @@ -771,7 +773,7 @@ static int db_next_hash(Process *p, DbTable *tbl, Eterm key, Eterm *ret) b = next_live(tb, &ix, &lck, b->next); if (tb->common.status & (DB_BAG | DB_DUPLICATE_BAG)) { while (b != 0) { - if (!has_live_key(tb, b, key, hval)) { + if (!has_key(tb, b, key, hval)) { break; } b = next_live(tb, &ix, &lck, b->next); @@ -781,6 +783,7 @@ static int db_next_hash(Process *p, DbTable *tbl, Eterm key, Eterm *ret) *ret = am_EOT; } else { + ASSERT(!is_pseudo_deleted(b)); *ret = db_copy_key(p, tbl, &b->dbterm); RUNLOCK_HASH(lck); } @@ -2466,7 +2469,7 @@ static SWord db_free_table_continue_hash(DbTable *tbl, SWord reds) erts_atomic_set_relb(&tb->fixdel, (erts_aint_t)NULL); while(tb->nslots != 0) { - reds -= EXT_SEGSZ/64 + free_seg(tb, 1); + reds -= EXT_SEGSZ/64 + free_seg(tb); /* * If we have done enough work, get out here. @@ -2664,6 +2667,34 @@ static struct ext_segtab* alloc_ext_segtab(DbTableHash* tb, unsigned seg_ix) return est; } +static void calc_shrink_limit(DbTableHash* tb) +{ + erts_aint_t shrink_limit; + + if (tb->nslots >= (FIRST_SEGSZ + 2*EXT_SEGSZ)) { + /* + * Start shrink when we can remove one extra segment + * and still remain below 50% load. + */ + shrink_limit = (tb->nslots - EXT_SEGSZ) / 2; + } + else { + /* + * But don't shrink below two segments. + * Why? In order to have chance of getting rid of the last extra segment, + * and rehash it into the first small segment, we either have to start + * early and do speculative joining of buckets or we have to join a lot + * of buckets during each delete-op. + * + * Instead keep segment #2 once allocated. I also think it's a good bet + * a shrinking large table will grow large again. + */ + shrink_limit = 0; + } + erts_atomic_set_nob(&tb->shrink_limit, shrink_limit); +} + + /* Extend table with one new segment */ static void alloc_seg(DbTableHash *tb) @@ -2682,8 +2713,17 @@ static void alloc_seg(DbTableHash *tb) segtab[seg_ix] = (struct segment*) erts_db_alloc(ERTS_ALC_T_DB_SEG, (DbTable *) tb, SIZEOF_SEGMENT(EXT_SEGSZ)); - sys_memset(segtab[seg_ix], 0, SIZEOF_SEGMENT(EXT_SEGSZ)); +#ifdef DEBUG + { + int i; + for (i = 0; i < EXT_SEGSZ; i++) { + segtab[seg_ix]->buckets[i] = DBG_BUCKET_INACTIVE; + } + } +#endif tb->nslots += EXT_SEGSZ; + + calc_shrink_limit(tb); } static void dealloc_ext_segtab(void* lop_data) @@ -2693,10 +2733,19 @@ static void dealloc_ext_segtab(void* lop_data) erts_free(ERTS_ALC_T_DB_SEG, est); } -/* Shrink table by freeing the top segment +struct dealloc_seg_ops { + struct segment* segp; + Uint seg_sz; + + struct ext_segtab* est; +}; + +/* Shrink table by removing the top segment ** free_records: 1=free any records in segment, 0=assume segment is empty +** ds_ops: (out) Instructions for dealloc_seg(). */ -static int free_seg(DbTableHash *tb, int free_records) +static int remove_seg(DbTableHash *tb, int free_records, + struct dealloc_seg_ops *ds_ops) { const int seg_ix = SLOT_IX_TO_SEG_IX(tb->nslots) - 1; struct segment** const segtab = SEGTAB(tb); @@ -2704,24 +2753,47 @@ static int free_seg(DbTableHash *tb, int free_records) Uint seg_sz; int nrecords = 0; + ERTS_LC_ASSERT(IS_TAB_WLOCKED(tb) || tb->common.status & DB_DELETE + || erts_atomic_read_nob(&tb->is_resizing)); + ASSERT(segp != NULL); -#ifndef DEBUG - if (free_records) -#endif - { - int i = (seg_ix == 0) ? FIRST_SEGSZ : EXT_SEGSZ; - while (i--) { - HashDbTerm* p = segp->buckets[i]; + if (free_records) { + int ix, n; + if (seg_ix == 0) { + /* First segment (always fully active) */ + n = FIRST_SEGSZ; + ix = FIRST_SEGSZ-1; + } + else if (NACTIVE(tb) < tb->nslots) { + /* Last extended segment partially active */ + n = (NACTIVE(tb) - FIRST_SEGSZ) & EXT_SEGSZ_MASK; + ix = (NACTIVE(tb)-1) & EXT_SEGSZ_MASK; + } + else { + /* Full extended segment */ + n = EXT_SEGSZ; + ix = EXT_SEGSZ - 1; + } + for ( ; n > 0; n--, ix--) { + HashDbTerm* p = segp->buckets[ix & EXT_SEGSZ_MASK]; while(p != 0) { HashDbTerm* nxt = p->next; - ASSERT(free_records); /* segment not empty as assumed? */ free_term(tb, p); p = nxt; ++nrecords; } } } - +#ifdef DEBUG + else { + int ix = (seg_ix == 0) ? FIRST_SEGSZ-1 : EXT_SEGSZ-1; + for ( ; ix >= 0; ix--) { + ASSERT(segp->buckets[ix] == DBG_BUCKET_INACTIVE); + } + } +#endif + + ds_ops->est = NULL; if (seg_ix >= NSEG_1) { struct ext_segtab* est = ErtsContainerStruct_(segtab,struct ext_segtab,segtab); @@ -2730,35 +2802,64 @@ static int free_seg(DbTableHash *tb, int free_records) SET_SEGTAB(tb, est->prev_segtab); tb->nsegs = est->prev_nsegs; - if (!tb->common.is_thread_safe) { - /* - * Table is doing a graceful shrink operation and we must avoid - * deallocating this segtab while it may still be read by other - * threads. Schedule deallocation with thread progress to make - * sure no lingering threads are still hanging in BUCKET macro - * with an old segtab pointer. - */ - erts_schedule_db_free(&tb->common, dealloc_ext_segtab, - est, &est->lop, - SIZEOF_EXT_SEGTAB(est->nsegs)); - } - else - erts_db_free(ERTS_ALC_T_DB_SEG, (DbTable*)tb, est, - SIZEOF_EXT_SEGTAB(est->nsegs)); + ds_ops->est = est; } } + seg_sz = (seg_ix == 0) ? FIRST_SEGSZ : EXT_SEGSZ; - erts_db_free(ERTS_ALC_T_DB_SEG, (DbTable *)tb, segp, SIZEOF_SEGMENT(seg_sz)); + tb->nslots -= seg_sz; + ASSERT(tb->nslots >= 0); + + ds_ops->segp = segp; + ds_ops->seg_sz = seg_sz; #ifdef DEBUG if (seg_ix < tb->nsegs) SEGTAB(tb)[seg_ix] = NULL; #endif - tb->nslots -= seg_sz; - ASSERT(tb->nslots >= 0); + calc_shrink_limit(tb); return nrecords; } +/* + * Deallocate segment removed by remove_seg() + */ +static void dealloc_seg(DbTableHash *tb, struct dealloc_seg_ops* ds_ops) +{ + struct ext_segtab* est = ds_ops->est; + + if (est) { + if (!tb->common.is_thread_safe) { + /* + * Table is doing a graceful shrink operation and we must avoid + * deallocating this segtab while it may still be read by other + * threads. Schedule deallocation with thread progress to make + * sure no lingering threads are still hanging in BUCKET macro + * with an old segtab pointer. + */ + erts_schedule_db_free(&tb->common, dealloc_ext_segtab, + est, &est->lop, + SIZEOF_EXT_SEGTAB(est->nsegs)); + } + else + erts_db_free(ERTS_ALC_T_DB_SEG, (DbTable*)tb, est, + SIZEOF_EXT_SEGTAB(est->nsegs)); + } + + erts_db_free(ERTS_ALC_T_DB_SEG, (DbTable *)tb, + ds_ops->segp, SIZEOF_SEGMENT(ds_ops->seg_sz)); +} + +/* Remove and deallocate top segment and all its contained objects */ +static int free_seg(DbTableHash *tb) +{ + struct dealloc_seg_ops ds_ops; + int reds; + + reds = remove_seg(tb, 1, &ds_ops); + dealloc_seg(tb, &ds_ops); + return reds; +} /* ** Copy terms from ptr1 until ptr2 @@ -2880,6 +2981,7 @@ static void grow(DbTableHash* tb, int nitems) pnext = &BUCKET(tb, from_ix); p = *pnext; to_pnext = &BUCKET(tb, to_ix); + ASSERT(*to_pnext == DBG_BUCKET_INACTIVE); while (p != NULL) { if (is_pseudo_deleted(p)) { /* rare but possible with fine locking */ *pnext = p->next; @@ -2916,19 +3018,21 @@ abort: */ static void shrink(DbTableHash* tb, int nitems) { - HashDbTerm** src_bp; - HashDbTerm** dst_bp; + struct dealloc_seg_ops ds_ops; + HashDbTerm* src; + HashDbTerm* tail; HashDbTerm** bp; erts_rwmtx_t* lck; int src_ix, dst_ix, low_szm; int nactive; int loop_limit = 5; + ds_ops.segp = NULL; do { if (!begin_resizing(tb)) return; /* already in progress */ nactive = NACTIVE(tb); - if (!(nactive > FIRST_SEGSZ && nitems < SHRINK_LIMIT(nactive))) { + if (!(nitems < SHRINK_LIMIT(tb))) { goto abort; /* already done (race) */ } src_ix = nactive - 1; @@ -2945,41 +3049,49 @@ static void shrink(DbTableHash* tb, int nitems) goto abort; } - src_bp = &BUCKET(tb, src_ix); - dst_bp = &BUCKET(tb, dst_ix); - bp = src_bp; - - /* - * We join lists by appending "dst" at the end of "src" - * as we must step through "src" anyway to purge pseudo deleted. - */ - while(*bp != NULL) { - if (is_pseudo_deleted(*bp)) { - HashDbTerm* deleted = *bp; - *bp = deleted->next; - free_term(tb, deleted); - } else { - bp = &(*bp)->next; - } - } - *bp = *dst_bp; - *dst_bp = *src_bp; - *src_bp = NULL; - + src = BUCKET(tb, src_ix); +#ifdef DEBUG + BUCKET(tb, src_ix) = DBG_BUCKET_INACTIVE; +#endif nactive = src_ix; erts_atomic_set_nob(&tb->nactive, nactive); if (dst_ix == 0) { erts_atomic_set_relb(&tb->szm, low_szm); } - WUNLOCK_HASH(lck); - if (tb->nslots - src_ix >= EXT_SEGSZ) { - free_seg(tb, 0); + remove_seg(tb, 0, &ds_ops); } done_resizing(tb); - } while (--loop_limit - && nactive > FIRST_SEGSZ && nitems < SHRINK_LIMIT(nactive)); + if (src) { + /* + * We join buckets by appending "dst" list at the end of "src" list + * as we must step through "src" anyway to purge pseudo deleted. + */ + bp = &BUCKET(tb, dst_ix); + tail = *bp; + *bp = src; + + while(*bp != NULL) { + if (is_pseudo_deleted(*bp)) { + HashDbTerm* deleted = *bp; + *bp = deleted->next; + free_term(tb, deleted); + } else { + bp = &(*bp)->next; + } + } + *bp = tail; + } + + WUNLOCK_HASH(lck); + + if (ds_ops.segp) { + dealloc_seg(tb, &ds_ops); + ds_ops.segp = NULL; + } + + } while (--loop_limit && nitems < SHRINK_LIMIT(tb)); return; abort: @@ -3262,6 +3374,12 @@ Eterm erts_ets_hash_sizeof_ext_segtab(void) return make_small(((SIZEOF_EXT_SEGTAB(0)-1) / sizeof(UWord)) + 1); } +void +erts_db_foreach_thr_prgr_offheap_hash(void (*func)(ErlOffHeap *, void *), + void *arg) +{ +} + #ifdef ERTS_ENABLE_LOCK_COUNT void erts_lcnt_enable_db_hash_lock_count(DbTableHash *tb, int enable) { int i; diff --git a/erts/emulator/beam/erl_db_hash.h b/erts/emulator/beam/erl_db_hash.h index eae5537ba4..b26b82056f 100644 --- a/erts/emulator/beam/erl_db_hash.h +++ b/erts/emulator/beam/erl_db_hash.h @@ -63,9 +63,10 @@ typedef struct db_table_hash_fine_locks { typedef struct db_table_hash { DbTableCommon common; - /* SMP: szm and nactive are write-protected by is_resizing or table write lock */ + /* szm, nactive, shrink_limit are write-protected by is_resizing or table write lock */ erts_atomic_t szm; /* current size mask. */ erts_atomic_t nactive; /* Number of "active" slots */ + erts_atomic_t shrink_limit; /* Shrink table when fewer objects than this */ erts_atomic_t segtab; /* The segment table (struct segment**) */ struct segment* first_segtab[1]; @@ -110,6 +111,9 @@ typedef struct { void db_calc_stats_hash(DbTableHash* tb, DbHashStats*); Eterm erts_ets_hash_sizeof_ext_segtab(void); +void +erts_db_foreach_thr_prgr_offheap_hash(void (*func)(ErlOffHeap *, void *), + void *arg); #ifdef ERTS_ENABLE_LOCK_COUNT void erts_lcnt_enable_db_hash_lock_count(DbTableHash *tb, int enable); diff --git a/erts/emulator/beam/erl_db_tree.c b/erts/emulator/beam/erl_db_tree.c index 492ea81b63..19b94b0634 100644 --- a/erts/emulator/beam/erl_db_tree.c +++ b/erts/emulator/beam/erl_db_tree.c @@ -3936,6 +3936,12 @@ static int doit_select_replace(DbTableCommon *tb, TreeDbTerm **this, return 1; } +void +erts_db_foreach_thr_prgr_offheap_tree(void (*func)(ErlOffHeap *, void *), + void *arg) +{ +} + #ifdef TREE_DEBUG static void do_dump_tree2(DbTableCommon* tb, int to, void *to_arg, int show, TreeDbTerm *t, int offset) diff --git a/erts/emulator/beam/erl_db_tree.h b/erts/emulator/beam/erl_db_tree.h index 54da2a6bc1..06e0005801 100644 --- a/erts/emulator/beam/erl_db_tree.h +++ b/erts/emulator/beam/erl_db_tree.h @@ -53,4 +53,8 @@ void db_initialize_tree(void); int db_create_tree(Process *p, DbTable *tbl); +void +erts_db_foreach_thr_prgr_offheap_tree(void (*func)(ErlOffHeap *, void *), + void *arg); + #endif /* _DB_TREE_H */ diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c index 67a73e4d57..13b1f8ab4d 100644 --- a/erts/emulator/beam/erl_gc.c +++ b/erts/emulator/beam/erl_gc.c @@ -151,6 +151,7 @@ static void grow_new_heap(Process *p, Uint new_sz, Eterm* objv, int nobj); static void sweep_off_heap(Process *p, int fullsweep); static void offset_heap(Eterm* hp, Uint sz, Sint offs, char* area, Uint area_size); static void offset_heap_ptr(Eterm* hp, Uint sz, Sint offs, char* area, Uint area_size); +static void offset_heap_ptr_nstack(Eterm* hp, Uint sz, Sint offs, char* area, Uint area_size); static void offset_rootset(Process *p, Sint offs, char* area, Uint area_size, Eterm* objv, int nobj); static void offset_off_heap(Process* p, Sint offs, char* area, Uint area_size); @@ -1054,9 +1055,10 @@ erts_garbage_collect_hibernate(Process* p) n_htop = tmp_n_htop; \ } while(0) + /* * offset_nstack() can ignore the descriptor-based traversal the other - * nstack procedures use and simply call offset_heap_ptr() instead. + * nstack procedures use and do a simpler word by word traversal instead. * This relies on two facts: * 1. The only live non-Erlang terms on an nstack are return addresses, * and they will be skipped thanks to the low/high range check. @@ -1071,14 +1073,51 @@ static ERTS_INLINE void offset_nstack(Process* p, Sint offs, { if (p->hipe.nstack) { ASSERT(p->hipe.nsp && p->hipe.nstend); - offset_heap_ptr(hipe_nstack_start(p), hipe_nstack_used(p), - offs, area, area_size); + offset_heap_ptr_nstack(hipe_nstack_start(p), hipe_nstack_used(p), + offs, area, area_size); } else { ASSERT(!p->hipe.nsp && !p->hipe.nstend); } } +/* + * This is the same as offset_heap_ptr() + * + * Except for VALGRIND. It allows benign offsetting of undefined (dead) words + * on the nstack while also retaining them as undefined. This suppresses + * valgrinds "Conditional jump or move depends on uninitialised value(s)". + */ +static void +offset_heap_ptr_nstack(Eterm* hp, Uint sz, Sint offs, + char* area, Uint area_size) +{ + while (sz--) { + Eterm val = *hp; +#ifdef VALGRIND + Eterm val_vbits; + VALGRIND_GET_VBITS(&val, &val_vbits, sizeof(val)); + VALGRIND_MAKE_MEM_DEFINED(&val, sizeof(val)); +#endif + switch (primary_tag(val)) { + case TAG_PRIMARY_LIST: + case TAG_PRIMARY_BOXED: + if (ErtsInArea(ptr_val(val), area, area_size)) { +#ifdef VALGRIND + VALGRIND_SET_VBITS(&val, val_vbits, sizeof(val)); +#endif + *hp = offset_ptr(val, offs); + } + hp++; + break; + default: + hp++; + break; + } + } +} + + #else /* !HIPE */ #define fullsweep_nstack(p,n_htop) (n_htop) @@ -2848,7 +2887,7 @@ sweep_off_heap(Process *p, int fullsweep) if (is_external_header(((struct erl_off_heap_header*) boxed_val(ptr->thing_word))->thing_word)) erts_node_bookkeep(((ExternalThing*)ptr)->node, make_boxed(&ptr->thing_word), - ERL_NODE_DEC); + ERL_NODE_DEC, __FILE__, __LINE__); *prev = ptr = (struct erl_off_heap_header*) boxed_val(ptr->thing_word); ASSERT(!IS_MOVED_BOXED(ptr->thing_word)); switch (ptr->thing_word) { @@ -2879,7 +2918,7 @@ sweep_off_heap(Process *p, int fullsweep) if (is_external_header(ptr->thing_word)) { erts_node_bookkeep(((ExternalThing*)ptr)->node, make_boxed(&ptr->thing_word), - ERL_NODE_INC); + ERL_NODE_INC, __FILE__, __LINE__); } prev = &ptr->next; ptr = ptr->next; @@ -3050,9 +3089,11 @@ offset_heap(Eterm* hp, Uint sz, Sint offs, char* area, Uint area_size) if (is_external_header(oh->thing_word)) { erts_node_bookkeep(((ExternalThing*)oh)->node, - make_boxed(((Eterm*)oh)-offs), ERL_NODE_DEC); + make_boxed(((Eterm*)oh)-offs), + ERL_NODE_DEC, __FILE__, __LINE__); erts_node_bookkeep(((ExternalThing*)oh)->node, - make_boxed((Eterm*)oh), ERL_NODE_INC); + make_boxed((Eterm*)oh), ERL_NODE_INC, + __FILE__, __LINE__); } if (ErtsInArea(oh->next, area, area_size)) { diff --git a/erts/emulator/beam/erl_monitor_link.c b/erts/emulator/beam/erl_monitor_link.c index 1c6b4afaa3..43028be39d 100644 --- a/erts/emulator/beam/erl_monitor_link.c +++ b/erts/emulator/beam/erl_monitor_link.c @@ -671,6 +671,24 @@ erts_monitor_tree_foreach(ErtsMonitor *root, arg); } +void +erts_debug_monitor_tree_destroying_foreach(ErtsMonitor *root, + ErtsMonitorFunc func, + void *arg, + void *vysp) +{ + void *tmp_vysp = erts_alloc(ERTS_ALC_T_ML_YIELD_STATE, + sizeof(ErtsMonLnkYieldState)); + Sint reds; + sys_memcpy(tmp_vysp, tmp_vysp, sizeof(ErtsMonLnkYieldState)); + do { + reds = ml_rbt_foreach_yielding((ErtsMonLnkNode *) root, + (ErtsMonLnkNodeFunc) func, + arg, &tmp_vysp, (Sint) INT_MAX); + } while (reds <= 0); + ERTS_ML_ASSERT(!tmp_vysp); +} + int erts_monitor_tree_foreach_yielding(ErtsMonitor *root, ErtsMonitorFunc func, @@ -716,6 +734,19 @@ erts_monitor_list_foreach(ErtsMonitor *list, arg, &ystate, (Sint) INT_MAX)); } +void +erts_debug_monitor_list_destroying_foreach(ErtsMonitor *list, + ErtsMonitorFunc func, + void *arg, + void *vysp) +{ + void *tmp_vysp = vysp; + while (!ml_dl_list_foreach_yielding((ErtsMonLnkNode *) list, + (int (*)(ErtsMonLnkNode *, void *, Sint)) func, + arg, &tmp_vysp, (Sint) INT_MAX)); + ERTS_ML_ASSERT(!tmp_vysp); +} + int erts_monitor_list_foreach_yielding(ErtsMonitor *list, ErtsMonitorFunc func, @@ -1080,6 +1111,24 @@ erts_link_tree_foreach(ErtsLink *root, } +void +erts_debug_link_tree_destroying_foreach(ErtsLink *root, + ErtsLinkFunc func, + void *arg, + void *vysp) +{ + void *tmp_vysp = erts_alloc(ERTS_ALC_T_ML_YIELD_STATE, + sizeof(ErtsMonLnkYieldState)); + Sint reds; + sys_memcpy(tmp_vysp, vysp, sizeof(ErtsMonLnkYieldState)); + do { + reds = ml_rbt_foreach_yielding((ErtsMonLnkNode *) root, + (ErtsMonLnkNodeFunc) func, + arg, &tmp_vysp, (Sint) INT_MAX); + } while (reds <= 0); + ERTS_ML_ASSERT(!tmp_vysp); +} + int erts_link_tree_foreach_yielding(ErtsLink *root, ErtsLinkFunc func, diff --git a/erts/emulator/beam/erl_monitor_link.h b/erts/emulator/beam/erl_monitor_link.h index eff861fce8..86be400c09 100644 --- a/erts/emulator/beam/erl_monitor_link.h +++ b/erts/emulator/beam/erl_monitor_link.h @@ -1509,6 +1509,17 @@ ERTS_GLB_INLINE ErtsMonitorSuspend *erts_monitor_suspend(ErtsMonitor *mon) #endif +void +erts_debug_monitor_tree_destroying_foreach(ErtsMonitor *root, + ErtsMonitorFunc func, + void *arg, + void *vysp); +void +erts_debug_monitor_list_destroying_foreach(ErtsMonitor *list, + ErtsMonitorFunc func, + void *arg, + void *vysp); + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * Link Operations * \* */ @@ -2365,4 +2376,10 @@ erts_link_dist_delete(ErtsLink *lnk) #endif /* ERTS_GLB_INLINE_INCL_FUNC_DEF */ +void +erts_debug_link_tree_destroying_foreach(ErtsLink *root, + ErtsLinkFunc func, + void *arg, + void *vysp); + #endif /* ERL_MONITOR_LINK_H__ */ diff --git a/erts/emulator/beam/erl_node_tables.c b/erts/emulator/beam/erl_node_tables.c index 4eb6c3e214..285252a53e 100644 --- a/erts/emulator/beam/erl_node_tables.c +++ b/erts/emulator/beam/erl_node_tables.c @@ -932,7 +932,8 @@ static void try_delete_node(void *venp) * * If refc > 0, the entry is in use. Keep the entry. */ - erts_node_bookkeep(enp, THE_NON_VALUE, ERL_NODE_DEC); + erts_node_bookkeep(enp, THE_NON_VALUE, ERL_NODE_DEC, + __FILE__, __LINE__); refc = erts_refc_dectest(&enp->refc, -1); if (refc == -1) (void) hash_erase(&erts_node_table, (void *) enp); @@ -976,7 +977,7 @@ static void print_node(void *venp, void *vpndp) if(pndp->sysname == NIL) { erts_print(pndp->to, pndp->to_arg, "Name: %T ", enp->sysname); } - erts_print(pndp->to, pndp->to_arg, " %d", enp->creation); + erts_print(pndp->to, pndp->to_arg, " %u", enp->creation); #ifdef DEBUG erts_print(pndp->to, pndp->to_arg, " (refc=%ld)", erts_refc_read(&enp->refc, 0)); @@ -1019,7 +1020,7 @@ void erts_print_node_info(fmtfn_t to, /* ----------------------------------------------------------------------- */ void -erts_set_this_node(Eterm sysname, Uint creation) +erts_set_this_node(Eterm sysname, Uint32 creation) { ERTS_LC_ASSERT(erts_thr_progress_is_blocking()); ASSERT(2 <= de_refc_read(erts_this_dist_entry, 2)); @@ -1164,6 +1165,12 @@ void erts_lcnt_update_distribution_locks(int enable) { * can damage the real-time properties of the system. * \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +#ifdef ERL_NODE_BOOKKEEP +#define ERTS_DBG_NC_ALLOC_TYPE ERTS_ALC_T_NC_STD +#else +#define ERTS_DBG_NC_ALLOC_TYPE ERTS_ALC_T_NC_TMP +#endif + #include "erl_db.h" #undef INIT_AM @@ -1188,10 +1195,12 @@ static Eterm AM_delayed_delete_timer; static Eterm AM_thread_progress_delete_timer; static Eterm AM_sequence; static Eterm AM_signal; +static Eterm AM_persistent_term; static void setup_reference_table(void); static Eterm reference_table_term(Uint **hpp, ErlOffHeap *ohp, Uint *szp); static void delete_reference_table(void); +static void clear_system(void); #undef ERTS_MAX__ #define ERTS_MAX__(A, B) ((A) > (B) ? (A) : (B)) @@ -1244,11 +1253,11 @@ typedef struct inserted_bin_ { Binary *bin_val; } InsertedBin; -static ReferredNode *referred_nodes; +static ReferredNode *referred_nodes = NULL; static int no_referred_nodes; -static ReferredDist *referred_dists; +static ReferredDist *referred_dists = NULL; static int no_referred_dists; -static InsertedBin *inserted_bins; +static InsertedBin *inserted_bins = NULL; Eterm erts_get_node_and_dist_references(struct process *proc) @@ -1284,9 +1293,15 @@ erts_get_node_and_dist_references(struct process *proc) INIT_AM(thread_progress_delete_timer); INIT_AM(signal); INIT_AM(sequence); + INIT_AM(persistent_term); references_atoms_need_init = 0; } +#ifdef ERL_NODE_BOOKKEEP + if (referred_nodes || referred_dists || inserted_bins) + delete_reference_table(); +#endif + setup_reference_table(); /* Get term size */ @@ -1304,7 +1319,11 @@ erts_get_node_and_dist_references(struct process *proc) ASSERT(endp == hp); +#ifndef ERL_NODE_BOOKKEEP delete_reference_table(); +#endif + + clear_system(); erts_thr_progress_unblock(); erts_proc_lock(proc, ERTS_PROC_LOCK_MAIN); @@ -1339,7 +1358,7 @@ insert_dist_referrer(ReferredDist *referred_dist, break; if(!drp) { - drp = (DistReferrer *) erts_alloc(ERTS_ALC_T_NC_TMP, + drp = (DistReferrer *) erts_alloc(ERTS_DBG_NC_ALLOC_TYPE, sizeof(DistReferrer)); drp->next = referred_dist->referrers; referred_dist->referrers = drp; @@ -1402,7 +1421,7 @@ insert_node_referrer(ReferredNode *referred_node, int type, Eterm id) break; if(!nrp) { - nrp = (NodeReferrer *) erts_alloc(ERTS_ALC_T_NC_TMP, + nrp = (NodeReferrer *) erts_alloc(ERTS_DBG_NC_ALLOC_TYPE, sizeof(NodeReferrer)); nrp->next = referred_node->referrers; ERTS_INIT_OFF_HEAP(&nrp->off_heap); @@ -1516,7 +1535,8 @@ insert_offheap(ErlOffHeap *oh, int type, Eterm id) erts_match_prog_foreach_offheap((Binary *) u.mref->mb, insert_offheap2, (void *) &a); - nib = erts_alloc(ERTS_ALC_T_NC_TMP, sizeof(InsertedBin)); + nib = erts_alloc(ERTS_DBG_NC_ALLOC_TYPE, + sizeof(InsertedBin)); nib->bin_val = (Binary *) u.mref->mb; nib->next = inserted_bins; inserted_bins = nib; @@ -1574,18 +1594,6 @@ static int clear_visited_monitor(ErtsMonitor *mon, void *p, Sint reds) } static void -insert_p_monitors(ErtsPTabElementCommon *p) -{ - Eterm id = p->id; - erts_monitor_tree_foreach(p->u.alive.monitors, - insert_monitor, - (void *) &id); - erts_monitor_list_foreach(p->u.alive.lt_monitors, - insert_monitor, - (void *) &id); -} - -static void insert_dist_monitors(DistEntry *dep) { if (dep->mld) { @@ -1600,8 +1608,10 @@ insert_dist_monitors(DistEntry *dep) static int -insert_sequence(ErtsDistExternal *edep, void *arg, Sint reds) +insert_sequence(DistSeqNode *seq, void *arg, Sint reds) { + ErtsDistExternal *edep = erts_get_dist_ext(&seq->hfrag); + insert_offheap(&seq->hfrag.off_heap, SEQUENCE_REF, *(Eterm*)arg); insert_dist_entry(edep->dep, SEQUENCE_REF, *(Eterm*)arg, 0); return 1; } @@ -1609,18 +1619,7 @@ insert_sequence(ErtsDistExternal *edep, void *arg, Sint reds) static void insert_dist_sequences(DistEntry *dep) { - erts_dist_seq_tree_foreach(dep, insert_sequence, (void *) &dep->sysname); -} - -static void -clear_visited_p_monitors(ErtsPTabElementCommon *p) -{ - erts_monitor_tree_foreach(p->u.alive.monitors, - clear_visited_monitor, - NULL); - erts_monitor_list_foreach(p->u.alive.lt_monitors, - clear_visited_monitor, - NULL); + erts_debug_dist_seq_tree_foreach(dep, insert_sequence, (void *) &dep->sysname); } static void @@ -1667,13 +1666,6 @@ static int clear_visited_link(ErtsLink *lnk, void *p, Sint reds) } static void -insert_p_links(ErtsPTabElementCommon *p) -{ - Eterm id = p->id; - erts_link_tree_foreach(p->u.alive.links, insert_link, (void *) &id); -} - -static void insert_dist_links(DistEntry *dep) { if (dep->mld) @@ -1683,14 +1675,6 @@ insert_dist_links(DistEntry *dep) } static void -clear_visited_p_links(ErtsPTabElementCommon *p) -{ - erts_link_tree_foreach(p->u.alive.links, - clear_visited_link, - NULL); -} - -static void clear_visited_dist_links(DistEntry *dep) { if (dep->mld) @@ -1885,15 +1869,11 @@ insert_process(Process *proc) insert_sig_ext, (void *) proc); - /* If the process is FREE, the proc->common field has been - re-used by the ptab delete, so we cannot trust it. */ - if (!(erts_atomic32_read_nob(&proc->state) & ERTS_PSFLG_FREE)) { - /* Insert links */ - insert_p_links(&proc->common); - - /* Insert monitors */ - insert_p_monitors(&proc->common); - } + /* Insert monitors and links... */ + erts_debug_proc_monitor_link_foreach(proc, + insert_monitor, + insert_link, + (void *) &proc->common.id); { DistEntry *dep = ERTS_PROC_GET_DIST_ENTRY(proc); @@ -1906,6 +1886,12 @@ insert_process(Process *proc) } static void +insert_process2(Process *proc, void *arg) +{ + insert_process(proc); +} + +static void insert_dist_suspended_procs(DistEntry *dep) { ErtsProcList *plist = erts_proclist_peek_first(dep->suspended); @@ -1916,16 +1902,47 @@ insert_dist_suspended_procs(DistEntry *dep) } } +static void clear_process(Process *proc); + +static void +clear_dist_suspended_procs(DistEntry *dep) +{ + ErtsProcList *plist = erts_proclist_peek_first(dep->suspended); + while (plist) { + if (is_not_immed(plist->u.pid)) + clear_process(plist->u.p); + plist = erts_proclist_peek_next(dep->suspended, plist); + } +} + +static void +insert_persistent_term(ErlOffHeap *ohp, void *arg) +{ + Eterm heap[3]; + insert_offheap(ohp, SYSTEM_REF, + TUPLE2(&heap[0], AM_system, AM_persistent_term)); +} + +static void +insert_ets_offheap_thr_prgr(ErlOffHeap *ohp, void *arg) +{ + Eterm heap[3]; + insert_offheap(ohp, ETS_REF, + TUPLE2(&heap[0], AM_system, AM_ets)); +} + #ifdef ERL_NODE_BOOKKEEP void -erts_node_bookkeep(ErlNode *np, Eterm term, int what) +erts_node_bookkeep(ErlNode *np, Eterm term, int what, char *f, int l) { - erts_aint_t slot = (erts_atomic_inc_read_nob(&np->slot) - 1) % 1024; + erts_aint_t slot = (erts_atomic_inc_read_nob(&np->slot) - 1) % ERTS_BOOKKEEP_SIZE; ErtsSchedulerData *esdp = erts_get_scheduler_data(); Eterm who = THE_NON_VALUE; ASSERT(np); np->books[slot].what = what; np->books[slot].term = term; + np->books[slot].file = f; + np->books[slot].line = l; if (esdp->current_process) { who = esdp->current_process->common.id; } else if (esdp->current_port) { @@ -1946,14 +1963,14 @@ setup_reference_table(void) inserted_bins = NULL; hash_get_info(&hi, &erts_node_table); - referred_nodes = erts_alloc(ERTS_ALC_T_NC_TMP, + referred_nodes = erts_alloc(ERTS_DBG_NC_ALLOC_TYPE, hi.objs*sizeof(ReferredNode)); no_referred_nodes = 0; hash_foreach(&erts_node_table, init_referred_node, NULL); ASSERT(no_referred_nodes == hi.objs); hash_get_info(&hi, &erts_dist_table); - referred_dists = erts_alloc(ERTS_ALC_T_NC_TMP, + referred_dists = erts_alloc(ERTS_DBG_NC_ALLOC_TYPE, hi.objs*sizeof(ReferredDist)); no_referred_dists = 0; hash_foreach(&erts_dist_table, init_referred_dist, NULL); @@ -1990,8 +2007,9 @@ setup_reference_table(void) if (proc) insert_process(proc); } + erts_debug_free_process_foreach(insert_process2, NULL); - erts_foreach_sys_msg_in_q(insert_sys_msg); + erts_debug_foreach_sys_msg_in_q(insert_sys_msg); /* Insert all ports */ max = erts_ptab_max(&erts_port); @@ -2008,10 +2026,18 @@ setup_reference_table(void) if (state & ERTS_PORT_SFLGS_DEAD) continue; - /* Insert links */ - insert_p_links(&prt->common); - /* Insert monitors */ - insert_p_monitors(&prt->common); + /* Insert links */ + erts_link_tree_foreach(ERTS_P_LINKS(prt), + insert_link, + (void *) &prt->common.id); + /* Insert monitors */ + erts_monitor_tree_foreach(ERTS_P_MONITORS(prt), + insert_monitor, + (void *) &prt->common.id); + /* Insert local target monitors */ + erts_monitor_list_foreach(ERTS_P_LT_MONITORS(prt), + insert_monitor, + (void *) &prt->common.id); /* Insert port data */ ohp = erts_port_data_offheap(prt); if (ohp) @@ -2091,11 +2117,16 @@ setup_reference_table(void) } /* Insert all ets tables */ - erts_db_foreach_table(insert_ets_table, NULL); + erts_db_foreach_table(insert_ets_table, NULL, 0); + erts_db_foreach_thr_prgr_offheap(insert_ets_offheap_thr_prgr, NULL); /* Insert all bif timers */ erts_debug_bif_timer_foreach(insert_bif_timer, NULL); + /* Insert persistent term storage */ + erts_debug_foreach_persistent_term_off_heap(insert_persistent_term, + NULL); + /* Insert node table (references to dist) */ hash_foreach(&erts_node_table, insert_erl_node, NULL); } @@ -2348,8 +2379,7 @@ static void noop_sig_ext(ErtsDistExternal *ext, void *arg) static void delete_reference_table(void) { - DistEntry *dep; - int i, max; + int i; for(i = 0; i < no_referred_nodes; i++) { NodeReferrer *nrp; NodeReferrer *tnrp; @@ -2358,11 +2388,13 @@ delete_reference_table(void) erts_cleanup_offheap(&nrp->off_heap); tnrp = nrp; nrp = nrp->next; - erts_free(ERTS_ALC_T_NC_TMP, (void *) tnrp); + erts_free(ERTS_DBG_NC_ALLOC_TYPE, (void *) tnrp); } } - if (referred_nodes) - erts_free(ERTS_ALC_T_NC_TMP, (void *) referred_nodes); + if (referred_nodes) { + erts_free(ERTS_DBG_NC_ALLOC_TYPE, (void *) referred_nodes); + referred_nodes = NULL; + } for(i = 0; i < no_referred_dists; i++) { DistReferrer *drp; @@ -2371,34 +2403,57 @@ delete_reference_table(void) while(drp) { tdrp = drp; drp = drp->next; - erts_free(ERTS_ALC_T_NC_TMP, (void *) tdrp); + erts_free(ERTS_DBG_NC_ALLOC_TYPE, (void *) tdrp); } } - if (referred_dists) - erts_free(ERTS_ALC_T_NC_TMP, (void *) referred_dists); + if (referred_dists) { + erts_free(ERTS_DBG_NC_ALLOC_TYPE, (void *) referred_dists); + referred_dists = NULL; + } while(inserted_bins) { InsertedBin *ib = inserted_bins; inserted_bins = inserted_bins->next; - erts_free(ERTS_ALC_T_NC_TMP, (void *)ib); + erts_free(ERTS_DBG_NC_ALLOC_TYPE, (void *)ib); } +} + +static void clear_process(Process *proc) +{ + erts_proc_sig_debug_foreach_sig(proc, + noop_sig_msg, + noop_sig_offheap, + clear_visited_monitor, + clear_visited_link, + noop_sig_ext, + (void *) proc); + + + /* Clear monitors and links... */ + erts_debug_proc_monitor_link_foreach(proc, + clear_visited_monitor, + clear_visited_link, + (void *) &proc->common.id); +} + +static void clear_process2(Process *proc, void *arg) +{ + clear_process(proc); +} - /* Cleanup... */ +static void +clear_system(void) +{ + DistEntry *dep; + int i, max; + /* Clear... */ max = erts_ptab_max(&erts_proc); for (i = 0; i < max; i++) { Process *proc = erts_pix2proc(i); - if (proc) { - clear_visited_p_links(&proc->common); - clear_visited_p_monitors(&proc->common); - erts_proc_sig_debug_foreach_sig(proc, - noop_sig_msg, - noop_sig_offheap, - clear_visited_monitor, - clear_visited_link, - noop_sig_ext, - (void *) proc); - } + if (proc) + clear_process(proc); } + erts_debug_free_process_foreach(clear_process2, NULL); max = erts_ptab_max(&erts_port); for (i = 0; i < max; i++) { @@ -2413,28 +2468,42 @@ delete_reference_table(void) if (state & ERTS_PORT_SFLGS_DEAD) continue; - clear_visited_p_links(&prt->common); - clear_visited_p_monitors(&prt->common); + /* Clear links */ + erts_link_tree_foreach(ERTS_P_LINKS(prt), + clear_visited_link, + (void *) &prt->common.id); + /* Clear monitors */ + erts_monitor_tree_foreach(ERTS_P_MONITORS(prt), + clear_visited_monitor, + (void *) &prt->common.id); + /* Clear local target monitors */ + erts_monitor_list_foreach(ERTS_P_LT_MONITORS(prt), + clear_visited_monitor, + (void *) &prt->common.id); } for(dep = erts_visible_dist_entries; dep; dep = dep->next) { clear_visited_dist_links(dep); clear_visited_dist_monitors(dep); + clear_dist_suspended_procs(dep); } for(dep = erts_hidden_dist_entries; dep; dep = dep->next) { clear_visited_dist_links(dep); clear_visited_dist_monitors(dep); + clear_dist_suspended_procs(dep); } for(dep = erts_pending_dist_entries; dep; dep = dep->next) { clear_visited_dist_links(dep); clear_visited_dist_monitors(dep); + clear_dist_suspended_procs(dep); } for(dep = erts_not_connected_dist_entries; dep; dep = dep->next) { clear_visited_dist_links(dep); clear_visited_dist_monitors(dep); + clear_dist_suspended_procs(dep); } } diff --git a/erts/emulator/beam/erl_node_tables.h b/erts/emulator/beam/erl_node_tables.h index aa8af12555..beae2df75f 100644 --- a/erts/emulator/beam/erl_node_tables.h +++ b/erts/emulator/beam/erl_node_tables.h @@ -187,6 +187,7 @@ set pagination off set $i = 0 set $node = referred_nodes[$node_ix].node while $i < $node->slot.counter + printf "%s:%d ", $node->books[$i].file, $node->books[$i].line printf "%p: ", $node->books[$i].term etp-1 $node->books[$i].who printf " " @@ -211,8 +212,12 @@ lists:usort(lists:filter(fun({V,N}) -> N /= 0 end, maps:to_list(Accs))). struct erl_node_bookkeeping { Eterm who; Eterm term; + char *file; + int line; enum { ERL_NODE_INC, ERL_NODE_DEC } what; }; + +#define ERTS_BOOKKEEP_SIZE (1024) #endif typedef struct erl_node_ { @@ -222,7 +227,7 @@ typedef struct erl_node_ { Uint32 creation; /* Creation */ DistEntry *dist_entry; /* Corresponding dist entry */ #ifdef ERL_NODE_BOOKKEEP - struct erl_node_bookkeeping books[1024]; + struct erl_node_bookkeeping books[ERTS_BOOKKEEP_SIZE]; erts_atomic_t slot; #endif } ErlNode; @@ -259,7 +264,7 @@ void erts_set_dist_entry_pending(DistEntry *); void erts_set_dist_entry_connected(DistEntry *, Eterm, Uint); ErlNode *erts_find_or_insert_node(Eterm, Uint32, Eterm); void erts_schedule_delete_node(ErlNode *); -void erts_set_this_node(Eterm, Uint); +void erts_set_this_node(Eterm, Uint32); Uint erts_node_table_size(void); void erts_init_node_tables(int); void erts_node_table_info(fmtfn_t, void *); @@ -276,14 +281,21 @@ Eterm erts_build_dhandle(Eterm **hpp, ErlOffHeap*, DistEntry*, Uint32 conn_id); Eterm erts_make_dhandle(Process *c_p, DistEntry*, Uint32 conn_id); ERTS_GLB_INLINE void erts_init_node_entry(ErlNode *np, erts_aint_t val); +#ifdef ERL_NODE_BOOKKEEP +#define erts_ref_node_entry(NP, MIN, T) erts_ref_node_entry__((NP), (MIN), (T), __FILE__, __LINE__) +#define erts_deref_node_entry(NP, T) erts_deref_node_entry__((NP), (T), __FILE__, __LINE__) +ERTS_GLB_INLINE erts_aint_t erts_ref_node_entry__(ErlNode *np, int min_val, Eterm term, char *file, int line); +ERTS_GLB_INLINE void erts_deref_node_entry__(ErlNode *np, Eterm term, char *file, int line); +#else ERTS_GLB_INLINE erts_aint_t erts_ref_node_entry(ErlNode *np, int min_val, Eterm term); ERTS_GLB_INLINE void erts_deref_node_entry(ErlNode *np, Eterm term); +#endif ERTS_GLB_INLINE void erts_de_rlock(DistEntry *dep); ERTS_GLB_INLINE void erts_de_runlock(DistEntry *dep); ERTS_GLB_INLINE void erts_de_rwlock(DistEntry *dep); ERTS_GLB_INLINE void erts_de_rwunlock(DistEntry *dep); #ifdef ERL_NODE_BOOKKEEP -void erts_node_bookkeep(ErlNode *, Eterm , int); +void erts_node_bookkeep(ErlNode *, Eterm , int, char *file, int line); #else #define erts_node_bookkeep(...) #endif @@ -296,21 +308,40 @@ erts_init_node_entry(ErlNode *np, erts_aint_t val) erts_refc_init(&np->refc, val); } +#ifdef ERL_NODE_BOOKKEEP + +ERTS_GLB_INLINE erts_aint_t +erts_ref_node_entry__(ErlNode *np, int min_val, Eterm term, char *file, int line) +{ + erts_node_bookkeep(np, term, ERL_NODE_INC, file, line); + return erts_refc_inctest(&np->refc, min_val); +} + +ERTS_GLB_INLINE void +erts_deref_node_entry__(ErlNode *np, Eterm term, char *file, int line) +{ + erts_node_bookkeep(np, term, ERL_NODE_DEC, file, line); + if (erts_refc_dectest(&np->refc, 0) == 0) + erts_schedule_delete_node(np); +} + +#else + ERTS_GLB_INLINE erts_aint_t erts_ref_node_entry(ErlNode *np, int min_val, Eterm term) { - erts_node_bookkeep(np, term, ERL_NODE_INC); return erts_refc_inctest(&np->refc, min_val); } ERTS_GLB_INLINE void erts_deref_node_entry(ErlNode *np, Eterm term) { - erts_node_bookkeep(np, term, ERL_NODE_DEC); if (erts_refc_dectest(&np->refc, 0) == 0) erts_schedule_delete_node(np); } +#endif + ERTS_GLB_INLINE void erts_de_rlock(DistEntry *dep) { diff --git a/erts/emulator/beam/erl_printf_term.c b/erts/emulator/beam/erl_printf_term.c index 2e33a8a782..67c486a0db 100644 --- a/erts/emulator/beam/erl_printf_term.c +++ b/erts/emulator/beam/erl_printf_term.c @@ -533,13 +533,34 @@ print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount) { case EXPORT_DEF: { Export* ep = *((Export **) (export_val(wobj) + 1)); - Atom* module = atom_tab(atom_val(ep->info.mfa.module)); - Atom* name = atom_tab(atom_val(ep->info.mfa.function)); + long tdcount; + int tres; PRINT_STRING(res, fn, arg, "fun "); - PRINT_BUF(res, fn, arg, module->name, module->len); + + /* We pass a temporary 'dcount' and adjust the real one later to ensure + * that the fun doesn't get split up between the module and function + * name. */ + tdcount = MAX_ATOM_SZ_LIMIT; + tres = print_atom_name(fn, arg, ep->info.mfa.module, &tdcount); + if (tres < 0) { + res = tres; + goto L_done; + } + *dcount -= (MAX_ATOM_SZ_LIMIT - tdcount); + res += tres; + PRINT_CHAR(res, fn, arg, ':'); - PRINT_BUF(res, fn, arg, name->name, name->len); + + tdcount = MAX_ATOM_SZ_LIMIT; + tres = print_atom_name(fn, arg, ep->info.mfa.function, &tdcount); + if (tres < 0) { + res = tres; + goto L_done; + } + *dcount -= (MAX_ATOM_SZ_LIMIT - tdcount); + res += tres; + PRINT_CHAR(res, fn, arg, '/'); PRINT_SWORD(res, fn, arg, 'd', 0, 1, (ErlPfSWord) ep->info.mfa.arity); diff --git a/erts/emulator/beam/erl_proc_sig_queue.c b/erts/emulator/beam/erl_proc_sig_queue.c index 6bbd59e8e3..b60fb64342 100644 --- a/erts/emulator/beam/erl_proc_sig_queue.c +++ b/erts/emulator/beam/erl_proc_sig_queue.c @@ -4689,10 +4689,12 @@ erts_proc_sig_debug_foreach_sig(Process *c_p, case ERTS_SIG_Q_OP_MONITOR_DOWN: switch (type) { case ERTS_SIG_Q_TYPE_GEN_EXIT: - if (ERTS_SIG_IS_GEN_EXIT_EXTERNAL(sig)) - debug_foreach_sig_external(sig, ext_func, arg); - else + if (!ERTS_SIG_IS_GEN_EXIT_EXTERNAL(sig)) debug_foreach_sig_heap_frags(&sig->hfrag, oh_func, arg); + else { + oh_func(&sig->hfrag.off_heap, arg); + debug_foreach_sig_external(sig, ext_func, arg); + } break; case ERTS_LNK_TYPE_PORT: case ERTS_LNK_TYPE_PROC: diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index 70f48ddd97..e8c83276f5 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -8568,9 +8568,6 @@ erts_start_schedulers(void) { ethr_tid tid; int res = 0; - Uint actual; - Uint wanted = erts_no_schedulers; - Uint wanted_no_schedulers = erts_no_schedulers; char name[16]; ethr_thr_opts opts = ETHR_THR_OPTS_DEFAULT_INITER; int ix; @@ -8584,40 +8581,34 @@ erts_start_schedulers(void) erts_snprintf(opts.name, 16, "runq_supervisor"); erts_atomic_init_nob(&runq_supervisor_sleeping, 0); if (0 != ethr_event_init(&runq_supervision_event)) - erts_exit(ERTS_ERROR_EXIT, "Failed to create run-queue supervision event\n"); + erts_exit(ERTS_ABORT_EXIT, "Failed to create run-queue supervision event\n"); res = ethr_thr_create(&runq_supervisor_tid, runq_supervisor, NULL, &opts); if (0 != res) - erts_exit(ERTS_ERROR_EXIT, "Failed to create run-queue supervision thread, " + erts_exit(ERTS_ABORT_EXIT, "Failed to create run-queue supervision thread, " "error = %d\n", res); } opts.suggested_stack_size = erts_sched_thread_suggested_stack_size; - if (wanted < 1) - wanted = 1; - if (wanted > ERTS_MAX_NO_OF_SCHEDULERS) { - wanted = ERTS_MAX_NO_OF_SCHEDULERS; - res = ENOTSUP; - } - - for (actual = 0; actual < wanted; actual++) { - ErtsSchedulerData *esdp = ERTS_SCHEDULER_IX(actual); - - ASSERT(actual == esdp->no - 1); - - erts_snprintf(opts.name, 16, "%lu_scheduler", actual + 1); + ASSERT(erts_no_schedulers > 0 && erts_no_schedulers <= ERTS_MAX_NO_OF_SCHEDULERS); + for (ix = 0; ix < erts_no_schedulers; ix++) { + ErtsSchedulerData *esdp = ERTS_SCHEDULER_IX(ix); + ASSERT(ix == esdp->no - 1); + erts_snprintf(opts.name, 16, "%lu_scheduler", ix + 1); res = ethr_thr_create(&esdp->tid, sched_thread_func, (void*)esdp, &opts); - if (res != 0) { - break; + erts_exit(ERTS_ABORT_EXIT, "Failed to create scheduler thread %d, error = %d\n", ix, res); } } - erts_no_schedulers = actual; + + /* Probably not needed as thread create will imply a memory barrier, + but we do one just to be safe. */ + ERTS_THR_MEMORY_BARRIER; { for (ix = 0; ix < erts_no_dirty_cpu_schedulers; ix++) { @@ -8626,7 +8617,7 @@ erts_start_schedulers(void) opts.suggested_stack_size = erts_dcpu_sched_thread_suggested_stack_size; res = ethr_thr_create(&esdp->tid,sched_dirty_cpu_thread_func,(void*)esdp,&opts); if (res != 0) - erts_exit(ERTS_ERROR_EXIT, "Failed to create dirty cpu scheduler thread %d, error = %d\n", ix, res); + erts_exit(ERTS_ABORT_EXIT, "Failed to create dirty cpu scheduler thread %d, error = %d\n", ix, res); } for (ix = 0; ix < erts_no_dirty_io_schedulers; ix++) { ErtsSchedulerData *esdp = ERTS_DIRTY_IO_SCHEDULER_IX(ix); @@ -8634,40 +8625,22 @@ erts_start_schedulers(void) opts.suggested_stack_size = erts_dio_sched_thread_suggested_stack_size; res = ethr_thr_create(&esdp->tid,sched_dirty_io_thread_func,(void*)esdp,&opts); if (res != 0) - erts_exit(ERTS_ERROR_EXIT, "Failed to create dirty io scheduler thread %d, error = %d\n", ix, res); + erts_exit(ERTS_ABORT_EXIT, "Failed to create dirty io scheduler thread %d, error = %d\n", ix, res); } } - ERTS_THR_MEMORY_BARRIER; - erts_snprintf(opts.name, 16, "aux"); res = ethr_thr_create(&tid, aux_thread, NULL, &opts); if (res != 0) - erts_exit(ERTS_ERROR_EXIT, "Failed to create aux thread, error = %d\n", res); + erts_exit(ERTS_ABORT_EXIT, "Failed to create aux thread, error = %d\n", res); for (ix = 0; ix < erts_no_poll_threads; ix++) { erts_snprintf(opts.name, 16, "%d_poller", ix); res = ethr_thr_create(&tid, poll_thread, (void*)(UWord)ix, &opts); if (res != 0) - erts_exit(ERTS_ERROR_EXIT, "Failed to create poll thread\n"); - } - - if (actual < 1) - erts_exit(ERTS_ERROR_EXIT, - "Failed to create any scheduler-threads: %s (%d)\n", - erl_errno_id(res), - res); - if (res != 0) { - erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf(); - ASSERT(actual != wanted_no_schedulers); - erts_dsprintf(dsbufp, - "Failed to create %beu scheduler-threads (%s:%d); " - "only %beu scheduler-thread%s created.\n", - wanted_no_schedulers, erl_errno_id(res), res, - actual, actual == 1 ? " was" : "s were"); - erts_send_error_to_logger_nogl(dsbufp); + erts_exit(ERTS_ABORT_EXIT, "Failed to create poll thread\n"); } } @@ -12143,6 +12116,7 @@ erts_proc_exit_handle_dist_monitor(ErtsMonitor *mon, void *vctxt, Sint reds) ErtsHeapFactory factory; Sint reds_consumed = 0; + ASSERT(c_p->flags & F_DISABLE_GC); ASSERT(erts_monitor_is_target(mon) && mon->type == ERTS_MON_TYPE_DIST_PROC); mdp = erts_monitor_to_data(mon); @@ -12190,7 +12164,6 @@ erts_proc_exit_handle_dist_monitor(ErtsMonitor *mon, void *vctxt, Sint reds) switch (code) { case ERTS_DSIG_SEND_CONTINUE: case ERTS_DSIG_SEND_YIELD: - erts_set_gc_state(c_p, 0); ctxt->dist_state = erts_dsend_export_trap_context(c_p, &ctx); reds_consumed = reds; /* force yield */ break; @@ -12198,7 +12171,6 @@ erts_proc_exit_handle_dist_monitor(ErtsMonitor *mon, void *vctxt, Sint reds) break; case ERTS_DSIG_SEND_TOO_LRG: erts_kill_dist_connection(dep, dist->connection_id); - erts_set_gc_state(c_p, 1); break; default: ASSERT(! "Invalid dsig send exit monitor result"); @@ -12402,6 +12374,7 @@ erts_proc_exit_handle_dist_link(ErtsLink *lnk, void *vctxt, Sint reds) ErtsHeapFactory factory; Sint reds_consumed = 0; + ASSERT(c_p->flags & F_DISABLE_GC); ASSERT(lnk->type == ERTS_LNK_TYPE_DIST_PROC); dlnk = erts_link_to_other(lnk, &ldp); dist = ((ErtsLinkDataExtended *) ldp)->dist; @@ -12441,7 +12414,6 @@ erts_proc_exit_handle_dist_link(ErtsLink *lnk, void *vctxt, Sint reds) switch (code) { case ERTS_DSIG_SEND_YIELD: case ERTS_DSIG_SEND_CONTINUE: - erts_set_gc_state(c_p, 0); ctxt->dist_state = erts_dsend_export_trap_context(c_p, &ctx); reds_consumed = reds; /* force yield */ break; @@ -12449,7 +12421,6 @@ erts_proc_exit_handle_dist_link(ErtsLink *lnk, void *vctxt, Sint reds) break; case ERTS_DSIG_SEND_TOO_LRG: erts_kill_dist_connection(dep, dist->connection_id); - erts_set_gc_state(c_p, 1); break; default: ASSERT(! "Invalid dsig send exit monitor result"); @@ -12997,6 +12968,8 @@ restart: yield_allowed = 0; #endif + /* Enable GC again, through strictly not needed it puts + the process in a consistent state. */ erts_set_gc_state(p, 1); /* Set state to not active as we don't want this process @@ -13541,3 +13514,79 @@ erts_debug_later_op_foreach(void (*callback)(void*), } } } + +void +erts_debug_free_process_foreach(void (*func)(Process *, void *), void *arg) +{ + ErtsRunQueue *rq; + int ix, prio; + for (ix = 0; ix < erts_no_run_queues; ix++) { + rq = ERTS_RUNQ_IX(ix); + for (prio = PRIORITY_MAX; prio < PRIORITY_LOW; prio++) { + Process *p = rq->procs.prio[prio].first; + for (; p; p = p->next) { + if (ERTS_PSFLG_FREE & erts_atomic32_read_nob(&p->state)) + (*func)(p, arg); + } + } + } +} + +void +erts_debug_proc_monitor_link_foreach(Process *proc, + int (*monitor_func)(ErtsMonitor *, void *, Sint ), + int (*link_func)(ErtsLink *, void *, Sint ), + void *arg) +{ + if (!(erts_atomic32_read_nob(&proc->state) & ERTS_PSFLG_FREE)) { + /* For all links */ + erts_link_tree_foreach(ERTS_P_LINKS(proc), + link_func, + arg); + /* For all monitors */ + erts_monitor_tree_foreach(ERTS_P_MONITORS(proc), + monitor_func, + arg); + /* For all local target monitors */ + erts_monitor_list_foreach(ERTS_P_LT_MONITORS(proc), + monitor_func, + arg); + } + else { + struct continue_exit_state *ce_state = proc->u.terminate; + + /* For all links */ + if (ce_state->phase == ERTS_CONTINUE_EXIT_LINKS) + erts_debug_link_tree_destroying_foreach(ce_state->links, + link_func, + arg, + ce_state->yield_state); + else + erts_link_tree_foreach(ce_state->links, + link_func, + arg); + + /* For all monitors */ + if (ce_state->phase == ERTS_CONTINUE_EXIT_MONITORS) + erts_debug_monitor_tree_destroying_foreach(ce_state->monitors, + monitor_func, + arg, + ce_state->yield_state); + else + erts_monitor_tree_foreach(ce_state->monitors, + monitor_func, + arg); + + /* For all local target monitors */ + if (ce_state->phase == ERTS_CONTINUE_EXIT_LT_MONITORS) + erts_debug_monitor_list_destroying_foreach(ce_state->lt_monitors, + monitor_func, + arg, + ce_state->yield_state); + else + erts_monitor_list_foreach(ce_state->lt_monitors, + monitor_func, + arg); + + } +} diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h index 3f3c7de64d..405611c584 100644 --- a/erts/emulator/beam/erl_process.h +++ b/erts/emulator/beam/erl_process.h @@ -701,6 +701,13 @@ void erts_debug_later_op_foreach(void (*callback)(void*), void (*func)(void *, ErtsThrPrgrVal, void *), void *arg); +void +erts_debug_free_process_foreach(void (*func)(Process *, void *), void *arg); +void +erts_debug_proc_monitor_link_foreach(Process *proc, + int (*monitor_func)(ErtsMonitor *, void *, Sint ), + int (*link_func)(ErtsLink *, void *, Sint ), + void *arg); #ifdef ERTS_INCLUDE_SCHEDULER_INTERNALS @@ -2355,6 +2362,8 @@ erts_try_change_runq_proc(Process *p, ErtsRunQueue *rq) old_rqint); if (act_rqint == old_rqint) return !0; + + old_rqint = act_rqint; } } diff --git a/erts/emulator/beam/erl_trace.c b/erts/emulator/beam/erl_trace.c index ffe0752b46..5c46a10d64 100644 --- a/erts/emulator/beam/erl_trace.c +++ b/erts/emulator/beam/erl_trace.c @@ -2195,11 +2195,12 @@ sys_msg_dispatcher_wait(void *vwait_p) erts_mtx_unlock(&smq_mtx); } +static ErtsSysMsgQ *local_sys_message_queue = NULL; + static void * sys_msg_dispatcher_func(void *unused) { ErtsThrPrgrCallbacks callbacks; - ErtsSysMsgQ *local_sys_message_queue = NULL; ErtsThrPrgrData *tpd; int wait = 0; @@ -2207,6 +2208,8 @@ sys_msg_dispatcher_func(void *unused) erts_lc_set_thread_name("system message dispatcher"); #endif + local_sys_message_queue = NULL; + callbacks.arg = (void *) &wait; callbacks.wakeup = sys_msg_dispatcher_wakeup; callbacks.prepare_wait = sys_msg_dispatcher_prep_wait; @@ -2263,6 +2266,8 @@ sys_msg_dispatcher_func(void *unused) Process *proc = NULL; Port *port = NULL; + ASSERT(is_value(smqp->msg)); + if (erts_thr_progress_update(tpd)) erts_thr_progress_leader_update(tpd); @@ -2375,6 +2380,7 @@ sys_msg_dispatcher_func(void *unused) erts_fprintf(stderr, "dropped\n"); #endif } + smqp->msg = THE_NON_VALUE; } } @@ -2382,32 +2388,38 @@ sys_msg_dispatcher_func(void *unused) } void -erts_foreach_sys_msg_in_q(void (*func)(Eterm, - Eterm, - Eterm, - ErlHeapFragment *)) +erts_debug_foreach_sys_msg_in_q(void (*func)(Eterm, + Eterm, + Eterm, + ErlHeapFragment *)) { - ErtsSysMsgQ *sm; - erts_mtx_lock(&smq_mtx); - for (sm = sys_message_queue; sm; sm = sm->next) { - Eterm to; - switch (sm->type) { - case SYS_MSG_TYPE_SYSMON: - to = erts_get_system_monitor(); - break; - case SYS_MSG_TYPE_SYSPROF: - to = erts_get_system_profile(); - break; - case SYS_MSG_TYPE_ERRLGR: - to = erts_get_system_logger(); - break; - default: - to = NIL; - break; - } - (*func)(sm->from, to, sm->msg, sm->bp); + ErtsSysMsgQ *smq[] = {sys_message_queue, local_sys_message_queue}; + int i; + + ERTS_LC_ASSERT(erts_thr_progress_is_blocking()); + + for (i = 0; i < sizeof(smq)/sizeof(smq[0]); i++) { + ErtsSysMsgQ *sm; + for (sm = smq[i]; sm; sm = sm->next) { + Eterm to; + switch (sm->type) { + case SYS_MSG_TYPE_SYSMON: + to = erts_get_system_monitor(); + break; + case SYS_MSG_TYPE_SYSPROF: + to = erts_get_system_profile(); + break; + case SYS_MSG_TYPE_ERRLGR: + to = erts_get_system_logger(); + break; + default: + to = NIL; + break; + } + if (is_value(sm->msg)) + (*func)(sm->from, to, sm->msg, sm->bp); + } } - erts_mtx_unlock(&smq_mtx); } diff --git a/erts/emulator/beam/erl_trace.h b/erts/emulator/beam/erl_trace.h index bb5c9ac276..d25f97c656 100644 --- a/erts/emulator/beam/erl_trace.h +++ b/erts/emulator/beam/erl_trace.h @@ -90,10 +90,10 @@ int erts_is_tracer_valid(Process* p); void erts_check_my_tracer_proc(Process *); void erts_block_sys_msg_dispatcher(void); void erts_release_sys_msg_dispatcher(void); -void erts_foreach_sys_msg_in_q(void (*func)(Eterm, - Eterm, - Eterm, - ErlHeapFragment *)); +void erts_debug_foreach_sys_msg_in_q(void (*func)(Eterm, + Eterm, + Eterm, + ErlHeapFragment *)); Eterm erts_set_system_logger(Eterm); Eterm erts_get_system_logger(void); void erts_queue_error_logger_message(Eterm, Eterm, ErlHeapFragment *); diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c index 4156eb8d1e..5cea253ebe 100644 --- a/erts/emulator/beam/external.c +++ b/erts/emulator/beam/external.c @@ -51,18 +51,17 @@ #define MAX_STRING_LEN 0xffff -/* MAX value for the creation field in pid, port and reference - for the local node and for the current external format. - - Larger creation values than this are allowed in external pid, port and refs - encoded with NEW_PID_EXT, NEW_PORT_EXT and NEWER_REFERENCE_EXT. - The point here is to prepare for future upgrade to 32-bit creation. - OTP-19 (erts-8.0) can handle big creation values from other (newer) nodes, - but do not use big creation values for the local node yet, - as we still may have to communicate with older nodes. +/* + * MAX value for the creation field in pid, port and reference + * for the old PID_EXT, PORT_EXT, REFERENCE_EXT and NEW_REFERENCE_EXT. + * Older nodes (OTP 19-22) will send us these so we must be able to decode them. + * + * From OTP 23 DFLAG_BIG_CREATION is mandatory so this node will always + * encode with new big 32-bit creations using NEW_PID_EXT, NEW_PORT_EXT + * and NEWER_REFERENCE_EXT. */ -#define ERTS_MAX_LOCAL_CREATION (3) -#define is_valid_creation(Cre) ((unsigned)(Cre) <= ERTS_MAX_LOCAL_CREATION) +#define ERTS_MAX_TINY_CREATION (3) +#define is_tiny_creation(Cre) ((unsigned)(Cre) <= ERTS_MAX_TINY_CREATION) #undef ERTS_DEBUG_USE_DIST_SEP #ifdef DEBUG @@ -2469,7 +2468,8 @@ enc_pid(ErtsAtomCacheMap *acmp, Eterm pid, byte* ep, Uint32 dflags) Eterm sysname = ((is_internal_pid(pid) && (dflags & DFLAG_INTERNAL_TAGS)) ? INTERNAL_LOCAL_SYSNAME : pid_node_name(pid)); Uint32 creation = pid_creation(pid); - byte* tagp = ep++; + + *ep++ = NEW_PID_EXT; /* insert atom here containing host and sysname */ ep = enc_atom(acmp, sysname, ep, dflags); @@ -2481,15 +2481,8 @@ enc_pid(ErtsAtomCacheMap *acmp, Eterm pid, byte* ep, Uint32 dflags) ep += 4; put_int32(os, ep); ep += 4; - if (creation <= ERTS_MAX_LOCAL_CREATION) { - *tagp = PID_EXT; - *ep++ = creation; - } else { - ASSERT(is_external_pid(pid)); - *tagp = NEW_PID_EXT; - put_int32(creation, ep); - ep += 4; - } + put_int32(creation, ep); + ep += 4; return ep; } @@ -2609,7 +2602,7 @@ dec_pid(ErtsDistExternal *edep, ErtsHeapFactory* factory, byte* ep, if (tag == PID_EXT) { cre = get_int8(ep); ep += 1; - if (!is_valid_creation(cre)) { + if (!is_tiny_creation(cre)) { return NULL; } } else { @@ -2870,25 +2863,18 @@ enc_term_int(TTBEncodeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Eterm sysname = (((dflags & DFLAG_INTERNAL_TAGS) && is_internal_ref(obj)) ? INTERNAL_LOCAL_SYSNAME : ref_node_name(obj)); Uint32 creation = ref_creation(obj); - byte* tagp = ep++; ASSERT(dflags & DFLAG_EXTENDED_REFERENCES); erts_magic_ref_save_bin(obj); + *ep++ = NEWER_REFERENCE_EXT; i = ref_no_numbers(obj); put_int16(i, ep); ep += 2; ep = enc_atom(acmp, sysname, ep, dflags); - if (creation <= ERTS_MAX_LOCAL_CREATION) { - *tagp = NEW_REFERENCE_EXT; - *ep++ = creation; - } else { - ASSERT(is_external_ref(obj)); - *tagp = NEWER_REFERENCE_EXT; - put_int32(creation, ep); - ep += 4; - } + put_int32(creation, ep); + ep += 4; ref_num = ref_numbers(obj); for (j = 0; j < i; j++) { put_int32(ref_num[j], ep); @@ -2901,21 +2887,14 @@ enc_term_int(TTBEncodeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Eterm sysname = (((dflags & DFLAG_INTERNAL_TAGS) && is_internal_port(obj)) ? INTERNAL_LOCAL_SYSNAME : port_node_name(obj)); Uint32 creation = port_creation(obj); - byte* tagp = ep++; + *ep++ = NEW_PORT_EXT; ep = enc_atom(acmp, sysname, ep, dflags); j = port_number(obj); put_int32(j, ep); ep += 4; - if (creation <= ERTS_MAX_LOCAL_CREATION) { - *tagp = PORT_EXT; - *ep++ = creation; - } else { - ASSERT(is_external_port(obj)); - *tagp = NEW_PORT_EXT; - put_int32(creation, ep); - ep += 4; - } + put_int32(creation, ep); + ep += 4; break; } case LIST_DEF: @@ -3610,7 +3589,7 @@ dec_term_atom_common: if (tag == PORT_EXT) { cre = get_int8(ep); ep++; - if (!is_valid_creation(cre)) { + if (!is_tiny_creation(cre)) { goto error; } } @@ -3657,7 +3636,7 @@ dec_term_atom_common: cre = get_int8(ep); ep += 1; - if (!is_valid_creation(cre)) { + if (!is_tiny_creation(cre)) { goto error; } goto ref_ext_common; @@ -3671,7 +3650,7 @@ dec_term_atom_common: cre = get_int8(ep); ep += 1; - if (!is_valid_creation(cre)) { + if (!is_tiny_creation(cre)) { goto error; } r0 = get_int32(ep); @@ -4334,30 +4313,21 @@ encode_size_struct_int(TTBSizeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj, result += 1 + 4 + 1 + i; /* tag,size,sign,digits */ break; case EXTERNAL_PID_DEF: - if (external_pid_creation(obj) > ERTS_MAX_LOCAL_CREATION) - result += 3; - /*fall through*/ case PID_DEF: result += (1 + encode_size_struct2(acmp, pid_node_name(obj), dflags) + - 4 + 4 + 1); + 4 + 4 + 4); break; case EXTERNAL_REF_DEF: - if (external_ref_creation(obj) > ERTS_MAX_LOCAL_CREATION) - result += 3; - /*fall through*/ case REF_DEF: ASSERT(dflags & DFLAG_EXTENDED_REFERENCES); i = ref_no_numbers(obj); result += (1 + 2 + encode_size_struct2(acmp, ref_node_name(obj), dflags) + - 1 + 4*i); + 4 + 4*i); break; case EXTERNAL_PORT_DEF: - if (external_port_creation(obj) > ERTS_MAX_LOCAL_CREATION) - result += 3; - /*fall through*/ case PORT_DEF: result += (1 + encode_size_struct2(acmp, port_node_name(obj), dflags) + - 4 + 1); + 4 + 4); break; case LIST_DEF: { int is_str = is_external_string(obj, &m); diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index 4c8d3d3dbe..0c2cf98033 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -907,7 +907,8 @@ Eterm erl_is_function(Process* p, Eterm arg1, Eterm arg2); /* beam_bif_load.c */ Eterm erts_check_process_code(Process *c_p, Eterm module, int *redsp, int fcalls); Eterm erts_proc_copy_literal_area(Process *c_p, int *redsp, int fcalls, int gc_allowed); - +void erts_debug_foreach_release_literal_area_off_heap(void (*func)(ErlOffHeap *, void *), + void *arg); typedef struct ErtsLiteralArea_ { struct erl_off_heap_header *off_heap; Eterm *end; @@ -1072,17 +1073,46 @@ Uint size_object_x(Eterm, erts_literal_area_t*); #define size_object_litopt(Term,LitArea) size_object_x(Term,LitArea) Uint copy_shared_calculate(Eterm, erts_shcopy_t*); -Eterm copy_shared_perform(Eterm, Uint, erts_shcopy_t*, Eterm**, ErlOffHeap*); - Uint size_shared(Eterm); +/* #define ERTS_COPY_REGISTER_LOCATION */ + +#ifdef ERTS_COPY_REGISTER_LOCATION + +#define copy_shared_perform(U, V, X, Y, Z) \ + copy_shared_perform_x((U), (V), (X), (Y), (Z), __FILE__, __LINE__) +Eterm copy_shared_perform_x(Eterm, Uint, erts_shcopy_t*, Eterm**, ErlOffHeap*, + char *file, int line); + +Eterm copy_struct_x(Eterm, Uint, Eterm**, ErlOffHeap*, Uint*, erts_literal_area_t*, + char *file, int line); +#define copy_struct(Obj,Sz,HPP,OH) \ + copy_struct_x(Obj,Sz,HPP,OH,NULL,NULL,__FILE__,__LINE__) +#define copy_struct_litopt(Obj,Sz,HPP,OH,LitArea) \ + copy_struct_x(Obj,Sz,HPP,OH,NULL,LitArea,__FILE__,__LINE__) + +#define copy_shallow(R, SZ, HPP, OH) \ + copy_shallow_x((R), (SZ), (HPP), (OH), __FILE__, __LINE__) +Eterm copy_shallow_x(Eterm* ERTS_RESTRICT, Uint, Eterm**, ErlOffHeap*, + char *file, int line); + +#else + +#define copy_shared_perform(U, V, X, Y, Z) \ + copy_shared_perform_x((U), (V), (X), (Y), (Z)) +Eterm copy_shared_perform_x(Eterm, Uint, erts_shcopy_t*, Eterm**, ErlOffHeap*); + Eterm copy_struct_x(Eterm, Uint, Eterm**, ErlOffHeap*, Uint*, erts_literal_area_t*); #define copy_struct(Obj,Sz,HPP,OH) \ copy_struct_x(Obj,Sz,HPP,OH,NULL,NULL) #define copy_struct_litopt(Obj,Sz,HPP,OH,LitArea) \ copy_struct_x(Obj,Sz,HPP,OH,NULL,LitArea) -Eterm copy_shallow(Eterm* ERTS_RESTRICT, Uint, Eterm**, ErlOffHeap*); +#define copy_shallow(R, SZ, HPP, OH) \ + copy_shallow_x((R), (SZ), (HPP), (OH)) +Eterm copy_shallow_x(Eterm* ERTS_RESTRICT, Uint, Eterm**, ErlOffHeap*); + +#endif void erts_move_multi_frags(Eterm** hpp, ErlOffHeap*, ErlHeapFragment* first, Eterm* refs, unsigned nrefs, int literals); @@ -1257,6 +1287,10 @@ Uint erts_persistent_term_count(void); void erts_init_persistent_dumping(void); extern ErtsLiteralArea** erts_persistent_areas; extern Uint erts_num_persistent_areas; +void erts_debug_foreach_persistent_term_off_heap(void (*func)(ErlOffHeap *, void *), + void *arg); +int erts_debug_have_accessed_literal_area(ErtsLiteralArea *lap); +void erts_debug_save_accessed_literal_area(ErtsLiteralArea *lap); /* external.c */ void erts_init_external(void); diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c index 311c5fdd6a..66ff8d8450 100644 --- a/erts/emulator/drivers/common/inet_drv.c +++ b/erts/emulator/drivers/common/inet_drv.c @@ -12733,7 +12733,7 @@ static void packet_inet_command(ErlDrvData e, char* buf, ErlDrvSizeT len) len -= 4; ptr += 4; if (len < anc_len) goto return_einval; - if (anc_len == 0 && !!0/*XXX-short-circuit-for-testing*/) { + if (anc_len == 0) { /* Empty ancillary data */ /* Now "ptr" is the user data ptr, "len" is data length: */ inet_output_count(desc, len); @@ -12772,10 +12772,7 @@ static void packet_inet_command(ErlDrvData e, char* buf, ErlDrvSizeT len) if (compile_ancillary_data(&mhdr, ptr, anc_len) != 0) { goto return_einval; } - if (mhdr.msg_controllen == 0) { - /* XXX Testing - only possible for anc_len == 0 */ - mhdr.msg_control = NULL; - } + ASSERT(mhdr.msg_controllen != 0); len -= anc_len; ptr += anc_len; /* Now "ptr" is the user data ptr, "len" is data length: */ diff --git a/erts/emulator/nifs/common/prim_file_nif.c b/erts/emulator/nifs/common/prim_file_nif.c index 9e9a14844e..5c5e9a2d30 100644 --- a/erts/emulator/nifs/common/prim_file_nif.c +++ b/erts/emulator/nifs/common/prim_file_nif.c @@ -162,6 +162,7 @@ WRAP_FILE_HANDLE_EXPORT(allocate_nif) WRAP_FILE_HANDLE_EXPORT(advise_nif) WRAP_FILE_HANDLE_EXPORT(get_handle_nif) WRAP_FILE_HANDLE_EXPORT(ipread_s32bu_p32bu_nif) +WRAP_FILE_HANDLE_EXPORT(read_handle_info_nif) static ErlNifFunc nif_funcs[] = { /* File handle ops */ @@ -176,6 +177,7 @@ static ErlNifFunc nif_funcs[] = { {"truncate_nif", 1, truncate_nif, ERL_NIF_DIRTY_JOB_IO_BOUND}, {"allocate_nif", 3, allocate_nif, ERL_NIF_DIRTY_JOB_IO_BOUND}, {"advise_nif", 4, advise_nif, ERL_NIF_DIRTY_JOB_IO_BOUND}, + {"read_handle_info_nif", 1, read_handle_info_nif, ERL_NIF_DIRTY_JOB_IO_BOUND}, /* Filesystem ops */ {"make_hard_link_nif", 2, make_hard_link_nif, ERL_NIF_DIRTY_JOB_IO_BOUND}, @@ -896,6 +898,26 @@ static ERL_NIF_TERM get_handle_nif_impl(efile_data_t *d, ErlNifEnv *env, int arg return efile_get_handle(env, d); } +static ERL_NIF_TERM build_file_info(ErlNifEnv *env, efile_fileinfo_t *info) { + /* #file_info as declared in file.hrl */ + return enif_make_tuple(env, 14, + am_file_info, + enif_make_uint64(env, info->size), + efile_filetype_to_atom(info->type), + efile_access_to_atom(info->access), + enif_make_int64(env, MAX(EFILE_MIN_FILETIME, info->a_time)), + enif_make_int64(env, MAX(EFILE_MIN_FILETIME, info->m_time)), + enif_make_int64(env, MAX(EFILE_MIN_FILETIME, info->c_time)), + enif_make_uint(env, info->mode), + enif_make_uint(env, info->links), + enif_make_uint(env, info->major_device), + enif_make_uint(env, info->minor_device), + enif_make_uint(env, info->inode), + enif_make_uint(env, info->uid), + enif_make_uint(env, info->gid) + ); +} + static ERL_NIF_TERM read_info_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { posix_errno_t posix_errno; @@ -914,23 +936,20 @@ static ERL_NIF_TERM read_info_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM a return posix_error_to_tuple(env, posix_errno); } - /* #file_info as declared in file.hrl */ - return enif_make_tuple(env, 14, - am_file_info, - enif_make_uint64(env, info.size), - efile_filetype_to_atom(info.type), - efile_access_to_atom(info.access), - enif_make_int64(env, MAX(EFILE_MIN_FILETIME, info.a_time)), - enif_make_int64(env, MAX(EFILE_MIN_FILETIME, info.m_time)), - enif_make_int64(env, MAX(EFILE_MIN_FILETIME, info.c_time)), - enif_make_uint(env, info.mode), - enif_make_uint(env, info.links), - enif_make_uint(env, info.major_device), - enif_make_uint(env, info.minor_device), - enif_make_uint(env, info.inode), - enif_make_uint(env, info.uid), - enif_make_uint(env, info.gid) - ); + return build_file_info(env, &info); +} + +static ERL_NIF_TERM read_handle_info_nif_impl(efile_data_t *d, ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { + posix_errno_t posix_errno; + efile_fileinfo_t info = {0}; + + ASSERT(argc == 0); + + if((posix_errno = efile_read_handle_info(d, &info))) { + return posix_error_to_tuple(env, posix_errno); + } + + return build_file_info(env, &info); } static ERL_NIF_TERM set_permissions_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { diff --git a/erts/emulator/nifs/common/prim_file_nif.h b/erts/emulator/nifs/common/prim_file_nif.h index 020714a03b..28c1ea9d00 100644 --- a/erts/emulator/nifs/common/prim_file_nif.h +++ b/erts/emulator/nifs/common/prim_file_nif.h @@ -170,6 +170,7 @@ int efile_close(efile_data_t *d, posix_errno_t *error); /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */ posix_errno_t efile_read_info(const efile_path_t *path, int follow_link, efile_fileinfo_t *result); +posix_errno_t efile_read_handle_info(efile_data_t *d, efile_fileinfo_t *result); /** @brief Sets the file times to the given values. Refer to efile_fileinfo_t * for a description of each. */ diff --git a/erts/emulator/nifs/common/net_nif.c b/erts/emulator/nifs/common/prim_net_nif.c index 8a69052935..11a8ff724e 100644 --- a/erts/emulator/nifs/common/net_nif.c +++ b/erts/emulator/nifs/common/prim_net_nif.c @@ -1653,4 +1653,4 @@ LOCAL_ERROR_REASON_ATOMS return !net; } -ERL_NIF_INIT(net, net_funcs, on_load, NULL, NULL, NULL) +ERL_NIF_INIT(prim_net, net_funcs, on_load, NULL, NULL, NULL) diff --git a/erts/emulator/nifs/common/socket_dbg.c b/erts/emulator/nifs/common/socket_dbg.c index 7dfc4b77bc..0005575017 100644 --- a/erts/emulator/nifs/common/socket_dbg.c +++ b/erts/emulator/nifs/common/socket_dbg.c @@ -37,23 +37,23 @@ #define TNAME(__T__) enif_thread_name( __T__ ) #define TSNAME() TNAME(TSELF()) -static FILE* dbgout = NULL; +FILE* esock_dbgout = NULL; extern void esock_dbg_init(char* filename) { if (filename != NULL) { if (strcmp(filename, ESOCK_DBGOUT_DEFAULT) == 0) { - dbgout = stdout; + esock_dbgout = stdout; } else if (strcmp(filename, ESOCK_DBGOUT_UNIQUE) == 0) { - char template[] = "/tmp/esock-dbg-XXXXXX"; - dbgout = fdopen(mkstemp(template), "w+"); + char template[] = "/tmp/esock-dbg-XXXXXX"; + esock_dbgout = fdopen(mkstemp(template), "w+"); } else { - dbgout = fopen(filename, "w+"); + esock_dbgout = fopen(filename, "w+"); } } else { char template[] = "/tmp/esock-dbg-XXXXXX"; - dbgout = fdopen(mkstemp(template), "w+"); + esock_dbgout = fdopen(mkstemp(template), "w+"); } } @@ -67,7 +67,7 @@ extern void esock_dbg_printf( const char* prefix, const char* format, ... ) { va_list args; - char f[512 + sizeof(format)]; // This has to suffice... + char f[512 + strlen(format)]; // This has to suffice... char stamp[30]; int res; @@ -87,9 +87,9 @@ void esock_dbg_printf( const char* prefix, const char* format, ... ) if (res > 0) { va_start (args, format); - enif_vfprintf (dbgout, f, args); + enif_vfprintf (esock_dbgout, f, args); va_end (args); - fflush(dbgout); + fflush(esock_dbgout); } return; diff --git a/erts/emulator/nifs/common/socket_dbg.h b/erts/emulator/nifs/common/socket_dbg.h index 47739b46da..8fce211a8a 100644 --- a/erts/emulator/nifs/common/socket_dbg.h +++ b/erts/emulator/nifs/common/socket_dbg.h @@ -40,12 +40,12 @@ #endif typedef unsigned long long llu_t; - +extern FILE* esock_dbgout; // Initiated by the 'init' function #define ESOCK_DBG_PRINTF( ___COND___ , proto ) \ if ( ___COND___ ) { \ esock_dbg_printf proto; \ - fflush(stdout); \ + fflush(esock_dbgout); \ } diff --git a/erts/emulator/nifs/common/socket_int.h b/erts/emulator/nifs/common/socket_int.h index d6977be5aa..4161775a04 100644 --- a/erts/emulator/nifs/common/socket_int.h +++ b/erts/emulator/nifs/common/socket_int.h @@ -102,6 +102,9 @@ typedef unsigned int BOOLEAN_T; /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * "Global" atoms + * + * Note that when an (global) atom is added here, it must also be added + * in the socket_nif.c file! */ #define GLOBAL_ATOM_DEFS \ @@ -130,6 +133,7 @@ typedef unsigned int BOOLEAN_T; GLOBAL_ATOM_DEF(busy_poll); \ GLOBAL_ATOM_DEF(checksum); \ GLOBAL_ATOM_DEF(close); \ + GLOBAL_ATOM_DEF(command); \ GLOBAL_ATOM_DEF(connect); \ GLOBAL_ATOM_DEF(congestion); \ GLOBAL_ATOM_DEF(context); \ diff --git a/erts/emulator/nifs/common/socket_nif.c b/erts/emulator/nifs/common/socket_nif.c index 9408f6a1bc..881a9c7ccd 100644 --- a/erts/emulator/nifs/common/socket_nif.c +++ b/erts/emulator/nifs/common/socket_nif.c @@ -24,7 +24,7 @@ * The first function is called 'nif_<something>', e.g. nif_open. * This does the initial validation and argument processing and then * calls the function that does the actual work. This is called - * 'n<something>'. + * 'esock_<something>'. * ---------------------------------------------------------------------- * * @@ -354,11 +354,11 @@ static void (*esock_sctp_freepaddrs)(struct sockaddr *addrs) = NULL; /* Debug stuff... */ -#define SOCKET_GLOBAL_DEBUG_DEFAULT FALSE -#define SOCKET_DEBUG_DEFAULT FALSE +#define ESOCK_GLOBAL_DEBUG_DEFAULT FALSE +#define ESOCK_DEBUG_DEFAULT FALSE /* Counters and stuff (Don't know where to sent this stuff anyway) */ -#define SOCKET_NIF_IOW_DEFAULT FALSE +#define ESOCK_NIF_IOW_DEFAULT FALSE @@ -398,10 +398,10 @@ static void (*esock_sctp_freepaddrs)(struct sockaddr *addrs) = NULL; #if defined(TCP_CA_NAME_MAX) -#define SOCKET_OPT_TCP_CONGESTION_NAME_MAX TCP_CA_NAME_MAX +#define ESOCK_OPT_TCP_CONGESTION_NAME_MAX TCP_CA_NAME_MAX #else /* This is really excessive, but just in case... */ -#define SOCKET_OPT_TCP_CONGESTION_NAME_MAX 256 +#define ESOCK_OPT_TCP_CONGESTION_NAME_MAX 256 #endif @@ -414,25 +414,25 @@ static void (*esock_sctp_freepaddrs)(struct sockaddr *addrs) = NULL; /* *** Socket state defs *** */ -#define SOCKET_FLAG_OPEN 0x0001 -#define SOCKET_FLAG_ACTIVE 0x0004 -#define SOCKET_FLAG_LISTEN 0x0008 -#define SOCKET_FLAG_CON 0x0010 -#define SOCKET_FLAG_ACC 0x0020 -#define SOCKET_FLAG_BUSY 0x0040 -#define SOCKET_FLAG_CLOSE 0x0080 - -#define SOCKET_STATE_CLOSED (0) -#define SOCKET_STATE_OPEN (SOCKET_FLAG_OPEN) -#define SOCKET_STATE_CONNECTED (SOCKET_STATE_OPEN | SOCKET_FLAG_ACTIVE) -#define SOCKET_STATE_LISTENING (SOCKET_STATE_OPEN | SOCKET_FLAG_LISTEN) -#define SOCKET_STATE_CONNECTING (SOCKET_STATE_OPEN | SOCKET_FLAG_CON) -#define SOCKET_STATE_ACCEPTING (SOCKET_STATE_LISTENING | SOCKET_FLAG_ACC) -#define SOCKET_STATE_CLOSING (SOCKET_FLAG_CLOSE) -#define SOCKET_STATE_DTOR (0xFFFF) +#define ESOCK_FLAG_OPEN 0x0001 +#define ESOCK_FLAG_ACTIVE 0x0004 +#define ESOCK_FLAG_LISTEN 0x0008 +#define ESOCK_FLAG_CON 0x0010 +#define ESOCK_FLAG_ACC 0x0020 +#define ESOCK_FLAG_BUSY 0x0040 +#define ESOCK_FLAG_CLOSE 0x0080 + +#define ESOCK_STATE_CLOSED (0) +#define ESOCK_STATE_OPEN (ESOCK_FLAG_OPEN) +#define ESOCK_STATE_CONNECTED (ESOCK_STATE_OPEN | ESOCK_FLAG_ACTIVE) +#define ESOCK_STATE_LISTENING (ESOCK_STATE_OPEN | ESOCK_FLAG_LISTEN) +#define ESOCK_STATE_CONNECTING (ESOCK_STATE_OPEN | ESOCK_FLAG_CON) +#define ESOCK_STATE_ACCEPTING (ESOCK_STATE_LISTENING | ESOCK_FLAG_ACC) +#define ESOCK_STATE_CLOSING (ESOCK_FLAG_CLOSE) +#define ESOCK_STATE_DTOR (0xFFFF) #define IS_CLOSED(d) \ - ((d)->state == SOCKET_STATE_CLOSED) + ((d)->state == ESOCK_STATE_CLOSED) /* #define IS_STATE(d, f) \ @@ -440,55 +440,59 @@ static void (*esock_sctp_freepaddrs)(struct sockaddr *addrs) = NULL; */ #define IS_CLOSING(d) \ - (((d)->state & SOCKET_STATE_CLOSING) == SOCKET_STATE_CLOSING) + (((d)->state & ESOCK_STATE_CLOSING) == ESOCK_STATE_CLOSING) #define IS_OPEN(d) \ - (((d)->state & SOCKET_FLAG_OPEN) == SOCKET_FLAG_OPEN) + (((d)->state & ESOCK_FLAG_OPEN) == ESOCK_FLAG_OPEN) #define IS_CONNECTED(d) \ - (((d)->state & SOCKET_STATE_CONNECTED) == SOCKET_STATE_CONNECTED) + (((d)->state & ESOCK_STATE_CONNECTED) == ESOCK_STATE_CONNECTED) #define IS_CONNECTING(d) \ - (((d)->state & SOCKET_FLAG_CON) == SOCKET_FLAG_CON) + (((d)->state & ESOCK_FLAG_CON) == ESOCK_FLAG_CON) /* #define IS_BUSY(d) \ - (((d)->state & SOCKET_FLAG_BUSY) == SOCKET_FLAG_BUSY) + (((d)->state & ESOCK_FLAG_BUSY) == ESOCK_FLAG_BUSY) */ -#define SOCKET_SEND_FLAG_CONFIRM 0 -#define SOCKET_SEND_FLAG_DONTROUTE 1 -#define SOCKET_SEND_FLAG_EOR 2 -#define SOCKET_SEND_FLAG_MORE 3 -#define SOCKET_SEND_FLAG_NOSIGNAL 4 -#define SOCKET_SEND_FLAG_OOB 5 -#define SOCKET_SEND_FLAG_LOW SOCKET_SEND_FLAG_CONFIRM -#define SOCKET_SEND_FLAG_HIGH SOCKET_SEND_FLAG_OOB - -#define SOCKET_RECV_FLAG_CMSG_CLOEXEC 0 -#define SOCKET_RECV_FLAG_ERRQUEUE 1 -#define SOCKET_RECV_FLAG_OOB 2 -#define SOCKET_RECV_FLAG_PEEK 3 -#define SOCKET_RECV_FLAG_TRUNC 4 -#define SOCKET_RECV_FLAG_LOW SOCKET_RECV_FLAG_CMSG_CLOEXEC -#define SOCKET_RECV_FLAG_HIGH SOCKET_RECV_FLAG_TRUNC - -#define SOCKET_RECV_BUFFER_SIZE_DEFAULT 8192 -#define SOCKET_RECV_CTRL_BUFFER_SIZE_DEFAULT 1024 -#define SOCKET_SEND_CTRL_BUFFER_SIZE_DEFAULT 1024 - -#define VT2S(__VT__) (((__VT__) == SOCKET_OPT_VALUE_TYPE_UNSPEC) ? "unspec" : \ - (((__VT__) == SOCKET_OPT_VALUE_TYPE_INT) ? "int" : \ - ((__VT__) == SOCKET_OPT_VALUE_TYPE_BOOL) ? "bool" : \ +#define ESOCK_GET_RESOURCE(ENV, REF, RES) \ + enif_get_resource((ENV), (REF), esocks, (RES)) + +#define ESOCK_SEND_FLAG_CONFIRM 0 +#define ESOCK_SEND_FLAG_DONTROUTE 1 +#define ESOCK_SEND_FLAG_EOR 2 +#define ESOCK_SEND_FLAG_MORE 3 +#define ESOCK_SEND_FLAG_NOSIGNAL 4 +#define ESOCK_SEND_FLAG_OOB 5 +#define ESOCK_SEND_FLAG_LOW ESOCK_SEND_FLAG_CONFIRM +#define ESOCK_SEND_FLAG_HIGH ESOCK_SEND_FLAG_OOB + +#define ESOCK_RECV_FLAG_CMSG_CLOEXEC 0 +#define ESOCK_RECV_FLAG_ERRQUEUE 1 +#define ESOCK_RECV_FLAG_OOB 2 +#define ESOCK_RECV_FLAG_PEEK 3 +#define ESOCK_RECV_FLAG_TRUNC 4 +#define ESOCK_RECV_FLAG_LOW ESOCK_RECV_FLAG_CMSG_CLOEXEC +#define ESOCK_RECV_FLAG_HIGH ESOCK_RECV_FLAG_TRUNC + +#define ESOCK_RECV_BUFFER_SIZE_DEFAULT 8192 +#define ESOCK_RECV_CTRL_BUFFER_SIZE_DEFAULT 1024 +#define ESOCK_SEND_CTRL_BUFFER_SIZE_DEFAULT 1024 + +#define VT2S(__VT__) (((__VT__) == ESOCK_OPT_VALUE_TYPE_UNSPEC) ? "unspec" : \ + (((__VT__) == ESOCK_OPT_VALUE_TYPE_INT) ? "int" : \ + ((__VT__) == ESOCK_OPT_VALUE_TYPE_BOOL) ? "bool" : \ "undef")) -#define SOCKET_OPT_VALUE_TYPE_UNSPEC 0 -#define SOCKET_OPT_VALUE_TYPE_INT 1 -#define SOCKET_OPT_VALUE_TYPE_BOOL 2 +#define ESOCK_OPT_VALUE_TYPE_UNSPEC 0 +#define ESOCK_OPT_VALUE_TYPE_INT 1 +#define ESOCK_OPT_VALUE_TYPE_BOOL 2 #define ESOCK_DESC_PATTERN_CREATED 0x03030303 #define ESOCK_DESC_PATTERN_DTOR 0xC0C0C0C0 +/* typedef union { struct { // 0 = not open, 1 = open @@ -501,15 +505,16 @@ typedef union { unsigned int listen:2; // unsigned int listening:1; // unsigned int accepting:1; - /* Room for more... */ + / * Room for more... * / } flags; unsigned int field; // Make it easy to reset all flags... } SocketState; +*/ /* #define IS_OPEN(d) ((d)->state.flags.open) -#define IS_CONNECTED(d) ((d)->state.flags.connect == SOCKET_STATE_CONNECTED) -#define IS_CONNECTING(d) ((d)->state.flags.connect == SOCKET_STATE_CONNECTING) +#define IS_CONNECTED(d) ((d)->state.flags.connect == ESOCK_STATE_CONNECTED) +#define IS_CONNECTING(d) ((d)->state.flags.connect == ESOCK_STATE_CONNECTING) */ @@ -520,150 +525,151 @@ typedef union { */ /* domain */ -#define SOCKET_DOMAIN_LOCAL 1 -#define SOCKET_DOMAIN_INET 2 -#define SOCKET_DOMAIN_INET6 3 +#define ESOCK_DOMAIN_LOCAL 1 +#define ESOCK_DOMAIN_INET 2 +#define ESOCK_DOMAIN_INET6 3 /* type */ -#define SOCKET_TYPE_STREAM 1 -#define SOCKET_TYPE_DGRAM 2 -#define SOCKET_TYPE_RAW 3 -// #define SOCKET_TYPE_RDM 4 -#define SOCKET_TYPE_SEQPACKET 5 +#define ESOCK_TYPE_STREAM 1 +#define ESOCK_TYPE_DGRAM 2 +#define ESOCK_TYPE_RAW 3 +// #define ESOCK_TYPE_RDM 4 +#define ESOCK_TYPE_SEQPACKET 5 /* protocol */ -#define SOCKET_PROTOCOL_DEFAULT 0 -#define SOCKET_PROTOCOL_IP 1 -#define SOCKET_PROTOCOL_TCP 2 -#define SOCKET_PROTOCOL_UDP 3 -#define SOCKET_PROTOCOL_SCTP 4 -#define SOCKET_PROTOCOL_ICMP 5 -#define SOCKET_PROTOCOL_IGMP 6 +#define ESOCK_PROTOCOL_DEFAULT 0 +#define ESOCK_PROTOCOL_IP 1 +#define ESOCK_PROTOCOL_TCP 2 +#define ESOCK_PROTOCOL_UDP 3 +#define ESOCK_PROTOCOL_SCTP 4 +#define ESOCK_PROTOCOL_ICMP 5 +#define ESOCK_PROTOCOL_IGMP 6 /* shutdown how */ -#define SOCKET_SHUTDOWN_HOW_RD 0 -#define SOCKET_SHUTDOWN_HOW_WR 1 -#define SOCKET_SHUTDOWN_HOW_RDWR 2 - - -#define SOCKET_OPT_LEVEL_OTP 0 -#define SOCKET_OPT_LEVEL_SOCKET 1 -#define SOCKET_OPT_LEVEL_IP 2 -#define SOCKET_OPT_LEVEL_IPV6 3 -#define SOCKET_OPT_LEVEL_TCP 4 -#define SOCKET_OPT_LEVEL_UDP 5 -#define SOCKET_OPT_LEVEL_SCTP 6 - -#define SOCKET_OPT_OTP_DEBUG 1 -#define SOCKET_OPT_OTP_IOW 2 -#define SOCKET_OPT_OTP_CTRL_PROC 3 -#define SOCKET_OPT_OTP_RCVBUF 4 -#define SOCKET_OPT_OTP_RCVCTRLBUF 6 -#define SOCKET_OPT_OTP_SNDCTRLBUF 7 -#define SOCKET_OPT_OTP_FD 8 -#define SOCKET_OPT_OTP_DOMAIN 0xFF01 // INTERNAL AND ONLY GET -#define SOCKET_OPT_OTP_TYPE 0xFF02 // INTERNAL AND ONLY GET -#define SOCKET_OPT_OTP_PROTOCOL 0xFF03 // INTERNAL AND ONLY GET - -#define SOCKET_OPT_SOCK_ACCEPTCONN 1 -#define SOCKET_OPT_SOCK_BINDTODEVICE 3 -#define SOCKET_OPT_SOCK_BROADCAST 4 -#define SOCKET_OPT_SOCK_DEBUG 6 -#define SOCKET_OPT_SOCK_DOMAIN 7 -#define SOCKET_OPT_SOCK_DONTROUTE 8 -#define SOCKET_OPT_SOCK_KEEPALIVE 10 -#define SOCKET_OPT_SOCK_LINGER 11 -#define SOCKET_OPT_SOCK_OOBINLINE 13 -#define SOCKET_OPT_SOCK_PEEK_OFF 15 -#define SOCKET_OPT_SOCK_PRIORITY 17 -#define SOCKET_OPT_SOCK_PROTOCOL 18 -#define SOCKET_OPT_SOCK_RCVBUF 19 -#define SOCKET_OPT_SOCK_RCVLOWAT 21 -#define SOCKET_OPT_SOCK_RCVTIMEO 22 -#define SOCKET_OPT_SOCK_REUSEADDR 23 -#define SOCKET_OPT_SOCK_REUSEPORT 24 -#define SOCKET_OPT_SOCK_SNDBUF 27 -#define SOCKET_OPT_SOCK_SNDLOWAT 29 -#define SOCKET_OPT_SOCK_SNDTIMEO 30 -#define SOCKET_OPT_SOCK_TIMESTAMP 31 -#define SOCKET_OPT_SOCK_TYPE 32 - -#define SOCKET_OPT_IP_ADD_MEMBERSHIP 1 -#define SOCKET_OPT_IP_ADD_SOURCE_MEMBERSHIP 2 -#define SOCKET_OPT_IP_BLOCK_SOURCE 3 -#define SOCKET_OPT_IP_DROP_MEMBERSHIP 5 -#define SOCKET_OPT_IP_DROP_SOURCE_MEMBERSHIP 6 -#define SOCKET_OPT_IP_FREEBIND 7 -#define SOCKET_OPT_IP_HDRINCL 8 -#define SOCKET_OPT_IP_MINTTL 9 -#define SOCKET_OPT_IP_MSFILTER 10 -#define SOCKET_OPT_IP_MTU 11 -#define SOCKET_OPT_IP_MTU_DISCOVER 12 -#define SOCKET_OPT_IP_MULTICAST_ALL 13 -#define SOCKET_OPT_IP_MULTICAST_IF 14 -#define SOCKET_OPT_IP_MULTICAST_LOOP 15 -#define SOCKET_OPT_IP_MULTICAST_TTL 16 -#define SOCKET_OPT_IP_NODEFRAG 17 -#define SOCKET_OPT_IP_PKTINFO 19 -#define SOCKET_OPT_IP_RECVDSTADDR 20 -#define SOCKET_OPT_IP_RECVERR 21 -#define SOCKET_OPT_IP_RECVIF 22 -#define SOCKET_OPT_IP_RECVOPTS 23 -#define SOCKET_OPT_IP_RECVORIGDSTADDR 24 -#define SOCKET_OPT_IP_RECVTOS 25 -#define SOCKET_OPT_IP_RECVTTL 26 -#define SOCKET_OPT_IP_RETOPTS 27 -#define SOCKET_OPT_IP_ROUTER_ALERT 28 -#define SOCKET_OPT_IP_SENDSRCADDR 29 // Same as IP_RECVDSTADDR? -#define SOCKET_OPT_IP_TOS 30 -#define SOCKET_OPT_IP_TRANSPARENT 31 -#define SOCKET_OPT_IP_TTL 32 -#define SOCKET_OPT_IP_UNBLOCK_SOURCE 33 - -#define SOCKET_OPT_IPV6_ADDRFORM 1 -#define SOCKET_OPT_IPV6_ADD_MEMBERSHIP 2 -#define SOCKET_OPT_IPV6_AUTHHDR 3 -#define SOCKET_OPT_IPV6_DROP_MEMBERSHIP 6 -#define SOCKET_OPT_IPV6_DSTOPTS 7 -#define SOCKET_OPT_IPV6_FLOWINFO 11 -#define SOCKET_OPT_IPV6_HOPLIMIT 12 -#define SOCKET_OPT_IPV6_HOPOPTS 13 -#define SOCKET_OPT_IPV6_MTU 17 -#define SOCKET_OPT_IPV6_MTU_DISCOVER 18 -#define SOCKET_OPT_IPV6_MULTICAST_HOPS 19 -#define SOCKET_OPT_IPV6_MULTICAST_IF 20 -#define SOCKET_OPT_IPV6_MULTICAST_LOOP 21 -#define SOCKET_OPT_IPV6_RECVERR 24 -#define SOCKET_OPT_IPV6_RECVPKTINFO 25 // PKTINFO on FreeBSD -#define SOCKET_OPT_IPV6_ROUTER_ALERT 27 -#define SOCKET_OPT_IPV6_RTHDR 28 -#define SOCKET_OPT_IPV6_UNICAST_HOPS 30 -#define SOCKET_OPT_IPV6_V6ONLY 32 - -#define SOCKET_OPT_TCP_CONGESTION 1 -#define SOCKET_OPT_TCP_CORK 2 -#define SOCKET_OPT_TCP_MAXSEG 7 -#define SOCKET_OPT_TCP_NODELAY 9 - -#define SOCKET_OPT_UDP_CORK 1 - -#define SOCKET_OPT_SCTP_ASSOCINFO 2 -#define SOCKET_OPT_SCTP_AUTOCLOSE 8 -#define SOCKET_OPT_SCTP_DISABLE_FRAGMENTS 12 -#define SOCKET_OPT_SCTP_EVENTS 14 -#define SOCKET_OPT_SCTP_INITMSG 18 -#define SOCKET_OPT_SCTP_MAXSEG 21 -#define SOCKET_OPT_SCTP_NODELAY 23 -#define SOCKET_OPT_SCTP_RTOINFO 29 +#define ESOCK_SHUTDOWN_HOW_RD 0 +#define ESOCK_SHUTDOWN_HOW_WR 1 +#define ESOCK_SHUTDOWN_HOW_RDWR 2 + + +#define ESOCK_OPT_LEVEL_OTP 0 +#define ESOCK_OPT_LEVEL_SOCKET 1 +#define ESOCK_OPT_LEVEL_IP 2 +#define ESOCK_OPT_LEVEL_IPV6 3 +#define ESOCK_OPT_LEVEL_TCP 4 +#define ESOCK_OPT_LEVEL_UDP 5 +#define ESOCK_OPT_LEVEL_SCTP 6 + +#define ESOCK_OPT_OTP_DEBUG 1 +#define ESOCK_OPT_OTP_IOW 2 +#define ESOCK_OPT_OTP_CTRL_PROC 3 +#define ESOCK_OPT_OTP_RCVBUF 4 +#define ESOCK_OPT_OTP_RCVCTRLBUF 6 +#define ESOCK_OPT_OTP_SNDCTRLBUF 7 +#define ESOCK_OPT_OTP_FD 8 +#define ESOCK_OPT_OTP_DOMAIN 0xFF01 // INTERNAL AND ONLY GET +#define ESOCK_OPT_OTP_TYPE 0xFF02 // INTERNAL AND ONLY GET +#define ESOCK_OPT_OTP_PROTOCOL 0xFF03 // INTERNAL AND ONLY GET + +#define ESOCK_OPT_SOCK_ACCEPTCONN 1 +#define ESOCK_OPT_SOCK_BINDTODEVICE 3 +#define ESOCK_OPT_SOCK_BROADCAST 4 +#define ESOCK_OPT_SOCK_DEBUG 6 +#define ESOCK_OPT_SOCK_DOMAIN 7 +#define ESOCK_OPT_SOCK_DONTROUTE 8 +#define ESOCK_OPT_SOCK_KEEPALIVE 10 +#define ESOCK_OPT_SOCK_LINGER 11 +#define ESOCK_OPT_SOCK_OOBINLINE 13 +#define ESOCK_OPT_SOCK_PEEK_OFF 15 +#define ESOCK_OPT_SOCK_PRIORITY 17 +#define ESOCK_OPT_SOCK_PROTOCOL 18 +#define ESOCK_OPT_SOCK_RCVBUF 19 +#define ESOCK_OPT_SOCK_RCVLOWAT 21 +#define ESOCK_OPT_SOCK_RCVTIMEO 22 +#define ESOCK_OPT_SOCK_REUSEADDR 23 +#define ESOCK_OPT_SOCK_REUSEPORT 24 +#define ESOCK_OPT_SOCK_SNDBUF 27 +#define ESOCK_OPT_SOCK_SNDLOWAT 29 +#define ESOCK_OPT_SOCK_SNDTIMEO 30 +#define ESOCK_OPT_SOCK_TIMESTAMP 31 +#define ESOCK_OPT_SOCK_TYPE 32 + +#define ESOCK_OPT_IP_ADD_MEMBERSHIP 1 +#define ESOCK_OPT_IP_ADD_SOURCE_MEMBERSHIP 2 +#define ESOCK_OPT_IP_BLOCK_SOURCE 3 +#define ESOCK_OPT_IP_DROP_MEMBERSHIP 5 +#define ESOCK_OPT_IP_DROP_SOURCE_MEMBERSHIP 6 +#define ESOCK_OPT_IP_FREEBIND 7 +#define ESOCK_OPT_IP_HDRINCL 8 +#define ESOCK_OPT_IP_MINTTL 9 +#define ESOCK_OPT_IP_MSFILTER 10 +#define ESOCK_OPT_IP_MTU 11 +#define ESOCK_OPT_IP_MTU_DISCOVER 12 +#define ESOCK_OPT_IP_MULTICAST_ALL 13 +#define ESOCK_OPT_IP_MULTICAST_IF 14 +#define ESOCK_OPT_IP_MULTICAST_LOOP 15 +#define ESOCK_OPT_IP_MULTICAST_TTL 16 +#define ESOCK_OPT_IP_NODEFRAG 17 +#define ESOCK_OPT_IP_PKTINFO 19 +#define ESOCK_OPT_IP_RECVDSTADDR 20 +#define ESOCK_OPT_IP_RECVERR 21 +#define ESOCK_OPT_IP_RECVIF 22 +#define ESOCK_OPT_IP_RECVOPTS 23 +#define ESOCK_OPT_IP_RECVORIGDSTADDR 24 +#define ESOCK_OPT_IP_RECVTOS 25 +#define ESOCK_OPT_IP_RECVTTL 26 +#define ESOCK_OPT_IP_RETOPTS 27 +#define ESOCK_OPT_IP_ROUTER_ALERT 28 +#define ESOCK_OPT_IP_SENDSRCADDR 29 // Same as IP_RECVDSTADDR? +#define ESOCK_OPT_IP_TOS 30 +#define ESOCK_OPT_IP_TRANSPARENT 31 +#define ESOCK_OPT_IP_TTL 32 +#define ESOCK_OPT_IP_UNBLOCK_SOURCE 33 + +#define ESOCK_OPT_IPV6_ADDRFORM 1 +#define ESOCK_OPT_IPV6_ADD_MEMBERSHIP 2 +#define ESOCK_OPT_IPV6_AUTHHDR 3 +#define ESOCK_OPT_IPV6_DROP_MEMBERSHIP 6 +#define ESOCK_OPT_IPV6_DSTOPTS 7 +#define ESOCK_OPT_IPV6_FLOWINFO 11 +#define ESOCK_OPT_IPV6_HOPLIMIT 12 +#define ESOCK_OPT_IPV6_HOPOPTS 13 +#define ESOCK_OPT_IPV6_MTU 17 +#define ESOCK_OPT_IPV6_MTU_DISCOVER 18 +#define ESOCK_OPT_IPV6_MULTICAST_HOPS 19 +#define ESOCK_OPT_IPV6_MULTICAST_IF 20 +#define ESOCK_OPT_IPV6_MULTICAST_LOOP 21 +#define ESOCK_OPT_IPV6_RECVERR 24 +#define ESOCK_OPT_IPV6_RECVPKTINFO 25 // PKTINFO on FreeBSD +#define ESOCK_OPT_IPV6_ROUTER_ALERT 27 +#define ESOCK_OPT_IPV6_RTHDR 28 +#define ESOCK_OPT_IPV6_UNICAST_HOPS 30 +#define ESOCK_OPT_IPV6_V6ONLY 32 + +#define ESOCK_OPT_TCP_CONGESTION 1 +#define ESOCK_OPT_TCP_CORK 2 +#define ESOCK_OPT_TCP_MAXSEG 7 +#define ESOCK_OPT_TCP_NODELAY 9 + +#define ESOCK_OPT_UDP_CORK 1 + +#define ESOCK_OPT_SCTP_ASSOCINFO 2 +#define ESOCK_OPT_SCTP_AUTOCLOSE 8 +#define ESOCK_OPT_SCTP_DISABLE_FRAGMENTS 12 +#define ESOCK_OPT_SCTP_EVENTS 14 +#define ESOCK_OPT_SCTP_INITMSG 18 +#define ESOCK_OPT_SCTP_MAXSEG 21 +#define ESOCK_OPT_SCTP_NODELAY 23 +#define ESOCK_OPT_SCTP_RTOINFO 29 /* We should *eventually* use this instead of hard-coding the size (to 1) */ #define ESOCK_RECVMSG_IOVEC_SZ 1 +#define ESOCK_CMD_DEBUG 0x0001 -#define SOCKET_SUPPORTS_OPTIONS 0x0001 -#define SOCKET_SUPPORTS_SCTP 0x0002 -#define SOCKET_SUPPORTS_IPV6 0x0003 -#define SOCKET_SUPPORTS_LOCAL 0x0004 +#define ESOCK_SUPPORTS_OPTIONS 0x0001 +#define ESOCK_SUPPORTS_SCTP 0x0002 +#define ESOCK_SUPPORTS_IPV6 0x0003 +#define ESOCK_SUPPORTS_LOCAL 0x0004 #define ESOCK_WHICH_PROTO_ERROR -1 #define ESOCK_WHICH_PROTO_UNSUP -2 @@ -672,7 +678,7 @@ typedef union { /* =================================================================== * * * - * Various enif macros * + * Various esockmacros * * * * =================================================================== */ @@ -681,6 +687,12 @@ typedef union { /* Socket specific debug */ #define SSDBG( __D__ , proto ) ESOCK_DBG_PRINTF( (__D__)->dbg , proto ) +#define SOCK_CNT_INC( __E__, __D__, SF, ACNT, CNT, INC) \ + { \ + if (cnt_inc(CNT, INC) && (__D__)->iow) { \ + esock_send_wrap_msg(__E__, __D__, SF, ACNT); \ + } \ + } /* =================================================================== * @@ -865,6 +877,7 @@ typedef struct { Uint32 readByteCnt; Uint32 readTries; Uint32 readWaits; + Uint32 readFails; /* +++ Accept stuff +++ */ ErlNifMutex* accMtx; @@ -948,6 +961,7 @@ extern char* erl_errno_id(int error); /* THIS IS JUST TEMPORARY??? */ * does the actual work. Except for the info function. * * nif_info + * nif_command * nif_supports * nif_open * nif_bind @@ -973,6 +987,7 @@ extern char* erl_errno_id(int error); /* THIS IS JUST TEMPORARY??? */ #define ESOCK_NIF_FUNCS \ ESOCK_NIF_FUNC_DEF(info); \ + ESOCK_NIF_FUNC_DEF(command); \ ESOCK_NIF_FUNC_DEF(supports); \ ESOCK_NIF_FUNC_DEF(open); \ ESOCK_NIF_FUNC_DEF(bind); \ @@ -1004,1110 +1019,1143 @@ ESOCK_NIF_FUNCS #if !defined(__WIN32__) + /* And here comes the functions that does the actual work (for the most part) */ -static ERL_NIF_TERM nsupports(ErlNifEnv* env, int key); -static ERL_NIF_TERM nsupports_options(ErlNifEnv* env); -static ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env); -static ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env); -static ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env); -static ERL_NIF_TERM nsupports_options_tcp(ErlNifEnv* env); -static ERL_NIF_TERM nsupports_options_udp(ErlNifEnv* env); -static ERL_NIF_TERM nsupports_options_sctp(ErlNifEnv* env); -static ERL_NIF_TERM nsupports_sctp(ErlNifEnv* env); -static ERL_NIF_TERM nsupports_ipv6(ErlNifEnv* env); -static ERL_NIF_TERM nsupports_local(ErlNifEnv* env); - -static ERL_NIF_TERM nopen(ErlNifEnv* env, + +static BOOLEAN_T ecommand2command(ErlNifEnv* env, + ERL_NIF_TERM ecommand, + Uint16* command, + ERL_NIF_TERM* edata); +static ERL_NIF_TERM esock_command(ErlNifEnv* env, + Uint16 cmd, + ERL_NIF_TERM ecdata); +static ERL_NIF_TERM esock_command_debug(ErlNifEnv* env, ERL_NIF_TERM ecdata); + +static ERL_NIF_TERM esock_global_info(ErlNifEnv* env); +static ERL_NIF_TERM esock_socket_info(ErlNifEnv* env, + ESockDescriptor* descP); +static ERL_NIF_TERM esock_socket_info_counters(ErlNifEnv* env, + ESockDescriptor* descP); +#define ESOCK_SOCKET_INFO_REQ_FUNCS \ + ESOCK_SOCKET_INFO_REQ_FUNC_DEF(readers); \ + ESOCK_SOCKET_INFO_REQ_FUNC_DEF(writers); \ + ESOCK_SOCKET_INFO_REQ_FUNC_DEF(acceptors); + +#define ESOCK_SOCKET_INFO_REQ_FUNC_DEF(F) \ + static ERL_NIF_TERM esock_socket_info_##F(ErlNifEnv* env, \ + ESockDescriptor* descP); +ESOCK_SOCKET_INFO_REQ_FUNCS +#undef ESOCK_SOCKET_INFO_REQ_FUNC_DEF + +static ERL_NIF_TERM socket_info_reqs(ErlNifEnv* env, + ESockDescriptor* descP, + ErlNifMutex* mtx, + ESockRequestor* crp, + ESockRequestQueue* q); + +static ERL_NIF_TERM esock_supports(ErlNifEnv* env, int key); +static ERL_NIF_TERM esock_supports_options(ErlNifEnv* env); +static ERL_NIF_TERM esock_supports_options_socket(ErlNifEnv* env); +static ERL_NIF_TERM esock_supports_options_ip(ErlNifEnv* env); +static ERL_NIF_TERM esock_supports_options_ipv6(ErlNifEnv* env); +static ERL_NIF_TERM esock_supports_options_tcp(ErlNifEnv* env); +static ERL_NIF_TERM esock_supports_options_udp(ErlNifEnv* env); +static ERL_NIF_TERM esock_supports_options_sctp(ErlNifEnv* env); +static ERL_NIF_TERM esock_supports_sctp(ErlNifEnv* env); +static ERL_NIF_TERM esock_supports_ipv6(ErlNifEnv* env); +static ERL_NIF_TERM esock_supports_local(ErlNifEnv* env); + +static ERL_NIF_TERM esock_open(ErlNifEnv* env, int domain, int type, int protocol, char* netns); -static BOOLEAN_T nopen_which_protocol(SOCKET sock, int* proto); +static BOOLEAN_T esock_open_which_protocol(SOCKET sock, int* proto); -static ERL_NIF_TERM nbind(ErlNifEnv* env, - ESockDescriptor* descP, - ESockAddress* sockAddrP, - unsigned int addrLen); -static ERL_NIF_TERM nconnect(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef); -static ERL_NIF_TERM nlisten(ErlNifEnv* env, - ESockDescriptor* descP, - int backlog); -static ERL_NIF_TERM naccept_erts(ErlNifEnv* env, +static ERL_NIF_TERM esock_bind(ErlNifEnv* env, + ESockDescriptor* descP, + ESockAddress* sockAddrP, + unsigned int addrLen); +static ERL_NIF_TERM esock_connect(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef); +static ERL_NIF_TERM esock_listen(ErlNifEnv* env, + ESockDescriptor* descP, + int backlog); +static ERL_NIF_TERM esock_accept(ErlNifEnv* env, ESockDescriptor* descP, ERL_NIF_TERM sockRef, ERL_NIF_TERM ref); -static ERL_NIF_TERM naccept_listening(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - ERL_NIF_TERM ref); -static ERL_NIF_TERM naccept_listening_error(ErlNifEnv* env, +static ERL_NIF_TERM esock_accept_listening(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM ref); +static ERL_NIF_TERM esock_accept_listening_error(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM accRef, + ErlNifPid caller, + int save_errno); +static ERL_NIF_TERM esock_accept_listening_accept(ErlNifEnv* env, + ESockDescriptor* descP, + SOCKET accSock, + ErlNifPid caller, + ESockAddress* remote); +static ERL_NIF_TERM esock_accept_accepting(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM ref); +static ERL_NIF_TERM esock_accept_accepting_current(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM ref); +static ERL_NIF_TERM esock_accept_accepting_current_accept(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + SOCKET accSock, + ESockAddress* remote); +static ERL_NIF_TERM esock_accept_accepting_current_error(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM opRef, + int save_errno); +static ERL_NIF_TERM esock_accept_accepting_other(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM ref, + ErlNifPid caller); +static ERL_NIF_TERM esock_accept_busy_retry(ErlNifEnv* env, ESockDescriptor* descP, ERL_NIF_TERM sockRef, ERL_NIF_TERM accRef, - ErlNifPid caller, - int save_errno); -static ERL_NIF_TERM naccept_listening_accept(ErlNifEnv* env, - ESockDescriptor* descP, - SOCKET accSock, - ErlNifPid caller, - ESockAddress* remote); -static ERL_NIF_TERM naccept_accepting(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - ERL_NIF_TERM ref); -static ERL_NIF_TERM naccept_accepting_current(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - ERL_NIF_TERM ref); -static ERL_NIF_TERM naccept_accepting_current_accept(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - SOCKET accSock, - ESockAddress* remote); -static ERL_NIF_TERM naccept_accepting_current_error(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - ERL_NIF_TERM opRef, - int save_errno); -static ERL_NIF_TERM naccept_accepting_other(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM ref, - ErlNifPid caller); -static ERL_NIF_TERM naccept_busy_retry(ErlNifEnv* env, + ErlNifPid* pid, + unsigned int nextState); +static BOOLEAN_T esock_accept_accepted(ErlNifEnv* env, ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - ERL_NIF_TERM accRef, - ErlNifPid* pid, - unsigned int nextState); -static BOOLEAN_T naccept_accepted(ErlNifEnv* env, - ESockDescriptor* descP, - SOCKET accSock, - ErlNifPid pid, - ESockAddress* remote, - ERL_NIF_TERM* result); -static ERL_NIF_TERM nsend(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - ERL_NIF_TERM sendRef, - ErlNifBinary* dataP, - int flags); -static ERL_NIF_TERM nsendto(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - ERL_NIF_TERM sendRef, - ErlNifBinary* dataP, - int flags, - ESockAddress* toAddrP, - unsigned int toAddrLen); -static ERL_NIF_TERM nsendmsg_erts(ErlNifEnv* env, + SOCKET accSock, + ErlNifPid pid, + ESockAddress* remote, + ERL_NIF_TERM* result); +static ERL_NIF_TERM esock_send(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM sendRef, + ErlNifBinary* dataP, + int flags); +static ERL_NIF_TERM esock_sendto(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM sendRef, + ErlNifBinary* dataP, + int flags, + ESockAddress* toAddrP, + unsigned int toAddrLen); +static ERL_NIF_TERM esock_sendmsg(ErlNifEnv* env, ESockDescriptor* descP, ERL_NIF_TERM sockRef, ERL_NIF_TERM sendRef, ERL_NIF_TERM eMsgHdr, int flags); -static ERL_NIF_TERM nrecv(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sendRef, - ERL_NIF_TERM recvRef, - int len, - int flags); -static ERL_NIF_TERM nrecvfrom_erts(ErlNifEnv* env, +static ERL_NIF_TERM esock_recv(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sendRef, + ERL_NIF_TERM recvRef, + int len, + int flags); +static ERL_NIF_TERM esock_recvfrom(ErlNifEnv* env, ESockDescriptor* descP, ERL_NIF_TERM sockRef, ERL_NIF_TERM recvRef, Uint16 bufSz, int flags); -static ERL_NIF_TERM nrecvmsg_erts(ErlNifEnv* env, +static ERL_NIF_TERM esock_recvmsg(ErlNifEnv* env, ESockDescriptor* descP, ERL_NIF_TERM sockRef, ERL_NIF_TERM recvRef, Uint16 bufLen, Uint16 ctrlLen, int flags); -static ERL_NIF_TERM nclose(ErlNifEnv* env, - ESockDescriptor* descP); -static BOOLEAN_T nclose_check(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM* reason); -static ERL_NIF_TERM nclose_do(ErlNifEnv* env, - ESockDescriptor* descP); -static ERL_NIF_TERM nshutdown(ErlNifEnv* env, - ESockDescriptor* descP, - int how); -static ERL_NIF_TERM nsetopt(ErlNifEnv* env, - ESockDescriptor* descP, - BOOLEAN_T isEncoded, - BOOLEAN_T isOTP, - int level, - int eOpt, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_close(ErlNifEnv* env, + ESockDescriptor* descP); +static BOOLEAN_T esock_close_check(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM* reason); +static ERL_NIF_TERM esock_close_do(ErlNifEnv* env, + ESockDescriptor* descP); +static ERL_NIF_TERM esock_shutdown(ErlNifEnv* env, + ESockDescriptor* descP, + int how); +static ERL_NIF_TERM esock_setopt(ErlNifEnv* env, + ESockDescriptor* descP, + BOOLEAN_T isEncoded, + BOOLEAN_T isOTP, + int level, + int eOpt, + ERL_NIF_TERM eVal); /* Set OTP level options */ -static ERL_NIF_TERM nsetopt_otp(ErlNifEnv* env, - ESockDescriptor* descP, - int eOpt, - ERL_NIF_TERM eVal); -/* *** nsetopt_otp_debug *** - * *** nsetopt_otp_iow *** - * *** nsetopt_otp_ctrl_proc *** - * *** nsetopt_otp_rcvbuf *** - * *** nsetopt_otp_rcvctrlbuf *** - * *** nsetopt_otp_sndctrlbuf *** - */ -#define NSETOPT_OTP_FUNCS \ - NSETOPT_OTP_FUNC_DEF(debug); \ - NSETOPT_OTP_FUNC_DEF(iow); \ - NSETOPT_OTP_FUNC_DEF(ctrl_proc); \ - NSETOPT_OTP_FUNC_DEF(rcvbuf); \ - NSETOPT_OTP_FUNC_DEF(rcvctrlbuf); \ - NSETOPT_OTP_FUNC_DEF(sndctrlbuf); -#define NSETOPT_OTP_FUNC_DEF(F) \ - static ERL_NIF_TERM nsetopt_otp_##F(ErlNifEnv* env, \ - ESockDescriptor* descP, \ - ERL_NIF_TERM eVal) -NSETOPT_OTP_FUNCS -#undef NSETOPT_OTP_FUNC_DEF +static ERL_NIF_TERM esock_setopt_otp(ErlNifEnv* env, + ESockDescriptor* descP, + int eOpt, + ERL_NIF_TERM eVal); +/* *** esock_setopt_otp_debug *** + * *** esock_setopt_otp_iow *** + * *** esock_setopt_otp_ctrl_proc *** + * *** esock_setopt_otp_rcvbuf *** + * *** esock_setopt_otp_rcvctrlbuf *** + * *** esock_setopt_otp_sndctrlbuf *** + */ +#define ESOCK_SETOPT_OTP_FUNCS \ + ESOCK_SETOPT_OTP_FUNC_DEF(debug); \ + ESOCK_SETOPT_OTP_FUNC_DEF(iow); \ + ESOCK_SETOPT_OTP_FUNC_DEF(ctrl_proc); \ + ESOCK_SETOPT_OTP_FUNC_DEF(rcvbuf); \ + ESOCK_SETOPT_OTP_FUNC_DEF(rcvctrlbuf); \ + ESOCK_SETOPT_OTP_FUNC_DEF(sndctrlbuf); +#define ESOCK_SETOPT_OTP_FUNC_DEF(F) \ + static ERL_NIF_TERM esock_setopt_otp_##F(ErlNifEnv* env, \ + ESockDescriptor* descP, \ + ERL_NIF_TERM eVal) +ESOCK_SETOPT_OTP_FUNCS +#undef ESOCK_SETOPT_OTP_FUNC_DEF /* Set native options */ -static ERL_NIF_TERM nsetopt_native(ErlNifEnv* env, - ESockDescriptor* descP, - int level, - int eOpt, - ERL_NIF_TERM eVal); -static ERL_NIF_TERM nsetopt_level(ErlNifEnv* env, - ESockDescriptor* descP, - int level, - int eOpt, - ERL_NIF_TERM eVal); -static ERL_NIF_TERM nsetopt_lvl_socket(ErlNifEnv* env, +static ERL_NIF_TERM esock_setopt_native(ErlNifEnv* env, + ESockDescriptor* descP, + int level, + int eOpt, + ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_level(ErlNifEnv* env, ESockDescriptor* descP, + int level, int eOpt, ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_socket(ErlNifEnv* env, + ESockDescriptor* descP, + int eOpt, + ERL_NIF_TERM eVal); /* *** Handling set of socket options for level = socket *** */ #if defined(SO_BINDTODEVICE) -static ERL_NIF_TERM nsetopt_lvl_sock_bindtodevice(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_sock_bindtodevice(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(SO_BROADCAST) -static ERL_NIF_TERM nsetopt_lvl_sock_broadcast(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_sock_broadcast(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(SO_DEBUG) -static ERL_NIF_TERM nsetopt_lvl_sock_debug(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_sock_debug(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(SO_DONTROUTE) -static ERL_NIF_TERM nsetopt_lvl_sock_dontroute(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_sock_dontroute(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(SO_KEEPALIVE) -static ERL_NIF_TERM nsetopt_lvl_sock_keepalive(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_sock_keepalive(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(SO_LINGER) -static ERL_NIF_TERM nsetopt_lvl_sock_linger(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_sock_linger(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(SO_OOBINLINE) -static ERL_NIF_TERM nsetopt_lvl_sock_oobinline(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_sock_oobinline(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(SO_PEEK_OFF) -static ERL_NIF_TERM nsetopt_lvl_sock_peek_off(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_sock_peek_off(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(SO_PRIORITY) -static ERL_NIF_TERM nsetopt_lvl_sock_priority(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_sock_priority(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(SO_RCVBUF) -static ERL_NIF_TERM nsetopt_lvl_sock_rcvbuf(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_sock_rcvbuf(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(SO_RCVLOWAT) -static ERL_NIF_TERM nsetopt_lvl_sock_rcvlowat(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_sock_rcvlowat(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(SO_RCVTIMEO) -static ERL_NIF_TERM nsetopt_lvl_sock_rcvtimeo(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_sock_rcvtimeo(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(SO_REUSEADDR) -static ERL_NIF_TERM nsetopt_lvl_sock_reuseaddr(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_sock_reuseaddr(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(SO_REUSEPORT) -static ERL_NIF_TERM nsetopt_lvl_sock_reuseport(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_sock_reuseport(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(SO_SNDBUF) -static ERL_NIF_TERM nsetopt_lvl_sock_sndbuf(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_sock_sndbuf(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(SO_SNDLOWAT) -static ERL_NIF_TERM nsetopt_lvl_sock_sndlowat(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_sock_sndlowat(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(SO_SNDTIMEO) -static ERL_NIF_TERM nsetopt_lvl_sock_sndtimeo(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_sock_sndtimeo(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(SO_TIMESTAMP) -static ERL_NIF_TERM nsetopt_lvl_sock_timestamp(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_sock_timestamp(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif -static ERL_NIF_TERM nsetopt_lvl_ip(ErlNifEnv* env, - ESockDescriptor* descP, - int eOpt, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ip(ErlNifEnv* env, + ESockDescriptor* descP, + int eOpt, + ERL_NIF_TERM eVal); /* *** Handling set of socket options for level = ip *** */ #if defined(IP_ADD_MEMBERSHIP) -static ERL_NIF_TERM nsetopt_lvl_ip_add_membership(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ip_add_membership(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IP_ADD_SOURCE_MEMBERSHIP) -static ERL_NIF_TERM nsetopt_lvl_ip_add_source_membership(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ip_add_source_membership(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IP_BLOCK_SOURCE) -static ERL_NIF_TERM nsetopt_lvl_ip_block_source(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ip_block_source(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IP_DROP_MEMBERSHIP) -static ERL_NIF_TERM nsetopt_lvl_ip_drop_membership(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ip_drop_membership(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IP_DROP_SOURCE_MEMBERSHIP) -static ERL_NIF_TERM nsetopt_lvl_ip_drop_source_membership(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ip_drop_source_membership(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IP_FREEBIND) -static ERL_NIF_TERM nsetopt_lvl_ip_freebind(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ip_freebind(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IP_HDRINCL) -static ERL_NIF_TERM nsetopt_lvl_ip_hdrincl(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ip_hdrincl(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IP_MINTTL) -static ERL_NIF_TERM nsetopt_lvl_ip_minttl(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ip_minttl(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IP_MSFILTER) && defined(IP_MSFILTER_SIZE) -static ERL_NIF_TERM nsetopt_lvl_ip_msfilter(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ip_msfilter(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); static BOOLEAN_T decode_ip_msfilter_mode(ErlNifEnv* env, ERL_NIF_TERM eVal, Uint32* mode); -static ERL_NIF_TERM nsetopt_lvl_ip_msfilter_set(ErlNifEnv* env, - SOCKET sock, - struct ip_msfilter* msfP, - SOCKLEN_T optLen); +static ERL_NIF_TERM esock_setopt_lvl_ip_msfilter_set(ErlNifEnv* env, + SOCKET sock, + struct ip_msfilter* msfP, + SOCKLEN_T optLen); #endif #if defined(IP_MTU_DISCOVER) -static ERL_NIF_TERM nsetopt_lvl_ip_mtu_discover(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ip_mtu_discover(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IP_MULTICAST_ALL) -static ERL_NIF_TERM nsetopt_lvl_ip_multicast_all(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ip_multicast_all(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IP_MULTICAST_IF) -static ERL_NIF_TERM nsetopt_lvl_ip_multicast_if(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ip_multicast_if(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IP_MULTICAST_LOOP) -static ERL_NIF_TERM nsetopt_lvl_ip_multicast_loop(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ip_multicast_loop(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IP_MULTICAST_TTL) -static ERL_NIF_TERM nsetopt_lvl_ip_multicast_ttl(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ip_multicast_ttl(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IP_NODEFRAG) -static ERL_NIF_TERM nsetopt_lvl_ip_nodefrag(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ip_nodefrag(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IP_PKTINFO) -static ERL_NIF_TERM nsetopt_lvl_ip_pktinfo(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ip_pktinfo(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IP_RECVDSTADDR) -static ERL_NIF_TERM nsetopt_lvl_ip_recvdstaddr(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ip_recvdstaddr(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IP_RECVERR) -static ERL_NIF_TERM nsetopt_lvl_ip_recverr(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ip_recverr(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IP_RECVIF) -static ERL_NIF_TERM nsetopt_lvl_ip_recvif(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ip_recvif(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IP_RECVOPTS) -static ERL_NIF_TERM nsetopt_lvl_ip_recvopts(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ip_recvopts(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IP_RECVORIGDSTADDR) -static ERL_NIF_TERM nsetopt_lvl_ip_recvorigdstaddr(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ip_recvorigdstaddr(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IP_RECVTOS) -static ERL_NIF_TERM nsetopt_lvl_ip_recvtos(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ip_recvtos(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IP_RECVTTL) -static ERL_NIF_TERM nsetopt_lvl_ip_recvttl(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ip_recvttl(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IP_RETOPTS) -static ERL_NIF_TERM nsetopt_lvl_ip_retopts(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); -#endif -#if defined(IP_ROUTER_ALERT) -static ERL_NIF_TERM nsetopt_lvl_ip_router_alert(ErlNifEnv* env, +static ERL_NIF_TERM esock_setopt_lvl_ip_retopts(ErlNifEnv* env, ESockDescriptor* descP, ERL_NIF_TERM eVal); #endif +#if defined(IP_ROUTER_ALERT) +static ERL_NIF_TERM esock_setopt_lvl_ip_router_alert(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); +#endif #if defined(IP_SENDSRCADDR) -static ERL_NIF_TERM nsetopt_lvl_ip_sendsrcaddr(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ip_sendsrcaddr(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IP_TOS) -static ERL_NIF_TERM nsetopt_lvl_ip_tos(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ip_tos(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IP_TRANSPARENT) -static ERL_NIF_TERM nsetopt_lvl_ip_transparent(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ip_transparent(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IP_TTL) -static ERL_NIF_TERM nsetopt_lvl_ip_ttl(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ip_ttl(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IP_UNBLOCK_SOURCE) -static ERL_NIF_TERM nsetopt_lvl_ip_unblock_source(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ip_unblock_source(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IP_DROP_MEMBERSHIP) || defined(IP_ADD_MEMBERSHIP) static -ERL_NIF_TERM nsetopt_lvl_ip_update_membership(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal, - int opt); +ERL_NIF_TERM esock_setopt_lvl_ip_update_membership(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal, + int opt); #endif #if defined(IP_ADD_SOURCE_MEMBERSHIP) || defined(IP_DROP_SOURCE_MEMBERSHIP) || defined(IP_BLOCK_SOURCE) || defined(IP_UNBLOCK_SOURCE) static -ERL_NIF_TERM nsetopt_lvl_ip_update_source(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal, - int opt); +ERL_NIF_TERM esock_setopt_lvl_ip_update_source(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal, + int opt); #endif /* *** Handling set of socket options for level = ipv6 *** */ #if defined(HAVE_IPV6) -static ERL_NIF_TERM nsetopt_lvl_ipv6(ErlNifEnv* env, - ESockDescriptor* descP, - int eOpt, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ipv6(ErlNifEnv* env, + ESockDescriptor* descP, + int eOpt, + ERL_NIF_TERM eVal); #if defined(IPV6_ADDRFORM) -static ERL_NIF_TERM nsetopt_lvl_ipv6_addrform(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ipv6_addrform(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IPV6_ADD_MEMBERSHIP) -static ERL_NIF_TERM nsetopt_lvl_ipv6_add_membership(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ipv6_add_membership(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IPV6_AUTHHDR) -static ERL_NIF_TERM nsetopt_lvl_ipv6_authhdr(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ipv6_authhdr(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IPV6_DROP_MEMBERSHIP) -static ERL_NIF_TERM nsetopt_lvl_ipv6_drop_membership(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ipv6_drop_membership(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IPV6_DSTOPTS) -static ERL_NIF_TERM nsetopt_lvl_ipv6_dstopts(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ipv6_dstopts(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IPV6_FLOWINFO) -static ERL_NIF_TERM nsetopt_lvl_ipv6_flowinfo(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ipv6_flowinfo(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IPV6_HOPLIMIT) -static ERL_NIF_TERM nsetopt_lvl_ipv6_hoplimit(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ipv6_hoplimit(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IPV6_HOPOPTS) -static ERL_NIF_TERM nsetopt_lvl_ipv6_hopopts(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ipv6_hopopts(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IPV6_MTU) -static ERL_NIF_TERM nsetopt_lvl_ipv6_mtu(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ipv6_mtu(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IPV6_MTU_DISCOVER) -static ERL_NIF_TERM nsetopt_lvl_ipv6_mtu_discover(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ipv6_mtu_discover(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IPV6_MULTICAST_HOPS) -static ERL_NIF_TERM nsetopt_lvl_ipv6_multicast_hops(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ipv6_multicast_hops(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IPV6_MULTICAST_IF) -static ERL_NIF_TERM nsetopt_lvl_ipv6_multicast_if(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ipv6_multicast_if(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IPV6_MULTICAST_LOOP) -static ERL_NIF_TERM nsetopt_lvl_ipv6_multicast_loop(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ipv6_multicast_loop(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IPV6_RECVERR) -static ERL_NIF_TERM nsetopt_lvl_ipv6_recverr(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ipv6_recverr(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IPV6_RECVPKTINFO) || defined(IPV6_PKTINFO) -static ERL_NIF_TERM nsetopt_lvl_ipv6_recvpktinfo(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ipv6_recvpktinfo(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IPV6_ROUTER_ALERT) -static ERL_NIF_TERM nsetopt_lvl_ipv6_router_alert(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ipv6_router_alert(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IPV6_RTHDR) -static ERL_NIF_TERM nsetopt_lvl_ipv6_rthdr(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ipv6_rthdr(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IPV6_UNICAST_HOPS) -static ERL_NIF_TERM nsetopt_lvl_ipv6_unicast_hops(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ipv6_unicast_hops(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IPV6_V6ONLY) -static ERL_NIF_TERM nsetopt_lvl_ipv6_v6only(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_ipv6_v6only(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(IPV6_ADD_MEMBERSHIP) || defined(IPV6_DROP_MEMBERSHIP) -static ERL_NIF_TERM nsetopt_lvl_ipv6_update_membership(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal, - int opt); +static ERL_NIF_TERM esock_setopt_lvl_ipv6_update_membership(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal, + int opt); #endif #endif // defined(HAVE_IPV6) -static ERL_NIF_TERM nsetopt_lvl_tcp(ErlNifEnv* env, - ESockDescriptor* descP, - int eOpt, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_tcp(ErlNifEnv* env, + ESockDescriptor* descP, + int eOpt, + ERL_NIF_TERM eVal); #if defined(TCP_CONGESTION) -static ERL_NIF_TERM nsetopt_lvl_tcp_congestion(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_tcp_congestion(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(TCP_MAXSEG) -static ERL_NIF_TERM nsetopt_lvl_tcp_maxseg(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_tcp_maxseg(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(TCP_NODELAY) -static ERL_NIF_TERM nsetopt_lvl_tcp_nodelay(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_tcp_nodelay(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif -static ERL_NIF_TERM nsetopt_lvl_udp(ErlNifEnv* env, - ESockDescriptor* descP, - int eOpt, - ERL_NIF_TERM eVal); -#if defined(UDP_CORK) -static ERL_NIF_TERM nsetopt_lvl_udp_cork(ErlNifEnv* env, +static ERL_NIF_TERM esock_setopt_lvl_udp(ErlNifEnv* env, ESockDescriptor* descP, + int eOpt, ERL_NIF_TERM eVal); +#if defined(UDP_CORK) +static ERL_NIF_TERM esock_setopt_lvl_udp_cork(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(HAVE_SCTP) -static ERL_NIF_TERM nsetopt_lvl_sctp(ErlNifEnv* env, - ESockDescriptor* descP, - int eOpt, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_sctp(ErlNifEnv* env, + ESockDescriptor* descP, + int eOpt, + ERL_NIF_TERM eVal); #if defined(SCTP_ASSOCINFO) -static ERL_NIF_TERM nsetopt_lvl_sctp_associnfo(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_sctp_associnfo(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(SCTP_AUTOCLOSE) -static ERL_NIF_TERM nsetopt_lvl_sctp_autoclose(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_sctp_autoclose(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(SCTP_DISABLE_FRAGMENTS) -static ERL_NIF_TERM nsetopt_lvl_sctp_disable_fragments(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_sctp_disable_fragments(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(SCTP_EVENTS) -static ERL_NIF_TERM nsetopt_lvl_sctp_events(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_sctp_events(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(SCTP_INITMSG) -static ERL_NIF_TERM nsetopt_lvl_sctp_initmsg(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_sctp_initmsg(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(SCTP_MAXSEG) -static ERL_NIF_TERM nsetopt_lvl_sctp_maxseg(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_sctp_maxseg(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(SCTP_NODELAY) -static ERL_NIF_TERM nsetopt_lvl_sctp_nodelay(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_sctp_nodelay(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #if defined(SCTP_RTOINFO) -static ERL_NIF_TERM nsetopt_lvl_sctp_rtoinfo(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_lvl_sctp_rtoinfo(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal); #endif #endif // defined(HAVE_SCTP) -static ERL_NIF_TERM ngetopt(ErlNifEnv* env, - ESockDescriptor* descP, - BOOLEAN_T isEncoded, - BOOLEAN_T isOTP, - int level, - ERL_NIF_TERM eOpt); +static ERL_NIF_TERM esock_getopt(ErlNifEnv* env, + ESockDescriptor* descP, + BOOLEAN_T isEncoded, + BOOLEAN_T isOTP, + int level, + ERL_NIF_TERM eOpt); -static ERL_NIF_TERM ngetopt_otp(ErlNifEnv* env, - ESockDescriptor* descP, - int eOpt); -/* *** ngetopt_otp_debug *** - * *** ngetopt_otp_iow *** - * *** ngetopt_otp_ctrl_proc *** - * *** ngetopt_otp_rcvbuf *** - * *** ngetopt_otp_rcvctrlbuf *** - * *** ngetopt_otp_sndctrlbuf *** - * *** ngetopt_otp_fd *** - * *** ngetopt_otp_domain *** - * *** ngetopt_otp_type *** - * *** ngetopt_otp_protocol *** - */ -#define NGETOPT_OTP_FUNCS \ - NGETOPT_OTP_FUNC_DEF(debug); \ - NGETOPT_OTP_FUNC_DEF(iow); \ - NGETOPT_OTP_FUNC_DEF(ctrl_proc); \ - NGETOPT_OTP_FUNC_DEF(rcvbuf); \ - NGETOPT_OTP_FUNC_DEF(rcvctrlbuf); \ - NGETOPT_OTP_FUNC_DEF(sndctrlbuf); \ - NGETOPT_OTP_FUNC_DEF(fd); \ - NGETOPT_OTP_FUNC_DEF(domain); \ - NGETOPT_OTP_FUNC_DEF(type); \ - NGETOPT_OTP_FUNC_DEF(protocol); -#define NGETOPT_OTP_FUNC_DEF(F) \ - static ERL_NIF_TERM ngetopt_otp_##F(ErlNifEnv* env, \ - ESockDescriptor* descP) -NGETOPT_OTP_FUNCS -#undef NGETOPT_OTP_FUNC_DEF +static ERL_NIF_TERM esock_getopt_otp(ErlNifEnv* env, + ESockDescriptor* descP, + int eOpt); +/* *** esock_getopt_otp_debug *** + * *** esock_getopt_otp_iow *** + * *** esock_getopt_otp_ctrl_proc *** + * *** esock_getopt_otp_rcvbuf *** + * *** esock_getopt_otp_rcvctrlbuf *** + * *** esock_getopt_otp_sndctrlbuf *** + * *** esock_getopt_otp_fd *** + * *** esock_getopt_otp_domain *** + * *** esock_getopt_otp_type *** + * *** esock_getopt_otp_protocol *** + */ +#define ESOCK_GETOPT_OTP_FUNCS \ + ESOCK_GETOPT_OTP_FUNC_DEF(debug); \ + ESOCK_GETOPT_OTP_FUNC_DEF(iow); \ + ESOCK_GETOPT_OTP_FUNC_DEF(ctrl_proc); \ + ESOCK_GETOPT_OTP_FUNC_DEF(rcvbuf); \ + ESOCK_GETOPT_OTP_FUNC_DEF(rcvctrlbuf); \ + ESOCK_GETOPT_OTP_FUNC_DEF(sndctrlbuf); \ + ESOCK_GETOPT_OTP_FUNC_DEF(fd); \ + ESOCK_GETOPT_OTP_FUNC_DEF(domain); \ + ESOCK_GETOPT_OTP_FUNC_DEF(type); \ + ESOCK_GETOPT_OTP_FUNC_DEF(protocol); +#define ESOCK_GETOPT_OTP_FUNC_DEF(F) \ + static ERL_NIF_TERM esock_getopt_otp_##F(ErlNifEnv* env, \ + ESockDescriptor* descP) +ESOCK_GETOPT_OTP_FUNCS +#undef ESOCK_GETOPT_OTP_FUNC_DEF -static ERL_NIF_TERM ngetopt_native(ErlNifEnv* env, - ESockDescriptor* descP, - int level, - ERL_NIF_TERM eOpt); -static ERL_NIF_TERM ngetopt_native_unspec(ErlNifEnv* env, - ESockDescriptor* descP, - int level, - int opt, - SOCKOPTLEN_T valueSz); -static ERL_NIF_TERM ngetopt_level(ErlNifEnv* env, - ESockDescriptor* descP, - int level, - int eOpt); -static ERL_NIF_TERM ngetopt_lvl_socket(ErlNifEnv* env, +static ERL_NIF_TERM esock_getopt_native(ErlNifEnv* env, + ESockDescriptor* descP, + int level, + ERL_NIF_TERM eOpt); +static ERL_NIF_TERM esock_getopt_native_unspec(ErlNifEnv* env, + ESockDescriptor* descP, + int level, + int opt, + SOCKOPTLEN_T valueSz); +static ERL_NIF_TERM esock_getopt_level(ErlNifEnv* env, ESockDescriptor* descP, + int level, int eOpt); +static ERL_NIF_TERM esock_getopt_lvl_socket(ErlNifEnv* env, + ESockDescriptor* descP, + int eOpt); #if defined(SO_ACCEPTCONN) -static ERL_NIF_TERM ngetopt_lvl_sock_acceptconn(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_sock_acceptconn(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(SO_BINDTODEVICE) -static ERL_NIF_TERM ngetopt_lvl_sock_bindtodevice(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_sock_bindtodevice(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(SO_BROADCAST) -static ERL_NIF_TERM ngetopt_lvl_sock_broadcast(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_sock_broadcast(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(SO_DEBUG) -static ERL_NIF_TERM ngetopt_lvl_sock_debug(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_sock_debug(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(SO_DOMAIN) -static ERL_NIF_TERM ngetopt_lvl_sock_domain(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_sock_domain(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(SO_DONTROUTE) -static ERL_NIF_TERM ngetopt_lvl_sock_dontroute(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_sock_dontroute(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(SO_KEEPALIVE) -static ERL_NIF_TERM ngetopt_lvl_sock_keepalive(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_sock_keepalive(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(SO_LINGER) -static ERL_NIF_TERM ngetopt_lvl_sock_linger(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_sock_linger(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(SO_OOBINLINE) -static ERL_NIF_TERM ngetopt_lvl_sock_oobinline(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_sock_oobinline(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(SO_PEEK_OFF) -static ERL_NIF_TERM ngetopt_lvl_sock_peek_off(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_sock_peek_off(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(SO_PRIORITY) -static ERL_NIF_TERM ngetopt_lvl_sock_priority(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_sock_priority(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(SO_PROTOCOL) -static ERL_NIF_TERM ngetopt_lvl_sock_protocol(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_sock_protocol(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(SO_RCVBUF) -static ERL_NIF_TERM ngetopt_lvl_sock_rcvbuf(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_sock_rcvbuf(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(SO_RCVLOWAT) -static ERL_NIF_TERM ngetopt_lvl_sock_rcvlowat(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_sock_rcvlowat(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(SO_RCVTIMEO) -static ERL_NIF_TERM ngetopt_lvl_sock_rcvtimeo(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_sock_rcvtimeo(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(SO_REUSEADDR) -static ERL_NIF_TERM ngetopt_lvl_sock_reuseaddr(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_sock_reuseaddr(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(SO_REUSEPORT) -static ERL_NIF_TERM ngetopt_lvl_sock_reuseport(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_sock_reuseport(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(SO_SNDBUF) -static ERL_NIF_TERM ngetopt_lvl_sock_sndbuf(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_sock_sndbuf(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(SO_SNDLOWAT) -static ERL_NIF_TERM ngetopt_lvl_sock_sndlowat(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_sock_sndlowat(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(SO_SNDTIMEO) -static ERL_NIF_TERM ngetopt_lvl_sock_sndtimeo(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_sock_sndtimeo(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(SO_TIMESTAMP) -static ERL_NIF_TERM ngetopt_lvl_sock_timestamp(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_sock_timestamp(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(SO_TYPE) -static ERL_NIF_TERM ngetopt_lvl_sock_type(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_sock_type(ErlNifEnv* env, + ESockDescriptor* descP); #endif -static ERL_NIF_TERM ngetopt_lvl_ip(ErlNifEnv* env, - ESockDescriptor* descP, - int eOpt); +static ERL_NIF_TERM esock_getopt_lvl_ip(ErlNifEnv* env, + ESockDescriptor* descP, + int eOpt); #if defined(IP_FREEBIND) -static ERL_NIF_TERM ngetopt_lvl_ip_freebind(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ip_freebind(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IP_HDRINCL) -static ERL_NIF_TERM ngetopt_lvl_ip_hdrincl(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ip_hdrincl(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IP_MINTTL) -static ERL_NIF_TERM ngetopt_lvl_ip_minttl(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ip_minttl(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IP_MTU) -static ERL_NIF_TERM ngetopt_lvl_ip_mtu(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ip_mtu(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IP_MTU_DISCOVER) -static ERL_NIF_TERM ngetopt_lvl_ip_mtu_discover(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ip_mtu_discover(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IP_MULTICAST_ALL) -static ERL_NIF_TERM ngetopt_lvl_ip_multicast_all(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ip_multicast_all(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IP_MULTICAST_IF) -static ERL_NIF_TERM ngetopt_lvl_ip_multicast_if(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ip_multicast_if(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IP_MULTICAST_LOOP) -static ERL_NIF_TERM ngetopt_lvl_ip_multicast_loop(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ip_multicast_loop(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IP_MULTICAST_TTL) -static ERL_NIF_TERM ngetopt_lvl_ip_multicast_ttl(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ip_multicast_ttl(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IP_NODEFRAG) -static ERL_NIF_TERM ngetopt_lvl_ip_nodefrag(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ip_nodefrag(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IP_PKTINFO) -static ERL_NIF_TERM ngetopt_lvl_ip_pktinfo(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ip_pktinfo(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IP_RECVDSTADDR) -static ERL_NIF_TERM ngetopt_lvl_ip_recvdstaddr(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ip_recvdstaddr(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IP_RECVERR) -static ERL_NIF_TERM ngetopt_lvl_ip_recverr(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ip_recverr(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IP_RECVIF) -static ERL_NIF_TERM ngetopt_lvl_ip_recvif(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ip_recvif(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IP_RECVOPTS) -static ERL_NIF_TERM ngetopt_lvl_ip_recvopts(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ip_recvopts(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IP_RECVORIGDSTADDR) -static ERL_NIF_TERM ngetopt_lvl_ip_recvorigdstaddr(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ip_recvorigdstaddr(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IP_RECVTOS) -static ERL_NIF_TERM ngetopt_lvl_ip_recvtos(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ip_recvtos(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IP_RECVTTL) -static ERL_NIF_TERM ngetopt_lvl_ip_recvttl(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ip_recvttl(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IP_RETOPTS) -static ERL_NIF_TERM ngetopt_lvl_ip_retopts(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ip_retopts(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IP_ROUTER_ALERT) -static ERL_NIF_TERM ngetopt_lvl_ip_router_alert(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ip_router_alert(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IP_SENDSRCADDR) -static ERL_NIF_TERM ngetopt_lvl_ip_sendsrcaddr(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ip_sendsrcaddr(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IP_TOS) -static ERL_NIF_TERM ngetopt_lvl_ip_tos(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ip_tos(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IP_TRANSPARENT) -static ERL_NIF_TERM ngetopt_lvl_ip_transparent(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ip_transparent(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IP_TTL) -static ERL_NIF_TERM ngetopt_lvl_ip_ttl(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ip_ttl(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(HAVE_IPV6) -static ERL_NIF_TERM ngetopt_lvl_ipv6(ErlNifEnv* env, - ESockDescriptor* descP, - int eOpt); +static ERL_NIF_TERM esock_getopt_lvl_ipv6(ErlNifEnv* env, + ESockDescriptor* descP, + int eOpt); #if defined(IPV6_AUTHHDR) -static ERL_NIF_TERM ngetopt_lvl_ipv6_authhdr(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ipv6_authhdr(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IPV6_DSTOPTS) -static ERL_NIF_TERM ngetopt_lvl_ipv6_dstopts(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ipv6_dstopts(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IPV6_FLOWINFO) -static ERL_NIF_TERM ngetopt_lvl_ipv6_flowinfo(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ipv6_flowinfo(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IPV6_HOPLIMIT) -static ERL_NIF_TERM ngetopt_lvl_ipv6_hoplimit(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ipv6_hoplimit(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IPV6_HOPOPTS) -static ERL_NIF_TERM ngetopt_lvl_ipv6_hopopts(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ipv6_hopopts(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IPV6_MTU) -static ERL_NIF_TERM ngetopt_lvl_ipv6_mtu(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ipv6_mtu(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IPV6_MTU_DISCOVER) -static ERL_NIF_TERM ngetopt_lvl_ipv6_mtu_discover(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ipv6_mtu_discover(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IPV6_MULTICAST_HOPS) -static ERL_NIF_TERM ngetopt_lvl_ipv6_multicast_hops(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ipv6_multicast_hops(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IPV6_MULTICAST_IF) -static ERL_NIF_TERM ngetopt_lvl_ipv6_multicast_if(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ipv6_multicast_if(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IPV6_MULTICAST_LOOP) -static ERL_NIF_TERM ngetopt_lvl_ipv6_multicast_loop(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ipv6_multicast_loop(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IPV6_RECVERR) -static ERL_NIF_TERM ngetopt_lvl_ipv6_recverr(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ipv6_recverr(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IPV6_RECVPKTINFO) || defined(IPV6_PKTINFO) -static ERL_NIF_TERM ngetopt_lvl_ipv6_recvpktinfo(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ipv6_recvpktinfo(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IPV6_ROUTER_ALERT) -static ERL_NIF_TERM ngetopt_lvl_ipv6_router_alert(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ipv6_router_alert(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IPV6_RTHDR) -static ERL_NIF_TERM ngetopt_lvl_ipv6_rthdr(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ipv6_rthdr(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IPV6_UNICAST_HOPS) -static ERL_NIF_TERM ngetopt_lvl_ipv6_unicast_hops(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ipv6_unicast_hops(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(IPV6_V6ONLY) -static ERL_NIF_TERM ngetopt_lvl_ipv6_v6only(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_ipv6_v6only(ErlNifEnv* env, + ESockDescriptor* descP); #endif #endif // defined(HAVE_IPV6) -static ERL_NIF_TERM ngetopt_lvl_tcp(ErlNifEnv* env, - ESockDescriptor* descP, - int eOpt); +static ERL_NIF_TERM esock_getopt_lvl_tcp(ErlNifEnv* env, + ESockDescriptor* descP, + int eOpt); #if defined(TCP_CONGESTION) -static ERL_NIF_TERM ngetopt_lvl_tcp_congestion(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_tcp_congestion(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(TCP_MAXSEG) -static ERL_NIF_TERM ngetopt_lvl_tcp_maxseg(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_tcp_maxseg(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(TCP_NODELAY) -static ERL_NIF_TERM ngetopt_lvl_tcp_nodelay(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_tcp_nodelay(ErlNifEnv* env, + ESockDescriptor* descP); #endif -static ERL_NIF_TERM ngetopt_lvl_udp(ErlNifEnv* env, - ESockDescriptor* descP, - int eOpt); +static ERL_NIF_TERM esock_getopt_lvl_udp(ErlNifEnv* env, + ESockDescriptor* descP, + int eOpt); #if defined(UDP_CORK) -static ERL_NIF_TERM ngetopt_lvl_udp_cork(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_udp_cork(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(HAVE_SCTP) -static ERL_NIF_TERM ngetopt_lvl_sctp(ErlNifEnv* env, - ESockDescriptor* descP, - int eOpt); +static ERL_NIF_TERM esock_getopt_lvl_sctp(ErlNifEnv* env, + ESockDescriptor* descP, + int eOpt); #if defined(SCTP_ASSOCINFO) -static ERL_NIF_TERM ngetopt_lvl_sctp_associnfo(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_sctp_associnfo(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(SCTP_AUTOCLOSE) -static ERL_NIF_TERM ngetopt_lvl_sctp_autoclose(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_sctp_autoclose(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(SCTP_DISABLE_FRAGMENTS) -static ERL_NIF_TERM ngetopt_lvl_sctp_disable_fragments(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_sctp_disable_fragments(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(SCTP_MAXSEG) -static ERL_NIF_TERM ngetopt_lvl_sctp_maxseg(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_sctp_maxseg(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(SCTP_INITMSG) -static ERL_NIF_TERM ngetopt_lvl_sctp_initmsg(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_sctp_initmsg(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(SCTP_NODELAY) -static ERL_NIF_TERM ngetopt_lvl_sctp_nodelay(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_sctp_nodelay(ErlNifEnv* env, + ESockDescriptor* descP); #endif #if defined(SCTP_RTOINFO) -static ERL_NIF_TERM ngetopt_lvl_sctp_rtoinfo(ErlNifEnv* env, - ESockDescriptor* descP); +static ERL_NIF_TERM esock_getopt_lvl_sctp_rtoinfo(ErlNifEnv* env, + ESockDescriptor* descP); #endif #endif // defined(HAVE_SCTP) -static ERL_NIF_TERM nsockname(ErlNifEnv* env, - ESockDescriptor* descP); -static ERL_NIF_TERM npeername(ErlNifEnv* env, - ESockDescriptor* descP); -static ERL_NIF_TERM ncancel(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM op, - ERL_NIF_TERM sockRef, - ERL_NIF_TERM opRef); -static ERL_NIF_TERM ncancel_connect(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM opRef); -static ERL_NIF_TERM ncancel_accept(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - ERL_NIF_TERM opRef); -static ERL_NIF_TERM ncancel_accept_current(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef); -static ERL_NIF_TERM ncancel_accept_waiting(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM opRef); -static ERL_NIF_TERM ncancel_send(ErlNifEnv* env, +static ERL_NIF_TERM esock_sockname(ErlNifEnv* env, + ESockDescriptor* descP); +static ERL_NIF_TERM esock_peername(ErlNifEnv* env, + ESockDescriptor* descP); +static ERL_NIF_TERM esock_cancel(ErlNifEnv* env, ESockDescriptor* descP, + ERL_NIF_TERM op, ERL_NIF_TERM sockRef, ERL_NIF_TERM opRef); -static ERL_NIF_TERM ncancel_send_current(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef); -static ERL_NIF_TERM ncancel_send_waiting(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM opRef); -static ERL_NIF_TERM ncancel_recv(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - ERL_NIF_TERM opRef); -static ERL_NIF_TERM ncancel_recv_current(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef); -static ERL_NIF_TERM ncancel_recv_waiting(ErlNifEnv* env, +static ERL_NIF_TERM esock_cancel_connect(ErlNifEnv* env, ESockDescriptor* descP, ERL_NIF_TERM opRef); -static ERL_NIF_TERM ncancel_read_select(ErlNifEnv* env, +static ERL_NIF_TERM esock_cancel_accept(ErlNifEnv* env, ESockDescriptor* descP, + ERL_NIF_TERM sockRef, ERL_NIF_TERM opRef); -static ERL_NIF_TERM ncancel_write_select(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM opRef); -static ERL_NIF_TERM ncancel_mode_select(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM opRef, - int smode, - int rmode); +static ERL_NIF_TERM esock_cancel_accept_current(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef); +static ERL_NIF_TERM esock_cancel_accept_waiting(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM opRef); +static ERL_NIF_TERM esock_cancel_send(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM opRef); +static ERL_NIF_TERM esock_cancel_send_current(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef); +static ERL_NIF_TERM esock_cancel_send_waiting(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM opRef); +static ERL_NIF_TERM esock_cancel_recv(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM opRef); +static ERL_NIF_TERM esock_cancel_recv_current(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef); +static ERL_NIF_TERM esock_cancel_recv_waiting(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM opRef); +static ERL_NIF_TERM esock_cancel_read_select(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM opRef); +static ERL_NIF_TERM esock_cancel_write_select(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM opRef); +static ERL_NIF_TERM esock_cancel_mode_select(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM opRef, + int smode, + int rmode); #if defined(USE_SETOPT_STR_OPT) -static ERL_NIF_TERM nsetopt_str_opt(ErlNifEnv* env, - ESockDescriptor* descP, - int level, - int opt, - int max, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_str_opt(ErlNifEnv* env, + ESockDescriptor* descP, + int level, + int opt, + int max, + ERL_NIF_TERM eVal); #endif -static ERL_NIF_TERM nsetopt_bool_opt(ErlNifEnv* env, - ESockDescriptor* descP, - int level, - int opt, - ERL_NIF_TERM eVal); -static ERL_NIF_TERM nsetopt_int_opt(ErlNifEnv* env, - ESockDescriptor* descP, - int level, - int opt, - ERL_NIF_TERM eVal); -static ERL_NIF_TERM nsetopt_timeval_opt(ErlNifEnv* env, - ESockDescriptor* descP, - int level, - int opt, - ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_bool_opt(ErlNifEnv* env, + ESockDescriptor* descP, + int level, + int opt, + ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_int_opt(ErlNifEnv* env, + ESockDescriptor* descP, + int level, + int opt, + ERL_NIF_TERM eVal); +static ERL_NIF_TERM esock_setopt_timeval_opt(ErlNifEnv* env, + ESockDescriptor* descP, + int level, + int opt, + ERL_NIF_TERM eVal); #if defined(USE_GETOPT_STR_OPT) -static ERL_NIF_TERM ngetopt_str_opt(ErlNifEnv* env, - ESockDescriptor* descP, - int level, - int opt, - int max); +static ERL_NIF_TERM esock_getopt_str_opt(ErlNifEnv* env, + ESockDescriptor* descP, + int level, + int opt, + int max); #endif -static ERL_NIF_TERM ngetopt_bool_opt(ErlNifEnv* env, - ESockDescriptor* descP, - int level, - int opt); -static ERL_NIF_TERM ngetopt_int_opt(ErlNifEnv* env, - ESockDescriptor* descP, - int level, - int opt); -static ERL_NIF_TERM ngetopt_timeval_opt(ErlNifEnv* env, - ESockDescriptor* descP, - int level, - int opt); +static ERL_NIF_TERM esock_getopt_bool_opt(ErlNifEnv* env, + ESockDescriptor* descP, + int level, + int opt); +static ERL_NIF_TERM esock_getopt_int_opt(ErlNifEnv* env, + ESockDescriptor* descP, + int level, + int opt); +static ERL_NIF_TERM esock_getopt_timeval_opt(ErlNifEnv* env, + ESockDescriptor* descP, + int level, + int opt); static BOOLEAN_T send_check_writer(ErlNifEnv* env, ESockDescriptor* descP, @@ -2238,10 +2286,10 @@ static ERL_NIF_TERM recvmsg_check_msg(ErlNifEnv* env, ErlNifBinary* ctrlBufP, ERL_NIF_TERM sockRef); -static ERL_NIF_TERM nfinalize_connection(ErlNifEnv* env, +static ERL_NIF_TERM esock_finalize_connection(ErlNifEnv* env, + ESockDescriptor* descP); +static ERL_NIF_TERM esock_finalize_close(ErlNifEnv* env, ESockDescriptor* descP); -static ERL_NIF_TERM nfinalize_close(ErlNifEnv* env, - ESockDescriptor* descP); extern char* encode_msghdr(ErlNifEnv* env, ESockDescriptor* descP, @@ -2374,11 +2422,11 @@ static BOOLEAN_T decode_native_get_opt(ErlNifEnv* env, // static void encode_bool(BOOLEAN_T val, ERL_NIF_TERM* eVal); static ERL_NIF_TERM encode_ip_tos(ErlNifEnv* env, int val); -static void socket_stop_handle_current(ErlNifEnv* env, - const char* role, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - ESockRequestor* reqP); +static void esock_stop_handle_current(ErlNifEnv* env, + const char* role, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ESockRequestor* reqP); static void inform_waiting_procs(ErlNifEnv* env, const char* role, ESockDescriptor* descP, @@ -2517,31 +2565,35 @@ static size_t my_strnlen(const char *s, size_t maxlen); #endif */ -static void socket_dtor(ErlNifEnv* env, void* obj); -static void socket_stop(ErlNifEnv* env, - void* obj, - int fd, - int is_direct_call); -static void socket_down(ErlNifEnv* env, - void* obj, - const ErlNifPid* pid, - const ErlNifMonitor* mon); +static void esock_dtor(ErlNifEnv* env, void* obj); +static void esock_stop(ErlNifEnv* env, + void* obj, + int fd, + int is_direct_call); +static void esock_down(ErlNifEnv* env, + void* obj, + const ErlNifPid* pid, + const ErlNifMonitor* mon); #if !defined(__WIN32__) -static void socket_down_acceptor(ErlNifEnv* env, +static void esock_down_acceptor(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + const ErlNifPid* pid); +static void esock_down_writer(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + const ErlNifPid* pid); +static void esock_down_reader(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + const ErlNifPid* pid); + +static char* esock_send_wrap_msg(ErlNifEnv* env, ESockDescriptor* descP, ERL_NIF_TERM sockRef, - const ErlNifPid* pid); -static void socket_down_writer(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - const ErlNifPid* pid); -static void socket_down_reader(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - const ErlNifPid* pid); - + ERL_NIF_TERM cnt); static char* esock_send_close_msg(ErlNifEnv* env, ESockDescriptor* descP, ErlNifPid* pid); @@ -2560,6 +2612,9 @@ static ERL_NIF_TERM mk_abort_msg(ErlNifEnv* env, ERL_NIF_TERM sockRef, ERL_NIF_TERM opRef, ERL_NIF_TERM reason); +static ERL_NIF_TERM mk_wrap_msg(ErlNifEnv* env, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM cnt); static ERL_NIF_TERM mk_close_msg(ErlNifEnv* env, ERL_NIF_TERM sockRef, ERL_NIF_TERM closeRef); @@ -2634,7 +2689,10 @@ static char str_exsend[] = "exsend"; // failed send -/* *** Global atoms *** */ +/* *** Global atoms *** + * Note that when an (global) atom is added here, it must also be added + * in the socket_int.h file! + */ #define GLOBAL_ATOMS \ GLOBAL_ATOM_DECL(abort); \ GLOBAL_ATOM_DECL(accept); \ @@ -2661,6 +2719,7 @@ static char str_exsend[] = "exsend"; // failed send GLOBAL_ATOM_DECL(busy_poll); \ GLOBAL_ATOM_DECL(checksum); \ GLOBAL_ATOM_DECL(close); \ + GLOBAL_ATOM_DECL(command); \ GLOBAL_ATOM_DECL(connect); \ GLOBAL_ATOM_DECL(congestion); \ GLOBAL_ATOM_DECL(context); \ @@ -2857,6 +2916,8 @@ ERL_NIF_TERM esock_atom_socket_tag; // This has a "special" name ('$socket') LOCAL_ATOM_DECL(closed); \ LOCAL_ATOM_DECL(closing); \ LOCAL_ATOM_DECL(cookie_life); \ + LOCAL_ATOM_DECL(counter_wrap); \ + LOCAL_ATOM_DECL(counters); \ LOCAL_ATOM_DECL(data_in); \ LOCAL_ATOM_DECL(do); \ LOCAL_ATOM_DECL(dont); \ @@ -2880,6 +2941,7 @@ ERL_NIF_TERM esock_atom_socket_tag; // This has a "special" name ('$socket') LOCAL_ATOM_DECL(mode); \ LOCAL_ATOM_DECL(multiaddr); \ LOCAL_ATOM_DECL(null); \ + LOCAL_ATOM_DECL(num_acceptors); \ LOCAL_ATOM_DECL(num_dinet); \ LOCAL_ATOM_DECL(num_dinet6); \ LOCAL_ATOM_DECL(num_dlocal); \ @@ -2889,14 +2951,21 @@ ERL_NIF_TERM esock_atom_socket_tag; // This has a "special" name ('$socket') LOCAL_ATOM_DECL(num_psctp); \ LOCAL_ATOM_DECL(num_ptcp); \ LOCAL_ATOM_DECL(num_pudp); \ + LOCAL_ATOM_DECL(num_readers); \ LOCAL_ATOM_DECL(num_sockets); \ LOCAL_ATOM_DECL(num_tdgrams); \ LOCAL_ATOM_DECL(num_tseqpkgs); \ LOCAL_ATOM_DECL(num_tstreams); \ + LOCAL_ATOM_DECL(num_writers); \ LOCAL_ATOM_DECL(partial_delivery); \ LOCAL_ATOM_DECL(peer_error); \ LOCAL_ATOM_DECL(peer_rwnd); \ LOCAL_ATOM_DECL(probe); \ + LOCAL_ATOM_DECL(read_byte); \ + LOCAL_ATOM_DECL(read_fails); \ + LOCAL_ATOM_DECL(read_pkg); \ + LOCAL_ATOM_DECL(read_tries); \ + LOCAL_ATOM_DECL(read_waits); \ LOCAL_ATOM_DECL(select); \ LOCAL_ATOM_DECL(sender_dry); \ LOCAL_ATOM_DECL(send_failure); \ @@ -2905,7 +2974,12 @@ ERL_NIF_TERM esock_atom_socket_tag; // This has a "special" name ('$socket') LOCAL_ATOM_DECL(sourceaddr); \ LOCAL_ATOM_DECL(timeout); \ LOCAL_ATOM_DECL(true); \ - LOCAL_ATOM_DECL(want); + LOCAL_ATOM_DECL(want); \ + LOCAL_ATOM_DECL(write_byte); \ + LOCAL_ATOM_DECL(write_fails); \ + LOCAL_ATOM_DECL(write_pkg); \ + LOCAL_ATOM_DECL(write_tries); \ + LOCAL_ATOM_DECL(write_waits); /* Local error reason atoms */ #define LOCAL_ERROR_REASON_ATOMS \ @@ -2926,11 +3000,11 @@ LOCAL_ERROR_REASON_ATOMS /* *** Sockets *** */ -static ErlNifResourceType* sockets; -static ErlNifResourceTypeInit socketInit = { - socket_dtor, - socket_stop, - (ErlNifResourceDown*) socket_down +static ErlNifResourceType* esocks; +static ErlNifResourceTypeInit esockInit = { + esock_dtor, + esock_stop, + (ErlNifResourceDown*) esock_down }; // Initiated when the nif is loaded @@ -2967,8 +3041,8 @@ static ESOCK_INLINE ErlNifEnv* esock_alloc_env(const char* slogan) * Utility and admin functions: * ---------------------------- * nif_info/0 + * nif_command/1 * nif_supports/1 - * (nif_debug/1) * * The "proper" socket functions: * ------------------------------ @@ -3008,7 +3082,7 @@ static ESOCK_INLINE ErlNifEnv* esock_alloc_env(const char* slogan) * Description: * This is currently just a placeholder... */ -#define MKCT(E, T, C) MKT2((E), (T), MKI((E), (C))) +#define MKCT(E, T, C) MKT2((E), (T), MKUI((E), (C))) static ERL_NIF_TERM nif_info(ErlNifEnv* env, @@ -3018,43 +3092,338 @@ ERL_NIF_TERM nif_info(ErlNifEnv* env, #if defined(__WIN32__) return enif_raise_exception(env, MKA(env, "notsup")); #else - if (argc != 0) { + ERL_NIF_TERM info; + + SGDBG( ("SOCKET", "nif_info -> entry with %d args\r\n", argc) ); + + switch (argc) { + case 0: + info = esock_global_info(env); + break; + + case 1: + { + ESockDescriptor* descP; + + if (!ESOCK_GET_RESOURCE(env, argv[0], (void**) &descP)) { + return enif_make_badarg(env); + } + SSDBG( descP, ("SOCKET", "nif_info -> get socket info\r\n") ); + info = esock_socket_info(env, descP); + } + break; + + default: return enif_make_badarg(env); - } else { - ERL_NIF_TERM numSockets = MKCT(env, atom_num_sockets, data.numSockets); - ERL_NIF_TERM numTypeDGrams = MKCT(env, atom_num_tdgrams, data.numTypeDGrams); - ERL_NIF_TERM numTypeStreams = MKCT(env, atom_num_tstreams, data.numTypeStreams); - ERL_NIF_TERM numTypeSeqPkgs = MKCT(env, atom_num_tseqpkgs, data.numTypeSeqPkgs); - ERL_NIF_TERM numDomLocal = MKCT(env, atom_num_dlocal, data.numDomainLocal); - ERL_NIF_TERM numDomInet = MKCT(env, atom_num_dinet, data.numDomainInet); - ERL_NIF_TERM numDomInet6 = MKCT(env, atom_num_dinet6, data.numDomainInet6); - ERL_NIF_TERM numProtoIP = MKCT(env, atom_num_pip, data.numProtoIP); - ERL_NIF_TERM numProtoTCP = MKCT(env, atom_num_ptcp, data.numProtoTCP); - ERL_NIF_TERM numProtoUDP = MKCT(env, atom_num_pudp, data.numProtoUDP); - ERL_NIF_TERM numProtoSCTP = MKCT(env, atom_num_psctp, data.numProtoSCTP); - ERL_NIF_TERM gcnt[] = {numSockets, - numTypeDGrams, numTypeStreams, numTypeSeqPkgs, - numDomLocal, numDomInet, numDomInet6, - numProtoIP, numProtoTCP, numProtoUDP, numProtoSCTP}; - unsigned int lenGCnt = sizeof(gcnt) / sizeof(ERL_NIF_TERM); - ERL_NIF_TERM lgcnt = MKLA(env, gcnt, lenGCnt); - ERL_NIF_TERM keys[] = {esock_atom_debug, atom_iow, atom_global_counters}; - ERL_NIF_TERM vals[] = {BOOL2ATOM(data.dbg), BOOL2ATOM(data.iow), lgcnt}; - ERL_NIF_TERM info; - unsigned int numKeys = sizeof(keys) / sizeof(ERL_NIF_TERM); - unsigned int numVals = sizeof(vals) / sizeof(ERL_NIF_TERM); + } - ESOCK_ASSERT( (numKeys == numVals) ); + return info; + +#endif +} - if (!MKMA(env, keys, vals, numKeys, &info)) - return enif_make_badarg(env); + +/* + * This function return a property list containing "global" info. + */ +#if !defined(__WIN32__) +static +ERL_NIF_TERM esock_global_info(ErlNifEnv* env) +{ + ERL_NIF_TERM numSockets = MKCT(env, atom_num_sockets, data.numSockets); + ERL_NIF_TERM numTypeDGrams = MKCT(env, atom_num_tdgrams, data.numTypeDGrams); + ERL_NIF_TERM numTypeStreams = MKCT(env, atom_num_tstreams, data.numTypeStreams); + ERL_NIF_TERM numTypeSeqPkgs = MKCT(env, atom_num_tseqpkgs, data.numTypeSeqPkgs); + ERL_NIF_TERM numDomLocal = MKCT(env, atom_num_dlocal, data.numDomainLocal); + ERL_NIF_TERM numDomInet = MKCT(env, atom_num_dinet, data.numDomainInet); + ERL_NIF_TERM numDomInet6 = MKCT(env, atom_num_dinet6, data.numDomainInet6); + ERL_NIF_TERM numProtoIP = MKCT(env, atom_num_pip, data.numProtoIP); + ERL_NIF_TERM numProtoTCP = MKCT(env, atom_num_ptcp, data.numProtoTCP); + ERL_NIF_TERM numProtoUDP = MKCT(env, atom_num_pudp, data.numProtoUDP); + ERL_NIF_TERM numProtoSCTP = MKCT(env, atom_num_psctp, data.numProtoSCTP); + ERL_NIF_TERM gcnt[] = {numSockets, + numTypeDGrams, numTypeStreams, numTypeSeqPkgs, + numDomLocal, numDomInet, numDomInet6, + numProtoIP, numProtoTCP, numProtoUDP, numProtoSCTP}; + unsigned int lenGCnt = sizeof(gcnt) / sizeof(ERL_NIF_TERM); + ERL_NIF_TERM lgcnt = MKLA(env, gcnt, lenGCnt); + ERL_NIF_TERM keys[] = {esock_atom_debug, atom_iow, atom_global_counters}; + ERL_NIF_TERM vals[] = {BOOL2ATOM(data.dbg), BOOL2ATOM(data.iow), lgcnt}; + ERL_NIF_TERM info; + unsigned int numKeys = sizeof(keys) / sizeof(ERL_NIF_TERM); + unsigned int numVals = sizeof(vals) / sizeof(ERL_NIF_TERM); + + ESOCK_ASSERT( (numKeys == numVals) ); + + if (!MKMA(env, keys, vals, numKeys, &info)) + return enif_make_badarg(env); + + return info; +} + + + +/* + * This function return a property *map*. The properties are: + * counters: A list of each socket counter and there current values + * readers: The number of current and waiting readers + * writers: The number of current and waiting writers + * acceptors: The number of current and waiting acceptors + */ +static +ERL_NIF_TERM esock_socket_info(ErlNifEnv* env, + ESockDescriptor* descP) +{ + ERL_NIF_TERM counters = esock_socket_info_counters(env, descP); + ERL_NIF_TERM readers = esock_socket_info_readers(env, descP); + ERL_NIF_TERM writers = esock_socket_info_writers(env, descP); + ERL_NIF_TERM acceptors = esock_socket_info_acceptors(env, descP); + ERL_NIF_TERM keys[] = {atom_counters, atom_num_readers, + atom_num_writers, atom_num_acceptors}; + ERL_NIF_TERM vals[] = {counters, readers, writers, acceptors}; + ERL_NIF_TERM info; + unsigned int numKeys = sizeof(keys) / sizeof(ERL_NIF_TERM); + unsigned int numVals = sizeof(vals) / sizeof(ERL_NIF_TERM); + + SSDBG( descP, ("SOCKET", "esock_socket_info -> " + "\r\n numKeys: %d" + "\r\n numVals: %d" + "\r\n", numKeys, numVals) ); + + ESOCK_ASSERT( (numKeys == numVals) ); + + if (!MKMA(env, keys, vals, numKeys, &info)) + return enif_make_badarg(env); + + SSDBG( descP, ("SOCKET", "esock_socket_info -> done with" + "\r\n info: %T" + "\r\n", info) ); + + return info; - return info; +} + + +/* + * Collect all counters for a socket. + */ +static +ERL_NIF_TERM esock_socket_info_counters(ErlNifEnv* env, + ESockDescriptor* descP) +{ + ERL_NIF_TERM info; + + MLOCK(descP->writeMtx); + MLOCK(descP->readMtx); + + { + ERL_NIF_TERM readByteCnt = MKCT(env, atom_read_byte, descP->readByteCnt); + ERL_NIF_TERM readFails = MKCT(env, atom_read_fails, descP->readFails); + ERL_NIF_TERM readPkgCnt = MKCT(env, atom_read_pkg, descP->readPkgCnt); + ERL_NIF_TERM readTries = MKCT(env, atom_read_tries, descP->readTries); + ERL_NIF_TERM readWaits = MKCT(env, atom_read_waits, descP->readWaits); + ERL_NIF_TERM writeByteCnt = MKCT(env, atom_write_byte, descP->writeByteCnt); + ERL_NIF_TERM writeFails = MKCT(env, atom_write_fails, descP->writeFails); + ERL_NIF_TERM writePkgCnt = MKCT(env, atom_write_pkg, descP->writePkgCnt); + ERL_NIF_TERM writeTries = MKCT(env, atom_write_tries, descP->writeTries); + ERL_NIF_TERM writeWaits = MKCT(env, atom_write_waits, descP->writeWaits); + ERL_NIF_TERM acnt[] = {readByteCnt, readFails, readPkgCnt, + readTries, readWaits, + writeByteCnt, writeFails, writePkgCnt, + writeTries, writeWaits}; + unsigned int lenACnt = sizeof(acnt) / sizeof(ERL_NIF_TERM); + + info = MKLA(env, acnt, lenACnt); + + SSDBG( descP, ("SOCKET", "esock_socket_info_counters -> " + "\r\n lenACnt: %d" + "\r\n info: %T" + "\r\n", lenACnt, info) ); + } + + MUNLOCK(descP->readMtx); + MUNLOCK(descP->writeMtx); + + SSDBG( descP, ("SOCKET", "esock_socket_info_counters -> done with" + "\r\n info: %T" + "\r\n", info) ); + + return info; +} +#endif + + +/* ---------------------------------------------------------------------- + * nif_command + * + * Description: + * This function is intended to handle "various" commands. That is, + * commands and operations that are not part of the socket API proper. + * Currently it handles setting the global debug. Its a map with two + * attributes command and (command) data: + * #{command :: atom(), data :: term()} + * + * Command Data + * debug boolean() + * + */ + +static +ERL_NIF_TERM nif_command(ErlNifEnv* env, + int argc, + const ERL_NIF_TERM argv[]) +{ +#if defined(__WIN32__) + return enif_raise_exception(env, MKA(env, "notsup")); +#else + ERL_NIF_TERM ecmd, ecdata, result; + Uint16 cmd; + + SGDBG( ("SOCKET", "nif_command -> entry with %d args\r\n", argc) ); + + if ((argc != 1) || + !IS_MAP(env, argv[0])) { + return enif_make_badarg(env); + } + ecmd = argv[0]; + + SGDBG( ("SOCKET", "nif_command -> " + "\r\n (e) command: %T" + "\r\n", ecmd) ); + + if (!ecommand2command(env, ecmd, &cmd, &ecdata)) { + SGDBG( ("SOCKET", "nif_command -> invalid command\r\n") ); + return esock_make_error(env, esock_atom_einval); + } + + SGDBG( ("SOCKET", "nif_command -> " + "\r\n command: %d" + "\r\n (e) command data: %T" + "\r\n", cmd, ecdata) ); + + result = esock_command(env, cmd, ecdata); + + SGDBG( ("SOCKET", "nif_command -> done with result: " + "\r\n %T" + "\r\n", result) ); + + return result; + #endif } +#if !defined(__WIN32__) +static +ERL_NIF_TERM esock_command(ErlNifEnv* env, Uint16 cmd, ERL_NIF_TERM ecdata) +{ + ERL_NIF_TERM result; + + SGDBG( ("SOCKET", "esock_command -> entry with 0x%lX\r\n", cmd) ); + + switch (cmd) { + case ESOCK_CMD_DEBUG: + result = esock_command_debug(env, ecdata); + break; + + default: + result = esock_make_error(env, esock_atom_einval); + break; + } + + return result; +} + + + +static +ERL_NIF_TERM esock_command_debug(ErlNifEnv* env, ERL_NIF_TERM ecdata) +{ + ERL_NIF_TERM result; + + /* The data *should* be a boolean() */ + + if (COMPARE(ecdata, esock_atom_true) == 0) { + data.dbg = TRUE; + result = esock_atom_ok; + } else if (COMPARE(ecdata, esock_atom_false) == 0) { + data.dbg = FALSE; + result = esock_atom_ok; + } else { + SGDBG( ("SOCKET", "esock_command_debug -> invalid debug value: %T\r\n", + ecdata) ); + result = esock_make_error(env, esock_atom_einval); + } + + return result; +} +#endif + + +/* *** esock_socket_info_readers *** + * *** esock_socket_info_writers *** + * *** esock_socket_info_acceptors *** + * + * Calculate how many readers | writers | acceptors we have for this socket. + * Current requestor + any waiting requestors (of the type). + * + */ + +#if !defined(__WIN32__) +#define ESOCK_INFO_REQ_FUNCS \ + ESOCK_INFO_REQ_FUNC_DECL(readers, readMtx, currentReaderP, readersQ) \ + ESOCK_INFO_REQ_FUNC_DECL(writers, writeMtx, currentWriterP, writersQ) \ + ESOCK_INFO_REQ_FUNC_DECL(acceptors, accMtx, currentAcceptorP, acceptorsQ) + +#define ESOCK_INFO_REQ_FUNC_DECL(F, MTX, CRP, Q) \ + static \ + ERL_NIF_TERM esock_socket_info_##F(ErlNifEnv* env, \ + ESockDescriptor* descP) \ + { \ + return socket_info_reqs(env, descP, descP->MTX, descP->CRP, &descP->Q); \ + } +ESOCK_INFO_REQ_FUNCS +#undef ESOCK_INFO_REQ_FUNC_DECL + + +static +ERL_NIF_TERM socket_info_reqs(ErlNifEnv* env, + ESockDescriptor* descP, + ErlNifMutex* mtx, + ESockRequestor* crp, + ESockRequestQueue* q) +{ + ESockRequestQueueElement* tmp; + ERL_NIF_TERM info; + unsigned int cnt = 0; + + MLOCK(mtx); + + if (crp != NULL) { + // We have an active requestor! + cnt++; + + // And add all the waiting requestors + tmp = q->first; + while (tmp != NULL) { + cnt++; + tmp = tmp->nextP; + } + } + + MUNLOCK(mtx); + + info = MKUI(env, cnt); + + SSDBG( descP, ("SOCKET", "socket_info_reqs -> done with" + "\r\n info: %T" + "\r\n", info) ); + + return info; +} +#endif + /* ---------------------------------------------------------------------- * nif_supports @@ -3097,40 +3466,40 @@ ERL_NIF_TERM nif_supports(ErlNifEnv* env, return enif_make_badarg(env); } - return nsupports(env, key); + return esock_supports(env, key); #endif } -/* nsupports - what features do we support +/* esock_supports - what features do we support * * This is to prove information about what features actually * work on the current platform. */ #if !defined(__WIN32__) static -ERL_NIF_TERM nsupports(ErlNifEnv* env, int key) +ERL_NIF_TERM esock_supports(ErlNifEnv* env, int key) { ERL_NIF_TERM result; - SGDBG( ("SOCKET", "nsupports -> entry with 0x%lX\r\n", key) ); + SGDBG( ("SOCKET", "esock_supports -> entry with 0x%lX\r\n", key) ); switch (key) { - case SOCKET_SUPPORTS_OPTIONS: - result = nsupports_options(env); + case ESOCK_SUPPORTS_OPTIONS: + result = esock_supports_options(env); break; - case SOCKET_SUPPORTS_SCTP: - result = nsupports_sctp(env); + case ESOCK_SUPPORTS_SCTP: + result = esock_supports_sctp(env); break; - case SOCKET_SUPPORTS_IPV6: - result = nsupports_ipv6(env); + case ESOCK_SUPPORTS_IPV6: + result = esock_supports_ipv6(env); break; - case SOCKET_SUPPORTS_LOCAL: - result = nsupports_local(env); + case ESOCK_SUPPORTS_LOCAL: + result = esock_supports_local(env); break; default: @@ -3145,19 +3514,19 @@ ERL_NIF_TERM nsupports(ErlNifEnv* env, int key) #if !defined(__WIN32__) static -ERL_NIF_TERM nsupports_options(ErlNifEnv* env) +ERL_NIF_TERM esock_supports_options(ErlNifEnv* env) { - ERL_NIF_TERM sockOpts = nsupports_options_socket(env); + ERL_NIF_TERM sockOpts = esock_supports_options_socket(env); ERL_NIF_TERM sockOptsT = MKT2(env, esock_atom_socket, sockOpts); - ERL_NIF_TERM ipOpts = nsupports_options_ip(env); + ERL_NIF_TERM ipOpts = esock_supports_options_ip(env); ERL_NIF_TERM ipOptsT = MKT2(env, esock_atom_ip, ipOpts); - ERL_NIF_TERM ipv6Opts = nsupports_options_ipv6(env); + ERL_NIF_TERM ipv6Opts = esock_supports_options_ipv6(env); ERL_NIF_TERM ipv6OptsT = MKT2(env, esock_atom_ipv6, ipv6Opts); - ERL_NIF_TERM tcpOpts = nsupports_options_tcp(env); + ERL_NIF_TERM tcpOpts = esock_supports_options_tcp(env); ERL_NIF_TERM tcpOptsT = MKT2(env, esock_atom_tcp, tcpOpts); - ERL_NIF_TERM udpOpts = nsupports_options_udp(env); + ERL_NIF_TERM udpOpts = esock_supports_options_udp(env); ERL_NIF_TERM udpOptsT = MKT2(env, esock_atom_udp, udpOpts); - ERL_NIF_TERM sctpOpts = nsupports_options_sctp(env); + ERL_NIF_TERM sctpOpts = esock_supports_options_sctp(env); ERL_NIF_TERM sctpOptsT = MKT2(env, esock_atom_sctp, sctpOpts); ERL_NIF_TERM optsA[] = {sockOptsT, ipOptsT, ipv6OptsT, @@ -3173,13 +3542,13 @@ ERL_NIF_TERM nsupports_options(ErlNifEnv* env) #if !defined(__WIN32__) static -ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env) +ERL_NIF_TERM esock_supports_options_socket(ErlNifEnv* env) { SocketTArray opts = TARRAY_CREATE(128); ERL_NIF_TERM tmp, optsL; - /* *** SOCKET_OPT_SOCK_ACCEPTCONN => SO_ACCEPTCONN *** */ + /* *** ESOCK_OPT_SOCK_ACCEPTCONN => SO_ACCEPTCONN *** */ #if defined(SO_ACCEPTCONN) tmp = MKT2(env, esock_atom_acceptconn, esock_atom_true); #else @@ -3188,12 +3557,12 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SOCK_ACCEPTFILTER => SO_ACCEPTFILTER *** */ + /* *** ESOCK_OPT_SOCK_ACCEPTFILTER => SO_ACCEPTFILTER *** */ tmp = MKT2(env, esock_atom_acceptfilter, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SOCK_BINDTODEVICE => SO_BINDTODEVICE *** */ + /* *** ESOCK_OPT_SOCK_BINDTODEVICE => SO_BINDTODEVICE *** */ #if defined(SO_BINDTODEVICE) tmp = MKT2(env, esock_atom_bindtodevice, esock_atom_true); #else @@ -3202,7 +3571,7 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SOCK_BROADCAST => SO_BROADCAST *** */ + /* *** ESOCK_OPT_SOCK_BROADCAST => SO_BROADCAST *** */ #if defined(SO_BROADCAST) tmp = MKT2(env, esock_atom_broadcast, esock_atom_true); #else @@ -3211,12 +3580,12 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SOCK_BUSY_POLL => SO_BUSY_POLL *** */ + /* *** ESOCK_OPT_SOCK_BUSY_POLL => SO_BUSY_POLL *** */ tmp = MKT2(env, esock_atom_busy_poll, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SOCK_DEBUG => SO_DEBUG *** */ + /* *** ESOCK_OPT_SOCK_DEBUG => SO_DEBUG *** */ #if defined(SO_DEBUG) tmp = MKT2(env, esock_atom_debug, esock_atom_true); #else @@ -3225,7 +3594,7 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SOCK_DOMAIN => SO_DOMAIN *** */ + /* *** ESOCK_OPT_SOCK_DOMAIN => SO_DOMAIN *** */ #if defined(SO_DOMAIN) tmp = MKT2(env, esock_atom_domain, esock_atom_true); #else @@ -3234,7 +3603,7 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SOCK_DONTROUTE => SO_DONTROUTE *** */ + /* *** ESOCK_OPT_SOCK_DONTROUTE => SO_DONTROUTE *** */ #if defined(SO_DONTROUTE) tmp = MKT2(env, esock_atom_dontroute, esock_atom_true); #else @@ -3243,12 +3612,12 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SOCK_ERROR => SO_ERROR *** */ + /* *** ESOCK_OPT_SOCK_ERROR => SO_ERROR *** */ tmp = MKT2(env, esock_atom_error, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SOCK_KEEPALIVE => SO_KEEPALIVE *** */ + /* *** ESOCK_OPT_SOCK_KEEPALIVE => SO_KEEPALIVE *** */ #if defined(SO_KEEPALIVE) tmp = MKT2(env, esock_atom_keepalive, esock_atom_true); #else @@ -3257,7 +3626,7 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SOCK_LINGER => SO_LINGER *** */ + /* *** ESOCK_OPT_SOCK_LINGER => SO_LINGER *** */ #if defined(SO_LINGER) tmp = MKT2(env, esock_atom_linger, esock_atom_true); #else @@ -3266,12 +3635,12 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SOCK_MARK => SO_MARK *** */ + /* *** ESOCK_OPT_SOCK_MARK => SO_MARK *** */ tmp = MKT2(env, esock_atom_mark, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SOCK_OOBINLINE => SO_OOBINLINE *** */ + /* *** ESOCK_OPT_SOCK_OOBINLINE => SO_OOBINLINE *** */ #if defined(SO_OOBINLINE) tmp = MKT2(env, esock_atom_oobinline, esock_atom_true); #else @@ -3280,12 +3649,12 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_PASSCRED => SO_PASSCRED *** */ + /* *** ESOCK_OPT_PASSCRED => SO_PASSCRED *** */ tmp = MKT2(env, esock_atom_passcred, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SOCK_PEEK_OFF => SO_PEEK_OFF *** */ + /* *** ESOCK_OPT_SOCK_PEEK_OFF => SO_PEEK_OFF *** */ #if defined(SO_PEEK_OFF) tmp = MKT2(env, esock_atom_peek_off, esock_atom_true); #else @@ -3294,12 +3663,12 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SOCK_PEEKCRED => SO_PEEKCRED *** */ + /* *** ESOCK_OPT_SOCK_PEEKCRED => SO_PEEKCRED *** */ tmp = MKT2(env, esock_atom_peekcred, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SOCK_PRIORITY => SO_PRIORITY *** */ + /* *** ESOCK_OPT_SOCK_PRIORITY => SO_PRIORITY *** */ #if defined(SO_PRIORITY) tmp = MKT2(env, esock_atom_priority, esock_atom_true); #else @@ -3308,7 +3677,7 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SOCK_PROTOCOL => SO_PROTOCOL *** */ + /* *** ESOCK_OPT_SOCK_PROTOCOL => SO_PROTOCOL *** */ #if defined(SO_PROTOCOL) tmp = MKT2(env, esock_atom_protocol, esock_atom_true); #else @@ -3317,7 +3686,7 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SOCK_RCVBUF => SO_RCVBUF *** */ + /* *** ESOCK_OPT_SOCK_RCVBUF => SO_RCVBUF *** */ #if defined(SO_RCVBUF) tmp = MKT2(env, esock_atom_rcvbuf, esock_atom_true); #else @@ -3326,12 +3695,12 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SOCK_RCVBUFFORCE => SO_RCVBUFFORCE *** */ + /* *** ESOCK_OPT_SOCK_RCVBUFFORCE => SO_RCVBUFFORCE *** */ tmp = MKT2(env, esock_atom_rcvbufforce, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SOCK_RCVLOWAT => SO_RCVLOWAT *** */ + /* *** ESOCK_OPT_SOCK_RCVLOWAT => SO_RCVLOWAT *** */ #if defined(SO_RCVLOWAT) tmp = MKT2(env, esock_atom_rcvlowat, esock_atom_true); #else @@ -3340,7 +3709,7 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SOCK_RCVTIMEO => SO_RCVTIMEO *** */ + /* *** ESOCK_OPT_SOCK_RCVTIMEO => SO_RCVTIMEO *** */ #if defined(SO_RCVTIMEO) tmp = MKT2(env, esock_atom_rcvtimeo, esock_atom_true); #else @@ -3349,7 +3718,7 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SOCK_REUSEADDR => SO_REUSEADDR *** */ + /* *** ESOCK_OPT_SOCK_REUSEADDR => SO_REUSEADDR *** */ #if defined(SO_REUSEADDR) tmp = MKT2(env, esock_atom_reuseaddr, esock_atom_true); #else @@ -3358,7 +3727,7 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SOCK_REUSEPORT => SO_REUSEPORT *** */ + /* *** ESOCK_OPT_SOCK_REUSEPORT => SO_REUSEPORT *** */ #if defined(SO_REUSEPORT) tmp = MKT2(env, esock_atom_reuseport, esock_atom_true); #else @@ -3367,17 +3736,17 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SOCK_RXQ_OVFL => SO_RXQ_OVFL *** */ + /* *** ESOCK_OPT_SOCK_RXQ_OVFL => SO_RXQ_OVFL *** */ tmp = MKT2(env, esock_atom_rxq_ovfl, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SOCK_SETFIB => SO_SETFIB *** */ + /* *** ESOCK_OPT_SOCK_SETFIB => SO_SETFIB *** */ tmp = MKT2(env, esock_atom_setfib, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SOCK_SNDBUF => SO_SNDBUF *** */ + /* *** ESOCK_OPT_SOCK_SNDBUF => SO_SNDBUF *** */ #if defined(SO_SNDBUF) tmp = MKT2(env, esock_atom_sndbuf, esock_atom_true); #else @@ -3386,12 +3755,12 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SOCK_SNDBUFFORCE => SO_SNDBUFFORCE *** */ + /* *** ESOCK_OPT_SOCK_SNDBUFFORCE => SO_SNDBUFFORCE *** */ tmp = MKT2(env, esock_atom_sndbufforce, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SOCK_SNDLOWAT => SO_SNDLOWAT *** */ + /* *** ESOCK_OPT_SOCK_SNDLOWAT => SO_SNDLOWAT *** */ #if defined(SO_SNDLOWAT) tmp = MKT2(env, esock_atom_sndlowat, esock_atom_true); #else @@ -3400,7 +3769,7 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SOCK_SNDTIMEO => SO_SNDTIMEO *** */ + /* *** ESOCK_OPT_SOCK_SNDTIMEO => SO_SNDTIMEO *** */ #if defined(SO_SNDTIMEO) tmp = MKT2(env, esock_atom_sndtimeo, esock_atom_true); #else @@ -3409,7 +3778,7 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SOCK_TIMESTAMP => SO_TIMESTAMP *** */ + /* *** ESOCK_OPT_SOCK_TIMESTAMP => SO_TIMESTAMP *** */ #if defined(SO_TIMESTAMP) tmp = MKT2(env, esock_atom_timestamp, esock_atom_true); #else @@ -3418,7 +3787,7 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SOCK_TYPE => SO_TYPE *** */ + /* *** ESOCK_OPT_SOCK_TYPE => SO_TYPE *** */ #if defined(SO_TYPE) tmp = MKT2(env, esock_atom_type, esock_atom_true); #else @@ -3437,13 +3806,13 @@ ERL_NIF_TERM nsupports_options_socket(ErlNifEnv* env) #if !defined(__WIN32__) static -ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env) +ERL_NIF_TERM esock_supports_options_ip(ErlNifEnv* env) { SocketTArray opts = TARRAY_CREATE(128); ERL_NIF_TERM tmp, optsL; - /* *** SOCKET_OPT_IP_ADD_MEMBERSHIP => IP_ADD_MEMBERSHIP *** */ + /* *** ESOCK_OPT_IP_ADD_MEMBERSHIP => IP_ADD_MEMBERSHIP *** */ #if defined(IP_ADD_MEMBERSHIP) tmp = MKT2(env, esock_atom_add_membership, esock_atom_true); #else @@ -3452,7 +3821,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_ADD_SOURCE_MEMBERSHIP => IP_ADD_SOURCE_MEMBERSHIP *** */ + /* *** ESOCK_OPT_IP_ADD_SOURCE_MEMBERSHIP => IP_ADD_SOURCE_MEMBERSHIP *** */ #if defined(IP_ADD_SOURCE_MEMBERSHIP) tmp = MKT2(env, esock_atom_add_source_membership, esock_atom_true); #else @@ -3461,7 +3830,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_BLOCK_SOURCE => IP_BLOCK_SOURCE *** */ + /* *** ESOCK_OPT_IP_BLOCK_SOURCE => IP_BLOCK_SOURCE *** */ #if defined(IP_BLOCK_SOURCE) tmp = MKT2(env, esock_atom_block_source, esock_atom_true); #else @@ -3470,12 +3839,12 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_DONTFRAG => IP_DONTFRAG *** */ + /* *** ESOCK_OPT_IP_DONTFRAG => IP_DONTFRAG *** */ tmp = MKT2(env, esock_atom_dontfrag, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_DROP_MEMBERSHIP => IP_DROP_MEMBERSHIP *** */ + /* *** ESOCK_OPT_IP_DROP_MEMBERSHIP => IP_DROP_MEMBERSHIP *** */ #if defined(IP_DROP_MEMBERSHIP) tmp = MKT2(env, esock_atom_drop_membership, esock_atom_true); #else @@ -3484,7 +3853,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_DROP_SOURCE_MEMBERSHIP => IP_DROP_SOURCE_MEMBERSHIP *** */ + /* *** ESOCK_OPT_IP_DROP_SOURCE_MEMBERSHIP => IP_DROP_SOURCE_MEMBERSHIP *** */ #if defined(IP_DROP_SOURCE_MEMBERSHIP) tmp = MKT2(env, esock_atom_drop_source_membership, esock_atom_true); #else @@ -3493,7 +3862,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_FREEBIND => IP_FREEBIND *** */ + /* *** ESOCK_OPT_IP_FREEBIND => IP_FREEBIND *** */ #if defined(IP_FREEBIND) tmp = MKT2(env, esock_atom_freebind, esock_atom_true); #else @@ -3502,7 +3871,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_HDRINCL => IP_HDRINCL *** */ + /* *** ESOCK_OPT_IP_HDRINCL => IP_HDRINCL *** */ #if defined(IP_HDRINCL) tmp = MKT2(env, esock_atom_hdrincl, esock_atom_true); #else @@ -3511,7 +3880,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_MINTTL => IP_MINTTL *** */ + /* *** ESOCK_OPT_IP_MINTTL => IP_MINTTL *** */ #if defined(IP_MINTTL) tmp = MKT2(env, esock_atom_minttl, esock_atom_true); #else @@ -3520,7 +3889,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_MSFILTER => IP_MSFILTER / IP_MSFILTER_SIZE *** */ + /* *** ESOCK_OPT_IP_MSFILTER => IP_MSFILTER / IP_MSFILTER_SIZE *** */ #if defined(IP_MSFILTER) && defined(IP_MSFILTER_SIZE) tmp = MKT2(env, esock_atom_msfilter, esock_atom_true); #else @@ -3529,12 +3898,12 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_MTU => IP_MTU *** */ + /* *** ESOCK_OPT_IP_MTU => IP_MTU *** */ tmp = MKT2(env, esock_atom_mtu, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_MTU_DISCOVER => IP_MTU_DISCOVER *** */ + /* *** ESOCK_OPT_IP_MTU_DISCOVER => IP_MTU_DISCOVER *** */ #if defined(IP_MTU_DISCOVER) tmp = MKT2(env, esock_atom_mtu_discover, esock_atom_true); #else @@ -3543,7 +3912,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_MULTICAST_ALL => IP_MULTICAST_ALL *** */ + /* *** ESOCK_OPT_IP_MULTICAST_ALL => IP_MULTICAST_ALL *** */ #if defined(IP_MULTICAST_ALL) tmp = MKT2(env, esock_atom_multicast_all, esock_atom_true); #else @@ -3552,7 +3921,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_MULTICAST_IF => IP_MULTICAST_IF *** */ + /* *** ESOCK_OPT_IP_MULTICAST_IF => IP_MULTICAST_IF *** */ #if defined(IP_MULTICAST_IF) tmp = MKT2(env, esock_atom_multicast_if, esock_atom_true); #else @@ -3561,7 +3930,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_MULTICAST_LOOP => IP_MULTICAST_LOOP *** */ + /* *** ESOCK_OPT_IP_MULTICAST_LOOP => IP_MULTICAST_LOOP *** */ #if defined(IP_MULTICAST_LOOP) tmp = MKT2(env, esock_atom_multicast_loop, esock_atom_true); #else @@ -3570,7 +3939,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_MULTICAST_TTL => IP_MULTICAST_TTL *** */ + /* *** ESOCK_OPT_IP_MULTICAST_TTL => IP_MULTICAST_TTL *** */ #if defined(IP_MULTICAST_TTL) tmp = MKT2(env, esock_atom_multicast_ttl, esock_atom_true); #else @@ -3579,7 +3948,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_NODEFRAG => IP_NODEFRAG *** */ + /* *** ESOCK_OPT_IP_NODEFRAG => IP_NODEFRAG *** */ #if defined(IP_NODEFRAG) tmp = MKT2(env, esock_atom_nodefrag, esock_atom_true); #else @@ -3588,12 +3957,12 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_OPTIONS => IP_OPTIONS *** */ + /* *** ESOCK_OPT_IP_OPTIONS => IP_OPTIONS *** */ tmp = MKT2(env, esock_atom_options, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_PKTINFO => IP_PKTINFO *** */ + /* *** ESOCK_OPT_IP_PKTINFO => IP_PKTINFO *** */ #if defined(IP_PKTINFO) tmp = MKT2(env, esock_atom_pktinfo, esock_atom_true); #else @@ -3602,7 +3971,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_RECVDSTADDR => IP_RECVDSTADDR *** */ + /* *** ESOCK_OPT_IP_RECVDSTADDR => IP_RECVDSTADDR *** */ #if defined(IP_RECVDSTADDR) tmp = MKT2(env, esock_atom_recvdstaddr, esock_atom_true); #else @@ -3611,7 +3980,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_RECVERR => IP_RECVERR *** */ + /* *** ESOCK_OPT_IP_RECVERR => IP_RECVERR *** */ #if defined(IP_RECVERR) tmp = MKT2(env, esock_atom_recverr, esock_atom_true); #else @@ -3620,7 +3989,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_RECVIF => IP_RECVIF *** */ + /* *** ESOCK_OPT_IP_RECVIF => IP_RECVIF *** */ #if defined(IP_RECVIF) tmp = MKT2(env, esock_atom_recvif, esock_atom_true); #else @@ -3629,7 +3998,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_RECVOPTS => IP_RECVOPTS *** */ + /* *** ESOCK_OPT_IP_RECVOPTS => IP_RECVOPTS *** */ #if defined(IP_RECVOPTS) tmp = MKT2(env, esock_atom_recvopts, esock_atom_true); #else @@ -3638,7 +4007,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_RECVORIGDSTADDR => IP_RECVORIGDSTADDR *** */ + /* *** ESOCK_OPT_IP_RECVORIGDSTADDR => IP_RECVORIGDSTADDR *** */ #if defined(IP_RECVORIGDSTADDR) tmp = MKT2(env, esock_atom_recvorigdstaddr, esock_atom_true); #else @@ -3647,7 +4016,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_RECVTOS => IP_RECVTOS *** */ + /* *** ESOCK_OPT_IP_RECVTOS => IP_RECVTOS *** */ #if defined(IP_RECVTOS) tmp = MKT2(env, esock_atom_recvtos, esock_atom_true); #else @@ -3656,7 +4025,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_RECVTTL => IP_RECVTTL *** */ + /* *** ESOCK_OPT_IP_RECVTTL => IP_RECVTTL *** */ #if defined(IP_RECVTTL) tmp = MKT2(env, esock_atom_recvttl, esock_atom_true); #else @@ -3665,7 +4034,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_RETOPTS => IP_RETOPTS *** */ + /* *** ESOCK_OPT_IP_RETOPTS => IP_RETOPTS *** */ #if defined(IP_RETOPTS) tmp = MKT2(env, esock_atom_retopts, esock_atom_true); #else @@ -3674,7 +4043,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_ROUTER_ALERT => IP_ROUTER_ALERT *** */ + /* *** ESOCK_OPT_IP_ROUTER_ALERT => IP_ROUTER_ALERT *** */ #if defined(IP_ROUTER_ALERT) tmp = MKT2(env, esock_atom_router_alert, esock_atom_true); #else @@ -3683,7 +4052,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_SENDSRCADDR => IP_SENDSRCADDR *** */ + /* *** ESOCK_OPT_IP_SENDSRCADDR => IP_SENDSRCADDR *** */ #if defined(IP_SENDSRCADDR) tmp = MKT2(env, esock_atom_sendsrcaddr, esock_atom_true); #else @@ -3692,7 +4061,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_TOS => IP_TOS *** */ + /* *** ESOCK_OPT_IP_TOS => IP_TOS *** */ #if defined(IP_TOS) tmp = MKT2(env, esock_atom_tos, esock_atom_true); #else @@ -3701,7 +4070,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_TRANSPARENT => IP_TRANSPARENT *** */ + /* *** ESOCK_OPT_IP_TRANSPARENT => IP_TRANSPARENT *** */ #if defined(IP_TRANSPARENT) tmp = MKT2(env, esock_atom_transparent, esock_atom_true); #else @@ -3710,7 +4079,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_TTL => IP_TTL *** */ + /* *** ESOCK_OPT_IP_TTL => IP_TTL *** */ #if defined(IP_TTL) tmp = MKT2(env, esock_atom_ttl, esock_atom_true); #else @@ -3719,7 +4088,7 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IP_UNBLOCK_SOURCE => IP_UNBLOCK_SOURCE *** */ + /* *** ESOCK_OPT_IP_UNBLOCK_SOURCE => IP_UNBLOCK_SOURCE *** */ #if defined(IP_UNBLOCK_SOURCE) tmp = MKT2(env, esock_atom_unblock_source, esock_atom_true); #else @@ -3738,13 +4107,13 @@ ERL_NIF_TERM nsupports_options_ip(ErlNifEnv* env) #if !defined(__WIN32__) static -ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env) +ERL_NIF_TERM esock_supports_options_ipv6(ErlNifEnv* env) { SocketTArray opts = TARRAY_CREATE(128); ERL_NIF_TERM tmp, optsL; - /* *** SOCKET_OPT_IPV6_ADDRFORM => IPV6_ADDRFORM *** */ + /* *** ESOCK_OPT_IPV6_ADDRFORM => IPV6_ADDRFORM *** */ #if defined(IPV6_ADDRFORM) tmp = MKT2(env, esock_atom_addrform, esock_atom_true); #else @@ -3753,7 +4122,7 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IPV6_ADD_MEMBERSHIP => IPV6_ADD_MEMBERSHIP *** */ + /* *** ESOCK_OPT_IPV6_ADD_MEMBERSHIP => IPV6_ADD_MEMBERSHIP *** */ #if defined(IPV6_ADD_MEMBERSHIP) tmp = MKT2(env, esock_atom_add_membership, esock_atom_true); #else @@ -3762,7 +4131,7 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IPV6_AUTHHDR => IPV6_AUTHHDR *** */ + /* *** ESOCK_OPT_IPV6_AUTHHDR => IPV6_AUTHHDR *** */ #if defined(IPV6_AUTHHDR) tmp = MKT2(env, esock_atom_authhdr, esock_atom_true); #else @@ -3771,17 +4140,17 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IPV6_AUTH_LEVEL => IPV6_AUTH_LEVEL *** */ + /* *** ESOCK_OPT_IPV6_AUTH_LEVEL => IPV6_AUTH_LEVEL *** */ tmp = MKT2(env, esock_atom_auth_level, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IPV6_CHECKSUM => IPV6_CHECKSUM *** */ + /* *** ESOCK_OPT_IPV6_CHECKSUM => IPV6_CHECKSUM *** */ tmp = MKT2(env, esock_atom_checksum, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IPV6_DROP_MEMBERSHIP => IPV6_DROP_MEMBERSHIP *** */ + /* *** ESOCK_OPT_IPV6_DROP_MEMBERSHIP => IPV6_DROP_MEMBERSHIP *** */ #if defined(IPV6_DROP_MEMBERSHIP) tmp = MKT2(env, esock_atom_drop_membership, esock_atom_true); #else @@ -3790,7 +4159,7 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IPV6_DSTOPTS => IPV6_DSTOPTS *** */ + /* *** ESOCK_OPT_IPV6_DSTOPTS => IPV6_DSTOPTS *** */ #if defined(IPV6_DSTOPTS) tmp = MKT2(env, esock_atom_dstopts, esock_atom_true); #else @@ -3799,22 +4168,22 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IPV6_ESP_NETWORK_LEVEL => IPV6_ESP_NETWORK_LEVEL *** */ + /* *** ESOCK_OPT_IPV6_ESP_NETWORK_LEVEL => IPV6_ESP_NETWORK_LEVEL *** */ tmp = MKT2(env, esock_atom_esp_network_level, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IPV6_ESP_TRANS_LEVEL => IPV6_ESP_TRANS_LEVEL *** */ + /* *** ESOCK_OPT_IPV6_ESP_TRANS_LEVEL => IPV6_ESP_TRANS_LEVEL *** */ tmp = MKT2(env, esock_atom_esp_trans_level, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IPV6_FAITH => IPV6_FAITH *** */ + /* *** ESOCK_OPT_IPV6_FAITH => IPV6_FAITH *** */ tmp = MKT2(env, esock_atom_faith, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IPV6_FLOWINFO => IPV6_FLOWINFO *** */ + /* *** ESOCK_OPT_IPV6_FLOWINFO => IPV6_FLOWINFO *** */ #if defined(IPV6_FLOWINFO) tmp = MKT2(env, esock_atom_flowinfo, esock_atom_true); #else @@ -3823,7 +4192,7 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IPV6_HOPLIMIT => IPV6_HOPLIMIT *** */ + /* *** ESOCK_OPT_IPV6_HOPLIMIT => IPV6_HOPLIMIT *** */ #if defined(IPV6_HOPLIMIT) tmp = MKT2(env, esock_atom_hoplimit, esock_atom_true); #else @@ -3832,7 +4201,7 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IPV6_HOPOPTS => IPV6_HOPOPTS *** */ + /* *** ESOCK_OPT_IPV6_HOPOPTS => IPV6_HOPOPTS *** */ #if defined(IPV6_HOPOPTS) tmp = MKT2(env, esock_atom_hopopts, esock_atom_true); #else @@ -3841,22 +4210,22 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IPV6_IPCOMP_LEVEL => IPV6_IPCOMP_LEVEL *** */ + /* *** ESOCK_OPT_IPV6_IPCOMP_LEVEL => IPV6_IPCOMP_LEVEL *** */ tmp = MKT2(env, esock_atom_ipcomp_level, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IPV6_JOIN_GROUP => IPV6_JOIN_GROUP *** */ + /* *** ESOCK_OPT_IPV6_JOIN_GROUP => IPV6_JOIN_GROUP *** */ tmp = MKT2(env, esock_atom_join_group, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IPV6_LEAVE_GROUP => IPV6_LEAVE_GROUP *** */ + /* *** ESOCK_OPT_IPV6_LEAVE_GROUP => IPV6_LEAVE_GROUP *** */ tmp = MKT2(env, esock_atom_leave_group, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IPV6_MTU => IPV6_MTU *** */ + /* *** ESOCK_OPT_IPV6_MTU => IPV6_MTU *** */ #if defined(IPV6_MTU) tmp = MKT2(env, esock_atom_mtu, esock_atom_true); #else @@ -3865,7 +4234,7 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IPV6_MTU_DISCOVER => IPV6_MTU_DISCOVER *** */ + /* *** ESOCK_OPT_IPV6_MTU_DISCOVER => IPV6_MTU_DISCOVER *** */ #if defined(IPV6_MTU_DISCOVER) tmp = MKT2(env, esock_atom_mtu_discover, esock_atom_true); #else @@ -3874,7 +4243,7 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IPV6_MULTICAST_HOPS => IPV6_MULTICAST_HOPS *** */ + /* *** ESOCK_OPT_IPV6_MULTICAST_HOPS => IPV6_MULTICAST_HOPS *** */ #if defined(IPV6_MULTICAST_HOPS) tmp = MKT2(env, esock_atom_multicast_hops, esock_atom_true); #else @@ -3883,7 +4252,7 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IPV6_MULTICAST_IF => IPV6_MULTICAST_IF *** */ + /* *** ESOCK_OPT_IPV6_MULTICAST_IF => IPV6_MULTICAST_IF *** */ #if defined(IPV6_MULTICAST_IF) tmp = MKT2(env, esock_atom_multicast_if, esock_atom_true); #else @@ -3892,7 +4261,7 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IPV6_MULTICAST_LOOP => IPV6_MULTICAST_LOOP *** */ + /* *** ESOCK_OPT_IPV6_MULTICAST_LOOP => IPV6_MULTICAST_LOOP *** */ #if defined(IPV6_MULTICAST_LOOP) tmp = MKT2(env, esock_atom_multicast_loop, esock_atom_true); #else @@ -3901,17 +4270,17 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IPV6_PORTRANGE => IPV6_PORTRANGE *** */ + /* *** ESOCK_OPT_IPV6_PORTRANGE => IPV6_PORTRANGE *** */ tmp = MKT2(env, esock_atom_portrange, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IPV6_PKTOPTIONS => IPV6_PKTOPTIONS *** */ + /* *** ESOCK_OPT_IPV6_PKTOPTIONS => IPV6_PKTOPTIONS *** */ tmp = MKT2(env, esock_atom_pktoptions, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IPV6_RECVERR => IPV6_RECVERR *** */ + /* *** ESOCK_OPT_IPV6_RECVERR => IPV6_RECVERR *** */ #if defined(IPV6_RECVERR) tmp = MKT2(env, esock_atom_recverr, esock_atom_true); #else @@ -3920,7 +4289,7 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IPV6_RECVPKTINFO => IPV6_RECVPKTINFO *** */ + /* *** ESOCK_OPT_IPV6_RECVPKTINFO => IPV6_RECVPKTINFO *** */ #if defined(IPV6_RECVPKTINFO) tmp = MKT2(env, esock_atom_recvpktinfo, esock_atom_true); #else @@ -3929,12 +4298,12 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IPV6_RECVTCLASS => IPV6_RECVTCLASS *** */ + /* *** ESOCK_OPT_IPV6_RECVTCLASS => IPV6_RECVTCLASS *** */ tmp = MKT2(env, esock_atom_recvtclass, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IPV6_ROUTER_ALERT => IPV6_ROUTER_ALERT *** */ + /* *** ESOCK_OPT_IPV6_ROUTER_ALERT => IPV6_ROUTER_ALERT *** */ #if defined(IPV6_ROUTER_ALERT) tmp = MKT2(env, esock_atom_router_alert, esock_atom_true); #else @@ -3943,7 +4312,7 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IPV6_RTHDR => IPV6_RTHDR *** */ + /* *** ESOCK_OPT_IPV6_RTHDR => IPV6_RTHDR *** */ #if defined(IPV6_RTHDR) tmp = MKT2(env, esock_atom_rthdr, esock_atom_true); #else @@ -3952,12 +4321,12 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IPV6_TCLASS => IPV6_TCLASS *** */ + /* *** ESOCK_OPT_IPV6_TCLASS => IPV6_TCLASS *** */ tmp = MKT2(env, esock_atom_tclass, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IPV6_UNICAST_HOPS => IPV6_UNICAST_HOPS *** */ + /* *** ESOCK_OPT_IPV6_UNICAST_HOPS => IPV6_UNICAST_HOPS *** */ #if defined(IPV6_UNICAST_HOPS) tmp = MKT2(env, esock_atom_unicast_hops, esock_atom_true); #else @@ -3966,12 +4335,12 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IPV6_USE_MIN_MTU => IPV6_USE_MIN_MTU *** */ + /* *** ESOCK_OPT_IPV6_USE_MIN_MTU => IPV6_USE_MIN_MTU *** */ tmp = MKT2(env, esock_atom_use_min_mtu, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_IPV6_V6ONLY => IPV6_V6ONLY *** */ + /* *** ESOCK_OPT_IPV6_V6ONLY => IPV6_V6ONLY *** */ #if defined(IPV6_V6ONLY) tmp = MKT2(env, esock_atom_v6only, esock_atom_true); #else @@ -3990,13 +4359,13 @@ ERL_NIF_TERM nsupports_options_ipv6(ErlNifEnv* env) #if !defined(__WIN32__) static -ERL_NIF_TERM nsupports_options_tcp(ErlNifEnv* env) +ERL_NIF_TERM esock_supports_options_tcp(ErlNifEnv* env) { SocketTArray opts = TARRAY_CREATE(32); ERL_NIF_TERM tmp, optsL; - /* *** SOCKET_OPT_TCP_CONGESTION => TCP_CONGESTION *** */ + /* *** ESOCK_OPT_TCP_CONGESTION => TCP_CONGESTION *** */ #if defined(TCP_CONGESTION) tmp = MKT2(env, esock_atom_congestion, esock_atom_true); #else @@ -4005,7 +4374,7 @@ ERL_NIF_TERM nsupports_options_tcp(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_TCP_CORK => TCP_CORK *** */ + /* *** ESOCK_OPT_TCP_CORK => TCP_CORK *** */ #if defined(TCP_CORK) tmp = MKT2(env, esock_atom_cork, esock_atom_true); #else @@ -4014,27 +4383,27 @@ ERL_NIF_TERM nsupports_options_tcp(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_TCP_INFO => TCP_INFO *** */ + /* *** ESOCK_OPT_TCP_INFO => TCP_INFO *** */ tmp = MKT2(env, esock_atom_info, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_TCP_KEEPCNT => TCP_KEEPCNT *** */ + /* *** ESOCK_OPT_TCP_KEEPCNT => TCP_KEEPCNT *** */ tmp = MKT2(env, esock_atom_keepcnt, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_TCP_KEEPIDLE => TCP_KEEPIDLE *** */ + /* *** ESOCK_OPT_TCP_KEEPIDLE => TCP_KEEPIDLE *** */ tmp = MKT2(env, esock_atom_keepidle, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_TCP_KEEPINTVL => TCP_KEEPINTVL *** */ + /* *** ESOCK_OPT_TCP_KEEPINTVL => TCP_KEEPINTVL *** */ tmp = MKT2(env, esock_atom_keepintvl, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_TCP_MAXSEG => TCP_MAXSEG *** */ + /* *** ESOCK_OPT_TCP_MAXSEG => TCP_MAXSEG *** */ #if defined(TCP_MAXSEG) tmp = MKT2(env, esock_atom_maxseg, esock_atom_true); #else @@ -4043,12 +4412,12 @@ ERL_NIF_TERM nsupports_options_tcp(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_TCP_MD5SIG => TCP_MD5SIG *** */ + /* *** ESOCK_OPT_TCP_MD5SIG => TCP_MD5SIG *** */ tmp = MKT2(env, esock_atom_md5sig, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_TCP_NODELAY => TCP_NODELAY *** */ + /* *** ESOCK_OPT_TCP_NODELAY => TCP_NODELAY *** */ #if defined(TCP_NODELAY) tmp = MKT2(env, esock_atom_nodelay, esock_atom_true); #else @@ -4057,22 +4426,22 @@ ERL_NIF_TERM nsupports_options_tcp(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_TCP_NOOPT => TCP_NOOPT *** */ + /* *** ESOCK_OPT_TCP_NOOPT => TCP_NOOPT *** */ tmp = MKT2(env, esock_atom_noopt, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_TCP_NOPUSH => TCP_NOPUSH *** */ + /* *** ESOCK_OPT_TCP_NOPUSH => TCP_NOPUSH *** */ tmp = MKT2(env, esock_atom_nopush, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_TCP_SYNCNT => TCP_SYNCNT *** */ + /* *** ESOCK_OPT_TCP_SYNCNT => TCP_SYNCNT *** */ tmp = MKT2(env, esock_atom_syncnt, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_TCP_USER_TIMEOUT => TCP_USER_TIMEOUT *** */ + /* *** ESOCK_OPT_TCP_USER_TIMEOUT => TCP_USER_TIMEOUT *** */ tmp = MKT2(env, esock_atom_user_timeout, esock_atom_false); TARRAY_ADD(opts, tmp); @@ -4087,13 +4456,13 @@ ERL_NIF_TERM nsupports_options_tcp(ErlNifEnv* env) #if !defined(__WIN32__) static -ERL_NIF_TERM nsupports_options_udp(ErlNifEnv* env) +ERL_NIF_TERM esock_supports_options_udp(ErlNifEnv* env) { SocketTArray opts = TARRAY_CREATE(8); ERL_NIF_TERM tmp, optsL; - /* *** SOCKET_OPT_UDP_CORK => UDP_CORK *** */ + /* *** ESOCK_OPT_UDP_CORK => UDP_CORK *** */ #if defined(UDP_CORK) tmp = MKT2(env, esock_atom_cork, esock_atom_true); #else @@ -4112,18 +4481,18 @@ ERL_NIF_TERM nsupports_options_udp(ErlNifEnv* env) #if !defined(__WIN32__) static -ERL_NIF_TERM nsupports_options_sctp(ErlNifEnv* env) +ERL_NIF_TERM esock_supports_options_sctp(ErlNifEnv* env) { SocketTArray opts = TARRAY_CREATE(64); ERL_NIF_TERM tmp, optsL; - /* *** SOCKET_OPT_SCTP_ADAPTION_LAYER => SCTP_ADAPTION_LAYER *** */ + /* *** ESOCK_OPT_SCTP_ADAPTION_LAYER => SCTP_ADAPTION_LAYER *** */ tmp = MKT2(env, esock_atom_adaption_layer, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SCTP_ASSOCINFO => SCTP_ASSOCINFO *** */ + /* *** ESOCK_OPT_SCTP_ASSOCINFO => SCTP_ASSOCINFO *** */ #if defined(SCTP_ASSOCINFO) tmp = MKT2(env, esock_atom_associnfo, esock_atom_true); #else @@ -4132,32 +4501,32 @@ ERL_NIF_TERM nsupports_options_sctp(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SCTP_AUTH_ACTIVE_KEY => SCTP_AUTH_ACTIVE_KEY *** */ + /* *** ESOCK_OPT_SCTP_AUTH_ACTIVE_KEY => SCTP_AUTH_ACTIVE_KEY *** */ tmp = MKT2(env, esock_atom_auth_active_key, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SCTP_AUTH_ASCONF => SCTP_AUTH_ASCONF *** */ + /* *** ESOCK_OPT_SCTP_AUTH_ASCONF => SCTP_AUTH_ASCONF *** */ tmp = MKT2(env, esock_atom_auth_asconf, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SCTP_AUTH_CHUNK => SCTP_AUTH_CHUNK *** */ + /* *** ESOCK_OPT_SCTP_AUTH_CHUNK => SCTP_AUTH_CHUNK *** */ tmp = MKT2(env, esock_atom_auth_chunk, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SCTP_AUTH_DELETE_KEY => SCTP_AUTH_DELETE_KEY *** */ + /* *** ESOCK_OPT_SCTP_AUTH_DELETE_KEY => SCTP_AUTH_DELETE_KEY *** */ tmp = MKT2(env, esock_atom_auth_delete_key, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SCTP_AUTH_KEY => SCTP_AUTH_KEY *** */ + /* *** ESOCK_OPT_SCTP_AUTH_KEY => SCTP_AUTH_KEY *** */ tmp = MKT2(env, esock_atom_auth_key, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SCTP_AUTOCLOSE => SCTP_AUTOCLOSE *** */ + /* *** ESOCK_OPT_SCTP_AUTOCLOSE => SCTP_AUTOCLOSE *** */ #if defined(SCTP_AUTOCLOSE) tmp = MKT2(env, esock_atom_autoclose, esock_atom_true); #else @@ -4166,22 +4535,22 @@ ERL_NIF_TERM nsupports_options_sctp(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SCTP_CONTEXT => SCTP_CONTEXT *** */ + /* *** ESOCK_OPT_SCTP_CONTEXT => SCTP_CONTEXT *** */ tmp = MKT2(env, esock_atom_context, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SCTP_DEFAULT_SEND_PARAMS => SCTP_DEFAULT_SEND_PARAMS *** */ + /* *** ESOCK_OPT_SCTP_DEFAULT_SEND_PARAMS => SCTP_DEFAULT_SEND_PARAMS *** */ tmp = MKT2(env, esock_atom_default_send_params, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SCTP_DELAYED_ACK_TIME => SCTP_DELAYED_ACK_TIME *** */ + /* *** ESOCK_OPT_SCTP_DELAYED_ACK_TIME => SCTP_DELAYED_ACK_TIME *** */ tmp = MKT2(env, esock_atom_delayed_ack_time, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SCTP_DISABLE_FRAGMENTS => SCTP_DISABLE_FRAGMENTS *** */ + /* *** ESOCK_OPT_SCTP_DISABLE_FRAGMENTS => SCTP_DISABLE_FRAGMENTS *** */ #if defined(SCTP_DISABLE_FRAGMENTS) tmp = MKT2(env, esock_atom_disable_fragments, esock_atom_true); #else @@ -4190,12 +4559,12 @@ ERL_NIF_TERM nsupports_options_sctp(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SCTP_HMAC_IDENT => SCTP_HMAC_IDENT *** */ + /* *** ESOCK_OPT_SCTP_HMAC_IDENT => SCTP_HMAC_IDENT *** */ tmp = MKT2(env, esock_atom_hmac_ident, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SCTP_EVENTS => SCTP_EVENTS *** */ + /* *** ESOCK_OPT_SCTP_EVENTS => SCTP_EVENTS *** */ #if defined(SCTP_EVENTS) tmp = MKT2(env, esock_atom_events, esock_atom_true); #else @@ -4204,22 +4573,22 @@ ERL_NIF_TERM nsupports_options_sctp(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SCTP_EXPLICIT_EOR => SCTP_EXPLICIT_EOR *** */ + /* *** ESOCK_OPT_SCTP_EXPLICIT_EOR => SCTP_EXPLICIT_EOR *** */ tmp = MKT2(env, esock_atom_explicit_eor, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SCTP_FRAGMENT_INTERLEAVE => SCTP_FRAGMENT_INTERLEAVE *** */ + /* *** ESOCK_OPT_SCTP_FRAGMENT_INTERLEAVE => SCTP_FRAGMENT_INTERLEAVE *** */ tmp = MKT2(env, esock_atom_fragment_interleave, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SCTP_GET_PEER_ADDR_INFO => SCTP_GET_PEER_ADDR_INFO *** */ + /* *** ESOCK_OPT_SCTP_GET_PEER_ADDR_INFO => SCTP_GET_PEER_ADDR_INFO *** */ tmp = MKT2(env, esock_atom_get_peer_addr_info, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SCTP_INITMSG => SCTP_INITMSG *** */ + /* *** ESOCK_OPT_SCTP_INITMSG => SCTP_INITMSG *** */ #if defined(SCTP_INITMSG) tmp = MKT2(env, esock_atom_initmsg, esock_atom_true); #else @@ -4228,17 +4597,17 @@ ERL_NIF_TERM nsupports_options_sctp(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SCTP_I_WANT_MAPPED_V4_ADDR => SCTP_I_WANT_MAPPED_V4_ADDR *** */ + /* *** ESOCK_OPT_SCTP_I_WANT_MAPPED_V4_ADDR => SCTP_I_WANT_MAPPED_V4_ADDR *** */ tmp = MKT2(env, esock_atom_i_want_mapped_v4_addr, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SCTP_LOCAL_AUTH_CHUNKS => SCTP_LOCAL_AUTH_CHUNKS *** */ + /* *** ESOCK_OPT_SCTP_LOCAL_AUTH_CHUNKS => SCTP_LOCAL_AUTH_CHUNKS *** */ tmp = MKT2(env, esock_atom_local_auth_chunks, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SCTP_MAXSEG => SCTP_MAXSEG *** */ + /* *** ESOCK_OPT_SCTP_MAXSEG => SCTP_MAXSEG *** */ #if defined(SCTP_MAXSEG) tmp = MKT2(env, esock_atom_maxseg, esock_atom_true); #else @@ -4247,12 +4616,12 @@ ERL_NIF_TERM nsupports_options_sctp(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SCTP_MAXBURST => SCTP_MAXBURST *** */ + /* *** ESOCK_OPT_SCTP_MAXBURST => SCTP_MAXBURST *** */ tmp = MKT2(env, esock_atom_maxburst, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SCTP_NODELAY => SCTP_NODELAY *** */ + /* *** ESOCK_OPT_SCTP_NODELAY => SCTP_NODELAY *** */ #if defined(SCTP_NODELAY) tmp = MKT2(env, esock_atom_nodelay, esock_atom_true); #else @@ -4261,32 +4630,32 @@ ERL_NIF_TERM nsupports_options_sctp(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SCTP_PARTIAL_DELIVERY_POINT => SCTP_PARTIAL_DELIVERY_POINT *** */ + /* *** ESOCK_OPT_SCTP_PARTIAL_DELIVERY_POINT => SCTP_PARTIAL_DELIVERY_POINT *** */ tmp = MKT2(env, esock_atom_partial_delivery_point, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SCTP_PEER_ADDR_PARAMS => SCTP_PEER_ADDR_PARAMS *** */ + /* *** ESOCK_OPT_SCTP_PEER_ADDR_PARAMS => SCTP_PEER_ADDR_PARAMS *** */ tmp = MKT2(env, esock_atom_peer_addr_params, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SCTP_PEER_AUTH_CHUNKS => SCTP_PEER_AUTH_CHUNKS *** */ + /* *** ESOCK_OPT_SCTP_PEER_AUTH_CHUNKS => SCTP_PEER_AUTH_CHUNKS *** */ tmp = MKT2(env, esock_atom_peer_auth_chunks, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SCTP_PRIMARY_ADDR => SCTP_PRIMARY_ADDR *** */ + /* *** ESOCK_OPT_SCTP_PRIMARY_ADDR => SCTP_PRIMARY_ADDR *** */ tmp = MKT2(env, esock_atom_primary_addr, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SCTP_RESET_STREAMS => SCTP_RESET_STREAMS *** */ + /* *** ESOCK_OPT_SCTP_RESET_STREAMS => SCTP_RESET_STREAMS *** */ tmp = MKT2(env, esock_atom_reset_streams, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SCTP_RTOINFO => SCTP_RTOINFO *** */ + /* *** ESOCK_OPT_SCTP_RTOINFO => SCTP_RTOINFO *** */ #if defined(SCTP_RTOINFO) tmp = MKT2(env, esock_atom_rtoinfo, esock_atom_true); #else @@ -4295,17 +4664,17 @@ ERL_NIF_TERM nsupports_options_sctp(ErlNifEnv* env) TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SCTP_SET_PEER_PRIMARY_ADDR => SCTP_SET_PEER_PRIMARY_ADDR *** */ + /* *** ESOCK_OPT_SCTP_SET_PEER_PRIMARY_ADDR => SCTP_SET_PEER_PRIMARY_ADDR *** */ tmp = MKT2(env, esock_atom_set_peer_primary_addr, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SCTP_STATUS => SCTP_STATUS *** */ + /* *** ESOCK_OPT_SCTP_STATUS => SCTP_STATUS *** */ tmp = MKT2(env, esock_atom_status, esock_atom_false); TARRAY_ADD(opts, tmp); - /* *** SOCKET_OPT_SCTP_USE_EXT_RECVINFO => SCTP_USE_EXT_RECVINFO *** */ + /* *** ESOCK_OPT_SCTP_USE_EXT_RECVINFO => SCTP_USE_EXT_RECVINFO *** */ tmp = MKT2(env, esock_atom_use_ext_recvinfo, esock_atom_false); TARRAY_ADD(opts, tmp); @@ -4320,7 +4689,7 @@ ERL_NIF_TERM nsupports_options_sctp(ErlNifEnv* env) #if !defined(__WIN32__) static -ERL_NIF_TERM nsupports_sctp(ErlNifEnv* env) +ERL_NIF_TERM esock_supports_sctp(ErlNifEnv* env) { ERL_NIF_TERM supports; @@ -4338,7 +4707,7 @@ ERL_NIF_TERM nsupports_sctp(ErlNifEnv* env) #if !defined(__WIN32__) static -ERL_NIF_TERM nsupports_ipv6(ErlNifEnv* env) +ERL_NIF_TERM esock_supports_ipv6(ErlNifEnv* env) { ERL_NIF_TERM supports; @@ -4357,7 +4726,7 @@ ERL_NIF_TERM nsupports_ipv6(ErlNifEnv* env) #if !defined(__WIN32__) static -ERL_NIF_TERM nsupports_local(ErlNifEnv* env) +ERL_NIF_TERM esock_supports_local(ErlNifEnv* env) { ERL_NIF_TERM supports; @@ -4449,7 +4818,7 @@ ERL_NIF_TERM nif_open(ErlNifEnv* env, #endif - result = nopen(env, domain, type, proto, netns); + result = esock_open(env, domain, type, proto, netns); SGDBG( ("SOCKET", "nif_open -> done with result: " "\r\n %T" @@ -4461,7 +4830,7 @@ ERL_NIF_TERM nif_open(ErlNifEnv* env, } -/* nopen - create an endpoint for communication +/* esock_open - create an endpoint for communication * * Assumes the input has been validated. * @@ -4472,9 +4841,9 @@ ERL_NIF_TERM nif_open(ErlNifEnv* env, #if !defined(__WIN32__) static -ERL_NIF_TERM nopen(ErlNifEnv* env, - int domain, int type, int protocol, - char* netns) +ERL_NIF_TERM esock_open(ErlNifEnv* env, + int domain, int type, int protocol, + char* netns) { ESockDescriptor* descP; ERL_NIF_TERM res; @@ -4485,7 +4854,7 @@ ERL_NIF_TERM nopen(ErlNifEnv* env, int current_ns = 0; #endif - SGDBG( ("SOCKET", "nopen -> entry with" + SGDBG( ("SOCKET", "esock_open -> entry with" "\r\n domain: %d" "\r\n type: %d" "\r\n protocol: %d" @@ -4501,7 +4870,7 @@ ERL_NIF_TERM nopen(ErlNifEnv* env, if ((sock = sock_open(domain, type, proto)) == INVALID_SOCKET) return esock_make_error_errno(env, sock_errno()); - SGDBG( ("SOCKET", "nopen -> open success: %d\r\n", sock) ); + SGDBG( ("SOCKET", "esock_open -> open success: %d\r\n", sock) ); /* NOTE that if the protocol = 0 (default) and the domain is not @@ -4513,7 +4882,7 @@ ERL_NIF_TERM nopen(ErlNifEnv* env, && (domain != AF_LOCAL) #endif ) - if (!nopen_which_protocol(sock, &proto)) { + if (!esock_open_which_protocol(sock, &proto)) { if (proto == ESOCK_WHICH_PROTO_ERROR) { save_errno = sock_errno(); while ((sock_close(sock) == INVALID_SOCKET) && @@ -4543,7 +4912,7 @@ ERL_NIF_TERM nopen(ErlNifEnv* env, return esock_make_error_errno(env, save_errno); } - SGDBG( ("SOCKET", "nopen -> event success: %d\r\n", event) ); + SGDBG( ("SOCKET", "esock_open -> event success: %d\r\n", event) ); SET_NONBLOCKING(sock); @@ -4555,7 +4924,7 @@ ERL_NIF_TERM nopen(ErlNifEnv* env, return enif_make_badarg(env); } - descP->state = SOCKET_STATE_OPEN; + descP->state = ESOCK_STATE_OPEN; descP->domain = domain; descP->type = type; descP->protocol = proto; @@ -4584,7 +4953,7 @@ ERL_NIF_TERM nopen(ErlNifEnv* env, if (enif_self(env, &descP->ctrlPid) == NULL) return esock_make_error(env, atom_exself); - if (MONP("nopen -> ctrl", + if (MONP("esock_open -> ctrl", env, descP, &descP->ctrlPid, &descP->ctrlMon) != 0) @@ -4598,7 +4967,7 @@ ERL_NIF_TERM nopen(ErlNifEnv* env, static -BOOLEAN_T nopen_which_protocol(SOCKET sock, int* proto) +BOOLEAN_T esock_open_which_protocol(SOCKET sock, int* proto) { #if defined(SO_PROTOCOL) int val; @@ -4757,7 +5126,7 @@ ERL_NIF_TERM nif_bind(ErlNifEnv* env, /* Extract arguments and perform preliminary validation */ if ((argc != 2) || - !enif_get_resource(env, argv[0], sockets, (void**) &descP)) { + !ESOCK_GET_RESOURCE(env, argv[0], (void**) &descP)) { return enif_make_badarg(env); } eSockAddr = argv[1]; @@ -4774,13 +5143,13 @@ ERL_NIF_TERM nif_bind(ErlNifEnv* env, /* Make sure we are ready * Not sure how this would even happen, but... */ - if (descP->state != SOCKET_STATE_OPEN) + if (descP->state != ESOCK_STATE_OPEN) return esock_make_error(env, atom_exbadstate); if ((xres = esock_decode_sockaddr(env, eSockAddr, &sockAddr, &addrLen)) != NULL) return esock_make_error_str(env, xres); - return nbind(env, descP, &sockAddr, addrLen); + return esock_bind(env, descP, &sockAddr, addrLen); #endif // if defined(__WIN32__) } @@ -4788,24 +5157,24 @@ ERL_NIF_TERM nif_bind(ErlNifEnv* env, #if !defined(__WIN32__) static -ERL_NIF_TERM nbind(ErlNifEnv* env, - ESockDescriptor* descP, - ESockAddress* sockAddrP, - unsigned int addrLen) +ERL_NIF_TERM esock_bind(ErlNifEnv* env, + ESockDescriptor* descP, + ESockAddress* sockAddrP, + unsigned int addrLen) { int port, ntohs_port; - SSDBG( descP, ("SOCKET", "nbind -> try bind\r\n") ); + SSDBG( descP, ("SOCKET", "esock_bind -> try bind\r\n") ); if (IS_SOCKET_ERROR(sock_bind(descP->sock, (struct sockaddr*) sockAddrP, addrLen))) { return esock_make_error_errno(env, sock_errno()); } - SSDBG( descP, ("SOCKET", "nbind -> bound - get port\r\n") ); + SSDBG( descP, ("SOCKET", "esock_bind -> bound - get port\r\n") ); port = which_address_port(sockAddrP); - SSDBG( descP, ("SOCKET", "nbind -> port: %d\r\n", port) ); + SSDBG( descP, ("SOCKET", "esock_bind -> port: %d\r\n", port) ); if (port == 0) { SOCKLEN_T len = sizeof(ESockAddress); sys_memzero((char *) sockAddrP, len); @@ -4817,7 +5186,8 @@ ERL_NIF_TERM nbind(ErlNifEnv* env, ntohs_port = sock_ntohs(port); - SSDBG( descP, ("SOCKET", "nbind -> done with port = %d\r\n", ntohs_port) ); + SSDBG( descP, ("SOCKET", + "esock_bind -> done with port = %d\r\n", ntohs_port) ); return esock_make_ok2(env, MKI(env, ntohs_port)); @@ -4857,7 +5227,7 @@ ERL_NIF_TERM nif_connect(ErlNifEnv* env, sockRef = argv[0]; if ((argc != 2) || - !enif_get_resource(env, sockRef, sockets, (void**) &descP)) { + !ESOCK_GET_RESOURCE(env, sockRef, (void**) &descP)) { return enif_make_badarg(env); } eSockAddr = argv[1]; @@ -4884,7 +5254,7 @@ ERL_NIF_TERM nif_connect(ErlNifEnv* env, MLOCK(descP->writeMtx); MLOCK(descP->cfgMtx); - res = nconnect(env, descP, sockRef); + res = esock_connect(env, descP, sockRef); MUNLOCK(descP->cfgMtx); MUNLOCK(descP->writeMtx); @@ -4898,9 +5268,9 @@ ERL_NIF_TERM nif_connect(ErlNifEnv* env, #if !defined(__WIN32__) static -ERL_NIF_TERM nconnect(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef) +ERL_NIF_TERM esock_connect(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef) { ERL_NIF_TERM res, ref; int code, sres, save_errno = 0; @@ -4913,17 +5283,17 @@ ERL_NIF_TERM nconnect(ErlNifEnv* env, return esock_make_error(env, atom_closed); if (!IS_OPEN(descP)) { - SSDBG( descP, ("SOCKET", "nconnect -> not open\r\n") ); + SSDBG( descP, ("SOCKET", "esock_connect -> not open\r\n") ); return esock_make_error(env, atom_exbadstate); } if (IS_CONNECTED(descP)) { - SSDBG( descP, ("SOCKET", "nconnect -> already connected\r\n") ); + SSDBG( descP, ("SOCKET", "esock_connect -> already connected\r\n") ); return esock_make_error(env, atom_eisconn); } if (IS_CONNECTING(descP) && !is_connector(env, descP)) { - SSDBG( descP, ("SOCKET", "nconnect -> already connecting\r\n") ); + SSDBG( descP, ("SOCKET", "esock_connect -> already connecting\r\n") ); return esock_make_error(env, esock_atom_einval); } @@ -4937,14 +5307,15 @@ ERL_NIF_TERM nconnect(ErlNifEnv* env, descP->addrLen); save_errno = sock_errno(); - SSDBG( descP, ("SOCKET", "nconnect -> connect result: %d, %d\r\n", + SSDBG( descP, ("SOCKET", "esock_connect -> connect result: %d, %d\r\n", code, save_errno) ); if (IS_SOCKET_ERROR(code)) { switch (save_errno) { case ERRNO_BLOCK: /* Winsock2 */ case EINPROGRESS: /* Unix & OSE!! */ - SSDBG( descP, ("SOCKET", "nconnect -> would block => select\r\n") ); + SSDBG( descP, ("SOCKET", + "esock_connect -> would block => select\r\n") ); ref = MKREF(env); @@ -4958,13 +5329,13 @@ ERL_NIF_TERM nconnect(ErlNifEnv* env, if (enif_self(env, &descP->connPid) == NULL) return esock_make_error(env, atom_exself); - if (MONP("nconnect -> conn", + if (MONP("esock_connect -> conn", env, descP, &descP->connPid, &descP->connMon) != 0) return esock_make_error(env, atom_exmon); - descP->state = SOCKET_STATE_CONNECTING; + descP->state = ESOCK_STATE_CONNECTING; if ((sres = esock_select_write(env, descP->sock, descP, NULL, sockRef, ref)) < 0) { @@ -4979,18 +5350,19 @@ ERL_NIF_TERM nconnect(ErlNifEnv* env, break; case EISCONN: - SSDBG( descP, ("SOCKET", "nconnect -> *already* connected\r\n") ); + SSDBG( descP, ("SOCKET", + "esock_connect -> *already* connected\r\n") ); { /* This is ***strange*** so make sure */ int err = 0; if (!verify_is_connected(descP, &err)) { - descP->state = SOCKET_STATE_OPEN; /* restore state */ + descP->state = ESOCK_STATE_OPEN; /* restore state */ res = esock_make_error_errno(env, err); } else { - descP->state = SOCKET_STATE_CONNECTED; + descP->state = ESOCK_STATE_CONNECTED; /* And just to be on the safe side, reset these */ enif_set_pid_undefined(&descP->connPid); - DEMONP("nconnect -> connected", + DEMONP("esock_connect -> connected", env, descP, &descP->connMon); descP->isReadable = TRUE; descP->isWritable = TRUE; @@ -5000,7 +5372,7 @@ ERL_NIF_TERM nconnect(ErlNifEnv* env, break; default: - SSDBG( descP, ("SOCKET", "nconnect -> other error(1): %d\r\n", + SSDBG( descP, ("SOCKET", "esock_connect -> other error(1): %d\r\n", save_errno) ); res = esock_make_error_errno(env, save_errno); break; @@ -5008,11 +5380,11 @@ ERL_NIF_TERM nconnect(ErlNifEnv* env, } else if (code == 0) { /* ok we are connected */ - SSDBG( descP, ("SOCKET", "nconnect -> connected\r\n") ); + SSDBG( descP, ("SOCKET", "esock_connect -> connected\r\n") ); - descP->state = SOCKET_STATE_CONNECTED; + descP->state = ESOCK_STATE_CONNECTED; enif_set_pid_undefined(&descP->connPid); - DEMONP("nconnect -> connected", env, descP, &descP->connMon); + DEMONP("esock_connect -> connected", env, descP, &descP->connMon); descP->isReadable = TRUE; descP->isWritable = TRUE; @@ -5021,7 +5393,7 @@ ERL_NIF_TERM nconnect(ErlNifEnv* env, } else { /* Do we really need this case? */ - SSDBG( descP, ("SOCKET", "nconnect -> other error(2): %d\r\n", + SSDBG( descP, ("SOCKET", "esock_connect -> other error(2): %d\r\n", save_errno) ); res = esock_make_error_errno(env, save_errno); @@ -5058,23 +5430,23 @@ ERL_NIF_TERM nif_finalize_connection(ErlNifEnv* env, /* Extract arguments and perform preliminary validation */ if ((argc != 1) || - !enif_get_resource(env, argv[0], sockets, (void**) &descP)) { + !ESOCK_GET_RESOURCE(env, argv[0], (void**) &descP)) { return enif_make_badarg(env); } - return nfinalize_connection(env, descP); + return esock_finalize_connection(env, descP); #endif } -/* *** nfinalize_connection *** +/* *** esock_finalize_connection *** * Perform the final check to verify a connection. */ #if !defined(__WIN32__) static -ERL_NIF_TERM nfinalize_connection(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_finalize_connection(ErlNifEnv* env, + ESockDescriptor* descP) { int error; @@ -5082,13 +5454,14 @@ ERL_NIF_TERM nfinalize_connection(ErlNifEnv* env, return esock_make_error(env, atom_enotconn); if (!verify_is_connected(descP, &error)) { - descP->state = SOCKET_STATE_OPEN; /* restore state */ + descP->state = ESOCK_STATE_OPEN; /* restore state */ return esock_make_error_errno(env, error); } - descP->state = SOCKET_STATE_CONNECTED; + descP->state = ESOCK_STATE_CONNECTED; enif_set_pid_undefined(&descP->connPid); - DEMONP("nfinalize_connection -> connected", env, descP, &descP->connMon); + DEMONP("esock_finalize_connection -> connected", + env, descP, &descP->connMon); descP->isReadable = TRUE; descP->isWritable = TRUE; @@ -5201,7 +5574,7 @@ ERL_NIF_TERM nif_listen(ErlNifEnv* env, /* Extract arguments and perform preliminary validation */ if ((argc != 2) || - !enif_get_resource(env, argv[0], sockets, (void**) &descP) || + !ESOCK_GET_RESOURCE(env, argv[0], (void**) &descP) || !GET_INT(env, argv[1], &backlog)) { return enif_make_badarg(env); } @@ -5212,7 +5585,7 @@ ERL_NIF_TERM nif_listen(ErlNifEnv* env, "\r\n backlog: %d" "\r\n", descP->sock, argv[0], backlog) ); - return nlisten(env, descP, backlog); + return esock_listen(env, descP, backlog); #endif // if defined(__WIN32__) } @@ -5221,9 +5594,9 @@ ERL_NIF_TERM nif_listen(ErlNifEnv* env, #if !defined(__WIN32__) static -ERL_NIF_TERM nlisten(ErlNifEnv* env, - ESockDescriptor* descP, - int backlog) +ERL_NIF_TERM esock_listen(ErlNifEnv* env, + ESockDescriptor* descP, + int backlog) { /* @@ -5233,7 +5606,7 @@ ERL_NIF_TERM nlisten(ErlNifEnv* env, if (IS_CLOSED(descP) || IS_CLOSING(descP)) return esock_make_error(env, atom_closed); - if (descP->state == SOCKET_STATE_CLOSED) + if (descP->state == ESOCK_STATE_CLOSED) return esock_make_error(env, atom_exbadstate); if (!IS_OPEN(descP)) @@ -5247,7 +5620,7 @@ ERL_NIF_TERM nlisten(ErlNifEnv* env, if (IS_SOCKET_ERROR(sock_listen(descP->sock, backlog))) return esock_make_error_errno(env, sock_errno()); - descP->state = SOCKET_STATE_LISTENING; + descP->state = ESOCK_STATE_LISTENING; return esock_atom_ok; @@ -5284,7 +5657,7 @@ ERL_NIF_TERM nif_accept(ErlNifEnv* env, sockRef = argv[0]; if ((argc != 2) || - !enif_get_resource(env, sockRef, sockets, (void**) &descP)) { + !ESOCK_GET_RESOURCE(env, sockRef, (void**) &descP)) { return enif_make_badarg(env); } ref = argv[1]; @@ -5305,15 +5678,15 @@ ERL_NIF_TERM nif_accept(ErlNifEnv* env, "\r\n", descP->sock, sockRef, ref, - ((descP->state == SOCKET_STATE_LISTENING) ? "listening" : - ((descP->state == SOCKET_STATE_ACCEPTING) ? "accepting" : "other")), + ((descP->state == ESOCK_STATE_LISTENING) ? "listening" : + ((descP->state == ESOCK_STATE_ACCEPTING) ? "accepting" : "other")), descP->currentAcceptorP, descP->currentAcceptor.pid, esock_make_monitor_term(env, &descP->currentAcceptor.mon), descP->currentAcceptor.env, descP->currentAcceptor.ref) ); - res = naccept_erts(env, descP, sockRef, ref); + res = esock_accept(env, descP, sockRef, ref); MUNLOCK(descP->accMtx); @@ -5325,7 +5698,7 @@ ERL_NIF_TERM nif_accept(ErlNifEnv* env, #if !defined(__WIN32__) static -ERL_NIF_TERM naccept_erts(ErlNifEnv* env, +ERL_NIF_TERM esock_accept(ErlNifEnv* env, ESockDescriptor* descP, ERL_NIF_TERM sockRef, ERL_NIF_TERM ref) @@ -5336,12 +5709,12 @@ ERL_NIF_TERM naccept_erts(ErlNifEnv* env, return esock_make_error(env, atom_closed); switch (descP->state) { - case SOCKET_STATE_LISTENING: - res = naccept_listening(env, descP, sockRef, ref); + case ESOCK_STATE_LISTENING: + res = esock_accept_listening(env, descP, sockRef, ref); break; - case SOCKET_STATE_ACCEPTING: - res = naccept_accepting(env, descP, sockRef, ref); + case ESOCK_STATE_ACCEPTING: + res = esock_accept_accepting(env, descP, sockRef, ref); break; default: @@ -5354,16 +5727,16 @@ ERL_NIF_TERM naccept_erts(ErlNifEnv* env, #endif // if !defined(__WIN32__) -/* *** naccept_listening *** +/* *** esock_accept_listening *** * * We have no active acceptor (and therefor no acceptors in queue). */ #if !defined(__WIN32__) static -ERL_NIF_TERM naccept_listening(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - ERL_NIF_TERM accRef) +ERL_NIF_TERM esock_accept_listening(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM accRef) { ESockAddress remote; unsigned int n; @@ -5372,14 +5745,14 @@ ERL_NIF_TERM naccept_listening(ErlNifEnv* env, ErlNifPid caller; ERL_NIF_TERM res; - SSDBG( descP, ("SOCKET", "naccept_listening -> get caller\r\n") ); + SSDBG( descP, ("SOCKET", "esock_accept_listening -> get caller\r\n") ); if (enif_self(env, &caller) == NULL) return esock_make_error(env, atom_exself); n = sizeof(remote); sys_memzero((char *) &remote, n); - SSDBG( descP, ("SOCKET", "naccept_listening -> try accept\r\n") ); + SSDBG( descP, ("SOCKET", "esock_accept_listening -> try accept\r\n") ); accSock = sock_accept(descP->sock, (struct sockaddr*) &remote, &n); if (accSock == INVALID_SOCKET) { @@ -5387,10 +5760,11 @@ ERL_NIF_TERM naccept_listening(ErlNifEnv* env, SSDBG( descP, ("SOCKET", - "naccept_listening -> accept failed (%d)\r\n", save_errno) ); + "esock_accept_listening -> accept failed (%d)\r\n", + save_errno) ); - res = naccept_listening_error(env, descP, sockRef, accRef, - caller, save_errno); + res = esock_accept_listening_error(env, descP, sockRef, accRef, + caller, save_errno); } else { @@ -5398,9 +5772,9 @@ ERL_NIF_TERM naccept_listening(ErlNifEnv* env, * We got one */ - SSDBG( descP, ("SOCKET", "naccept_listening -> success\r\n") ); + SSDBG( descP, ("SOCKET", "esock_accept_listening -> success\r\n") ); - res = naccept_listening_accept(env, descP, accSock, caller, &remote); + res = esock_accept_listening_accept(env, descP, accSock, caller, &remote); } @@ -5408,7 +5782,7 @@ ERL_NIF_TERM naccept_listening(ErlNifEnv* env, } -/* *** naccept_listening_error *** +/* *** esock_accept_listening_error *** * * The accept call resultet in an error - handle it. * There are only two cases: @@ -5416,12 +5790,12 @@ ERL_NIF_TERM naccept_listening(ErlNifEnv* env, * 2) Other => Return the value (converted to an atom) */ static -ERL_NIF_TERM naccept_listening_error(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - ERL_NIF_TERM accRef, - ErlNifPid caller, - int save_errno) +ERL_NIF_TERM esock_accept_listening_error(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM accRef, + ErlNifPid caller, + int save_errno) { ERL_NIF_TERM res; @@ -5430,10 +5804,10 @@ ERL_NIF_TERM naccept_listening_error(ErlNifEnv* env, /* *** Try again later *** */ SSDBG( descP, - ("SOCKET", "naccept_listening_error -> would block\r\n") ); + ("SOCKET", "esock_accept_listening_error -> would block\r\n") ); descP->currentAcceptor.pid = caller; - if (MONP("naccept_listening -> current acceptor", + if (MONP("esock_accept_listening -> current acceptor", env, descP, &descP->currentAcceptor.pid, &descP->currentAcceptor.mon) != 0) { @@ -5445,14 +5819,14 @@ ERL_NIF_TERM naccept_listening_error(ErlNifEnv* env, descP->currentAcceptor.ref = CP_TERM(descP->currentAcceptor.env, accRef); descP->currentAcceptorP = &descP->currentAcceptor; - res = naccept_busy_retry(env, descP, - sockRef, accRef, - NULL, SOCKET_STATE_ACCEPTING); + res = esock_accept_busy_retry(env, descP, + sockRef, accRef, + NULL, ESOCK_STATE_ACCEPTING); } } else { SSDBG( descP, ("SOCKET", - "naccept_listening -> errno: %d\r\n", save_errno) ); + "esock_accept_listening -> errno: %d\r\n", save_errno) ); res = esock_make_error_errno(env, save_errno); } @@ -5460,20 +5834,20 @@ ERL_NIF_TERM naccept_listening_error(ErlNifEnv* env, } -/* *** naccept_listening_accept *** +/* *** esock_accept_listening_accept *** * * The accept call was successful (accepted) - handle the new connection. */ static -ERL_NIF_TERM naccept_listening_accept(ErlNifEnv* env, - ESockDescriptor* descP, - SOCKET accSock, - ErlNifPid caller, - ESockAddress* remote) +ERL_NIF_TERM esock_accept_listening_accept(ErlNifEnv* env, + ESockDescriptor* descP, + SOCKET accSock, + ErlNifPid caller, + ESockAddress* remote) { ERL_NIF_TERM res; - naccept_accepted(env, descP, accSock, caller, remote, &res); + esock_accept_accepted(env, descP, accSock, caller, remote, &res); return res; } @@ -5481,7 +5855,7 @@ ERL_NIF_TERM naccept_listening_accept(ErlNifEnv* env, -/* *** naccept_accepting *** +/* *** esock_accept_accepting *** * * We have an active acceptor and possibly acceptors waiting in queue. * If the pid of the calling process is not the pid of the "current process", @@ -5489,20 +5863,20 @@ ERL_NIF_TERM naccept_listening_accept(ErlNifEnv* env, */ #if !defined(__WIN32__) static -ERL_NIF_TERM naccept_accepting(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - ERL_NIF_TERM ref) +ERL_NIF_TERM esock_accept_accepting(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM ref) { ErlNifPid caller; ERL_NIF_TERM res; - SSDBG( descP, ("SOCKET", "naccept_accepting -> get caller\r\n") ); + SSDBG( descP, ("SOCKET", "esock_accept_accepting -> get caller\r\n") ); if (enif_self(env, &caller) == NULL) return esock_make_error(env, atom_exself); - SSDBG( descP, ("SOCKET", "naccept_accepting -> check: " + SSDBG( descP, ("SOCKET", "esock_accept_accepting -> check: " "are caller current acceptor:" "\r\n Caller: %T" "\r\n Current: %T" @@ -5511,18 +5885,19 @@ ERL_NIF_TERM naccept_accepting(ErlNifEnv* env, if (COMPARE_PIDS(&descP->currentAcceptor.pid, &caller) == 0) { SSDBG( descP, - ("SOCKET", "naccept_accepting -> current acceptor\r\n") ); + ("SOCKET", "esock_accept_accepting -> current acceptor\r\n") ); - res = naccept_accepting_current(env, descP, sockRef, ref); + res = esock_accept_accepting_current(env, descP, sockRef, ref); } else { /* Not the "current acceptor", so (maybe) push onto queue */ SSDBG( descP, - ("SOCKET", "naccept_accepting -> *not* current acceptor\r\n") ); + ("SOCKET", + "esock_accept_accepting -> *not* current acceptor\r\n") ); - res = naccept_accepting_other(env, descP, ref, caller); + res = esock_accept_accepting_other(env, descP, ref, caller); } @@ -5532,14 +5907,14 @@ ERL_NIF_TERM naccept_accepting(ErlNifEnv* env, -/* *** naccept_accepting_current *** +/* *** esock_accept_accepting_current *** * Handles when the current acceptor makes another attempt. */ static -ERL_NIF_TERM naccept_accepting_current(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - ERL_NIF_TERM accRef) +ERL_NIF_TERM esock_accept_accepting_current(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM accRef) { ESockAddress remote; unsigned int n; @@ -5547,7 +5922,8 @@ ERL_NIF_TERM naccept_accepting_current(ErlNifEnv* env, int save_errno; ERL_NIF_TERM res; - SSDBG( descP, ("SOCKET", "naccept_accepting_current -> try accept\r\n") ); + SSDBG( descP, ("SOCKET", + "esock_accept_accepting_current -> try accept\r\n") ); n = sizeof(descP->remote); sys_memzero((char *) &remote, n); accSock = sock_accept(descP->sock, (struct sockaddr*) &remote, &n); @@ -5557,18 +5933,19 @@ ERL_NIF_TERM naccept_accepting_current(ErlNifEnv* env, SSDBG( descP, ("SOCKET", - "naccept_accepting_current -> accept failed: %d\r\n", + "esock_accept_accepting_current -> accept failed: %d\r\n", save_errno) ); - res = naccept_accepting_current_error(env, descP, sockRef, - accRef, save_errno); + res = esock_accept_accepting_current_error(env, descP, sockRef, + accRef, save_errno); } else { - SSDBG( descP, ("SOCKET", "naccept_accepting_current -> accepted\r\n") ); + SSDBG( descP, ("SOCKET", + "esock_accept_accepting_current -> accepted\r\n") ); - res = naccept_accepting_current_accept(env, descP, sockRef, - accSock, &remote); + res = esock_accept_accepting_current_accept(env, descP, sockRef, + accSock, &remote); } @@ -5576,27 +5953,27 @@ ERL_NIF_TERM naccept_accepting_current(ErlNifEnv* env, } -/* *** naccept_accepting_current_accept *** +/* *** esock_accept_accepting_current_accept *** * Handles when the current acceptor succeeded in its accept call - * handle the new connection. */ static -ERL_NIF_TERM naccept_accepting_current_accept(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - SOCKET accSock, - ESockAddress* remote) +ERL_NIF_TERM esock_accept_accepting_current_accept(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + SOCKET accSock, + ESockAddress* remote) { ERL_NIF_TERM res; - if (naccept_accepted(env, descP, accSock, - descP->currentAcceptor.pid, remote, &res)) { + if (esock_accept_accepted(env, descP, accSock, + descP->currentAcceptor.pid, remote, &res)) { /* Clean out the old cobweb's before trying to invite a new spider */ descP->currentAcceptor.ref = esock_atom_undefined; enif_set_pid_undefined(&descP->currentAcceptor.pid); - esock_free_env("naccept_accepting_current_accept - " + esock_free_env("esock_accept_accepting_current_accept - " "current-accept-env", descP->currentAcceptor.env); descP->currentAcceptor.env = NULL; @@ -5605,10 +5982,10 @@ ERL_NIF_TERM naccept_accepting_current_accept(ErlNifEnv* env, SSDBG( descP, ("SOCKET", - "naccept_accepting_current_accept -> " + "esock_accept_accepting_current_accept -> " "no more writers\r\n") ); - descP->state = SOCKET_STATE_LISTENING; + descP->state = ESOCK_STATE_LISTENING; descP->currentAcceptorP = NULL; ESOCK_ASSERT(!descP->currentAcceptor.env); @@ -5622,18 +5999,18 @@ ERL_NIF_TERM naccept_accepting_current_accept(ErlNifEnv* env, } -/* *** naccept_accepting_current_error *** +/* *** esock_accept_accepting_current_error *** * The accept call of current acceptor resultet in an error - handle it. * There are only two cases: * 1) BLOCK => Attempt a "retry" * 2) Other => Return the value (converted to an atom) */ static -ERL_NIF_TERM naccept_accepting_current_error(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - ERL_NIF_TERM opRef, - int save_errno) +ERL_NIF_TERM esock_accept_accepting_current_error(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM opRef, + int save_errno) { ESockRequestor req; ERL_NIF_TERM res, reason; @@ -5647,13 +6024,13 @@ ERL_NIF_TERM naccept_accepting_current_error(ErlNifEnv* env, SSDBG( descP, ("SOCKET", - "naccept_accepting_current_error -> " + "esock_accept_accepting_current_error -> " "would block: try again\r\n") ); - res = naccept_busy_retry(env, descP, sockRef, opRef, - &descP->currentAcceptor.pid, - /* No state change */ - descP->state); + res = esock_accept_busy_retry(env, descP, sockRef, opRef, + &descP->currentAcceptor.pid, + /* No state change */ + descP->state); } else { @@ -5662,12 +6039,13 @@ ERL_NIF_TERM naccept_accepting_current_error(ErlNifEnv* env, while (acceptor_pop(env, descP, &req)) { SSDBG( descP, - ("SOCKET", "naccept_accepting_current_error -> abort %T\r\n", + ("SOCKET", + "esock_accept_accepting_current_error -> abort %T\r\n", req.pid) ); esock_send_abort_msg(env, sockRef, req.ref, req.env, reason, &req.pid); req.env = NULL; - DEMONP("naccept_accepting_current_error -> pop'ed writer", + DEMONP("esock_accept_accepting_current_error -> pop'ed writer", env, descP, &req.mon); } @@ -5677,16 +6055,16 @@ ERL_NIF_TERM naccept_accepting_current_error(ErlNifEnv* env, } -/* *** naccept_accepting_other *** +/* *** esock_accept_accepting_other *** * Handles when the another acceptor makes an attempt, which * results (maybe) in the request beeing pushed onto the * acceptor queue. */ static -ERL_NIF_TERM naccept_accepting_other(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM ref, - ErlNifPid caller) +ERL_NIF_TERM esock_accept_accepting_other(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM ref, + ErlNifPid caller) { ERL_NIF_TERM result; @@ -5701,18 +6079,18 @@ ERL_NIF_TERM naccept_accepting_other(ErlNifEnv* env, -/* *** naccept_busy_retry *** +/* *** esock_accept_busy_retry *** * * Perform a retry select. If successful, set nextState. */ #if !defined(__WIN32__) static -ERL_NIF_TERM naccept_busy_retry(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - ERL_NIF_TERM accRef, - ErlNifPid* pid, - unsigned int nextState) +ERL_NIF_TERM esock_accept_busy_retry(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM accRef, + ErlNifPid* pid, + unsigned int nextState) { int sres; ERL_NIF_TERM res, reason; @@ -5731,17 +6109,17 @@ ERL_NIF_TERM naccept_busy_retry(ErlNifEnv* env, -/* *** naccept_accepted *** +/* *** esock_accept_accepted *** * * Generic function handling a successful accept. */ static -BOOLEAN_T naccept_accepted(ErlNifEnv* env, - ESockDescriptor* descP, - SOCKET accSock, - ErlNifPid pid, - ESockAddress* remote, - ERL_NIF_TERM* result) +BOOLEAN_T esock_accept_accepted(ErlNifEnv* env, + ESockDescriptor* descP, + SOCKET accSock, + ErlNifPid pid, + ESockAddress* remote, + ERL_NIF_TERM* result) { ESockDescriptor* accDescP; HANDLE accEvent; @@ -5779,7 +6157,7 @@ BOOLEAN_T naccept_accepted(ErlNifEnv* env, enif_release_resource(accDescP); accDescP->ctrlPid = pid; - if (MONP("naccept_accepted -> ctrl", + if (MONP("esock_accept_accepted -> ctrl", env, accDescP, &accDescP->ctrlPid, &accDescP->ctrlMon) != 0) { @@ -5792,7 +6170,7 @@ BOOLEAN_T naccept_accepted(ErlNifEnv* env, accDescP->remote = *remote; SET_NONBLOCKING(accDescP->sock); - accDescP->state = SOCKET_STATE_CONNECTED; + accDescP->state = ESOCK_STATE_CONNECTED; accDescP->isReadable = TRUE; accDescP->isWritable = TRUE; @@ -5845,7 +6223,7 @@ ERL_NIF_TERM nif_send(ErlNifEnv* env, sockRef = argv[0]; // We need this in case we send in case we send abort sendRef = argv[1]; - if (!enif_get_resource(env, sockRef, sockets, (void**) &descP)) { + if (!ESOCK_GET_RESOURCE(env, sockRef, (void**) &descP)) { return enif_make_badarg(env); } @@ -5870,7 +6248,7 @@ ERL_NIF_TERM nif_send(ErlNifEnv* env, * is done! */ - res = nsend(env, descP, sockRef, sendRef, &sndData, flags); + res = esock_send(env, descP, sockRef, sendRef, &sndData, flags); MUNLOCK(descP->writeMtx); @@ -5881,7 +6259,7 @@ ERL_NIF_TERM nif_send(ErlNifEnv* env, -/* *** nsend *** +/* *** esock_send *** * * Do the actual send. * Do some initial writer checks, do the actual send and then @@ -5890,12 +6268,12 @@ ERL_NIF_TERM nif_send(ErlNifEnv* env, */ #if !defined(__WIN32__) static -ERL_NIF_TERM nsend(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - ERL_NIF_TERM sendRef, - ErlNifBinary* sndDataP, - int flags) +ERL_NIF_TERM esock_send(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM sendRef, + ErlNifBinary* sndDataP, + int flags) { int save_errno; ssize_t written; @@ -5911,7 +6289,8 @@ ERL_NIF_TERM nsend(ErlNifEnv* env, /* We ignore the wrap for the moment. * Maybe we should issue a wrap-message to controlling process... */ - cnt_inc(&descP->writeTries, 1); + // cnt_inc(&descP->writeTries, 1); + SOCK_CNT_INC(env, descP, sockRef, atom_write_tries, &descP->writeTries, 1); written = sock_send(descP->sock, sndDataP->data, sndDataP->size, flags); if (IS_SOCKET_ERROR(written)) @@ -5966,16 +6345,15 @@ ERL_NIF_TERM nif_sendto(ErlNifEnv* env, /* Extract arguments and perform preliminary validation */ if ((argc != 5) || - !enif_get_resource(env, argv[0], sockets, (void**) &descP) || !GET_BIN(env, argv[2], &sndData) || !GET_UINT(env, argv[4], &eflags)) { return enif_make_badarg(env); } - sockRef = argv[0]; // We need this in case we send in case we send abort + sockRef = argv[0]; // We need this in case we send abort (to the caller) sendRef = argv[1]; eSockAddr = argv[3]; - if (!enif_get_resource(env, sockRef, sockets, (void**) &descP)) { + if (!ESOCK_GET_RESOURCE(env, sockRef, (void**) &descP)) { return enif_make_badarg(env); } @@ -6004,8 +6382,8 @@ ERL_NIF_TERM nif_sendto(ErlNifEnv* env, MLOCK(descP->writeMtx); - res = nsendto(env, descP, sockRef, sendRef, &sndData, flags, - &remoteAddr, remoteAddrLen); + res = esock_sendto(env, descP, sockRef, sendRef, &sndData, flags, + &remoteAddr, remoteAddrLen); MUNLOCK(descP->writeMtx); @@ -6021,14 +6399,14 @@ ERL_NIF_TERM nif_sendto(ErlNifEnv* env, #if !defined(__WIN32__) static -ERL_NIF_TERM nsendto(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - ERL_NIF_TERM sendRef, - ErlNifBinary* dataP, - int flags, - ESockAddress* toAddrP, - unsigned int toAddrLen) +ERL_NIF_TERM esock_sendto(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM sendRef, + ErlNifBinary* dataP, + int flags, + ESockAddress* toAddrP, + unsigned int toAddrLen) { int save_errno; ssize_t written; @@ -6044,7 +6422,8 @@ ERL_NIF_TERM nsendto(ErlNifEnv* env, /* We ignore the wrap for the moment. * Maybe we should issue a wrap-message to controlling process... */ - cnt_inc(&descP->writeTries, 1); + // cnt_inc(&descP->writeTries, 1); + SOCK_CNT_INC(env, descP, sockRef, atom_write_tries, &descP->writeTries, 1); if (toAddrP != NULL) { written = sock_sendto(descP->sock, @@ -6102,11 +6481,11 @@ ERL_NIF_TERM nif_sendmsg(ErlNifEnv* env, !GET_UINT(env, argv[3], &eflags)) { return enif_make_badarg(env); } - sockRef = argv[0]; // We need this in case we send in case we send abort + sockRef = argv[0]; // We need this in case we send abort (to the caller) sendRef = argv[1]; eMsgHdr = argv[2]; - if (!enif_get_resource(env, sockRef, sockets, (void**) &descP)) { + if (!ESOCK_GET_RESOURCE(env, sockRef, (void**) &descP)) { return enif_make_badarg(env); } @@ -6123,7 +6502,7 @@ ERL_NIF_TERM nif_sendmsg(ErlNifEnv* env, MLOCK(descP->writeMtx); - res = nsendmsg_erts(env, descP, sockRef, sendRef, eMsgHdr, flags); + res = esock_sendmsg(env, descP, sockRef, sendRef, eMsgHdr, flags); MUNLOCK(descP->writeMtx); @@ -6140,7 +6519,7 @@ ERL_NIF_TERM nif_sendmsg(ErlNifEnv* env, #if !defined(__WIN32__) static -ERL_NIF_TERM nsendmsg_erts(ErlNifEnv* env, +ERL_NIF_TERM esock_sendmsg(ErlNifEnv* env, ESockDescriptor* descP, ERL_NIF_TERM sockRef, ERL_NIF_TERM sendRef, @@ -6174,7 +6553,8 @@ ERL_NIF_TERM nsendmsg_erts(ErlNifEnv* env, /* We don't need the address */ - SSDBG( descP, ("SOCKET", "nsendmsg_erts -> connected: no address\r\n") ); + SSDBG( descP, ("SOCKET", + "esock_sendmsg -> connected: no address\r\n") ); msgHdr.msg_name = NULL; msgHdr.msg_namelen = 0; @@ -6189,7 +6569,7 @@ ERL_NIF_TERM nsendmsg_erts(ErlNifEnv* env, if (!GET_MAP_VAL(env, eMsgHdr, esock_atom_addr, &eAddr)) return esock_make_error(env, esock_atom_einval); - SSDBG( descP, ("SOCKET", "nsendmsg_erts -> not connected: " + SSDBG( descP, ("SOCKET", "esock_sendmsg -> not connected: " "\r\n address: %T" "\r\n", eAddr) ); @@ -6209,7 +6589,7 @@ ERL_NIF_TERM nsendmsg_erts(ErlNifEnv* env, if (!GET_LIST_LEN(env, eIOV, &iovLen) && (iovLen > 0)) return esock_make_error(env, esock_atom_einval); - SSDBG( descP, ("SOCKET", "nsendmsg_erts -> iov length: %d\r\n", iovLen) ); + SSDBG( descP, ("SOCKET", "esock_sendmsg -> iov length: %d\r\n", iovLen) ); iovBins = MALLOC(iovLen * sizeof(ErlNifBinary)); ESOCK_ASSERT( (iovBins != NULL) ); @@ -6227,7 +6607,7 @@ ERL_NIF_TERM nsendmsg_erts(ErlNifEnv* env, ctrlBufLen = 0; ctrlBuf = NULL; } - SSDBG( descP, ("SOCKET", "nsendmsg_erts -> optional ctrl: " + SSDBG( descP, ("SOCKET", "esock_sendmsg -> optional ctrl: " "\r\n ctrlBuf: 0x%lX" "\r\n ctrlBufLen: %d" "\r\n eCtrl: %T\r\n", ctrlBuf, ctrlBufLen, eCtrl) ); @@ -6245,7 +6625,8 @@ ERL_NIF_TERM nsendmsg_erts(ErlNifEnv* env, SSDBG( descP, ("SOCKET", - "nsendmsg_erts -> total (iov) data size: %d\r\n", dataSize) ); + "esock_sendmsg -> " + "total (iov) data size: %d\r\n", dataSize) ); /* Decode the ctrl and initiate that part of the msghdr. @@ -6273,7 +6654,8 @@ ERL_NIF_TERM nsendmsg_erts(ErlNifEnv* env, /* We ignore the wrap for the moment. * Maybe we should issue a wrap-message to controlling process... */ - cnt_inc(&descP->writeTries, 1); + // cnt_inc(&descP->writeTries, 1); + SOCK_CNT_INC(env, descP, sockRef, atom_write_tries, &descP->writeTries, 1); /* And now, finally, try to send the message */ written = sock_sendmsg(descP->sock, &msgHdr, flags); @@ -6402,10 +6784,10 @@ ERL_NIF_TERM nif_recv(ErlNifEnv* env, !GET_UINT(env, argv[3], &eflags)) { return enif_make_badarg(env); } - sockRef = argv[0]; // We need this in case we case we send abort + sockRef = argv[0]; // We need this in case we send abort (to the caller) recvRef = argv[1]; - if (!enif_get_resource(env, sockRef, sockets, (void**) &descP)) { + if (!ESOCK_GET_RESOURCE(env, sockRef, (void**) &descP)) { return enif_make_badarg(env); } @@ -6422,7 +6804,7 @@ ERL_NIF_TERM nif_recv(ErlNifEnv* env, * is done! */ - res = nrecv(env, descP, sockRef, recvRef, len, flags); + res = esock_recv(env, descP, sockRef, recvRef, len, flags); MUNLOCK(descP->readMtx); @@ -6439,12 +6821,12 @@ ERL_NIF_TERM nif_recv(ErlNifEnv* env, */ #if !defined(__WIN32__) static -ERL_NIF_TERM nrecv(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - ERL_NIF_TERM recvRef, - int len, - int flags) +ERL_NIF_TERM esock_recv(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM recvRef, + int len, + int flags) { ssize_t read; ErlNifBinary buf; @@ -6452,7 +6834,7 @@ ERL_NIF_TERM nrecv(ErlNifEnv* env, int save_errno; int bufSz = (len ? len : descP->rBufSz); - SSDBG( descP, ("SOCKET", "nrecv -> entry with" + SSDBG( descP, ("SOCKET", "esock_recv -> entry with" "\r\n len: %d (%d:%d)" "\r\n flags: %d" "\r\n", len, descP->rNumCnt, bufSz, flags) ); @@ -6471,13 +6853,11 @@ ERL_NIF_TERM nrecv(ErlNifEnv* env, if (!ALLOC_BIN(bufSz, &buf)) return esock_make_error(env, atom_exalloc); - /* We ignore the wrap for the moment. - * Maybe we should issue a wrap-message to controlling process... - */ - cnt_inc(&descP->readTries, 1); + // cnt_inc(&descP->readTries, 1); + SOCK_CNT_INC(env, descP, sockRef, atom_read_tries, &descP->readTries, 1); // If it fails (read = -1), we need errno... - SSDBG( descP, ("SOCKET", "nrecv -> try read (%d)\r\n", buf.size) ); + SSDBG( descP, ("SOCKET", "esock_recv -> try read (%d)\r\n", buf.size) ); read = sock_recv(descP->sock, buf.data, buf.size, flags); if (IS_SOCKET_ERROR(read)) { save_errno = sock_errno(); @@ -6485,7 +6865,8 @@ ERL_NIF_TERM nrecv(ErlNifEnv* env, save_errno = -1; // The value does not actually matter in this case } - SSDBG( descP, ("SOCKET", "nrecv -> read: %d (%d)\r\n", read, save_errno) ); + SSDBG( descP, ("SOCKET", + "esock_recv -> read: %d (%d)\r\n", read, save_errno) ); return recv_check_result(env, descP, read, len, @@ -6546,10 +6927,10 @@ ERL_NIF_TERM nif_recvfrom(ErlNifEnv* env, !GET_UINT(env, argv[3], &eflags)) { return enif_make_badarg(env); } - sockRef = argv[0]; // We need this in case we send in case we send abort + sockRef = argv[0]; // We need this in case we send abort (to the caller) recvRef = argv[1]; - if (!enif_get_resource(env, sockRef, sockets, (void**) &descP)) { + if (!ESOCK_GET_RESOURCE(env, sockRef, (void**) &descP)) { return enif_make_badarg(env); } @@ -6586,7 +6967,7 @@ ERL_NIF_TERM nif_recvfrom(ErlNifEnv* env, * </KOLLA> */ - res = nrecvfrom_erts(env, descP, sockRef, recvRef, bufSz, flags); + res = esock_recvfrom(env, descP, sockRef, recvRef, bufSz, flags); MUNLOCK(descP->readMtx); @@ -6602,7 +6983,7 @@ ERL_NIF_TERM nif_recvfrom(ErlNifEnv* env, */ #if !defined(__WIN32__) static -ERL_NIF_TERM nrecvfrom_erts(ErlNifEnv* env, +ERL_NIF_TERM esock_recvfrom(ErlNifEnv* env, ESockDescriptor* descP, ERL_NIF_TERM sockRef, ERL_NIF_TERM recvRef, @@ -6617,7 +6998,7 @@ ERL_NIF_TERM nrecvfrom_erts(ErlNifEnv* env, ERL_NIF_TERM readerCheck; int bufSz = (len ? len : descP->rBufSz); - SSDBG( descP, ("SOCKET", "nrecvfrom_erts -> entry with" + SSDBG( descP, ("SOCKET", "esock_recvfrom -> entry with" "\r\n len: %d (%d)" "\r\n flags: %d" "\r\n", len, bufSz, flags) ); @@ -6636,10 +7017,8 @@ ERL_NIF_TERM nrecvfrom_erts(ErlNifEnv* env, if (!ALLOC_BIN(bufSz, &buf)) return esock_make_error(env, atom_exalloc); - /* We ignore the wrap for the moment. - * Maybe we should issue a wrap-message to controlling process... - */ - cnt_inc(&descP->readTries, 1); + // cnt_inc(&descP->readTries, 1); + SOCK_CNT_INC(env, descP, sockRef, atom_read_tries, &descP->readTries, 1); addrLen = sizeof(fromAddr); sys_memzero((char*) &fromAddr, addrLen); @@ -6717,10 +7096,10 @@ ERL_NIF_TERM nif_recvmsg(ErlNifEnv* env, !GET_UINT(env, argv[4], &eflags)) { return enif_make_badarg(env); } - sockRef = argv[0]; // We need this in case we send in case we send abort + sockRef = argv[0]; // We need this in case we send abort (to the caller) recvRef = argv[1]; - if (!enif_get_resource(env, sockRef, sockets, (void**) &descP)) { + if (!ESOCK_GET_RESOURCE(env, sockRef, (void**) &descP)) { return enif_make_badarg(env); } @@ -6758,7 +7137,7 @@ ERL_NIF_TERM nif_recvmsg(ErlNifEnv* env, * </KOLLA> */ - res = nrecvmsg_erts(env, descP, sockRef, recvRef, bufSz, ctrlSz, flags); + res = esock_recvmsg(env, descP, sockRef, recvRef, bufSz, ctrlSz, flags); MUNLOCK(descP->readMtx); @@ -6774,7 +7153,7 @@ ERL_NIF_TERM nif_recvmsg(ErlNifEnv* env, */ #if !defined(__WIN32__) static -ERL_NIF_TERM nrecvmsg_erts(ErlNifEnv* env, +ERL_NIF_TERM esock_recvmsg(ErlNifEnv* env, ESockDescriptor* descP, ERL_NIF_TERM sockRef, ERL_NIF_TERM recvRef, @@ -6794,7 +7173,7 @@ ERL_NIF_TERM nrecvmsg_erts(ErlNifEnv* env, ERL_NIF_TERM readerCheck; ESockAddress addr; - SSDBG( descP, ("SOCKET", "nrecvmsg_erts -> entry with" + SSDBG( descP, ("SOCKET", "esock_recvmsg -> entry with" "\r\n bufSz: %d (%d)" "\r\n ctrlSz: %d (%d)" "\r\n flags: %d" @@ -6826,10 +7205,8 @@ ERL_NIF_TERM nrecvmsg_erts(ErlNifEnv* env, if (!ALLOC_BIN(ctrlSz, &ctrl)) return esock_make_error(env, atom_exalloc); - /* We ignore the wrap for the moment. - * Maybe we should issue a wrap-message to controlling process... - */ - cnt_inc(&descP->readTries, 1); + // cnt_inc(&descP->readTries, 1); + SOCK_CNT_INC(env, descP, sockRef, atom_read_tries, &descP->readTries, 1); addrLen = sizeof(addr); sys_memzero((char*) &addr, addrLen); @@ -6885,28 +7262,28 @@ ERL_NIF_TERM nif_close(ErlNifEnv* env, ESockDescriptor* descP; if ((argc != 1) || - !enif_get_resource(env, argv[0], sockets, (void**) &descP)) { + !ESOCK_GET_RESOURCE(env, argv[0], (void**) &descP)) { return enif_make_badarg(env); } if (IS_CLOSED(descP) || IS_CLOSING(descP)) return esock_make_error(env, atom_closed); - return nclose(env, descP); + return esock_close(env, descP); #endif // if defined(__WIN32__) } #if !defined(__WIN32__) static -ERL_NIF_TERM nclose(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_close(ErlNifEnv* env, + ESockDescriptor* descP) { ERL_NIF_TERM reply, reason; BOOLEAN_T doClose; SSDBG( descP, ("SOCKET", - "nclose -> [%d] entry (0x%lX, 0x%lX, 0x%lX, 0x%lX)\r\n", + "esock_close -> [%d] entry (0x%lX, 0x%lX, 0x%lX, 0x%lX)\r\n", descP->sock, descP->state, descP->currentWriterP, @@ -6915,10 +7292,10 @@ ERL_NIF_TERM nclose(ErlNifEnv* env, MLOCK(descP->closeMtx); - doClose = nclose_check(env, descP, &reason); + doClose = esock_close_check(env, descP, &reason); if (doClose) { - reply = nclose_do(env, descP); + reply = esock_close_do(env, descP); } else { reply = esock_make_error(env, reason); } @@ -6926,7 +7303,7 @@ ERL_NIF_TERM nclose(ErlNifEnv* env, MUNLOCK(descP->closeMtx); SSDBG( descP, - ("SOCKET", "nclose -> [%d] done when: " + ("SOCKET", "esock_close -> [%d] done when: " "\r\n state: 0x%lX" "\r\n reply: %T" "\r\n", descP->sock, descP->state, reply) ); @@ -6936,23 +7313,23 @@ ERL_NIF_TERM nclose(ErlNifEnv* env, -/* *** nclose_check *** +/* *** esock_close_check *** * * Check if we should try to perform the first stage close. */ static -BOOLEAN_T nclose_check(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM* reason) +BOOLEAN_T esock_close_check(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM* reason) { BOOLEAN_T doClose; - if (descP->state == SOCKET_STATE_CLOSED) { + if (descP->state == ESOCK_STATE_CLOSED) { doClose = FALSE; *reason = atom_closed; - } else if (descP->state == SOCKET_STATE_CLOSING) { + } else if (descP->state == ESOCK_STATE_CLOSING) { doClose = FALSE; *reason = atom_closing; @@ -6982,7 +7359,7 @@ BOOLEAN_T nclose_check(ErlNifEnv* env, * </KOLLA> */ - if (MONP("nclose_check -> closer", + if (MONP("esock_close_check -> closer", env, descP, &descP->closerPid, &descP->closerMon) != 0) { @@ -6993,7 +7370,7 @@ BOOLEAN_T nclose_check(ErlNifEnv* env, } else { descP->closeLocal = TRUE; - descP->state = SOCKET_STATE_CLOSING; + descP->state = ESOCK_STATE_CLOSING; descP->isReadable = FALSE; descP->isWritable = FALSE; doClose = TRUE; @@ -7009,13 +7386,13 @@ BOOLEAN_T nclose_check(ErlNifEnv* env, -/* *** nclose_do *** +/* *** esock_close_do *** * * Perform (do) the first stage close. */ static -ERL_NIF_TERM nclose_do(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_close_do(ErlNifEnv* env, + ESockDescriptor* descP) { int domain = descP->domain; int type = descP->type; @@ -7023,7 +7400,7 @@ ERL_NIF_TERM nclose_do(ErlNifEnv* env, int sres; ERL_NIF_TERM reply, reason; - descP->closeEnv = esock_alloc_env("nclose-do - close-env"); + descP->closeEnv = esock_alloc_env("esock_close_do - close-env"); descP->closeRef = MKREF(descP->closeEnv); sres = esock_select_stop(env, descP->sock, descP); @@ -7032,7 +7409,8 @@ ERL_NIF_TERM nclose_do(ErlNifEnv* env, /* Prep done - inform the caller it can finalize (close) directly */ SSDBG( descP, - ("SOCKET", "nclose -> [%d] stop was called\r\n", descP->sock) ); + ("SOCKET", + "esock_close -> [%d] stop was called\r\n", descP->sock) ); dec_socket(domain, type, protocol); reply = esock_atom_ok; @@ -7042,7 +7420,7 @@ ERL_NIF_TERM nclose_do(ErlNifEnv* env, /* The stop callback function has been *scheduled* which means that we * have to wait for it to complete. */ SSDBG( descP, - ("SOCKET", "nclose -> [%d] stop was scheduled\r\n", + ("SOCKET", "esock_close -> [%d] stop was scheduled\r\n", descP->sock) ); dec_socket(domain, type, protocol); // SHALL WE DO THIS AT finalize? @@ -7051,7 +7429,7 @@ ERL_NIF_TERM nclose_do(ErlNifEnv* env, } else { SSDBG( descP, - ("SOCKET", "nclose -> [%d] stop failed: %d\r\n", + ("SOCKET", "esock_close -> [%d] stop failed: %d\r\n", descP->sock, sres) ); /* <KOLLA> @@ -7065,7 +7443,7 @@ ERL_NIF_TERM nclose_do(ErlNifEnv* env, */ // Do we need this? - DEMONP("nclose_do -> closer", env, descP, &descP->closerMon); + DEMONP("esock_close_do -> closer", env, descP, &descP->closerMon); reason = MKT2(env, esock_atom_select_failed, MKI(env, sres)); reply = esock_make_error(env, reason); @@ -7103,22 +7481,22 @@ ERL_NIF_TERM nif_finalize_close(ErlNifEnv* env, /* Extract arguments and perform preliminary validation */ if ((argc != 1) || - !enif_get_resource(env, argv[0], sockets, (void**) &descP)) { + !ESOCK_GET_RESOURCE(env, argv[0], (void**) &descP)) { return enif_make_badarg(env); } - return nfinalize_close(env, descP); + return esock_finalize_close(env, descP); #endif // if defined(__WIN32__) } -/* *** nfinalize_close *** +/* *** esock_finalize_close *** * Perform the final step in the socket close. */ #if !defined(__WIN32__) static -ERL_NIF_TERM nfinalize_close(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_finalize_close(ErlNifEnv* env, + ESockDescriptor* descP) { ERL_NIF_TERM reply; @@ -7155,7 +7533,7 @@ ERL_NIF_TERM nfinalize_close(ErlNifEnv* env, descP->sock = INVALID_SOCKET; descP->event = INVALID_EVENT; - descP->state = SOCKET_STATE_CLOSED; + descP->state = ESOCK_STATE_CLOSED; return reply; } @@ -7187,7 +7565,7 @@ ERL_NIF_TERM nif_shutdown(ErlNifEnv* env, int how; if ((argc != 2) || - !enif_get_resource(env, argv[0], sockets, (void**) &descP) || + !ESOCK_GET_RESOURCE(env, argv[0], (void**) &descP) || !GET_UINT(env, argv[1], &ehow)) { return enif_make_badarg(env); } @@ -7198,7 +7576,7 @@ ERL_NIF_TERM nif_shutdown(ErlNifEnv* env, if (!ehow2how(ehow, &how)) return enif_make_badarg(env); - return nshutdown(env, descP, how); + return esock_shutdown(env, descP, how); #endif // if defined(__WIN32__) } @@ -7206,9 +7584,9 @@ ERL_NIF_TERM nif_shutdown(ErlNifEnv* env, #if !defined(__WIN32__) static -ERL_NIF_TERM nshutdown(ErlNifEnv* env, - ESockDescriptor* descP, - int how) +ERL_NIF_TERM esock_shutdown(ErlNifEnv* env, + ESockDescriptor* descP, + int how) { ERL_NIF_TERM reply; @@ -7276,7 +7654,7 @@ ERL_NIF_TERM nif_setopt(ErlNifEnv* env, /* Extract arguments and perform preliminary validation */ if ((argc != 5) || - !enif_get_resource(env, argv[0], sockets, (void**) &descP) || + !ESOCK_GET_RESOURCE(env, argv[0], (void**) &descP) || !GET_INT(env, argv[2], &eLevel) || !GET_INT(env, argv[3], &eOpt)) { SGDBG( ("SOCKET", "nif_setopt -> failed initial arg check\r\n") ); @@ -7313,7 +7691,7 @@ ERL_NIF_TERM nif_setopt(ErlNifEnv* env, MLOCK(descP->cfgMtx); - result = nsetopt(env, descP, isEncoded, isOTP, level, eOpt, eVal); + result = esock_setopt(env, descP, isEncoded, isOTP, level, eOpt, eVal); MUNLOCK(descP->cfgMtx); @@ -7330,13 +7708,13 @@ ERL_NIF_TERM nif_setopt(ErlNifEnv* env, #if !defined(__WIN32__) static -ERL_NIF_TERM nsetopt(ErlNifEnv* env, - ESockDescriptor* descP, - BOOLEAN_T isEncoded, - BOOLEAN_T isOTP, - int level, - int eOpt, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt(ErlNifEnv* env, + ESockDescriptor* descP, + BOOLEAN_T isEncoded, + BOOLEAN_T isOTP, + int level, + int eOpt, + ERL_NIF_TERM eVal) { ERL_NIF_TERM result; @@ -7344,11 +7722,11 @@ ERL_NIF_TERM nsetopt(ErlNifEnv* env, /* These are not actual socket options, * but options for our implementation. */ - result = nsetopt_otp(env, descP, eOpt, eVal); + result = esock_setopt_otp(env, descP, eOpt, eVal); } else if (!isEncoded) { - result = nsetopt_native(env, descP, level, eOpt, eVal); + result = esock_setopt_native(env, descP, level, eOpt, eVal); } else { - result = nsetopt_level(env, descP, level, eOpt, eVal); + result = esock_setopt_level(env, descP, level, eOpt, eVal); } return result; @@ -7356,45 +7734,45 @@ ERL_NIF_TERM nsetopt(ErlNifEnv* env, -/* nsetopt_otp - Handle OTP (level) options +/* esock_setopt_otp - Handle OTP (level) options */ static -ERL_NIF_TERM nsetopt_otp(ErlNifEnv* env, - ESockDescriptor* descP, - int eOpt, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_otp(ErlNifEnv* env, + ESockDescriptor* descP, + int eOpt, + ERL_NIF_TERM eVal) { ERL_NIF_TERM result; SSDBG( descP, - ("SOCKET", "nsetopt_otp -> entry with" + ("SOCKET", "esock_setopt_otp -> entry with" "\r\n eOpt: %d" "\r\n eVal: %T" "\r\n", eOpt, eVal) ); switch (eOpt) { - case SOCKET_OPT_OTP_DEBUG: - result = nsetopt_otp_debug(env, descP, eVal); + case ESOCK_OPT_OTP_DEBUG: + result = esock_setopt_otp_debug(env, descP, eVal); break; - case SOCKET_OPT_OTP_IOW: - result = nsetopt_otp_iow(env, descP, eVal); + case ESOCK_OPT_OTP_IOW: + result = esock_setopt_otp_iow(env, descP, eVal); break; - case SOCKET_OPT_OTP_CTRL_PROC: - result = nsetopt_otp_ctrl_proc(env, descP, eVal); + case ESOCK_OPT_OTP_CTRL_PROC: + result = esock_setopt_otp_ctrl_proc(env, descP, eVal); break; - case SOCKET_OPT_OTP_RCVBUF: - result = nsetopt_otp_rcvbuf(env, descP, eVal); + case ESOCK_OPT_OTP_RCVBUF: + result = esock_setopt_otp_rcvbuf(env, descP, eVal); break; - case SOCKET_OPT_OTP_RCVCTRLBUF: - result = nsetopt_otp_rcvctrlbuf(env, descP, eVal); + case ESOCK_OPT_OTP_RCVCTRLBUF: + result = esock_setopt_otp_rcvctrlbuf(env, descP, eVal); break; - case SOCKET_OPT_OTP_SNDCTRLBUF: - result = nsetopt_otp_sndctrlbuf(env, descP, eVal); + case ESOCK_OPT_OTP_SNDCTRLBUF: + result = esock_setopt_otp_sndctrlbuf(env, descP, eVal); break; default: @@ -7406,12 +7784,12 @@ ERL_NIF_TERM nsetopt_otp(ErlNifEnv* env, } -/* nsetopt_otp_debug - Handle the OTP (level) debug options +/* esock_setopt_otp_debug - Handle the OTP (level) debug options */ static -ERL_NIF_TERM nsetopt_otp_debug(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_otp_debug(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { descP->dbg = esock_decode_bool(eVal); @@ -7419,12 +7797,12 @@ ERL_NIF_TERM nsetopt_otp_debug(ErlNifEnv* env, } -/* nsetopt_otp_iow - Handle the OTP (level) iow options +/* esock_setopt_otp_iow - Handle the OTP (level) iow options */ static -ERL_NIF_TERM nsetopt_otp_iow(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_otp_iow(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { descP->iow = esock_decode_bool(eVal); @@ -7433,19 +7811,20 @@ ERL_NIF_TERM nsetopt_otp_iow(ErlNifEnv* env, -/* nsetopt_otp_ctrl_proc - Handle the OTP (level) controlling_process options +/* esock_setopt_otp_ctrl_proc - Handle the OTP (level) + * controlling_process options */ static -ERL_NIF_TERM nsetopt_otp_ctrl_proc(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_otp_ctrl_proc(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { ErlNifPid caller, newCtrlPid; ESockMonitor newCtrlMon; int xres; SSDBG( descP, - ("SOCKET", "nsetopt_otp_ctrl_proc -> entry with" + ("SOCKET", "esock_setopt_otp_ctrl_proc -> entry with" "\r\n eVal: %T" "\r\n", eVal) ); @@ -7454,7 +7833,8 @@ ERL_NIF_TERM nsetopt_otp_ctrl_proc(ErlNifEnv* env, return esock_make_error(env, atom_exself); if (COMPARE_PIDS(&descP->ctrlPid, &caller) != 0) { - SSDBG( descP, ("SOCKET", "nsetopt_otp_ctrl_proc -> not owner (%T)\r\n", + SSDBG( descP, ("SOCKET", + "esock_setopt_otp_ctrl_proc -> not owner (%T)\r\n", descP->ctrlPid) ); return esock_make_error(env, esock_atom_not_owner); } @@ -7464,13 +7844,14 @@ ERL_NIF_TERM nsetopt_otp_ctrl_proc(ErlNifEnv* env, return esock_make_error(env, esock_atom_einval); } - if ((xres = MONP("nsetopt_otp_ctrl_proc -> (new) ctrl", + if ((xres = MONP("esock_setopt_otp_ctrl_proc -> (new) ctrl", env, descP, &newCtrlPid, &newCtrlMon)) != 0) { - esock_warning_msg("Failed monitor %d) (new) controlling process\r\n", xres); + esock_warning_msg("Failed monitor (%d) (new) controlling process\r\n", + xres); return esock_make_error(env, esock_atom_einval); } - if ((xres = DEMONP("nsetopt_otp_ctrl_proc -> (old) ctrl", + if ((xres = DEMONP("esock_setopt_otp_ctrl_proc -> (old) ctrl", env, descP, &descP->ctrlMon)) != 0) { esock_warning_msg("Failed demonitor (%d) " "old controlling process %T (%T)\r\n", @@ -7480,14 +7861,14 @@ ERL_NIF_TERM nsetopt_otp_ctrl_proc(ErlNifEnv* env, descP->ctrlPid = newCtrlPid; descP->ctrlMon = newCtrlMon; - SSDBG( descP, ("SOCKET", "nsetopt_otp_ctrl_proc -> done\r\n") ); + SSDBG( descP, ("SOCKET", "esock_setopt_otp_ctrl_proc -> done\r\n") ); return esock_atom_ok; } -/* nsetopt_otp_rcvbuf - Handle the OTP (level) rcvbuf option +/* esock_setopt_otp_rcvbuf - Handle the OTP (level) rcvbuf option * The (otp) rcvbuf option is provided as: * * BufSz :: integer() | {N :: pos_integer(), BufSz :: pod_integer()} @@ -7495,9 +7876,9 @@ ERL_NIF_TERM nsetopt_otp_ctrl_proc(ErlNifEnv* env, * Where N is the max number of reads. */ static -ERL_NIF_TERM nsetopt_otp_rcvbuf(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_otp_rcvbuf(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { const ERL_NIF_TERM* t; // The array of the elements of the tuple int tsz; // The size of the tuple - should be 2 @@ -7514,7 +7895,7 @@ ERL_NIF_TERM nsetopt_otp_rcvbuf(ErlNifEnv* env, if ((xres = esock_decode_bufsz(env, eVal, - SOCKET_RECV_BUFFER_SIZE_DEFAULT, + ESOCK_RECV_BUFFER_SIZE_DEFAULT, &bufSz)) != NULL) return esock_make_error_str(env, xres); @@ -7531,7 +7912,7 @@ ERL_NIF_TERM nsetopt_otp_rcvbuf(ErlNifEnv* env, if ((xres = esock_decode_bufsz(env, t[1], - SOCKET_RECV_BUFFER_SIZE_DEFAULT, + ESOCK_RECV_BUFFER_SIZE_DEFAULT, &bufSz)) != NULL) return esock_make_error_str(env, xres); @@ -7547,19 +7928,19 @@ ERL_NIF_TERM nsetopt_otp_rcvbuf(ErlNifEnv* env, -/* nsetopt_otp_rcvctrlbuf - Handle the OTP (level) rcvctrlbuf option +/* esock_setopt_otp_rcvctrlbuf - Handle the OTP (level) rcvctrlbuf option */ static -ERL_NIF_TERM nsetopt_otp_rcvctrlbuf(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_otp_rcvctrlbuf(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { size_t val; char* xres; if ((xres = esock_decode_bufsz(env, eVal, - SOCKET_RECV_CTRL_BUFFER_SIZE_DEFAULT, + ESOCK_RECV_CTRL_BUFFER_SIZE_DEFAULT, &val)) != NULL) return esock_make_error_str(env, xres); @@ -7570,19 +7951,19 @@ ERL_NIF_TERM nsetopt_otp_rcvctrlbuf(ErlNifEnv* env, -/* nsetopt_otp_sndctrlbuf - Handle the OTP (level) sndctrlbuf option +/* esock_setopt_otp_sndctrlbuf - Handle the OTP (level) sndctrlbuf option */ static -ERL_NIF_TERM nsetopt_otp_sndctrlbuf(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_otp_sndctrlbuf(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { size_t val; char* xres; if ((xres = esock_decode_bufsz(env, eVal, - SOCKET_SEND_CTRL_BUFFER_SIZE_DEFAULT, + ESOCK_SEND_CTRL_BUFFER_SIZE_DEFAULT, &val)) != NULL) return esock_make_error_str(env, xres); @@ -7597,17 +7978,17 @@ ERL_NIF_TERM nsetopt_otp_sndctrlbuf(ErlNifEnv* env, * in "native mode" (option is provided as is and value as a binary). */ static -ERL_NIF_TERM nsetopt_native(ErlNifEnv* env, - ESockDescriptor* descP, - int level, - int opt, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_native(ErlNifEnv* env, + ESockDescriptor* descP, + int level, + int opt, + ERL_NIF_TERM eVal) { ErlNifBinary val; ERL_NIF_TERM result; SSDBG( descP, - ("SOCKET", "nsetopt_native -> entry with" + ("SOCKET", "esock_setopt_native -> entry with" "\r\n level: %d" "\r\n opt: %d" "\r\n eVal: %T" @@ -7625,7 +8006,7 @@ ERL_NIF_TERM nsetopt_native(ErlNifEnv* env, } SSDBG( descP, - ("SOCKET", "nsetopt_native -> done when" + ("SOCKET", "esock_setopt_native -> done when" "\r\n result: %T" "\r\n", result) ); @@ -7634,25 +8015,25 @@ ERL_NIF_TERM nsetopt_native(ErlNifEnv* env, -/* nsetopt_level - A "proper" level (option) has been specified +/* esock_setopt_level - A "proper" level (option) has been specified */ static -ERL_NIF_TERM nsetopt_level(ErlNifEnv* env, - ESockDescriptor* descP, - int level, - int eOpt, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_level(ErlNifEnv* env, + ESockDescriptor* descP, + int level, + int eOpt, + ERL_NIF_TERM eVal) { ERL_NIF_TERM result; SSDBG( descP, - ("SOCKET", "nsetopt_level -> entry with" + ("SOCKET", "esock_setopt_level -> entry with" "\r\n level: %d" "\r\n", level) ); switch (level) { case SOL_SOCKET: - result = nsetopt_lvl_socket(env, descP, eOpt, eVal); + result = esock_setopt_lvl_socket(env, descP, eOpt, eVal); break; #if defined(SOL_IP) @@ -7660,7 +8041,7 @@ ERL_NIF_TERM nsetopt_level(ErlNifEnv* env, #else case IPPROTO_IP: #endif - result = nsetopt_lvl_ip(env, descP, eOpt, eVal); + result = esock_setopt_lvl_ip(env, descP, eOpt, eVal); break; #if defined(HAVE_IPV6) @@ -7669,33 +8050,34 @@ ERL_NIF_TERM nsetopt_level(ErlNifEnv* env, #else case IPPROTO_IPV6: #endif - result = nsetopt_lvl_ipv6(env, descP, eOpt, eVal); + result = esock_setopt_lvl_ipv6(env, descP, eOpt, eVal); break; #endif case IPPROTO_TCP: - result = nsetopt_lvl_tcp(env, descP, eOpt, eVal); + result = esock_setopt_lvl_tcp(env, descP, eOpt, eVal); break; case IPPROTO_UDP: - result = nsetopt_lvl_udp(env, descP, eOpt, eVal); + result = esock_setopt_lvl_udp(env, descP, eOpt, eVal); break; #if defined(HAVE_SCTP) case IPPROTO_SCTP: - result = nsetopt_lvl_sctp(env, descP, eOpt, eVal); + result = esock_setopt_lvl_sctp(env, descP, eOpt, eVal); break; #endif default: SSDBG( descP, - ("SOCKET", "nsetopt_level -> unknown level (%d)\r\n", level) ); + ("SOCKET", + "esock_setopt_level -> unknown level (%d)\r\n", level) ); result = esock_make_error(env, esock_atom_einval); break; } SSDBG( descP, - ("SOCKET", "nsetopt_level -> done when" + ("SOCKET", "esock_setopt_level -> done when" "\r\n result: %T" "\r\n", result) ); @@ -7704,139 +8086,140 @@ ERL_NIF_TERM nsetopt_level(ErlNifEnv* env, -/* nsetopt_lvl_socket - Level *SOCKET* option +/* esock_setopt_lvl_socket - Level *SOCKET* option */ static -ERL_NIF_TERM nsetopt_lvl_socket(ErlNifEnv* env, - ESockDescriptor* descP, - int eOpt, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_socket(ErlNifEnv* env, + ESockDescriptor* descP, + int eOpt, + ERL_NIF_TERM eVal) { ERL_NIF_TERM result; SSDBG( descP, - ("SOCKET", "nsetopt_lvl_socket -> entry with" + ("SOCKET", "esock_setopt_lvl_socket -> entry with" "\r\n opt: %d" "\r\n", eOpt) ); switch (eOpt) { #if defined(SO_BINDTODEVICE) - case SOCKET_OPT_SOCK_BINDTODEVICE: - result = nsetopt_lvl_sock_bindtodevice(env, descP, eVal); + case ESOCK_OPT_SOCK_BINDTODEVICE: + result = esock_setopt_lvl_sock_bindtodevice(env, descP, eVal); break; #endif #if defined(SO_BROADCAST) - case SOCKET_OPT_SOCK_BROADCAST: - result = nsetopt_lvl_sock_broadcast(env, descP, eVal); + case ESOCK_OPT_SOCK_BROADCAST: + result = esock_setopt_lvl_sock_broadcast(env, descP, eVal); break; #endif #if defined(SO_DEBUG) - case SOCKET_OPT_SOCK_DEBUG: - result = nsetopt_lvl_sock_debug(env, descP, eVal); + case ESOCK_OPT_SOCK_DEBUG: + result = esock_setopt_lvl_sock_debug(env, descP, eVal); break; #endif #if defined(SO_DONTROUTE) - case SOCKET_OPT_SOCK_DONTROUTE: - result = nsetopt_lvl_sock_dontroute(env, descP, eVal); + case ESOCK_OPT_SOCK_DONTROUTE: + result = esock_setopt_lvl_sock_dontroute(env, descP, eVal); break; #endif #if defined(SO_KEEPALIVE) - case SOCKET_OPT_SOCK_KEEPALIVE: - result = nsetopt_lvl_sock_keepalive(env, descP, eVal); + case ESOCK_OPT_SOCK_KEEPALIVE: + result = esock_setopt_lvl_sock_keepalive(env, descP, eVal); break; #endif #if defined(SO_LINGER) - case SOCKET_OPT_SOCK_LINGER: - result = nsetopt_lvl_sock_linger(env, descP, eVal); + case ESOCK_OPT_SOCK_LINGER: + result = esock_setopt_lvl_sock_linger(env, descP, eVal); break; #endif #if defined(SO_PEEK_OFF) - case SOCKET_OPT_SOCK_PEEK_OFF: - result = nsetopt_lvl_sock_peek_off(env, descP, eVal); + case ESOCK_OPT_SOCK_PEEK_OFF: + result = esock_setopt_lvl_sock_peek_off(env, descP, eVal); break; #endif #if defined(SO_OOBINLINE) - case SOCKET_OPT_SOCK_OOBINLINE: - result = nsetopt_lvl_sock_oobinline(env, descP, eVal); + case ESOCK_OPT_SOCK_OOBINLINE: + result = esock_setopt_lvl_sock_oobinline(env, descP, eVal); break; #endif #if defined(SO_PRIORITY) - case SOCKET_OPT_SOCK_PRIORITY: - result = nsetopt_lvl_sock_priority(env, descP, eVal); + case ESOCK_OPT_SOCK_PRIORITY: + result = esock_setopt_lvl_sock_priority(env, descP, eVal); break; #endif #if defined(SO_RCVBUF) - case SOCKET_OPT_SOCK_RCVBUF: - result = nsetopt_lvl_sock_rcvbuf(env, descP, eVal); + case ESOCK_OPT_SOCK_RCVBUF: + result = esock_setopt_lvl_sock_rcvbuf(env, descP, eVal); break; #endif #if defined(SO_RCVLOWAT) - case SOCKET_OPT_SOCK_RCVLOWAT: - result = nsetopt_lvl_sock_rcvlowat(env, descP, eVal); + case ESOCK_OPT_SOCK_RCVLOWAT: + result = esock_setopt_lvl_sock_rcvlowat(env, descP, eVal); break; #endif #if defined(SO_RCVTIMEO) - case SOCKET_OPT_SOCK_RCVTIMEO: - result = nsetopt_lvl_sock_rcvtimeo(env, descP, eVal); + case ESOCK_OPT_SOCK_RCVTIMEO: + result = esock_setopt_lvl_sock_rcvtimeo(env, descP, eVal); break; #endif #if defined(SO_REUSEADDR) - case SOCKET_OPT_SOCK_REUSEADDR: - result = nsetopt_lvl_sock_reuseaddr(env, descP, eVal); + case ESOCK_OPT_SOCK_REUSEADDR: + result = esock_setopt_lvl_sock_reuseaddr(env, descP, eVal); break; #endif #if defined(SO_REUSEPORT) - case SOCKET_OPT_SOCK_REUSEPORT: - result = nsetopt_lvl_sock_reuseport(env, descP, eVal); + case ESOCK_OPT_SOCK_REUSEPORT: + result = esock_setopt_lvl_sock_reuseport(env, descP, eVal); break; #endif #if defined(SO_SNDBUF) - case SOCKET_OPT_SOCK_SNDBUF: - result = nsetopt_lvl_sock_sndbuf(env, descP, eVal); + case ESOCK_OPT_SOCK_SNDBUF: + result = esock_setopt_lvl_sock_sndbuf(env, descP, eVal); break; #endif #if defined(SO_SNDLOWAT) - case SOCKET_OPT_SOCK_SNDLOWAT: - result = nsetopt_lvl_sock_sndlowat(env, descP, eVal); + case ESOCK_OPT_SOCK_SNDLOWAT: + result = esock_setopt_lvl_sock_sndlowat(env, descP, eVal); break; #endif #if defined(SO_SNDTIMEO) - case SOCKET_OPT_SOCK_SNDTIMEO: - result = nsetopt_lvl_sock_sndtimeo(env, descP, eVal); + case ESOCK_OPT_SOCK_SNDTIMEO: + result = esock_setopt_lvl_sock_sndtimeo(env, descP, eVal); break; #endif #if defined(SO_TIMESTAMP) - case SOCKET_OPT_SOCK_TIMESTAMP: - result = nsetopt_lvl_sock_timestamp(env, descP, eVal); + case ESOCK_OPT_SOCK_TIMESTAMP: + result = esock_setopt_lvl_sock_timestamp(env, descP, eVal); break; #endif default: SSDBG( descP, - ("SOCKET", "nsetopt_lvl_socket -> unknown opt (%d)\r\n", eOpt) ); + ("SOCKET", + "esock_setopt_lvl_socket -> unknown opt (%d)\r\n", eOpt) ); result = esock_make_error(env, esock_atom_einval); break; } SSDBG( descP, - ("SOCKET", "nsetopt_lvl_socket -> done when" + ("SOCKET", "esock_setopt_lvl_socket -> done when" "\r\n result: %T" "\r\n", result) ); @@ -7846,66 +8229,66 @@ ERL_NIF_TERM nsetopt_lvl_socket(ErlNifEnv* env, #if defined(SO_BINDTODEVICE) static -ERL_NIF_TERM nsetopt_lvl_sock_bindtodevice(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_sock_bindtodevice(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_str_opt(env, descP, - SOL_SOCKET, SO_BROADCAST, - IFNAMSIZ, eVal); + return esock_setopt_str_opt(env, descP, + SOL_SOCKET, SO_BINDTODEVICE, + IFNAMSIZ, eVal); } #endif #if defined(SO_BROADCAST) static -ERL_NIF_TERM nsetopt_lvl_sock_broadcast(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_sock_broadcast(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_bool_opt(env, descP, SOL_SOCKET, SO_BROADCAST, eVal); + return esock_setopt_bool_opt(env, descP, SOL_SOCKET, SO_BROADCAST, eVal); } #endif #if defined(SO_DEBUG) static -ERL_NIF_TERM nsetopt_lvl_sock_debug(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_sock_debug(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_int_opt(env, descP, SOL_SOCKET, SO_DEBUG, eVal); + return esock_setopt_int_opt(env, descP, SOL_SOCKET, SO_DEBUG, eVal); } #endif #if defined(SO_DONTROUTE) static -ERL_NIF_TERM nsetopt_lvl_sock_dontroute(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_sock_dontroute(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_bool_opt(env, descP, SOL_SOCKET, SO_DONTROUTE, eVal); + return esock_setopt_bool_opt(env, descP, SOL_SOCKET, SO_DONTROUTE, eVal); } #endif #if defined(SO_KEEPALIVE) static -ERL_NIF_TERM nsetopt_lvl_sock_keepalive(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_sock_keepalive(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_bool_opt(env, descP, SOL_SOCKET, SO_KEEPALIVE, eVal); + return esock_setopt_bool_opt(env, descP, SOL_SOCKET, SO_KEEPALIVE, eVal); } #endif #if defined(SO_LINGER) static -ERL_NIF_TERM nsetopt_lvl_sock_linger(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_sock_linger(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { ERL_NIF_TERM result; struct linger val; @@ -7929,346 +8312,347 @@ ERL_NIF_TERM nsetopt_lvl_sock_linger(ErlNifEnv* env, #if defined(SO_OOBINLINE) static -ERL_NIF_TERM nsetopt_lvl_sock_oobinline(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_sock_oobinline(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_bool_opt(env, descP, SOL_SOCKET, SO_OOBINLINE, eVal); + return esock_setopt_bool_opt(env, descP, SOL_SOCKET, SO_OOBINLINE, eVal); } #endif #if defined(SO_PEEK_OFF) static -ERL_NIF_TERM nsetopt_lvl_sock_peek_off(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_sock_peek_off(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_int_opt(env, descP, SOL_SOCKET, SO_PEEK_OFF, eVal); + return esock_setopt_int_opt(env, descP, SOL_SOCKET, SO_PEEK_OFF, eVal); } #endif #if defined(SO_PRIORITY) static -ERL_NIF_TERM nsetopt_lvl_sock_priority(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_sock_priority(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_int_opt(env, descP, SOL_SOCKET, SO_PRIORITY, eVal); + return esock_setopt_int_opt(env, descP, SOL_SOCKET, SO_PRIORITY, eVal); } #endif #if defined(SO_RCVBUF) static -ERL_NIF_TERM nsetopt_lvl_sock_rcvbuf(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_sock_rcvbuf(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_int_opt(env, descP, SOL_SOCKET, SO_RCVBUF, eVal); + return esock_setopt_int_opt(env, descP, SOL_SOCKET, SO_RCVBUF, eVal); } #endif #if defined(SO_RCVLOWAT) static -ERL_NIF_TERM nsetopt_lvl_sock_rcvlowat(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_sock_rcvlowat(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_int_opt(env, descP, SOL_SOCKET, SO_RCVLOWAT, eVal); + return esock_setopt_int_opt(env, descP, SOL_SOCKET, SO_RCVLOWAT, eVal); } #endif #if defined(SO_RCVTIMEO) static -ERL_NIF_TERM nsetopt_lvl_sock_rcvtimeo(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_sock_rcvtimeo(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_timeval_opt(env, descP, SOL_SOCKET, SO_RCVTIMEO, eVal); + return esock_setopt_timeval_opt(env, descP, SOL_SOCKET, SO_RCVTIMEO, eVal); } #endif #if defined(SO_REUSEADDR) static -ERL_NIF_TERM nsetopt_lvl_sock_reuseaddr(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_sock_reuseaddr(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_bool_opt(env, descP, SOL_SOCKET, SO_REUSEADDR, eVal); + return esock_setopt_bool_opt(env, descP, SOL_SOCKET, SO_REUSEADDR, eVal); } #endif #if defined(SO_REUSEPORT) static -ERL_NIF_TERM nsetopt_lvl_sock_reuseport(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_sock_reuseport(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_bool_opt(env, descP, SOL_SOCKET, SO_REUSEPORT, eVal); + return esock_setopt_bool_opt(env, descP, SOL_SOCKET, SO_REUSEPORT, eVal); } #endif #if defined(SO_SNDBUF) static -ERL_NIF_TERM nsetopt_lvl_sock_sndbuf(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_sock_sndbuf(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_int_opt(env, descP, SOL_SOCKET, SO_SNDBUF, eVal); + return esock_setopt_int_opt(env, descP, SOL_SOCKET, SO_SNDBUF, eVal); } #endif #if defined(SO_SNDLOWAT) static -ERL_NIF_TERM nsetopt_lvl_sock_sndlowat(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_sock_sndlowat(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_int_opt(env, descP, SOL_SOCKET, SO_SNDLOWAT, eVal); + return esock_setopt_int_opt(env, descP, SOL_SOCKET, SO_SNDLOWAT, eVal); } #endif #if defined(SO_SNDTIMEO) static -ERL_NIF_TERM nsetopt_lvl_sock_sndtimeo(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_sock_sndtimeo(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { SSDBG( descP, - ("SOCKET", "nsetopt_lvl_sock_sndtimeo -> entry with" + ("SOCKET", "esock_setopt_lvl_sock_sndtimeo -> entry with" "\r\n eVal: %T" "\r\n", eVal) ); - return nsetopt_timeval_opt(env, descP, SOL_SOCKET, SO_SNDTIMEO, eVal); + return esock_setopt_timeval_opt(env, descP, SOL_SOCKET, SO_SNDTIMEO, eVal); } #endif #if defined(SO_TIMESTAMP) static -ERL_NIF_TERM nsetopt_lvl_sock_timestamp(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_sock_timestamp(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_bool_opt(env, descP, SOL_SOCKET, SO_TIMESTAMP, eVal); + return esock_setopt_bool_opt(env, descP, SOL_SOCKET, SO_TIMESTAMP, eVal); } #endif -/* nsetopt_lvl_ip - Level *IP* option(s) +/* esock_setopt_lvl_ip - Level *IP* option(s) */ static -ERL_NIF_TERM nsetopt_lvl_ip(ErlNifEnv* env, - ESockDescriptor* descP, - int eOpt, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ip(ErlNifEnv* env, + ESockDescriptor* descP, + int eOpt, + ERL_NIF_TERM eVal) { ERL_NIF_TERM result; SSDBG( descP, - ("SOCKET", "nsetopt_lvl_ip -> entry with" + ("SOCKET", "esock_setopt_lvl_ip -> entry with" "\r\n opt: %d" "\r\n", eOpt) ); switch (eOpt) { #if defined(IP_ADD_MEMBERSHIP) - case SOCKET_OPT_IP_ADD_MEMBERSHIP: - result = nsetopt_lvl_ip_add_membership(env, descP, eVal); + case ESOCK_OPT_IP_ADD_MEMBERSHIP: + result = esock_setopt_lvl_ip_add_membership(env, descP, eVal); break; #endif #if defined(IP_ADD_SOURCE_MEMBERSHIP) - case SOCKET_OPT_IP_ADD_SOURCE_MEMBERSHIP: - result = nsetopt_lvl_ip_add_source_membership(env, descP, eVal); + case ESOCK_OPT_IP_ADD_SOURCE_MEMBERSHIP: + result = esock_setopt_lvl_ip_add_source_membership(env, descP, eVal); break; #endif #if defined(IP_BLOCK_SOURCE) - case SOCKET_OPT_IP_BLOCK_SOURCE: - result = nsetopt_lvl_ip_block_source(env, descP, eVal); + case ESOCK_OPT_IP_BLOCK_SOURCE: + result = esock_setopt_lvl_ip_block_source(env, descP, eVal); break; #endif #if defined(IP_DROP_MEMBERSHIP) - case SOCKET_OPT_IP_DROP_MEMBERSHIP: - result = nsetopt_lvl_ip_drop_membership(env, descP, eVal); + case ESOCK_OPT_IP_DROP_MEMBERSHIP: + result = esock_setopt_lvl_ip_drop_membership(env, descP, eVal); break; #endif #if defined(IP_DROP_SOURCE_MEMBERSHIP) - case SOCKET_OPT_IP_DROP_SOURCE_MEMBERSHIP: - result = nsetopt_lvl_ip_drop_source_membership(env, descP, eVal); + case ESOCK_OPT_IP_DROP_SOURCE_MEMBERSHIP: + result = esock_setopt_lvl_ip_drop_source_membership(env, descP, eVal); break; #endif #if defined(IP_FREEBIND) - case SOCKET_OPT_IP_FREEBIND: - result = nsetopt_lvl_ip_freebind(env, descP, eVal); + case ESOCK_OPT_IP_FREEBIND: + result = esock_setopt_lvl_ip_freebind(env, descP, eVal); break; #endif #if defined(IP_HDRINCL) - case SOCKET_OPT_IP_HDRINCL: - result = nsetopt_lvl_ip_hdrincl(env, descP, eVal); + case ESOCK_OPT_IP_HDRINCL: + result = esock_setopt_lvl_ip_hdrincl(env, descP, eVal); break; #endif #if defined(IP_MINTTL) - case SOCKET_OPT_IP_MINTTL: - result = nsetopt_lvl_ip_minttl(env, descP, eVal); + case ESOCK_OPT_IP_MINTTL: + result = esock_setopt_lvl_ip_minttl(env, descP, eVal); break; #endif #if defined(IP_MSFILTER) && defined(IP_MSFILTER_SIZE) - case SOCKET_OPT_IP_MSFILTER: - result = nsetopt_lvl_ip_msfilter(env, descP, eVal); + case ESOCK_OPT_IP_MSFILTER: + result = esock_setopt_lvl_ip_msfilter(env, descP, eVal); break; #endif #if defined(IP_MTU_DISCOVER) - case SOCKET_OPT_IP_MTU_DISCOVER: - result = nsetopt_lvl_ip_mtu_discover(env, descP, eVal); + case ESOCK_OPT_IP_MTU_DISCOVER: + result = esock_setopt_lvl_ip_mtu_discover(env, descP, eVal); break; #endif #if defined(IP_MULTICAST_ALL) - case SOCKET_OPT_IP_MULTICAST_ALL: - result = nsetopt_lvl_ip_multicast_all(env, descP, eVal); + case ESOCK_OPT_IP_MULTICAST_ALL: + result = esock_setopt_lvl_ip_multicast_all(env, descP, eVal); break; #endif #if defined(IP_MULTICAST_IF) - case SOCKET_OPT_IP_MULTICAST_IF: - result = nsetopt_lvl_ip_multicast_if(env, descP, eVal); + case ESOCK_OPT_IP_MULTICAST_IF: + result = esock_setopt_lvl_ip_multicast_if(env, descP, eVal); break; #endif #if defined(IP_MULTICAST_LOOP) - case SOCKET_OPT_IP_MULTICAST_LOOP: - result = nsetopt_lvl_ip_multicast_loop(env, descP, eVal); + case ESOCK_OPT_IP_MULTICAST_LOOP: + result = esock_setopt_lvl_ip_multicast_loop(env, descP, eVal); break; #endif #if defined(IP_MULTICAST_TTL) - case SOCKET_OPT_IP_MULTICAST_TTL: - result = nsetopt_lvl_ip_multicast_ttl(env, descP, eVal); + case ESOCK_OPT_IP_MULTICAST_TTL: + result = esock_setopt_lvl_ip_multicast_ttl(env, descP, eVal); break; #endif #if defined(IP_NODEFRAG) - case SOCKET_OPT_IP_NODEFRAG: - result = nsetopt_lvl_ip_nodefrag(env, descP, eVal); + case ESOCK_OPT_IP_NODEFRAG: + result = esock_setopt_lvl_ip_nodefrag(env, descP, eVal); break; #endif #if defined(IP_PKTINFO) - case SOCKET_OPT_IP_PKTINFO: - result = nsetopt_lvl_ip_pktinfo(env, descP, eVal); + case ESOCK_OPT_IP_PKTINFO: + result = esock_setopt_lvl_ip_pktinfo(env, descP, eVal); break; #endif #if defined(IP_RECVDSTADDR) - case SOCKET_OPT_IP_RECVDSTADDR: - result = nsetopt_lvl_ip_recvdstaddr(env, descP, eVal); + case ESOCK_OPT_IP_RECVDSTADDR: + result = esock_setopt_lvl_ip_recvdstaddr(env, descP, eVal); break; #endif #if defined(IP_RECVERR) - case SOCKET_OPT_IP_RECVERR: - result = nsetopt_lvl_ip_recverr(env, descP, eVal); + case ESOCK_OPT_IP_RECVERR: + result = esock_setopt_lvl_ip_recverr(env, descP, eVal); break; #endif #if defined(IP_RECVIF) - case SOCKET_OPT_IP_RECVIF: - result = nsetopt_lvl_ip_recvif(env, descP, eVal); + case ESOCK_OPT_IP_RECVIF: + result = esock_setopt_lvl_ip_recvif(env, descP, eVal); break; #endif #if defined(IP_RECVOPTS) - case SOCKET_OPT_IP_RECVOPTS: - result = nsetopt_lvl_ip_recvopts(env, descP, eVal); + case ESOCK_OPT_IP_RECVOPTS: + result = esock_setopt_lvl_ip_recvopts(env, descP, eVal); break; #endif #if defined(IP_RECVORIGDSTADDR) - case SOCKET_OPT_IP_RECVORIGDSTADDR: - result = nsetopt_lvl_ip_recvorigdstaddr(env, descP, eVal); + case ESOCK_OPT_IP_RECVORIGDSTADDR: + result = esock_setopt_lvl_ip_recvorigdstaddr(env, descP, eVal); break; #endif #if defined(IP_RECVTOS) - case SOCKET_OPT_IP_RECVTOS: - result = nsetopt_lvl_ip_recvtos(env, descP, eVal); + case ESOCK_OPT_IP_RECVTOS: + result = esock_setopt_lvl_ip_recvtos(env, descP, eVal); break; #endif #if defined(IP_RECVTTL) - case SOCKET_OPT_IP_RECVTTL: - result = nsetopt_lvl_ip_recvttl(env, descP, eVal); + case ESOCK_OPT_IP_RECVTTL: + result = esock_setopt_lvl_ip_recvttl(env, descP, eVal); break; #endif #if defined(IP_RETOPTS) - case SOCKET_OPT_IP_RETOPTS: - result = nsetopt_lvl_ip_retopts(env, descP, eVal); + case ESOCK_OPT_IP_RETOPTS: + result = esock_setopt_lvl_ip_retopts(env, descP, eVal); break; #endif #if defined(IP_ROUTER_ALERT) - case SOCKET_OPT_IP_ROUTER_ALERT: - result = nsetopt_lvl_ip_router_alert(env, descP, eVal); + case ESOCK_OPT_IP_ROUTER_ALERT: + result = esock_setopt_lvl_ip_router_alert(env, descP, eVal); break; #endif #if defined(IP_SENDSRCADDR) - case SOCKET_OPT_IP_SENDSRCADDR: - result = nsetopt_lvl_ip_sendsrcaddr(env, descP, eVal); + case ESOCK_OPT_IP_SENDSRCADDR: + result = esock_setopt_lvl_ip_sendsrcaddr(env, descP, eVal); break; #endif #if defined(IP_TOS) - case SOCKET_OPT_IP_TOS: - result = nsetopt_lvl_ip_tos(env, descP, eVal); + case ESOCK_OPT_IP_TOS: + result = esock_setopt_lvl_ip_tos(env, descP, eVal); break; #endif #if defined(IP_TRANSPARENT) - case SOCKET_OPT_IP_TRANSPARENT: - result = nsetopt_lvl_ip_transparent(env, descP, eVal); + case ESOCK_OPT_IP_TRANSPARENT: + result = esock_setopt_lvl_ip_transparent(env, descP, eVal); break; #endif #if defined(IP_TTL) - case SOCKET_OPT_IP_TTL: - result = nsetopt_lvl_ip_ttl(env, descP, eVal); + case ESOCK_OPT_IP_TTL: + result = esock_setopt_lvl_ip_ttl(env, descP, eVal); break; #endif #if defined(IP_UNBLOCK_SOURCE) - case SOCKET_OPT_IP_UNBLOCK_SOURCE: - result = nsetopt_lvl_ip_unblock_source(env, descP, eVal); + case ESOCK_OPT_IP_UNBLOCK_SOURCE: + result = esock_setopt_lvl_ip_unblock_source(env, descP, eVal); break; #endif default: - SSDBG( descP, ("SOCKET", "nsetopt_lvl_ip -> unknown opt (%d)\r\n", eOpt) ); + SSDBG( descP, ("SOCKET", + "esock_setopt_lvl_ip -> unknown opt (%d)\r\n", eOpt) ); result = esock_make_error(env, esock_atom_einval); break; } SSDBG( descP, - ("SOCKET", "nsetopt_lvl_ip -> done when" + ("SOCKET", "esock_setopt_lvl_ip -> done when" "\r\n result: %T" "\r\n", result) ); @@ -8276,7 +8660,7 @@ ERL_NIF_TERM nsetopt_lvl_ip(ErlNifEnv* env, } -/* nsetopt_lvl_ip_add_membership - Level IP ADD_MEMBERSHIP option +/* esock_setopt_lvl_ip_add_membership - Level IP ADD_MEMBERSHIP option * * The value is a map with two attributes: multiaddr and interface. * The attribute 'multiaddr' is always a 4-tuple (IPv4 address). @@ -8285,16 +8669,18 @@ ERL_NIF_TERM nsetopt_lvl_ip(ErlNifEnv* env, */ #if defined(IP_ADD_MEMBERSHIP) static -ERL_NIF_TERM nsetopt_lvl_ip_add_membership(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ip_add_membership(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_lvl_ip_update_membership(env, descP, eVal, IP_ADD_MEMBERSHIP); + return esock_setopt_lvl_ip_update_membership(env, descP, eVal, + IP_ADD_MEMBERSHIP); } #endif -/* nsetopt_lvl_ip_add_source_membership - Level IP ADD_SOURCE_MEMBERSHIP option +/* esock_setopt_lvl_ip_add_source_membership - + * Level IP ADD_SOURCE_MEMBERSHIP option * * The value is a map with three attributes: multiaddr, interface and * sourceaddr. @@ -8305,17 +8691,17 @@ ERL_NIF_TERM nsetopt_lvl_ip_add_membership(ErlNifEnv* env, */ #if defined(IP_ADD_SOURCE_MEMBERSHIP) static -ERL_NIF_TERM nsetopt_lvl_ip_add_source_membership(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ip_add_source_membership(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_lvl_ip_update_source(env, descP, eVal, - IP_ADD_SOURCE_MEMBERSHIP); + return esock_setopt_lvl_ip_update_source(env, descP, eVal, + IP_ADD_SOURCE_MEMBERSHIP); } #endif -/* nsetopt_lvl_ip_block_source - Level IP BLOCK_SOURCE option +/* esock_setopt_lvl_ip_block_source - Level IP BLOCK_SOURCE option * * The value is a map with three attributes: multiaddr, interface and * sourceaddr. @@ -8326,16 +8712,16 @@ ERL_NIF_TERM nsetopt_lvl_ip_add_source_membership(ErlNifEnv* env, */ #if defined(IP_BLOCK_SOURCE) static -ERL_NIF_TERM nsetopt_lvl_ip_block_source(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ip_block_source(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_lvl_ip_update_source(env, descP, eVal, IP_BLOCK_SOURCE); + return esock_setopt_lvl_ip_update_source(env, descP, eVal, IP_BLOCK_SOURCE); } #endif -/* nsetopt_lvl_ip_drop_membership - Level IP DROP_MEMBERSHIP option +/* esock_setopt_lvl_ip_drop_membership - Level IP DROP_MEMBERSHIP option * * The value is a map with two attributes: multiaddr and interface. * The attribute 'multiaddr' is always a 4-tuple (IPv4 address). @@ -8348,18 +8734,19 @@ ERL_NIF_TERM nsetopt_lvl_ip_block_source(ErlNifEnv* env, */ #if defined(IP_DROP_MEMBERSHIP) static -ERL_NIF_TERM nsetopt_lvl_ip_drop_membership(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ip_drop_membership(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_lvl_ip_update_membership(env, descP, eVal, - IP_DROP_MEMBERSHIP); + return esock_setopt_lvl_ip_update_membership(env, descP, eVal, + IP_DROP_MEMBERSHIP); } #endif -/* nsetopt_lvl_ip_drop_source_membership - Level IP DROP_SOURCE_MEMBERSHIP option +/* esock_setopt_lvl_ip_drop_source_membership - + * Level IP DROP_SOURCE_MEMBERSHIP option * * The value is a map with three attributes: multiaddr, interface and * sourceaddr. @@ -8370,24 +8757,24 @@ ERL_NIF_TERM nsetopt_lvl_ip_drop_membership(ErlNifEnv* env, */ #if defined(IP_DROP_SOURCE_MEMBERSHIP) static -ERL_NIF_TERM nsetopt_lvl_ip_drop_source_membership(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ip_drop_source_membership(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_lvl_ip_update_source(env, descP, eVal, - IP_DROP_SOURCE_MEMBERSHIP); + return esock_setopt_lvl_ip_update_source(env, descP, eVal, + IP_DROP_SOURCE_MEMBERSHIP); } #endif -/* nsetopt_lvl_ip_freebind - Level IP FREEBIND option +/* esock_setopt_lvl_ip_freebind - Level IP FREEBIND option */ #if defined(IP_FREEBIND) static -ERL_NIF_TERM nsetopt_lvl_ip_freebind(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ip_freebind(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IP) int level = SOL_IP; @@ -8395,19 +8782,19 @@ ERL_NIF_TERM nsetopt_lvl_ip_freebind(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return nsetopt_bool_opt(env, descP, level, IP_FREEBIND, eVal); + return esock_setopt_bool_opt(env, descP, level, IP_FREEBIND, eVal); } #endif -/* nsetopt_lvl_ip_hdrincl - Level IP HDRINCL option +/* esock_setopt_lvl_ip_hdrincl - Level IP HDRINCL option */ #if defined(IP_HDRINCL) static -ERL_NIF_TERM nsetopt_lvl_ip_hdrincl(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ip_hdrincl(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IP) int level = SOL_IP; @@ -8415,19 +8802,19 @@ ERL_NIF_TERM nsetopt_lvl_ip_hdrincl(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return nsetopt_bool_opt(env, descP, level, IP_HDRINCL, eVal); + return esock_setopt_bool_opt(env, descP, level, IP_HDRINCL, eVal); } #endif -/* nsetopt_lvl_ip_minttl - Level IP MINTTL option +/* esock_setopt_lvl_ip_minttl - Level IP MINTTL option */ #if defined(IP_MINTTL) static -ERL_NIF_TERM nsetopt_lvl_ip_minttl(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ip_minttl(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IP) int level = SOL_IP; @@ -8435,26 +8822,26 @@ ERL_NIF_TERM nsetopt_lvl_ip_minttl(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return nsetopt_int_opt(env, descP, level, IP_MINTTL, eVal); + return esock_setopt_int_opt(env, descP, level, IP_MINTTL, eVal); } #endif -/* nsetopt_lvl_ip_msfilter - Level IP MSFILTER option +/* esock_setopt_lvl_ip_msfilter - Level IP MSFILTER option * * The value can be *either* the atom 'null' or a map of type ip_msfilter(). */ #if defined(IP_MSFILTER) && defined(IP_MSFILTER_SIZE) static -ERL_NIF_TERM nsetopt_lvl_ip_msfilter(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ip_msfilter(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { ERL_NIF_TERM result; if (COMPARE(eVal, atom_null) == 0) { - return nsetopt_lvl_ip_msfilter_set(env, descP->sock, NULL, 0); + return esock_setopt_lvl_ip_msfilter_set(env, descP->sock, NULL, 0); } else { struct ip_msfilter* msfP; Uint32 msfSz; @@ -8519,7 +8906,8 @@ ERL_NIF_TERM nsetopt_lvl_ip_msfilter(ErlNifEnv* env, } /* And now, finally, set the option */ - result = nsetopt_lvl_ip_msfilter_set(env, descP->sock, msfP, msfSz); + result = esock_setopt_lvl_ip_msfilter_set(env, descP->sock, + msfP, msfSz); FREE(msfP); return result; } @@ -8549,10 +8937,10 @@ BOOLEAN_T decode_ip_msfilter_mode(ErlNifEnv* env, static -ERL_NIF_TERM nsetopt_lvl_ip_msfilter_set(ErlNifEnv* env, - SOCKET sock, - struct ip_msfilter* msfP, - SOCKLEN_T optLen) +ERL_NIF_TERM esock_setopt_lvl_ip_msfilter_set(ErlNifEnv* env, + SOCKET sock, + struct ip_msfilter* msfP, + SOCKLEN_T optLen) { ERL_NIF_TERM result; int res; @@ -8574,15 +8962,15 @@ ERL_NIF_TERM nsetopt_lvl_ip_msfilter_set(ErlNifEnv* env, -/* nsetopt_lvl_ip_mtu_discover - Level IP MTU_DISCOVER option +/* esock_setopt_lvl_ip_mtu_discover - Level IP MTU_DISCOVER option * * The value is an atom of the type ip_pmtudisc(). */ #if defined(IP_MTU_DISCOVER) static -ERL_NIF_TERM nsetopt_lvl_ip_mtu_discover(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ip_mtu_discover(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { ERL_NIF_TERM result; int val; @@ -8615,13 +9003,13 @@ ERL_NIF_TERM nsetopt_lvl_ip_mtu_discover(ErlNifEnv* env, #endif -/* nsetopt_lvl_ip_multicast_all - Level IP MULTICAST_ALL option +/* esock_setopt_lvl_ip_multicast_all - Level IP MULTICAST_ALL option */ #if defined(IP_MULTICAST_ALL) static -ERL_NIF_TERM nsetopt_lvl_ip_multicast_all(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ip_multicast_all(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IP) int level = SOL_IP; @@ -8629,20 +9017,20 @@ ERL_NIF_TERM nsetopt_lvl_ip_multicast_all(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return nsetopt_bool_opt(env, descP, level, IP_MULTICAST_ALL, eVal); + return esock_setopt_bool_opt(env, descP, level, IP_MULTICAST_ALL, eVal); } #endif -/* nsetopt_lvl_ip_multicast_if - Level IP MULTICAST_IF option +/* esock_setopt_lvl_ip_multicast_if - Level IP MULTICAST_IF option * * The value is either the atom 'any' or a 4-tuple. */ #if defined(IP_MULTICAST_IF) static -ERL_NIF_TERM nsetopt_lvl_ip_multicast_if(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ip_multicast_if(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { ERL_NIF_TERM result; struct in_addr ifAddr; @@ -8673,13 +9061,13 @@ ERL_NIF_TERM nsetopt_lvl_ip_multicast_if(ErlNifEnv* env, #endif -/* nsetopt_lvl_ip_multicast_loop - Level IP MULTICAST_LOOP option +/* esock_setopt_lvl_ip_multicast_loop - Level IP MULTICAST_LOOP option */ #if defined(IP_MULTICAST_LOOP) static -ERL_NIF_TERM nsetopt_lvl_ip_multicast_loop(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ip_multicast_loop(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IP) int level = SOL_IP; @@ -8687,18 +9075,18 @@ ERL_NIF_TERM nsetopt_lvl_ip_multicast_loop(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return nsetopt_bool_opt(env, descP, level, IP_MULTICAST_LOOP, eVal); + return esock_setopt_bool_opt(env, descP, level, IP_MULTICAST_LOOP, eVal); } #endif -/* nsetopt_lvl_ip_multicast_ttl - Level IP MULTICAST_TTL option +/* esock_setopt_lvl_ip_multicast_ttl - Level IP MULTICAST_TTL option */ #if defined(IP_MULTICAST_TTL) static -ERL_NIF_TERM nsetopt_lvl_ip_multicast_ttl(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ip_multicast_ttl(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IP) int level = SOL_IP; @@ -8706,18 +9094,18 @@ ERL_NIF_TERM nsetopt_lvl_ip_multicast_ttl(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return nsetopt_int_opt(env, descP, level, IP_MULTICAST_TTL, eVal); + return esock_setopt_int_opt(env, descP, level, IP_MULTICAST_TTL, eVal); } #endif -/* nsetopt_lvl_ip_nodefrag - Level IP NODEFRAG option +/* esock_setopt_lvl_ip_nodefrag - Level IP NODEFRAG option */ #if defined(IP_NODEFRAG) static -ERL_NIF_TERM nsetopt_lvl_ip_nodefrag(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ip_nodefrag(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IP) int level = SOL_IP; @@ -8725,18 +9113,18 @@ ERL_NIF_TERM nsetopt_lvl_ip_nodefrag(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return nsetopt_bool_opt(env, descP, level, IP_NODEFRAG, eVal); + return esock_setopt_bool_opt(env, descP, level, IP_NODEFRAG, eVal); } #endif -/* nsetopt_lvl_ip_pktinfo - Level IP PKTINFO option +/* esock_setopt_lvl_ip_pktinfo - Level IP PKTINFO option */ #if defined(IP_PKTINFO) static -ERL_NIF_TERM nsetopt_lvl_ip_pktinfo(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ip_pktinfo(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IP) int level = SOL_IP; @@ -8744,18 +9132,18 @@ ERL_NIF_TERM nsetopt_lvl_ip_pktinfo(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return nsetopt_bool_opt(env, descP, level, IP_PKTINFO, eVal); + return esock_setopt_bool_opt(env, descP, level, IP_PKTINFO, eVal); } #endif -/* nsetopt_lvl_ip_recvdstaddr - Level IP RECVDSTADDR option +/* esock_setopt_lvl_ip_recvdstaddr - Level IP RECVDSTADDR option */ #if defined(IP_RECVDSTADDR) static -ERL_NIF_TERM nsetopt_lvl_ip_recvdstaddr(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ip_recvdstaddr(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IP) int level = SOL_IP; @@ -8763,18 +9151,18 @@ ERL_NIF_TERM nsetopt_lvl_ip_recvdstaddr(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return nsetopt_bool_opt(env, descP, level, IP_RECVDSTADDR, eVal); + return esock_setopt_bool_opt(env, descP, level, IP_RECVDSTADDR, eVal); } #endif -/* nsetopt_lvl_ip_recverr - Level IP RECVERR option +/* esock_setopt_lvl_ip_recverr - Level IP RECVERR option */ #if defined(IP_RECVERR) static -ERL_NIF_TERM nsetopt_lvl_ip_recverr(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ip_recverr(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IP) int level = SOL_IP; @@ -8782,18 +9170,18 @@ ERL_NIF_TERM nsetopt_lvl_ip_recverr(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return nsetopt_bool_opt(env, descP, level, IP_RECVERR, eVal); + return esock_setopt_bool_opt(env, descP, level, IP_RECVERR, eVal); } #endif -/* nsetopt_lvl_ip_recvif - Level IP RECVIF option +/* esock_setopt_lvl_ip_recvif - Level IP RECVIF option */ #if defined(IP_RECVIF) static -ERL_NIF_TERM nsetopt_lvl_ip_recvif(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ip_recvif(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IP) int level = SOL_IP; @@ -8801,18 +9189,18 @@ ERL_NIF_TERM nsetopt_lvl_ip_recvif(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return nsetopt_bool_opt(env, descP, level, IP_RECVIF, eVal); + return esock_setopt_bool_opt(env, descP, level, IP_RECVIF, eVal); } #endif -/* nsetopt_lvl_ip_recvopts - Level IP RECVOPTS option +/* esock_setopt_lvl_ip_recvopts - Level IP RECVOPTS option */ #if defined(IP_RECVOPTS) static -ERL_NIF_TERM nsetopt_lvl_ip_recvopts(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ip_recvopts(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IP) int level = SOL_IP; @@ -8820,18 +9208,18 @@ ERL_NIF_TERM nsetopt_lvl_ip_recvopts(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return nsetopt_bool_opt(env, descP, level, IP_RECVOPTS, eVal); + return esock_setopt_bool_opt(env, descP, level, IP_RECVOPTS, eVal); } #endif -/* nsetopt_lvl_ip_recvorigdstaddr - Level IP RECVORIGDSTADDR option +/* esock_setopt_lvl_ip_recvorigdstaddr - Level IP RECVORIGDSTADDR option */ #if defined(IP_RECVORIGDSTADDR) static -ERL_NIF_TERM nsetopt_lvl_ip_recvorigdstaddr(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ip_recvorigdstaddr(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IP) int level = SOL_IP; @@ -8839,18 +9227,18 @@ ERL_NIF_TERM nsetopt_lvl_ip_recvorigdstaddr(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return nsetopt_bool_opt(env, descP, level, IP_RECVORIGDSTADDR, eVal); + return esock_setopt_bool_opt(env, descP, level, IP_RECVORIGDSTADDR, eVal); } #endif -/* nsetopt_lvl_ip_recvtos - Level IP RECVTOS option +/* esock_setopt_lvl_ip_recvtos - Level IP RECVTOS option */ #if defined(IP_RECVTOS) static -ERL_NIF_TERM nsetopt_lvl_ip_recvtos(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ip_recvtos(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IP) int level = SOL_IP; @@ -8858,18 +9246,18 @@ ERL_NIF_TERM nsetopt_lvl_ip_recvtos(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return nsetopt_bool_opt(env, descP, level, IP_RECVTOS, eVal); + return esock_setopt_bool_opt(env, descP, level, IP_RECVTOS, eVal); } #endif -/* nsetopt_lvl_ip_recvttl - Level IP RECVTTL option +/* esock_setopt_lvl_ip_recvttl - Level IP RECVTTL option */ #if defined(IP_RECVTTL) static -ERL_NIF_TERM nsetopt_lvl_ip_recvttl(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ip_recvttl(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IP) int level = SOL_IP; @@ -8877,18 +9265,18 @@ ERL_NIF_TERM nsetopt_lvl_ip_recvttl(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return nsetopt_bool_opt(env, descP, level, IP_RECVTTL, eVal); + return esock_setopt_bool_opt(env, descP, level, IP_RECVTTL, eVal); } #endif -/* nsetopt_lvl_ip_retopts - Level IP RETOPTS option +/* esock_setopt_lvl_ip_retopts - Level IP RETOPTS option */ #if defined(IP_RETOPTS) static -ERL_NIF_TERM nsetopt_lvl_ip_retopts(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ip_retopts(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IP) int level = SOL_IP; @@ -8896,18 +9284,18 @@ ERL_NIF_TERM nsetopt_lvl_ip_retopts(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return nsetopt_bool_opt(env, descP, level, IP_RETOPTS, eVal); + return esock_setopt_bool_opt(env, descP, level, IP_RETOPTS, eVal); } #endif -/* nsetopt_lvl_ip_router_alert - Level IP ROUTER_ALERT option +/* esock_setopt_lvl_ip_router_alert - Level IP ROUTER_ALERT option */ #if defined(IP_ROUTER_ALERT) static -ERL_NIF_TERM nsetopt_lvl_ip_router_alert(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ip_router_alert(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IP) int level = SOL_IP; @@ -8915,18 +9303,18 @@ ERL_NIF_TERM nsetopt_lvl_ip_router_alert(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return nsetopt_int_opt(env, descP, level, IP_ROUTER_ALERT, eVal); + return esock_setopt_int_opt(env, descP, level, IP_ROUTER_ALERT, eVal); } #endif -/* nsetopt_lvl_ip_sendsrcaddr - Level IP SENDSRCADDR option +/* esock_setopt_lvl_ip_sendsrcaddr - Level IP SENDSRCADDR option */ #if defined(IP_SENDSRCADDR) static -ERL_NIF_TERM nsetopt_lvl_ip_sendsrcaddr(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ip_sendsrcaddr(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IP) int level = SOL_IP; @@ -8934,18 +9322,18 @@ ERL_NIF_TERM nsetopt_lvl_ip_sendsrcaddr(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return nsetopt_bool_opt(env, descP, level, IP_SENDSRCADDR, eVal); + return esock_setopt_bool_opt(env, descP, level, IP_SENDSRCADDR, eVal); } #endif -/* nsetopt_lvl_ip_tos - Level IP TOS option +/* esock_setopt_lvl_ip_tos - Level IP TOS option */ #if defined(IP_TOS) static -ERL_NIF_TERM nsetopt_lvl_ip_tos(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ip_tos(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IP) int level = SOL_IP; @@ -8972,13 +9360,13 @@ ERL_NIF_TERM nsetopt_lvl_ip_tos(ErlNifEnv* env, #endif -/* nsetopt_lvl_ip_transparent - Level IP TRANSPARENT option +/* esock_setopt_lvl_ip_transparent - Level IP TRANSPARENT option */ #if defined(IP_TRANSPARENT) static -ERL_NIF_TERM nsetopt_lvl_ip_transparent(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ip_transparent(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IP) int level = SOL_IP; @@ -8986,19 +9374,19 @@ ERL_NIF_TERM nsetopt_lvl_ip_transparent(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return nsetopt_bool_opt(env, descP, level, IP_TRANSPARENT, eVal); + return esock_setopt_bool_opt(env, descP, level, IP_TRANSPARENT, eVal); } #endif -/* nsetopt_lvl_ip_ttl - Level IP TTL option +/* esock_setopt_lvl_ip_ttl - Level IP TTL option */ #if defined(IP_TTL) static -ERL_NIF_TERM nsetopt_lvl_ip_ttl(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ip_ttl(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IP) int level = SOL_IP; @@ -9006,13 +9394,13 @@ ERL_NIF_TERM nsetopt_lvl_ip_ttl(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return nsetopt_int_opt(env, descP, level, IP_TTL, eVal); + return esock_setopt_int_opt(env, descP, level, IP_TTL, eVal); } #endif -/* nsetopt_lvl_ip_unblock_source - Level IP UNBLOCK_SOURCE option +/* esock_setopt_lvl_ip_unblock_source - Level IP UNBLOCK_SOURCE option * * The value is a map with three attributes: multiaddr, interface and * sourceaddr. @@ -9023,11 +9411,12 @@ ERL_NIF_TERM nsetopt_lvl_ip_ttl(ErlNifEnv* env, */ #if defined(IP_UNBLOCK_SOURCE) static -ERL_NIF_TERM nsetopt_lvl_ip_unblock_source(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ip_unblock_source(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_lvl_ip_update_source(env, descP, eVal, IP_UNBLOCK_SOURCE); + return esock_setopt_lvl_ip_update_source(env, descP, eVal, + IP_UNBLOCK_SOURCE); } #endif @@ -9035,10 +9424,10 @@ ERL_NIF_TERM nsetopt_lvl_ip_unblock_source(ErlNifEnv* env, #if defined(IP_ADD_MEMBERSHIP) || defined(IP_DROP_MEMBERSHIP) static -ERL_NIF_TERM nsetopt_lvl_ip_update_membership(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal, - int opt) +ERL_NIF_TERM esock_setopt_lvl_ip_update_membership(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal, + int opt) { ERL_NIF_TERM result, eMultiAddr, eInterface; struct ip_mreq mreq; @@ -9054,7 +9443,7 @@ ERL_NIF_TERM nsetopt_lvl_ip_update_membership(ErlNifEnv* env, // It must be a map if (!IS_MAP(env, eVal)) { SSDBG( descP, - ("SOCKET", "nsetopt_lvl_ip_update_membership -> " + ("SOCKET", "esock_setopt_lvl_ip_update_membership -> " "value *not* a map\r\n") ); return enif_make_badarg(env); } @@ -9062,21 +9451,21 @@ ERL_NIF_TERM nsetopt_lvl_ip_update_membership(ErlNifEnv* env, // It must have atleast two attributes if (!enif_get_map_size(env, eVal, &sz) || (sz < 2)) { SSDBG( descP, - ("SOCKET", "nsetopt_lvl_ip_update_membership -> " + ("SOCKET", "esock_setopt_lvl_ip_update_membership -> " "invalid map value: %T\r\n", eVal) ); return enif_make_badarg(env); } if (!GET_MAP_VAL(env, eVal, atom_multiaddr, &eMultiAddr)) { SSDBG( descP, - ("SOCKET", "nsetopt_lvl_ip_update_membership -> " + ("SOCKET", "esock_setopt_lvl_ip_update_membership -> " "failed get multiaddr (map) attribute\r\n") ); return enif_make_badarg(env); } if (!GET_MAP_VAL(env, eVal, atom_interface, &eInterface)) { SSDBG( descP, - ("SOCKET", "nsetopt_lvl_ip_update_membership -> " + ("SOCKET", "esock_setopt_lvl_ip_update_membership -> " "failed get interface (map) attribute\r\n") ); return enif_make_badarg(env); } @@ -9085,7 +9474,7 @@ ERL_NIF_TERM nsetopt_lvl_ip_update_membership(ErlNifEnv* env, eMultiAddr, &mreq.imr_multiaddr)) != NULL) { SSDBG( descP, - ("SOCKET", "nsetopt_lvl_ip_update_membership -> " + ("SOCKET", "esock_setopt_lvl_ip_update_membership -> " "failed decode multiaddr %T: %s\r\n", eMultiAddr, xres) ); return esock_make_error_str(env, xres); } @@ -9094,7 +9483,7 @@ ERL_NIF_TERM nsetopt_lvl_ip_update_membership(ErlNifEnv* env, eInterface, &mreq.imr_interface)) != NULL) { SSDBG( descP, - ("SOCKET", "nsetopt_lvl_ip_update_membership -> " + ("SOCKET", "esock_setopt_lvl_ip_update_membership -> " "failed decode interface %T: %s\r\n", eInterface, xres) ); return esock_make_error_str(env, xres); } @@ -9107,7 +9496,7 @@ ERL_NIF_TERM nsetopt_lvl_ip_update_membership(ErlNifEnv* env, result = esock_make_error_errno(env, save_errno); SSDBG( descP, - ("SOCKET", "nsetopt_lvl_ip_update_membership -> " + ("SOCKET", "esock_setopt_lvl_ip_update_membership -> " "failed setopt: %T (%d)\r\n", result, save_errno) ); } else { @@ -9121,10 +9510,10 @@ ERL_NIF_TERM nsetopt_lvl_ip_update_membership(ErlNifEnv* env, #if defined(IP_ADD_SOURCE_MEMBERSHIP) || defined(IP_DROP_SOURCE_MEMBERSHIP) || defined(IP_BLOCK_SOURCE) || defined(IP_UNBLOCK_SOURCE) static -ERL_NIF_TERM nsetopt_lvl_ip_update_source(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal, - int opt) +ERL_NIF_TERM esock_setopt_lvl_ip_update_source(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal, + int opt) { ERL_NIF_TERM result, eMultiAddr, eInterface, eSourceAddr; struct ip_mreq_source mreq; @@ -9184,146 +9573,147 @@ ERL_NIF_TERM nsetopt_lvl_ip_update_source(ErlNifEnv* env, /* *** Handling set of socket options for level = ipv6 *** */ -/* nsetopt_lvl_ipv6 - Level *IPv6* option(s) +/* esock_setopt_lvl_ipv6 - Level *IPv6* option(s) */ #if defined(HAVE_IPV6) static -ERL_NIF_TERM nsetopt_lvl_ipv6(ErlNifEnv* env, - ESockDescriptor* descP, - int eOpt, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ipv6(ErlNifEnv* env, + ESockDescriptor* descP, + int eOpt, + ERL_NIF_TERM eVal) { ERL_NIF_TERM result; SSDBG( descP, - ("SOCKET", "nsetopt_lvl_ipv6 -> entry with" + ("SOCKET", "esock_setopt_lvl_ipv6 -> entry with" "\r\n opt: %d" "\r\n", eOpt) ); switch (eOpt) { #if defined(IPV6_ADDRFORM) - case SOCKET_OPT_IPV6_ADDRFORM: - result = nsetopt_lvl_ipv6_addrform(env, descP, eVal); + case ESOCK_OPT_IPV6_ADDRFORM: + result = esock_setopt_lvl_ipv6_addrform(env, descP, eVal); break; #endif #if defined(IPV6_ADD_MEMBERSHIP) - case SOCKET_OPT_IPV6_ADD_MEMBERSHIP: - result = nsetopt_lvl_ipv6_add_membership(env, descP, eVal); + case ESOCK_OPT_IPV6_ADD_MEMBERSHIP: + result = esock_setopt_lvl_ipv6_add_membership(env, descP, eVal); break; #endif #if defined(IPV6_AUTHHDR) - case SOCKET_OPT_IPV6_AUTHHDR: - result = nsetopt_lvl_ipv6_authhdr(env, descP, eVal); + case ESOCK_OPT_IPV6_AUTHHDR: + result = esock_setopt_lvl_ipv6_authhdr(env, descP, eVal); break; #endif #if defined(IPV6_DROP_MEMBERSHIP) - case SOCKET_OPT_IPV6_DROP_MEMBERSHIP: - result = nsetopt_lvl_ipv6_drop_membership(env, descP, eVal); + case ESOCK_OPT_IPV6_DROP_MEMBERSHIP: + result = esock_setopt_lvl_ipv6_drop_membership(env, descP, eVal); break; #endif #if defined(IPV6_DSTOPTS) - case SOCKET_OPT_IPV6_DSTOPTS: - result = nsetopt_lvl_ipv6_dstopts(env, descP, eVal); + case ESOCK_OPT_IPV6_DSTOPTS: + result = esock_setopt_lvl_ipv6_dstopts(env, descP, eVal); break; #endif #if defined(IPV6_FLOWINFO) - case SOCKET_OPT_IPV6_FLOWINFO: - result = nsetopt_lvl_ipv6_flowinfo(env, descP, eVal); + case ESOCK_OPT_IPV6_FLOWINFO: + result = esock_setopt_lvl_ipv6_flowinfo(env, descP, eVal); break; #endif #if defined(IPV6_HOPLIMIT) - case SOCKET_OPT_IPV6_HOPLIMIT: - result = nsetopt_lvl_ipv6_hoplimit(env, descP, eVal); + case ESOCK_OPT_IPV6_HOPLIMIT: + result = esock_setopt_lvl_ipv6_hoplimit(env, descP, eVal); break; #endif #if defined(IPV6_HOPOPTS) - case SOCKET_OPT_IPV6_HOPOPTS: - result = nsetopt_lvl_ipv6_hopopts(env, descP, eVal); + case ESOCK_OPT_IPV6_HOPOPTS: + result = esock_setopt_lvl_ipv6_hopopts(env, descP, eVal); break; #endif #if defined(IPV6_MTU) - case SOCKET_OPT_IPV6_MTU: - result = nsetopt_lvl_ipv6_mtu(env, descP, eVal); + case ESOCK_OPT_IPV6_MTU: + result = esock_setopt_lvl_ipv6_mtu(env, descP, eVal); break; #endif #if defined(IPV6_MTU_DISCOVER) - case SOCKET_OPT_IPV6_MTU_DISCOVER: - result = nsetopt_lvl_ipv6_mtu_discover(env, descP, eVal); + case ESOCK_OPT_IPV6_MTU_DISCOVER: + result = esock_setopt_lvl_ipv6_mtu_discover(env, descP, eVal); break; #endif #if defined(IPV6_MULTICAST_HOPS) - case SOCKET_OPT_IPV6_MULTICAST_HOPS: - result = nsetopt_lvl_ipv6_multicast_hops(env, descP, eVal); + case ESOCK_OPT_IPV6_MULTICAST_HOPS: + result = esock_setopt_lvl_ipv6_multicast_hops(env, descP, eVal); break; #endif #if defined(IPV6_MULTICAST_IF) - case SOCKET_OPT_IPV6_MULTICAST_IF: - result = nsetopt_lvl_ipv6_multicast_if(env, descP, eVal); + case ESOCK_OPT_IPV6_MULTICAST_IF: + result = esock_setopt_lvl_ipv6_multicast_if(env, descP, eVal); break; #endif #if defined(IPV6_MULTICAST_LOOP) - case SOCKET_OPT_IPV6_MULTICAST_LOOP: - result = nsetopt_lvl_ipv6_multicast_loop(env, descP, eVal); + case ESOCK_OPT_IPV6_MULTICAST_LOOP: + result = esock_setopt_lvl_ipv6_multicast_loop(env, descP, eVal); break; #endif #if defined(IPV6_RECVERR) - case SOCKET_OPT_IPV6_RECVERR: - result = nsetopt_lvl_ipv6_recverr(env, descP, eVal); + case ESOCK_OPT_IPV6_RECVERR: + result = esock_setopt_lvl_ipv6_recverr(env, descP, eVal); break; #endif #if defined(IPV6_RECVPKTINFO) || defined(IPV6_PKTINFO) - case SOCKET_OPT_IPV6_RECVPKTINFO: - result = nsetopt_lvl_ipv6_recvpktinfo(env, descP, eVal); + case ESOCK_OPT_IPV6_RECVPKTINFO: + result = esock_setopt_lvl_ipv6_recvpktinfo(env, descP, eVal); break; #endif #if defined(IPV6_ROUTER_ALERT) - case SOCKET_OPT_IPV6_ROUTER_ALERT: - result = nsetopt_lvl_ipv6_router_alert(env, descP, eVal); + case ESOCK_OPT_IPV6_ROUTER_ALERT: + result = esock_setopt_lvl_ipv6_router_alert(env, descP, eVal); break; #endif #if defined(IPV6_RTHDR) - case SOCKET_OPT_IPV6_RTHDR: - result = nsetopt_lvl_ipv6_rthdr(env, descP, eVal); + case ESOCK_OPT_IPV6_RTHDR: + result = esock_setopt_lvl_ipv6_rthdr(env, descP, eVal); break; #endif #if defined(IPV6_UNICAST_HOPS) - case SOCKET_OPT_IPV6_UNICAST_HOPS: - result = nsetopt_lvl_ipv6_unicast_hops(env, descP, eVal); + case ESOCK_OPT_IPV6_UNICAST_HOPS: + result = esock_setopt_lvl_ipv6_unicast_hops(env, descP, eVal); break; #endif #if defined(IPV6_V6ONLY) - case SOCKET_OPT_IPV6_V6ONLY: - result = nsetopt_lvl_ipv6_v6only(env, descP, eVal); + case ESOCK_OPT_IPV6_V6ONLY: + result = esock_setopt_lvl_ipv6_v6only(env, descP, eVal); break; #endif default: SSDBG( descP, - ("SOCKET", "nsetopt_lvl_ipv6 -> unknown opt (%d)\r\n", eOpt) ); + ("SOCKET", + "esock_setopt_lvl_ipv6 -> unknown opt (%d)\r\n", eOpt) ); result = esock_make_error(env, esock_atom_einval); break; } SSDBG( descP, - ("SOCKET", "nsetopt_lvl_ipv6 -> done when" + ("SOCKET", "esock_setopt_lvl_ipv6 -> done when" "\r\n result: %T" "\r\n", result) ); @@ -9333,15 +9723,15 @@ ERL_NIF_TERM nsetopt_lvl_ipv6(ErlNifEnv* env, #if defined(IPV6_ADDRFORM) static -ERL_NIF_TERM nsetopt_lvl_ipv6_addrform(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ipv6_addrform(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { ERL_NIF_TERM result; int res, edomain, domain; SSDBG( descP, - ("SOCKET", "nsetopt_lvl_ipv6_addrform -> entry with" + ("SOCKET", "esock_setopt_lvl_ipv6_addrform -> entry with" "\r\n eVal: %T" "\r\n", eVal) ); @@ -9349,14 +9739,15 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_addrform(ErlNifEnv* env, return esock_make_error(env, esock_atom_einval); SSDBG( descP, - ("SOCKET", "nsetopt_lvl_ipv6_addrform -> decode" + ("SOCKET", "esock_setopt_lvl_ipv6_addrform -> decode" "\r\n edomain: %d" "\r\n", edomain) ); if (!edomain2domain(edomain, &domain)) return esock_make_error(env, esock_atom_einval); - SSDBG( descP, ("SOCKET", "nsetopt_lvl_ipv6_addrform -> try set opt to %d\r\n", + SSDBG( descP, ("SOCKET", + "esock_setopt_lvl_ipv6_addrform -> try set opt to %d\r\n", domain) ); res = socket_setopt(descP->sock, @@ -9379,11 +9770,11 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_addrform(ErlNifEnv* env, #if defined(IPV6_ADD_MEMBERSHIP) static -ERL_NIF_TERM nsetopt_lvl_ipv6_add_membership(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ipv6_add_membership(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_lvl_ipv6_update_membership(env, descP, eVal, + return esock_setopt_lvl_ipv6_update_membership(env, descP, eVal, IPV6_ADD_MEMBERSHIP); } #endif @@ -9391,28 +9782,29 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_add_membership(ErlNifEnv* env, #if defined(IPV6_AUTHHDR) static -ERL_NIF_TERM nsetopt_lvl_ipv6_authhdr(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ipv6_authhdr(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_bool_opt(env, descP, #if defined(SOL_IPV6) - SOL_IPV6, + int level = SOL_IPV6; #else - IPPROTO_IPV6, + int level = IPPROTO_IPV6; #endif - IPV6_AUTHHDR, eVal); + + + return esock_setopt_bool_opt(env, descP, level, IPV6_AUTHHDR, eVal); } #endif #if defined(IPV6_DROP_MEMBERSHIP) static -ERL_NIF_TERM nsetopt_lvl_ipv6_drop_membership(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ipv6_drop_membership(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_lvl_ipv6_update_membership(env, descP, eVal, + return esock_setopt_lvl_ipv6_update_membership(env, descP, eVal, IPV6_DROP_MEMBERSHIP); } #endif @@ -9420,9 +9812,9 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_drop_membership(ErlNifEnv* env, #if defined(IPV6_DSTOPTS) static -ERL_NIF_TERM nsetopt_lvl_ipv6_dstopts(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ipv6_dstopts(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IPV6) int level = SOL_IPV6; @@ -9430,16 +9822,16 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_dstopts(ErlNifEnv* env, int level = IPPROTO_IPV6; #endif - return nsetopt_bool_opt(env, descP, level, IPV6_DSTOPTS, eVal); + return esock_setopt_bool_opt(env, descP, level, IPV6_DSTOPTS, eVal); } #endif #if defined(IPV6_FLOWINFO) static -ERL_NIF_TERM nsetopt_lvl_ipv6_flowinfo(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ipv6_flowinfo(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IPV6) int level = SOL_IPV6; @@ -9447,16 +9839,16 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_flowinfo(ErlNifEnv* env, int level = IPPROTO_IPV6; #endif - return nsetopt_bool_opt(env, descP, level, IPV6_FLOWINFO, eVal); + return esock_setopt_bool_opt(env, descP, level, IPV6_FLOWINFO, eVal); } #endif #if defined(IPV6_HOPLIMIT) static -ERL_NIF_TERM nsetopt_lvl_ipv6_hoplimit(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ipv6_hoplimit(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IPV6) int level = SOL_IPV6; @@ -9464,16 +9856,16 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_hoplimit(ErlNifEnv* env, int level = IPPROTO_IPV6; #endif - return nsetopt_bool_opt(env, descP, level, IPV6_HOPLIMIT, eVal); + return esock_setopt_bool_opt(env, descP, level, IPV6_HOPLIMIT, eVal); } #endif #if defined(IPV6_HOPOPTS) static -ERL_NIF_TERM nsetopt_lvl_ipv6_hopopts(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ipv6_hopopts(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IPV6) int level = SOL_IPV6; @@ -9481,14 +9873,14 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_hopopts(ErlNifEnv* env, int level = IPPROTO_IPV6; #endif - return nsetopt_bool_opt(env, descP, level, IPV6_HOPOPTS, eVal); + return esock_setopt_bool_opt(env, descP, level, IPV6_HOPOPTS, eVal); } #endif #if defined(IPV6_MTU) static -ERL_NIF_TERM nsetopt_lvl_ipv6_mtu(ErlNifEnv* env, +ERL_NIF_TERM esock_setopt_lvl_ipv6_mtu(ErlNifEnv* env, ESockDescriptor* descP, ERL_NIF_TERM eVal) { @@ -9498,20 +9890,20 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_mtu(ErlNifEnv* env, int level = IPPROTO_IPV6; #endif - return nsetopt_int_opt(env, descP, level, IPV6_MTU, eVal); + return esock_setopt_int_opt(env, descP, level, IPV6_MTU, eVal); } #endif -/* nsetopt_lvl_ipv6_mtu_discover - Level IPv6 MTU_DISCOVER option +/* esock_setopt_lvl_ipv6_mtu_discover - Level IPv6 MTU_DISCOVER option * * The value is an atom of the type ipv6_pmtudisc(). */ #if defined(IPV6_MTU_DISCOVER) static -ERL_NIF_TERM nsetopt_lvl_ipv6_mtu_discover(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ipv6_mtu_discover(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { ERL_NIF_TERM result; int val; @@ -9547,9 +9939,9 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_mtu_discover(ErlNifEnv* env, #if defined(IPV6_MULTICAST_HOPS) static -ERL_NIF_TERM nsetopt_lvl_ipv6_multicast_hops(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ipv6_multicast_hops(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IPV6) int level = SOL_IPV6; @@ -9557,7 +9949,7 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_multicast_hops(ErlNifEnv* env, int level = IPPROTO_IPV6; #endif - return nsetopt_int_opt(env, descP, level, IPV6_MULTICAST_HOPS, eVal); + return esock_setopt_int_opt(env, descP, level, IPV6_MULTICAST_HOPS, eVal); } #endif @@ -9565,9 +9957,9 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_multicast_hops(ErlNifEnv* env, #if defined(IPV6_MULTICAST_IF) static -ERL_NIF_TERM nsetopt_lvl_ipv6_multicast_if(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ipv6_multicast_if(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IPV6) int level = SOL_IPV6; @@ -9575,7 +9967,7 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_multicast_if(ErlNifEnv* env, int level = IPPROTO_IPV6; #endif - return nsetopt_int_opt(env, descP, level, IPV6_MULTICAST_IF, eVal); + return esock_setopt_int_opt(env, descP, level, IPV6_MULTICAST_IF, eVal); } #endif @@ -9583,9 +9975,9 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_multicast_if(ErlNifEnv* env, #if defined(IPV6_MULTICAST_LOOP) static -ERL_NIF_TERM nsetopt_lvl_ipv6_multicast_loop(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ipv6_multicast_loop(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IPV6) int level = SOL_IPV6; @@ -9593,16 +9985,16 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_multicast_loop(ErlNifEnv* env, int level = IPPROTO_IPV6; #endif - return nsetopt_bool_opt(env, descP, level, IPV6_MULTICAST_LOOP, eVal); + return esock_setopt_bool_opt(env, descP, level, IPV6_MULTICAST_LOOP, eVal); } #endif #if defined(IPV6_RECVERR) static -ERL_NIF_TERM nsetopt_lvl_ipv6_recverr(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ipv6_recverr(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IPV6) int level = SOL_IPV6; @@ -9610,16 +10002,16 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_recverr(ErlNifEnv* env, int level = IPPROTO_IPV6; #endif - return nsetopt_bool_opt(env, descP, level, IPV6_RECVERR, eVal); + return esock_setopt_bool_opt(env, descP, level, IPV6_RECVERR, eVal); } #endif #if defined(IPV6_RECVPKTINFO) || defined(IPV6_PKTINFO) static -ERL_NIF_TERM nsetopt_lvl_ipv6_recvpktinfo(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ipv6_recvpktinfo(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IPV6) int level = SOL_IPV6; @@ -9632,16 +10024,16 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_recvpktinfo(ErlNifEnv* env, int opt = IPV6_PKTINFO; #endif - return nsetopt_bool_opt(env, descP, level, opt, eVal); + return esock_setopt_bool_opt(env, descP, level, opt, eVal); } #endif #if defined(IPV6_ROUTER_ALERT) static -ERL_NIF_TERM nsetopt_lvl_ipv6_router_alert(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ipv6_router_alert(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IPV6) int level = SOL_IPV6; @@ -9649,7 +10041,7 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_router_alert(ErlNifEnv* env, int level = IPPROTO_IPV6; #endif - return nsetopt_int_opt(env, descP, level, IPV6_ROUTER_ALERT, eVal); + return esock_setopt_int_opt(env, descP, level, IPV6_ROUTER_ALERT, eVal); } #endif @@ -9657,9 +10049,9 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_router_alert(ErlNifEnv* env, #if defined(IPV6_RTHDR) static -ERL_NIF_TERM nsetopt_lvl_ipv6_rthdr(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ipv6_rthdr(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IPV6) int level = SOL_IPV6; @@ -9667,16 +10059,16 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_rthdr(ErlNifEnv* env, int level = IPPROTO_IPV6; #endif - return nsetopt_bool_opt(env, descP, level, IPV6_RTHDR, eVal); + return esock_setopt_bool_opt(env, descP, level, IPV6_RTHDR, eVal); } #endif #if defined(IPV6_UNICAST_HOPS) static -ERL_NIF_TERM nsetopt_lvl_ipv6_unicast_hops(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ipv6_unicast_hops(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IPV6) int level = SOL_IPV6; @@ -9684,7 +10076,7 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_unicast_hops(ErlNifEnv* env, int level = IPPROTO_IPV6; #endif - return nsetopt_int_opt(env, descP, level, IPV6_UNICAST_HOPS, eVal); + return esock_setopt_int_opt(env, descP, level, IPV6_UNICAST_HOPS, eVal); } #endif @@ -9692,9 +10084,9 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_unicast_hops(ErlNifEnv* env, #if defined(IPV6_V6ONLY) static -ERL_NIF_TERM nsetopt_lvl_ipv6_v6only(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_ipv6_v6only(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { #if defined(SOL_IPV6) int level = SOL_IPV6; @@ -9702,17 +10094,17 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_v6only(ErlNifEnv* env, int level = IPPROTO_IPV6; #endif - return nsetopt_bool_opt(env, descP, level, IPV6_V6ONLY, eVal); + return esock_setopt_bool_opt(env, descP, level, IPV6_V6ONLY, eVal); } #endif #if defined(IPV6_ADD_MEMBERSHIP) || defined(IPV6_DROP_MEMBERSHIP) static -ERL_NIF_TERM nsetopt_lvl_ipv6_update_membership(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal, - int opt) +ERL_NIF_TERM esock_setopt_lvl_ipv6_update_membership(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal, + int opt) { ERL_NIF_TERM result, eMultiAddr, eInterface; struct ipv6_mreq mreq; @@ -9728,7 +10120,7 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_update_membership(ErlNifEnv* env, // It must be a map if (!IS_MAP(env, eVal)) { SSDBG( descP, - ("SOCKET", "nsetopt_lvl_ipv6_update_membership -> " + ("SOCKET", "esock_setopt_lvl_ipv6_update_membership -> " "value *not* a map\r\n") ); return enif_make_badarg(env); } @@ -9736,21 +10128,21 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_update_membership(ErlNifEnv* env, // It must have atleast two attributes if (!enif_get_map_size(env, eVal, &sz) || (sz < 2)) { SSDBG( descP, - ("SOCKET", "nsetopt_lvl_ipv6_update_membership -> " + ("SOCKET", "esock_setopt_lvl_ipv6_update_membership -> " "invalid map value: %T\r\n", eVal) ); return enif_make_badarg(env); } if (!GET_MAP_VAL(env, eVal, atom_multiaddr, &eMultiAddr)) { SSDBG( descP, - ("SOCKET", "nsetopt_lvl_ipv6_update_membership -> " + ("SOCKET", "esock_setopt_lvl_ipv6_update_membership -> " "failed get multiaddr (map) attribute\r\n") ); return enif_make_badarg(env); } if (!GET_MAP_VAL(env, eVal, atom_interface, &eInterface)) { SSDBG( descP, - ("SOCKET", "nsetopt_lvl_ipv6_update_membership -> " + ("SOCKET", "esock_setopt_lvl_ipv6_update_membership -> " "failed get interface (map) attribute\r\n") ); return enif_make_badarg(env); } @@ -9759,14 +10151,14 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_update_membership(ErlNifEnv* env, eMultiAddr, &mreq.ipv6mr_multiaddr)) != NULL) { SSDBG( descP, - ("SOCKET", "nsetopt_lvl_ipv6_update_membership -> " + ("SOCKET", "esock_setopt_lvl_ipv6_update_membership -> " "failed decode multiaddr %T: %s\r\n", eMultiAddr, xres) ); return esock_make_error_str(env, xres); } if (!GET_UINT(env, eInterface, &mreq.ipv6mr_interface)) { SSDBG( descP, - ("SOCKET", "nsetopt_lvl_ip_update_membership -> " + ("SOCKET", "esock_setopt_lvl_ip_update_membership -> " "failed decode interface %T: %s\r\n", eInterface, xres) ); return esock_make_error(env, esock_atom_einval); } @@ -9779,7 +10171,7 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_update_membership(ErlNifEnv* env, result = esock_make_error_errno(env, save_errno); SSDBG( descP, - ("SOCKET", "nsetopt_lvl_ipv6_update_membership -> " + ("SOCKET", "esock_setopt_lvl_ipv6_update_membership -> " "failed setopt: %T (%d)\r\n", result, save_errno) ); } else { @@ -9796,37 +10188,37 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_update_membership(ErlNifEnv* env, -/* nsetopt_lvl_tcp - Level *TCP* option(s) +/* esock_setopt_lvl_tcp - Level *TCP* option(s) */ static -ERL_NIF_TERM nsetopt_lvl_tcp(ErlNifEnv* env, - ESockDescriptor* descP, - int eOpt, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_tcp(ErlNifEnv* env, + ESockDescriptor* descP, + int eOpt, + ERL_NIF_TERM eVal) { ERL_NIF_TERM result; SSDBG( descP, - ("SOCKET", "nsetopt_lvl_tcp -> entry with" + ("SOCKET", "esock_setopt_lvl_tcp -> entry with" "\r\n opt: %d" "\r\n", eOpt) ); switch (eOpt) { #if defined(TCP_CONGESTION) - case SOCKET_OPT_TCP_CONGESTION: - result = nsetopt_lvl_tcp_congestion(env, descP, eVal); + case ESOCK_OPT_TCP_CONGESTION: + result = esock_setopt_lvl_tcp_congestion(env, descP, eVal); break; #endif #if defined(TCP_MAXSEG) - case SOCKET_OPT_TCP_MAXSEG: - result = nsetopt_lvl_tcp_maxseg(env, descP, eVal); + case ESOCK_OPT_TCP_MAXSEG: + result = esock_setopt_lvl_tcp_maxseg(env, descP, eVal); break; #endif #if defined(TCP_NODELAY) - case SOCKET_OPT_TCP_NODELAY: - result = nsetopt_lvl_tcp_nodelay(env, descP, eVal); + case ESOCK_OPT_TCP_NODELAY: + result = esock_setopt_lvl_tcp_nodelay(env, descP, eVal); break; #endif @@ -9839,67 +10231,68 @@ ERL_NIF_TERM nsetopt_lvl_tcp(ErlNifEnv* env, } -/* nsetopt_lvl_tcp_congestion - Level TCP CONGESTION option +/* esock_setopt_lvl_tcp_congestion - Level TCP CONGESTION option */ #if defined(TCP_CONGESTION) static -ERL_NIF_TERM nsetopt_lvl_tcp_congestion(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_tcp_congestion(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - int max = SOCKET_OPT_TCP_CONGESTION_NAME_MAX+1; + int max = ESOCK_OPT_TCP_CONGESTION_NAME_MAX+1; - return nsetopt_str_opt(env, descP, IPPROTO_TCP, TCP_CONGESTION, max, eVal); + return esock_setopt_str_opt(env, descP, + IPPROTO_TCP, TCP_CONGESTION, max, eVal); } #endif -/* nsetopt_lvl_tcp_maxseg - Level TCP MAXSEG option +/* esock_setopt_lvl_tcp_maxseg - Level TCP MAXSEG option */ #if defined(TCP_MAXSEG) static -ERL_NIF_TERM nsetopt_lvl_tcp_maxseg(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_tcp_maxseg(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_int_opt(env, descP, IPPROTO_TCP, TCP_MAXSEG, eVal); + return esock_setopt_int_opt(env, descP, IPPROTO_TCP, TCP_MAXSEG, eVal); } #endif -/* nsetopt_lvl_tcp_nodelay - Level TCP NODELAY option +/* esock_setopt_lvl_tcp_nodelay - Level TCP NODELAY option */ #if defined(TCP_NODELAY) static -ERL_NIF_TERM nsetopt_lvl_tcp_nodelay(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_tcp_nodelay(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_bool_opt(env, descP, IPPROTO_TCP, TCP_NODELAY, eVal); + return esock_setopt_bool_opt(env, descP, IPPROTO_TCP, TCP_NODELAY, eVal); } #endif -/* nsetopt_lvl_udp - Level *UDP* option(s) +/* esock_setopt_lvl_udp - Level *UDP* option(s) */ static -ERL_NIF_TERM nsetopt_lvl_udp(ErlNifEnv* env, - ESockDescriptor* descP, - int eOpt, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_udp(ErlNifEnv* env, + ESockDescriptor* descP, + int eOpt, + ERL_NIF_TERM eVal) { ERL_NIF_TERM result; SSDBG( descP, - ("SOCKET", "nsetopt_lvl_udp -> entry with" + ("SOCKET", "esock_setopt_lvl_udp -> entry with" "\r\n opt: %d" "\r\n", eOpt) ); switch (eOpt) { #if defined(UDP_CORK) - case SOCKET_OPT_UDP_CORK: - result = nsetopt_lvl_udp_cork(env, descP, eVal); + case ESOCK_OPT_UDP_CORK: + result = esock_setopt_lvl_udp_cork(env, descP, eVal); break; #endif @@ -9912,83 +10305,83 @@ ERL_NIF_TERM nsetopt_lvl_udp(ErlNifEnv* env, } -/* nsetopt_lvl_udp_cork - Level UDP CORK option +/* esock_setopt_lvl_udp_cork - Level UDP CORK option */ #if defined(UDP_CORK) static -ERL_NIF_TERM nsetopt_lvl_udp_cork(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_udp_cork(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_bool_opt(env, descP, IPPROTO_UDP, UDP_CORK, eVal); + return esock_setopt_bool_opt(env, descP, IPPROTO_UDP, UDP_CORK, eVal); } #endif -/* nsetopt_lvl_sctp - Level *SCTP* option(s) +/* esock_setopt_lvl_sctp - Level *SCTP* option(s) */ #if defined(HAVE_SCTP) static -ERL_NIF_TERM nsetopt_lvl_sctp(ErlNifEnv* env, - ESockDescriptor* descP, - int eOpt, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_sctp(ErlNifEnv* env, + ESockDescriptor* descP, + int eOpt, + ERL_NIF_TERM eVal) { ERL_NIF_TERM result; SSDBG( descP, - ("SOCKET", "nsetopt_lvl_sctp -> entry with" + ("SOCKET", "esock_setopt_lvl_sctp -> entry with" "\r\n opt: %d" "\r\n", eOpt) ); switch (eOpt) { #if defined(SCTP_ASSOCINFO) - case SOCKET_OPT_SCTP_ASSOCINFO: - result = nsetopt_lvl_sctp_associnfo(env, descP, eVal); + case ESOCK_OPT_SCTP_ASSOCINFO: + result = esock_setopt_lvl_sctp_associnfo(env, descP, eVal); break; #endif #if defined(SCTP_AUTOCLOSE) - case SOCKET_OPT_SCTP_AUTOCLOSE: - result = nsetopt_lvl_sctp_autoclose(env, descP, eVal); + case ESOCK_OPT_SCTP_AUTOCLOSE: + result = esock_setopt_lvl_sctp_autoclose(env, descP, eVal); break; #endif #if defined(SCTP_DISABLE_FRAGMENTS) - case SOCKET_OPT_SCTP_DISABLE_FRAGMENTS: - result = nsetopt_lvl_sctp_disable_fragments(env, descP, eVal); + case ESOCK_OPT_SCTP_DISABLE_FRAGMENTS: + result = esock_setopt_lvl_sctp_disable_fragments(env, descP, eVal); break; #endif #if defined(SCTP_EVENTS) - case SOCKET_OPT_SCTP_EVENTS: - result = nsetopt_lvl_sctp_events(env, descP, eVal); + case ESOCK_OPT_SCTP_EVENTS: + result = esock_setopt_lvl_sctp_events(env, descP, eVal); break; #endif #if defined(SCTP_INITMSG) - case SOCKET_OPT_SCTP_INITMSG: - result = nsetopt_lvl_sctp_initmsg(env, descP, eVal); + case ESOCK_OPT_SCTP_INITMSG: + result = esock_setopt_lvl_sctp_initmsg(env, descP, eVal); break; #endif #if defined(SCTP_MAXSEG) - case SOCKET_OPT_SCTP_MAXSEG: - result = nsetopt_lvl_sctp_maxseg(env, descP, eVal); + case ESOCK_OPT_SCTP_MAXSEG: + result = esock_setopt_lvl_sctp_maxseg(env, descP, eVal); break; #endif #if defined(SCTP_NODELAY) - case SOCKET_OPT_SCTP_NODELAY: - result = nsetopt_lvl_sctp_nodelay(env, descP, eVal); + case ESOCK_OPT_SCTP_NODELAY: + result = esock_setopt_lvl_sctp_nodelay(env, descP, eVal); break; #endif #if defined(SCTP_RTOINFO) - case SOCKET_OPT_SCTP_RTOINFO: - result = nsetopt_lvl_sctp_rtoinfo(env, descP, eVal); + case ESOCK_OPT_SCTP_RTOINFO: + result = esock_setopt_lvl_sctp_rtoinfo(env, descP, eVal); break; #endif @@ -10001,13 +10394,13 @@ ERL_NIF_TERM nsetopt_lvl_sctp(ErlNifEnv* env, } -/* nsetopt_lvl_sctp_associnfo - Level SCTP ASSOCINFO option +/* esock_setopt_lvl_sctp_associnfo - Level SCTP ASSOCINFO option */ #if defined(SCTP_ASSOCINFO) static -ERL_NIF_TERM nsetopt_lvl_sctp_associnfo(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_sctp_associnfo(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { ERL_NIF_TERM result; ERL_NIF_TERM eAssocId, eMaxRxt, eNumPeerDests; @@ -10018,7 +10411,7 @@ ERL_NIF_TERM nsetopt_lvl_sctp_associnfo(ErlNifEnv* env, unsigned int tmp; SSDBG( descP, - ("SOCKET", "nsetopt_lvl_sctp_associnfo -> entry with" + ("SOCKET", "esock_setopt_lvl_sctp_associnfo -> entry with" "\r\n eVal: %T" "\r\n", eVal) ); @@ -10031,7 +10424,8 @@ ERL_NIF_TERM nsetopt_lvl_sctp_associnfo(ErlNifEnv* env, return esock_make_error(env, esock_atom_einval); SSDBG( descP, - ("SOCKET", "nsetopt_lvl_sctp_associnfo -> extract attributes\r\n") ); + ("SOCKET", + "esock_setopt_lvl_sctp_associnfo -> extract attributes\r\n") ); if (!GET_MAP_VAL(env, eVal, atom_assoc_id, &eAssocId)) return esock_make_error(env, esock_atom_einval); @@ -10052,7 +10446,8 @@ ERL_NIF_TERM nsetopt_lvl_sctp_associnfo(ErlNifEnv* env, return esock_make_error(env, esock_atom_einval); SSDBG( descP, - ("SOCKET", "nsetopt_lvl_sctp_associnfo -> decode attributes\r\n") ); + ("SOCKET", + "esock_setopt_lvl_sctp_associnfo -> decode attributes\r\n") ); /* On some platforms the assoc id is typed as an unsigned integer (uint32) * So, to avoid warnings there, we always make an explicit cast... @@ -10105,7 +10500,8 @@ ERL_NIF_TERM nsetopt_lvl_sctp_associnfo(ErlNifEnv* env, return esock_make_error(env, esock_atom_einval); SSDBG( descP, - ("SOCKET", "nsetopt_lvl_sctp_associnfo -> set associnfo option\r\n") ); + ("SOCKET", + "esock_setopt_lvl_sctp_associnfo -> set associnfo option\r\n") ); res = socket_setopt(descP->sock, IPPROTO_SCTP, SCTP_ASSOCINFO, &assocParams, sizeof(assocParams)); @@ -10116,7 +10512,7 @@ ERL_NIF_TERM nsetopt_lvl_sctp_associnfo(ErlNifEnv* env, result = esock_atom_ok; SSDBG( descP, - ("SOCKET", "nsetopt_lvl_sctp_associnfo -> done with" + ("SOCKET", "esock_setopt_lvl_sctp_associnfo -> done with" "\r\n result: %T" "\r\n", result) ); @@ -10126,39 +10522,42 @@ ERL_NIF_TERM nsetopt_lvl_sctp_associnfo(ErlNifEnv* env, #endif -/* nsetopt_lvl_sctp_autoclose - Level SCTP AUTOCLOSE option +/* esock_setopt_lvl_sctp_autoclose - Level SCTP AUTOCLOSE option */ #if defined(SCTP_AUTOCLOSE) static -ERL_NIF_TERM nsetopt_lvl_sctp_autoclose(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_sctp_autoclose(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_int_opt(env, descP, IPPROTO_SCTP, SCTP_AUTOCLOSE, eVal); + return esock_setopt_int_opt(env, descP, + IPPROTO_SCTP, SCTP_AUTOCLOSE, eVal); } #endif -/* nsetopt_lvl_sctp_disable_fragments - Level SCTP DISABLE_FRAGMENTS option +/* esock_setopt_lvl_sctp_disable_fragments - + * Level SCTP DISABLE_FRAGMENTS option */ #if defined(SCTP_DISABLE_FRAGMENTS) static -ERL_NIF_TERM nsetopt_lvl_sctp_disable_fragments(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_sctp_disable_fragments(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_bool_opt(env, descP, IPPROTO_SCTP, SCTP_DISABLE_FRAGMENTS, eVal); + return esock_setopt_bool_opt(env, descP, + IPPROTO_SCTP, SCTP_DISABLE_FRAGMENTS, eVal); } #endif -/* nsetopt_lvl_sctp_events - Level SCTP EVENTS option +/* esock_setopt_lvl_sctp_events - Level SCTP EVENTS option */ #if defined(SCTP_EVENTS) static -ERL_NIF_TERM nsetopt_lvl_sctp_events(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_sctp_events(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { ERL_NIF_TERM result; ERL_NIF_TERM eDataIn, eAssoc, eAddr, eSndFailure; @@ -10175,7 +10574,7 @@ ERL_NIF_TERM nsetopt_lvl_sctp_events(ErlNifEnv* env, size_t sz; SSDBG( descP, - ("SOCKET", "nsetopt_lvl_sctp_events -> entry with" + ("SOCKET", "esock_setopt_lvl_sctp_events -> entry with" "\r\n eVal: %T" "\r\n", eVal) ); @@ -10188,7 +10587,8 @@ ERL_NIF_TERM nsetopt_lvl_sctp_events(ErlNifEnv* env, return esock_make_error(env, esock_atom_einval); SSDBG( descP, - ("SOCKET", "nsetopt_lvl_sctp_events -> extract attributes\r\n") ); + ("SOCKET", + "esock_setopt_lvl_sctp_events -> extract attributes\r\n") ); if (!GET_MAP_VAL(env, eVal, atom_data_in, &eDataIn)) return esock_make_error(env, esock_atom_einval); @@ -10225,7 +10625,8 @@ ERL_NIF_TERM nsetopt_lvl_sctp_events(ErlNifEnv* env, #endif SSDBG( descP, - ("SOCKET", "nsetopt_lvl_sctp_events -> decode attributes\r\n") ); + ("SOCKET", + "esock_setopt_lvl_sctp_events -> decode attributes\r\n") ); events.sctp_data_io_event = esock_decode_bool(eDataIn); events.sctp_association_event = esock_decode_bool(eAssoc); @@ -10243,7 +10644,8 @@ ERL_NIF_TERM nsetopt_lvl_sctp_events(ErlNifEnv* env, #endif SSDBG( descP, - ("SOCKET", "nsetopt_lvl_sctp_events -> set events option\r\n") ); + ("SOCKET", + "esock_setopt_lvl_sctp_events -> set events option\r\n") ); res = socket_setopt(descP->sock, IPPROTO_SCTP, SCTP_EVENTS, &events, sizeof(events)); @@ -10254,7 +10656,7 @@ ERL_NIF_TERM nsetopt_lvl_sctp_events(ErlNifEnv* env, result = esock_atom_ok; SSDBG( descP, - ("SOCKET", "nsetopt_lvl_sctp_events -> done with" + ("SOCKET", "esock_setopt_lvl_sctp_events -> done with" "\r\n result: %T" "\r\n", result) ); @@ -10264,13 +10666,13 @@ ERL_NIF_TERM nsetopt_lvl_sctp_events(ErlNifEnv* env, #endif -/* nsetopt_lvl_sctp_initmsg - Level SCTP INITMSG option +/* esock_setopt_lvl_sctp_initmsg - Level SCTP INITMSG option */ #if defined(SCTP_INITMSG) static -ERL_NIF_TERM nsetopt_lvl_sctp_initmsg(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_sctp_initmsg(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { ERL_NIF_TERM result; ERL_NIF_TERM eNumOut, eMaxIn, eMaxAttempts, eMaxInitTO; @@ -10280,7 +10682,7 @@ ERL_NIF_TERM nsetopt_lvl_sctp_initmsg(ErlNifEnv* env, unsigned int tmp; SSDBG( descP, - ("SOCKET", "nsetopt_lvl_sctp_initmsg -> entry with" + ("SOCKET", "esock_setopt_lvl_sctp_initmsg -> entry with" "\r\n eVal: %T" "\r\n", eVal) ); @@ -10293,7 +10695,8 @@ ERL_NIF_TERM nsetopt_lvl_sctp_initmsg(ErlNifEnv* env, return esock_make_error(env, esock_atom_einval); SSDBG( descP, - ("SOCKET", "nsetopt_lvl_sctp_initmsg -> extract attributes\r\n") ); + ("SOCKET", + "esock_setopt_lvl_sctp_initmsg -> extract attributes\r\n") ); if (!GET_MAP_VAL(env, eVal, atom_num_outstreams, &eNumOut)) return esock_make_error(env, esock_atom_einval); @@ -10308,7 +10711,8 @@ ERL_NIF_TERM nsetopt_lvl_sctp_initmsg(ErlNifEnv* env, return esock_make_error(env, esock_atom_einval); SSDBG( descP, - ("SOCKET", "nsetopt_lvl_sctp_initmsg -> decode attributes\r\n") ); + ("SOCKET", + "esock_setopt_lvl_sctp_initmsg -> decode attributes\r\n") ); if (!GET_UINT(env, eNumOut, &tmp)) return esock_make_error(env, esock_atom_einval); @@ -10327,7 +10731,8 @@ ERL_NIF_TERM nsetopt_lvl_sctp_initmsg(ErlNifEnv* env, initMsg.sinit_max_init_timeo = (Uint16) tmp; SSDBG( descP, - ("SOCKET", "nsetopt_lvl_sctp_initmsg -> set initmsg option\r\n") ); + ("SOCKET", + "esock_setopt_lvl_sctp_initmsg -> set initmsg option\r\n") ); res = socket_setopt(descP->sock, IPPROTO_SCTP, SCTP_INITMSG, &initMsg, sizeof(initMsg)); @@ -10338,7 +10743,7 @@ ERL_NIF_TERM nsetopt_lvl_sctp_initmsg(ErlNifEnv* env, result = esock_atom_ok; SSDBG( descP, - ("SOCKET", "nsetopt_lvl_sctp_initmsg -> done with" + ("SOCKET", "esock_setopt_lvl_sctp_initmsg -> done with" "\r\n result: %T" "\r\n", result) ); @@ -10348,39 +10753,39 @@ ERL_NIF_TERM nsetopt_lvl_sctp_initmsg(ErlNifEnv* env, #endif -/* nsetopt_lvl_sctp_maxseg - Level SCTP MAXSEG option +/* esock_setopt_lvl_sctp_maxseg - Level SCTP MAXSEG option */ #if defined(SCTP_MAXSEG) static -ERL_NIF_TERM nsetopt_lvl_sctp_maxseg(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_sctp_maxseg(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_int_opt(env, descP, IPPROTO_SCTP, SCTP_MAXSEG, eVal); + return esock_setopt_int_opt(env, descP, IPPROTO_SCTP, SCTP_MAXSEG, eVal); } #endif -/* nsetopt_lvl_sctp_nodelay - Level SCTP NODELAY option +/* esock_setopt_lvl_sctp_nodelay - Level SCTP NODELAY option */ #if defined(SCTP_NODELAY) static -ERL_NIF_TERM nsetopt_lvl_sctp_nodelay(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_sctp_nodelay(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { - return nsetopt_bool_opt(env, descP, IPPROTO_SCTP, SCTP_NODELAY, eVal); + return esock_setopt_bool_opt(env, descP, IPPROTO_SCTP, SCTP_NODELAY, eVal); } #endif -/* nsetopt_lvl_sctp_rtoinfo - Level SCTP RTOINFO option +/* esock_setopt_lvl_sctp_rtoinfo - Level SCTP RTOINFO option */ #if defined(SCTP_RTOINFO) static -ERL_NIF_TERM nsetopt_lvl_sctp_rtoinfo(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_lvl_sctp_rtoinfo(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM eVal) { ERL_NIF_TERM result; ERL_NIF_TERM eAssocId, eInitial, eMax, eMin; @@ -10389,7 +10794,7 @@ ERL_NIF_TERM nsetopt_lvl_sctp_rtoinfo(ErlNifEnv* env, size_t sz; SSDBG( descP, - ("SOCKET", "nsetopt_lvl_sctp_rtoinfo -> entry with" + ("SOCKET", "esock_setopt_lvl_sctp_rtoinfo -> entry with" "\r\n eVal: %T" "\r\n", eVal) ); @@ -10402,7 +10807,8 @@ ERL_NIF_TERM nsetopt_lvl_sctp_rtoinfo(ErlNifEnv* env, return esock_make_error(env, esock_atom_einval); SSDBG( descP, - ("SOCKET", "nsetopt_lvl_sctp_rtoinfo -> extract attributes\r\n") ); + ("SOCKET", + "esock_setopt_lvl_sctp_rtoinfo -> extract attributes\r\n") ); if (!GET_MAP_VAL(env, eVal, atom_assoc_id, &eAssocId)) return esock_make_error(env, esock_atom_einval); @@ -10417,7 +10823,8 @@ ERL_NIF_TERM nsetopt_lvl_sctp_rtoinfo(ErlNifEnv* env, return esock_make_error(env, esock_atom_einval); SSDBG( descP, - ("SOCKET", "nsetopt_lvl_sctp_rtoinfo -> decode attributes\r\n") ); + ("SOCKET", + "esock_setopt_lvl_sctp_rtoinfo -> decode attributes\r\n") ); /* On some platforms the assoc id is typed as an unsigned integer (uint32) * So, to avoid warnings there, we always make an explicit cast... @@ -10452,7 +10859,8 @@ ERL_NIF_TERM nsetopt_lvl_sctp_rtoinfo(ErlNifEnv* env, return esock_make_error(env, esock_atom_einval); SSDBG( descP, - ("SOCKET", "nsetopt_lvl_sctp_rtoinfo -> set associnfo option\r\n") ); + ("SOCKET", + "esock_setopt_lvl_sctp_rtoinfo -> set associnfo option\r\n") ); res = socket_setopt(descP->sock, IPPROTO_SCTP, SCTP_RTOINFO, &rtoInfo, sizeof(rtoInfo)); @@ -10463,7 +10871,7 @@ ERL_NIF_TERM nsetopt_lvl_sctp_rtoinfo(ErlNifEnv* env, result = esock_atom_ok; SSDBG( descP, - ("SOCKET", "nsetopt_lvl_sctp_rtoinfo -> done with" + ("SOCKET", "esock_setopt_lvl_sctp_rtoinfo -> done with" "\r\n result: %T" "\r\n", result) ); @@ -10479,14 +10887,14 @@ ERL_NIF_TERM nsetopt_lvl_sctp_rtoinfo(ErlNifEnv* env, -/* nsetopt_bool_opt - set an option that has an (integer) bool value +/* esock_setopt_bool_opt - set an option that has an (integer) bool value */ static -ERL_NIF_TERM nsetopt_bool_opt(ErlNifEnv* env, - ESockDescriptor* descP, - int level, - int opt, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_bool_opt(ErlNifEnv* env, + ESockDescriptor* descP, + int level, + int opt, + ERL_NIF_TERM eVal) { ERL_NIF_TERM result; BOOLEAN_T val; @@ -10506,14 +10914,14 @@ ERL_NIF_TERM nsetopt_bool_opt(ErlNifEnv* env, } -/* nsetopt_int_opt - set an option that has an integer value +/* esock_setopt_int_opt - set an option that has an integer value */ static -ERL_NIF_TERM nsetopt_int_opt(ErlNifEnv* env, - ESockDescriptor* descP, - int level, - int opt, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_int_opt(ErlNifEnv* env, + ESockDescriptor* descP, + int level, + int opt, + ERL_NIF_TERM eVal) { ERL_NIF_TERM result; int val; @@ -10523,7 +10931,7 @@ ERL_NIF_TERM nsetopt_int_opt(ErlNifEnv* env, /* SSDBG( descP, - ("SOCKET", "nsetopt_int_opt -> set option" + ("SOCKET", "esock_setopt_int_opt -> set option" "\r\n opt: %d" "\r\n val: %d" "\r\n", opt, val) ); @@ -10544,16 +10952,16 @@ ERL_NIF_TERM nsetopt_int_opt(ErlNifEnv* env, } -/* nsetopt_str_opt - set an option that has an string value +/* esock_setopt_str_opt - set an option that has an string value */ #if defined(USE_SETOPT_STR_OPT) static -ERL_NIF_TERM nsetopt_str_opt(ErlNifEnv* env, - ESockDescriptor* descP, - int level, - int opt, - int max, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_str_opt(ErlNifEnv* env, + ESockDescriptor* descP, + int level, + int opt, + int max, + ERL_NIF_TERM eVal) { ERL_NIF_TERM result; char* val = MALLOC(max); @@ -10578,14 +10986,14 @@ ERL_NIF_TERM nsetopt_str_opt(ErlNifEnv* env, #endif -/* nsetopt_timeval_opt - set an option that has an (timeval) bool value +/* esock_setopt_timeval_opt - set an option that has an (timeval) bool value */ static -ERL_NIF_TERM nsetopt_timeval_opt(ErlNifEnv* env, - ESockDescriptor* descP, - int level, - int opt, - ERL_NIF_TERM eVal) +ERL_NIF_TERM esock_setopt_timeval_opt(ErlNifEnv* env, + ESockDescriptor* descP, + int level, + int opt, + ERL_NIF_TERM eVal) { ERL_NIF_TERM result; struct timeval timeVal; @@ -10593,7 +11001,7 @@ ERL_NIF_TERM nsetopt_timeval_opt(ErlNifEnv* env, char* xres; SSDBG( descP, - ("SOCKET", "nsetopt_timeval_opt -> entry with" + ("SOCKET", "esock_setopt_timeval_opt -> entry with" "\r\n eVal: %T" "\r\n", eVal) ); @@ -10601,7 +11009,7 @@ ERL_NIF_TERM nsetopt_timeval_opt(ErlNifEnv* env, return esock_make_error_str(env, xres); SSDBG( descP, - ("SOCKET", "nsetopt_timeval_opt -> set timeval option\r\n") ); + ("SOCKET", "esock_setopt_timeval_opt -> set timeval option\r\n") ); res = socket_setopt(descP->sock, level, opt, &timeVal, sizeof(timeVal)); @@ -10611,7 +11019,7 @@ ERL_NIF_TERM nsetopt_timeval_opt(ErlNifEnv* env, result = esock_atom_ok; SSDBG( descP, - ("SOCKET", "nsetopt_timeval_opt -> done with" + ("SOCKET", "esock_setopt_timeval_opt -> done with" "\r\n result: %T" "\r\n", result) ); @@ -10631,19 +11039,19 @@ BOOLEAN_T elevel2level(BOOLEAN_T isEncoded, if (isEncoded) { switch (eLevel) { - case SOCKET_OPT_LEVEL_OTP: + case ESOCK_OPT_LEVEL_OTP: *isOTP = TRUE; *level = -1; result = TRUE; break; - case SOCKET_OPT_LEVEL_SOCKET: + case ESOCK_OPT_LEVEL_SOCKET: *isOTP = FALSE; *level = SOL_SOCKET; result = TRUE; break; - case SOCKET_OPT_LEVEL_IP: + case ESOCK_OPT_LEVEL_IP: *isOTP = FALSE; #if defined(SOL_IP) *level = SOL_IP; @@ -10654,7 +11062,7 @@ BOOLEAN_T elevel2level(BOOLEAN_T isEncoded, break; #if defined(HAVE_IPV6) - case SOCKET_OPT_LEVEL_IPV6: + case ESOCK_OPT_LEVEL_IPV6: *isOTP = FALSE; #if defined(SOL_IPV6) *level = SOL_IPV6; @@ -10665,20 +11073,20 @@ BOOLEAN_T elevel2level(BOOLEAN_T isEncoded, break; #endif - case SOCKET_OPT_LEVEL_TCP: + case ESOCK_OPT_LEVEL_TCP: *isOTP = FALSE; *level = IPPROTO_TCP; result = TRUE; break; - case SOCKET_OPT_LEVEL_UDP: + case ESOCK_OPT_LEVEL_UDP: *isOTP = FALSE; *level = IPPROTO_UDP; result = TRUE; break; #ifdef HAVE_SCTP - case SOCKET_OPT_LEVEL_SCTP: + case ESOCK_OPT_LEVEL_SCTP: *isOTP = FALSE; *level = IPPROTO_SCTP; result = TRUE; @@ -10823,7 +11231,7 @@ ERL_NIF_TERM nif_getopt(ErlNifEnv* env, SGDBG( ("SOCKET", "nif_getopt -> entry with argc: %d\r\n", argc) ); if ((argc != 4) || - !enif_get_resource(env, argv[0], sockets, (void**) &descP) || + !ESOCK_GET_RESOURCE(env, argv[0], (void**) &descP) || !GET_INT(env, argv[2], &eLevel)) { SGDBG( ("SOCKET", "nif_getopt -> failed processing args\r\n") ); return enif_make_badarg(env); @@ -10849,7 +11257,7 @@ ERL_NIF_TERM nif_getopt(ErlNifEnv* env, MLOCK(descP->cfgMtx); - result = ngetopt(env, descP, isEncoded, isOTP, level, eOpt); + result = esock_getopt(env, descP, isEncoded, isOTP, level, eOpt); MUNLOCK(descP->cfgMtx); @@ -10862,18 +11270,18 @@ ERL_NIF_TERM nif_getopt(ErlNifEnv* env, #if !defined(__WIN32__) static -ERL_NIF_TERM ngetopt(ErlNifEnv* env, - ESockDescriptor* descP, - BOOLEAN_T isEncoded, - BOOLEAN_T isOTP, - int level, - ERL_NIF_TERM eOpt) +ERL_NIF_TERM esock_getopt(ErlNifEnv* env, + ESockDescriptor* descP, + BOOLEAN_T isEncoded, + BOOLEAN_T isOTP, + int level, + ERL_NIF_TERM eOpt) { ERL_NIF_TERM result; int opt; SSDBG( descP, - ("SOCKET", "ngetopt -> entry with" + ("SOCKET", "esock_getopt -> entry with" "\r\n isEncoded: %s" "\r\n isOTP: %s" "\r\n level: %d" @@ -10885,20 +11293,20 @@ ERL_NIF_TERM ngetopt(ErlNifEnv* env, * but options for our implementation. */ if (GET_INT(env, eOpt, &opt)) - result = ngetopt_otp(env, descP, opt); + result = esock_getopt_otp(env, descP, opt); else result = esock_make_error(env, esock_atom_einval); } else if (!isEncoded) { - result = ngetopt_native(env, descP, level, eOpt); + result = esock_getopt_native(env, descP, level, eOpt); } else { if (GET_INT(env, eOpt, &opt)) - result = ngetopt_level(env, descP, level, opt); + result = esock_getopt_level(env, descP, level, opt); else result = esock_make_error(env, esock_atom_einval); } SSDBG( descP, - ("SOCKET", "ngetopt -> done when" + ("SOCKET", "esock_getopt -> done when" "\r\n result: %T" "\r\n", result) ); @@ -10907,60 +11315,60 @@ ERL_NIF_TERM ngetopt(ErlNifEnv* env, -/* ngetopt_otp - Handle OTP (level) options +/* esock_getopt_otp - Handle OTP (level) options */ static -ERL_NIF_TERM ngetopt_otp(ErlNifEnv* env, - ESockDescriptor* descP, - int eOpt) +ERL_NIF_TERM esock_getopt_otp(ErlNifEnv* env, + ESockDescriptor* descP, + int eOpt) { ERL_NIF_TERM result; SSDBG( descP, - ("SOCKET", "ngetopt_otp -> entry with" + ("SOCKET", "esock_getopt_otp -> entry with" "\r\n eOpt: %d" "\r\n", eOpt) ); switch (eOpt) { - case SOCKET_OPT_OTP_DEBUG: - result = ngetopt_otp_debug(env, descP); + case ESOCK_OPT_OTP_DEBUG: + result = esock_getopt_otp_debug(env, descP); break; - case SOCKET_OPT_OTP_IOW: - result = ngetopt_otp_iow(env, descP); + case ESOCK_OPT_OTP_IOW: + result = esock_getopt_otp_iow(env, descP); break; - case SOCKET_OPT_OTP_CTRL_PROC: - result = ngetopt_otp_ctrl_proc(env, descP); + case ESOCK_OPT_OTP_CTRL_PROC: + result = esock_getopt_otp_ctrl_proc(env, descP); break; - case SOCKET_OPT_OTP_RCVBUF: - result = ngetopt_otp_rcvbuf(env, descP); + case ESOCK_OPT_OTP_RCVBUF: + result = esock_getopt_otp_rcvbuf(env, descP); break; - case SOCKET_OPT_OTP_RCVCTRLBUF: - result = ngetopt_otp_rcvctrlbuf(env, descP); + case ESOCK_OPT_OTP_RCVCTRLBUF: + result = esock_getopt_otp_rcvctrlbuf(env, descP); break; - case SOCKET_OPT_OTP_SNDCTRLBUF: - result = ngetopt_otp_sndctrlbuf(env, descP); + case ESOCK_OPT_OTP_SNDCTRLBUF: + result = esock_getopt_otp_sndctrlbuf(env, descP); break; - case SOCKET_OPT_OTP_FD: - result = ngetopt_otp_fd(env, descP); + case ESOCK_OPT_OTP_FD: + result = esock_getopt_otp_fd(env, descP); break; /* *** INTERNAL *** */ - case SOCKET_OPT_OTP_DOMAIN: - result = ngetopt_otp_domain(env, descP); + case ESOCK_OPT_OTP_DOMAIN: + result = esock_getopt_otp_domain(env, descP); break; - case SOCKET_OPT_OTP_TYPE: - result = ngetopt_otp_type(env, descP); + case ESOCK_OPT_OTP_TYPE: + result = esock_getopt_otp_type(env, descP); break; - case SOCKET_OPT_OTP_PROTOCOL: - result = ngetopt_otp_protocol(env, descP); + case ESOCK_OPT_OTP_PROTOCOL: + result = esock_getopt_otp_protocol(env, descP); break; default: @@ -10969,7 +11377,7 @@ ERL_NIF_TERM ngetopt_otp(ErlNifEnv* env, } SSDBG( descP, - ("SOCKET", "ngetopt_otp -> done when" + ("SOCKET", "esock_getopt_otp -> done when" "\r\n result: %T" "\r\n", result) ); @@ -10977,11 +11385,11 @@ ERL_NIF_TERM ngetopt_otp(ErlNifEnv* env, } -/* ngetopt_otp_debug - Handle the OTP (level) debug option +/* esock_getopt_otp_debug - Handle the OTP (level) debug option */ static -ERL_NIF_TERM ngetopt_otp_debug(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_otp_debug(ErlNifEnv* env, + ESockDescriptor* descP) { ERL_NIF_TERM eVal = esock_encode_bool(descP->dbg); @@ -10989,11 +11397,11 @@ ERL_NIF_TERM ngetopt_otp_debug(ErlNifEnv* env, } -/* ngetopt_otp_iow - Handle the OTP (level) iow option +/* esock_getopt_otp_iow - Handle the OTP (level) iow option */ static -ERL_NIF_TERM ngetopt_otp_iow(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_otp_iow(ErlNifEnv* env, + ESockDescriptor* descP) { ERL_NIF_TERM eVal = esock_encode_bool(descP->iow); @@ -11001,11 +11409,11 @@ ERL_NIF_TERM ngetopt_otp_iow(ErlNifEnv* env, } -/* ngetopt_otp_ctrl_proc - Handle the OTP (level) controlling_process option +/* esock_getopt_otp_ctrl_proc - Handle the OTP (level) controlling_process option */ static -ERL_NIF_TERM ngetopt_otp_ctrl_proc(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_otp_ctrl_proc(ErlNifEnv* env, + ESockDescriptor* descP) { ERL_NIF_TERM eVal = MKPID(env, &descP->ctrlPid); @@ -11014,11 +11422,11 @@ ERL_NIF_TERM ngetopt_otp_ctrl_proc(ErlNifEnv* env, -/* ngetopt_otp_rcvbuf - Handle the OTP (level) rcvbuf option +/* esock_getopt_otp_rcvbuf - Handle the OTP (level) rcvbuf option */ static -ERL_NIF_TERM ngetopt_otp_rcvbuf(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_otp_rcvbuf(ErlNifEnv* env, + ESockDescriptor* descP) { ERL_NIF_TERM eVal; @@ -11032,11 +11440,11 @@ ERL_NIF_TERM ngetopt_otp_rcvbuf(ErlNifEnv* env, } -/* ngetopt_otp_rcvctrlbuf - Handle the OTP (level) rcvctrlbuf option +/* esock_getopt_otp_rcvctrlbuf - Handle the OTP (level) rcvctrlbuf option */ static -ERL_NIF_TERM ngetopt_otp_rcvctrlbuf(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_otp_rcvctrlbuf(ErlNifEnv* env, + ESockDescriptor* descP) { ERL_NIF_TERM eVal = MKI(env, descP->rCtrlSz); @@ -11044,11 +11452,11 @@ ERL_NIF_TERM ngetopt_otp_rcvctrlbuf(ErlNifEnv* env, } -/* ngetopt_otp_sndctrlbuf - Handle the OTP (level) sndctrlbuf option +/* esock_getopt_otp_sndctrlbuf - Handle the OTP (level) sndctrlbuf option */ static -ERL_NIF_TERM ngetopt_otp_sndctrlbuf(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_otp_sndctrlbuf(ErlNifEnv* env, + ESockDescriptor* descP) { ERL_NIF_TERM eVal = MKI(env, descP->wCtrlSz); @@ -11056,11 +11464,11 @@ ERL_NIF_TERM ngetopt_otp_sndctrlbuf(ErlNifEnv* env, } -/* ngetopt_otp_fd - Handle the OTP (level) fd option +/* esock_getopt_otp_fd - Handle the OTP (level) fd option */ static -ERL_NIF_TERM ngetopt_otp_fd(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_otp_fd(ErlNifEnv* env, + ESockDescriptor* descP) { ERL_NIF_TERM eVal = MKI(env, descP->sock); @@ -11068,11 +11476,11 @@ ERL_NIF_TERM ngetopt_otp_fd(ErlNifEnv* env, } -/* ngetopt_otp_domain - Handle the OTP (level) domain option +/* esock_getopt_otp_domain - Handle the OTP (level) domain option */ static -ERL_NIF_TERM ngetopt_otp_domain(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_otp_domain(ErlNifEnv* env, + ESockDescriptor* descP) { ERL_NIF_TERM result, reason; int val = descP->domain; @@ -11104,11 +11512,11 @@ ERL_NIF_TERM ngetopt_otp_domain(ErlNifEnv* env, } -/* ngetopt_otp_type - Handle the OTP (level) type options. +/* esock_getopt_otp_type - Handle the OTP (level) type options. */ static -ERL_NIF_TERM ngetopt_otp_type(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_otp_type(ErlNifEnv* env, + ESockDescriptor* descP) { ERL_NIF_TERM result, reason; int val = descP->type; @@ -11145,11 +11553,11 @@ ERL_NIF_TERM ngetopt_otp_type(ErlNifEnv* env, } -/* ngetopt_otp_protocol - Handle the OTP (level) protocol options. +/* esock_getopt_otp_protocol - Handle the OTP (level) protocol options. */ static -ERL_NIF_TERM ngetopt_otp_protocol(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_otp_protocol(ErlNifEnv* env, + ESockDescriptor* descP) { ERL_NIF_TERM result, reason; int val = descP->protocol; @@ -11197,10 +11605,10 @@ ERL_NIF_TERM ngetopt_otp_protocol(ErlNifEnv* env, * format: {NativeOpt :: integer(), ValueSize :: non_neg_integer()} */ static -ERL_NIF_TERM ngetopt_native(ErlNifEnv* env, - ESockDescriptor* descP, - int level, - ERL_NIF_TERM eOpt) +ERL_NIF_TERM esock_getopt_native(ErlNifEnv* env, + ESockDescriptor* descP, + int level, + ERL_NIF_TERM eOpt) { ERL_NIF_TERM result = enif_make_badarg(env); int opt; @@ -11208,7 +11616,7 @@ ERL_NIF_TERM ngetopt_native(ErlNifEnv* env, SOCKOPTLEN_T valueSz; SSDBG( descP, - ("SOCKET", "ngetopt_native -> entry with" + ("SOCKET", "esock_getopt_native -> entry with" "\r\n level: %d" "\r\n eOpt: %T" "\r\n", level, eOpt) ); @@ -11222,20 +11630,21 @@ ERL_NIF_TERM ngetopt_native(ErlNifEnv* env, if (decode_native_get_opt(env, eOpt, &opt, &valueType, (int*) &valueSz)) { SSDBG( descP, - ("SOCKET", "ngetopt_native -> decoded opt" + ("SOCKET", "esock_getopt_native -> decoded opt" "\r\n valueType: %d (%s)" "\r\n ValueSize: %d" "\r\n", valueType, VT2S(valueType), valueSz) ); switch (valueType) { - case SOCKET_OPT_VALUE_TYPE_UNSPEC: - result = ngetopt_native_unspec(env, descP, level, opt, valueSz); + case ESOCK_OPT_VALUE_TYPE_UNSPEC: + result = esock_getopt_native_unspec(env, descP, + level, opt, valueSz); break; - case SOCKET_OPT_VALUE_TYPE_INT: - result = ngetopt_int_opt(env, descP, level, opt); + case ESOCK_OPT_VALUE_TYPE_INT: + result = esock_getopt_int_opt(env, descP, level, opt); break; - case SOCKET_OPT_VALUE_TYPE_BOOL: - result = ngetopt_bool_opt(env, descP, level, opt); + case ESOCK_OPT_VALUE_TYPE_BOOL: + result = esock_getopt_bool_opt(env, descP, level, opt); break; default: result = esock_make_error(env, esock_atom_einval); @@ -11246,7 +11655,7 @@ ERL_NIF_TERM ngetopt_native(ErlNifEnv* env, } SSDBG( descP, - ("SOCKET", "ngetopt_native -> done when" + ("SOCKET", "esock_getopt_native -> done when" "\r\n result: %T" "\r\n", result) ); @@ -11255,17 +11664,17 @@ ERL_NIF_TERM ngetopt_native(ErlNifEnv* env, static -ERL_NIF_TERM ngetopt_native_unspec(ErlNifEnv* env, - ESockDescriptor* descP, - int level, - int opt, - SOCKOPTLEN_T valueSz) +ERL_NIF_TERM esock_getopt_native_unspec(ErlNifEnv* env, + ESockDescriptor* descP, + int level, + int opt, + SOCKOPTLEN_T valueSz) { ERL_NIF_TERM result = esock_make_error(env, esock_atom_einval); int res; SSDBG( descP, - ("SOCKET", "ngetopt_native_unspec -> entry with" + ("SOCKET", "esock_getopt_native_unspec -> entry with" "\r\n level: %d" "\r\n opt: %d" "\r\n valueSz: %d" @@ -11281,7 +11690,8 @@ ERL_NIF_TERM ngetopt_native_unspec(ErlNifEnv* env, SOCKOPTLEN_T vsz = valueSz; ErlNifBinary val; - SSDBG( descP, ("SOCKET", "ngetopt_native_unspec -> try alloc buffer\r\n") ); + SSDBG( descP, ("SOCKET", + "esock_getopt_native_unspec -> try alloc buffer\r\n") ); if (ALLOC_BIN(vsz, &val)) { int saveErrno; @@ -11313,7 +11723,7 @@ ERL_NIF_TERM ngetopt_native_unspec(ErlNifEnv* env, } SSDBG( descP, - ("SOCKET", "ngetopt_native_unspec -> done when" + ("SOCKET", "esock_getopt_native_unspec -> done when" "\r\n result: %T" "\r\n", result) ); @@ -11322,25 +11732,25 @@ ERL_NIF_TERM ngetopt_native_unspec(ErlNifEnv* env, -/* ngetopt_level - A "proper" level (option) has been specified +/* esock_getopt_level - A "proper" level (option) has been specified */ static -ERL_NIF_TERM ngetopt_level(ErlNifEnv* env, - ESockDescriptor* descP, - int level, - int eOpt) +ERL_NIF_TERM esock_getopt_level(ErlNifEnv* env, + ESockDescriptor* descP, + int level, + int eOpt) { ERL_NIF_TERM result; SSDBG( descP, - ("SOCKET", "ngetopt_level -> entry with" + ("SOCKET", "esock_getopt_level -> entry with" "\r\n level: %d" "\r\n eOpt: %d" "\r\n", level, eOpt) ); switch (level) { case SOL_SOCKET: - result = ngetopt_lvl_socket(env, descP, eOpt); + result = esock_getopt_lvl_socket(env, descP, eOpt); break; #if defined(SOL_IP) @@ -11348,7 +11758,7 @@ ERL_NIF_TERM ngetopt_level(ErlNifEnv* env, #else case IPPROTO_IP: #endif - result = ngetopt_lvl_ip(env, descP, eOpt); + result = esock_getopt_lvl_ip(env, descP, eOpt); break; #if defined(HAVE_IPV6) @@ -11357,21 +11767,21 @@ ERL_NIF_TERM ngetopt_level(ErlNifEnv* env, #else case IPPROTO_IPV6: #endif - result = ngetopt_lvl_ipv6(env, descP, eOpt); + result = esock_getopt_lvl_ipv6(env, descP, eOpt); break; #endif case IPPROTO_TCP: - result = ngetopt_lvl_tcp(env, descP, eOpt); + result = esock_getopt_lvl_tcp(env, descP, eOpt); break; case IPPROTO_UDP: - result = ngetopt_lvl_udp(env, descP, eOpt); + result = esock_getopt_lvl_udp(env, descP, eOpt); break; #if defined(HAVE_SCTP) case IPPROTO_SCTP: - result = ngetopt_lvl_sctp(env, descP, eOpt); + result = esock_getopt_lvl_sctp(env, descP, eOpt); break; #endif @@ -11381,7 +11791,7 @@ ERL_NIF_TERM ngetopt_level(ErlNifEnv* env, } SSDBG( descP, - ("SOCKET", "ngetopt_level -> done when" + ("SOCKET", "esock_getopt_level -> done when" "\r\n result: %T" "\r\n", result) ); @@ -11389,150 +11799,150 @@ ERL_NIF_TERM ngetopt_level(ErlNifEnv* env, } -/* ngetopt_lvl_socket - Level *SOCKET* option +/* esock_getopt_lvl_socket - Level *SOCKET* option */ static -ERL_NIF_TERM ngetopt_lvl_socket(ErlNifEnv* env, - ESockDescriptor* descP, - int eOpt) +ERL_NIF_TERM esock_getopt_lvl_socket(ErlNifEnv* env, + ESockDescriptor* descP, + int eOpt) { ERL_NIF_TERM result; SSDBG( descP, - ("SOCKET", "ngetopt_lvl_socket -> entry with" + ("SOCKET", "esock_getopt_lvl_socket -> entry with" "\r\n eOpt: %d" "\r\n", eOpt) ); switch (eOpt) { #if defined(SO_ACCEPTCONN) - case SOCKET_OPT_SOCK_ACCEPTCONN: - result = ngetopt_lvl_sock_acceptconn(env, descP); + case ESOCK_OPT_SOCK_ACCEPTCONN: + result = esock_getopt_lvl_sock_acceptconn(env, descP); break; #endif #if defined(SO_BINDTODEVICE) - case SOCKET_OPT_SOCK_BINDTODEVICE: - result = ngetopt_lvl_sock_bindtodevice(env, descP); + case ESOCK_OPT_SOCK_BINDTODEVICE: + result = esock_getopt_lvl_sock_bindtodevice(env, descP); break; #endif #if defined(SO_BROADCAST) - case SOCKET_OPT_SOCK_BROADCAST: - result = ngetopt_lvl_sock_broadcast(env, descP); + case ESOCK_OPT_SOCK_BROADCAST: + result = esock_getopt_lvl_sock_broadcast(env, descP); break; #endif #if defined(SO_DEBUG) - case SOCKET_OPT_SOCK_DEBUG: - result = ngetopt_lvl_sock_debug(env, descP); + case ESOCK_OPT_SOCK_DEBUG: + result = esock_getopt_lvl_sock_debug(env, descP); break; #endif #if defined(SO_DOMAIN) - case SOCKET_OPT_SOCK_DOMAIN: - result = ngetopt_lvl_sock_domain(env, descP); + case ESOCK_OPT_SOCK_DOMAIN: + result = esock_getopt_lvl_sock_domain(env, descP); break; #endif #if defined(SO_DONTROUTE) - case SOCKET_OPT_SOCK_DONTROUTE: - result = ngetopt_lvl_sock_dontroute(env, descP); + case ESOCK_OPT_SOCK_DONTROUTE: + result = esock_getopt_lvl_sock_dontroute(env, descP); break; #endif #if defined(SO_KEEPALIVE) - case SOCKET_OPT_SOCK_KEEPALIVE: - result = ngetopt_lvl_sock_keepalive(env, descP); + case ESOCK_OPT_SOCK_KEEPALIVE: + result = esock_getopt_lvl_sock_keepalive(env, descP); break; #endif #if defined(SO_LINGER) - case SOCKET_OPT_SOCK_LINGER: - result = ngetopt_lvl_sock_linger(env, descP); + case ESOCK_OPT_SOCK_LINGER: + result = esock_getopt_lvl_sock_linger(env, descP); break; #endif #if defined(SO_OOBINLINE) - case SOCKET_OPT_SOCK_OOBINLINE: - result = ngetopt_lvl_sock_oobinline(env, descP); + case ESOCK_OPT_SOCK_OOBINLINE: + result = esock_getopt_lvl_sock_oobinline(env, descP); break; #endif #if defined(SO_PEEK_OFF) - case SOCKET_OPT_SOCK_PEEK_OFF: - result = ngetopt_lvl_sock_peek_off(env, descP); + case ESOCK_OPT_SOCK_PEEK_OFF: + result = esock_getopt_lvl_sock_peek_off(env, descP); break; #endif #if defined(SO_PRIORITY) - case SOCKET_OPT_SOCK_PRIORITY: - result = ngetopt_lvl_sock_priority(env, descP); + case ESOCK_OPT_SOCK_PRIORITY: + result = esock_getopt_lvl_sock_priority(env, descP); break; #endif #if defined(SO_PROTOCOL) - case SOCKET_OPT_SOCK_PROTOCOL: - result = ngetopt_lvl_sock_protocol(env, descP); + case ESOCK_OPT_SOCK_PROTOCOL: + result = esock_getopt_lvl_sock_protocol(env, descP); break; #endif #if defined(SO_RCVBUF) - case SOCKET_OPT_SOCK_RCVBUF: - result = ngetopt_lvl_sock_rcvbuf(env, descP); + case ESOCK_OPT_SOCK_RCVBUF: + result = esock_getopt_lvl_sock_rcvbuf(env, descP); break; #endif #if defined(SO_RCVLOWAT) - case SOCKET_OPT_SOCK_RCVLOWAT: - result = ngetopt_lvl_sock_rcvlowat(env, descP); + case ESOCK_OPT_SOCK_RCVLOWAT: + result = esock_getopt_lvl_sock_rcvlowat(env, descP); break; #endif #if defined(SO_RCVTIMEO) - case SOCKET_OPT_SOCK_RCVTIMEO: - result = ngetopt_lvl_sock_rcvtimeo(env, descP); + case ESOCK_OPT_SOCK_RCVTIMEO: + result = esock_getopt_lvl_sock_rcvtimeo(env, descP); break; #endif #if defined(SO_REUSEADDR) - case SOCKET_OPT_SOCK_REUSEADDR: - result = ngetopt_lvl_sock_reuseaddr(env, descP); + case ESOCK_OPT_SOCK_REUSEADDR: + result = esock_getopt_lvl_sock_reuseaddr(env, descP); break; #endif #if defined(SO_REUSEPORT) - case SOCKET_OPT_SOCK_REUSEPORT: - result = ngetopt_lvl_sock_reuseport(env, descP); + case ESOCK_OPT_SOCK_REUSEPORT: + result = esock_getopt_lvl_sock_reuseport(env, descP); break; #endif #if defined(SO_SNDBUF) - case SOCKET_OPT_SOCK_SNDBUF: - result = ngetopt_lvl_sock_sndbuf(env, descP); + case ESOCK_OPT_SOCK_SNDBUF: + result = esock_getopt_lvl_sock_sndbuf(env, descP); break; #endif #if defined(SO_SNDLOWAT) - case SOCKET_OPT_SOCK_SNDLOWAT: - result = ngetopt_lvl_sock_sndlowat(env, descP); + case ESOCK_OPT_SOCK_SNDLOWAT: + result = esock_getopt_lvl_sock_sndlowat(env, descP); break; #endif #if defined(SO_SNDTIMEO) - case SOCKET_OPT_SOCK_SNDTIMEO: - result = ngetopt_lvl_sock_sndtimeo(env, descP); + case ESOCK_OPT_SOCK_SNDTIMEO: + result = esock_getopt_lvl_sock_sndtimeo(env, descP); break; #endif #if defined(SO_TIMESTAMP) - case SOCKET_OPT_SOCK_TIMESTAMP: - result = ngetopt_lvl_sock_timestamp(env, descP); + case ESOCK_OPT_SOCK_TIMESTAMP: + result = esock_getopt_lvl_sock_timestamp(env, descP); break; #endif #if defined(SO_TYPE) - case SOCKET_OPT_SOCK_TYPE: - result = ngetopt_lvl_sock_type(env, descP); + case ESOCK_OPT_SOCK_TYPE: + result = esock_getopt_lvl_sock_type(env, descP); break; #endif @@ -11542,7 +11952,7 @@ ERL_NIF_TERM ngetopt_lvl_socket(ErlNifEnv* env, } SSDBG( descP, - ("SOCKET", "ngetopt_lvl_socket -> done when" + ("SOCKET", "esock_getopt_lvl_socket -> done when" "\r\n result: %T" "\r\n", result) ); @@ -11552,51 +11962,52 @@ ERL_NIF_TERM ngetopt_lvl_socket(ErlNifEnv* env, #if defined(SO_ACCEPTCONN) static -ERL_NIF_TERM ngetopt_lvl_sock_acceptconn(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_sock_acceptconn(ErlNifEnv* env, + ESockDescriptor* descP) { - return ngetopt_bool_opt(env, descP, SOL_SOCKET, SO_ACCEPTCONN); + return esock_getopt_bool_opt(env, descP, SOL_SOCKET, SO_ACCEPTCONN); } #endif #if defined(SO_BINDTODEVICE) static -ERL_NIF_TERM ngetopt_lvl_sock_bindtodevice(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_sock_bindtodevice(ErlNifEnv* env, + ESockDescriptor* descP) { SSDBG( descP, - ("SOCKET", "ngetopt_lvl_sock_bindtodevice -> entry with\r\n") ); + ("SOCKET", "esock_getopt_lvl_sock_bindtodevice -> entry with\r\n") ); - return ngetopt_str_opt(env, descP, SOL_SOCKET, SO_BROADCAST, IFNAMSIZ+1); + return esock_getopt_str_opt(env, descP, + SOL_SOCKET, SO_BINDTODEVICE, IFNAMSIZ+1); } #endif #if defined(SO_BROADCAST) static -ERL_NIF_TERM ngetopt_lvl_sock_broadcast(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_sock_broadcast(ErlNifEnv* env, + ESockDescriptor* descP) { - return ngetopt_bool_opt(env, descP, SOL_SOCKET, SO_BROADCAST); + return esock_getopt_bool_opt(env, descP, SOL_SOCKET, SO_BROADCAST); } #endif #if defined(SO_DEBUG) static -ERL_NIF_TERM ngetopt_lvl_sock_debug(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_sock_debug(ErlNifEnv* env, + ESockDescriptor* descP) { - return ngetopt_int_opt(env, descP, SOL_SOCKET, SO_DEBUG); + return esock_getopt_int_opt(env, descP, SOL_SOCKET, SO_DEBUG); } #endif #if defined(SO_DOMAIN) static -ERL_NIF_TERM ngetopt_lvl_sock_domain(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_sock_domain(ErlNifEnv* env, + ESockDescriptor* descP) { ERL_NIF_TERM result, reason; int val; @@ -11640,28 +12051,28 @@ ERL_NIF_TERM ngetopt_lvl_sock_domain(ErlNifEnv* env, #if defined(SO_DONTROUTE) static -ERL_NIF_TERM ngetopt_lvl_sock_dontroute(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_sock_dontroute(ErlNifEnv* env, + ESockDescriptor* descP) { - return ngetopt_bool_opt(env, descP, SOL_SOCKET, SO_DONTROUTE); + return esock_getopt_bool_opt(env, descP, SOL_SOCKET, SO_DONTROUTE); } #endif #if defined(SO_KEEPALIVE) static -ERL_NIF_TERM ngetopt_lvl_sock_keepalive(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_sock_keepalive(ErlNifEnv* env, + ESockDescriptor* descP) { - return ngetopt_bool_opt(env, descP, SOL_SOCKET, SO_KEEPALIVE); + return esock_getopt_bool_opt(env, descP, SOL_SOCKET, SO_KEEPALIVE); } #endif #if defined(SO_LINGER) static -ERL_NIF_TERM ngetopt_lvl_sock_linger(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_sock_linger(ErlNifEnv* env, + ESockDescriptor* descP) { ERL_NIF_TERM result; struct linger val; @@ -11690,38 +12101,38 @@ ERL_NIF_TERM ngetopt_lvl_sock_linger(ErlNifEnv* env, #if defined(SO_OOBINLINE) static -ERL_NIF_TERM ngetopt_lvl_sock_oobinline(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_sock_oobinline(ErlNifEnv* env, + ESockDescriptor* descP) { - return ngetopt_bool_opt(env, descP, SOL_SOCKET, SO_OOBINLINE); + return esock_getopt_bool_opt(env, descP, SOL_SOCKET, SO_OOBINLINE); } #endif #if defined(SO_PEEK_OFF) static -ERL_NIF_TERM ngetopt_lvl_sock_peek_off(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_sock_peek_off(ErlNifEnv* env, + ESockDescriptor* descP) { - return ngetopt_int_opt(env, descP, SOL_SOCKET, SO_PEEK_OFF); + return esock_getopt_int_opt(env, descP, SOL_SOCKET, SO_PEEK_OFF); } #endif #if defined(SO_PRIORITY) static -ERL_NIF_TERM ngetopt_lvl_sock_priority(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_sock_priority(ErlNifEnv* env, + ESockDescriptor* descP) { - return ngetopt_int_opt(env, descP, SOL_SOCKET, SO_PRIORITY); + return esock_getopt_int_opt(env, descP, SOL_SOCKET, SO_PRIORITY); } #endif #if defined(SO_PROTOCOL) static -ERL_NIF_TERM ngetopt_lvl_sock_protocol(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_sock_protocol(ErlNifEnv* env, + ESockDescriptor* descP) { ERL_NIF_TERM result, reason; int val; @@ -11774,98 +12185,98 @@ ERL_NIF_TERM ngetopt_lvl_sock_protocol(ErlNifEnv* env, #if defined(SO_RCVBUF) static -ERL_NIF_TERM ngetopt_lvl_sock_rcvbuf(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_sock_rcvbuf(ErlNifEnv* env, + ESockDescriptor* descP) { - return ngetopt_int_opt(env, descP, SOL_SOCKET, SO_RCVBUF); + return esock_getopt_int_opt(env, descP, SOL_SOCKET, SO_RCVBUF); } #endif #if defined(SO_RCVLOWAT) static -ERL_NIF_TERM ngetopt_lvl_sock_rcvlowat(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_sock_rcvlowat(ErlNifEnv* env, + ESockDescriptor* descP) { - return ngetopt_int_opt(env, descP, SOL_SOCKET, SO_RCVLOWAT); + return esock_getopt_int_opt(env, descP, SOL_SOCKET, SO_RCVLOWAT); } #endif #if defined(SO_RCVTIMEO) static -ERL_NIF_TERM ngetopt_lvl_sock_rcvtimeo(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_sock_rcvtimeo(ErlNifEnv* env, + ESockDescriptor* descP) { - return ngetopt_timeval_opt(env, descP, SOL_SOCKET, SO_RCVTIMEO); + return esock_getopt_timeval_opt(env, descP, SOL_SOCKET, SO_RCVTIMEO); } #endif #if defined(SO_REUSEADDR) static -ERL_NIF_TERM ngetopt_lvl_sock_reuseaddr(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_sock_reuseaddr(ErlNifEnv* env, + ESockDescriptor* descP) { - return ngetopt_bool_opt(env, descP, SOL_SOCKET, SO_REUSEADDR); + return esock_getopt_bool_opt(env, descP, SOL_SOCKET, SO_REUSEADDR); } #endif #if defined(SO_REUSEPORT) static -ERL_NIF_TERM ngetopt_lvl_sock_reuseport(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_sock_reuseport(ErlNifEnv* env, + ESockDescriptor* descP) { - return ngetopt_bool_opt(env, descP, SOL_SOCKET, SO_REUSEPORT); + return esock_getopt_bool_opt(env, descP, SOL_SOCKET, SO_REUSEPORT); } #endif #if defined(SO_SNDBUF) static -ERL_NIF_TERM ngetopt_lvl_sock_sndbuf(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_sock_sndbuf(ErlNifEnv* env, + ESockDescriptor* descP) { - return ngetopt_int_opt(env, descP, SOL_SOCKET, SO_SNDBUF); + return esock_getopt_int_opt(env, descP, SOL_SOCKET, SO_SNDBUF); } #endif #if defined(SO_SNDLOWAT) static -ERL_NIF_TERM ngetopt_lvl_sock_sndlowat(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_sock_sndlowat(ErlNifEnv* env, + ESockDescriptor* descP) { - return ngetopt_int_opt(env, descP, SOL_SOCKET, SO_SNDLOWAT); + return esock_getopt_int_opt(env, descP, SOL_SOCKET, SO_SNDLOWAT); } #endif #if defined(SO_SNDTIMEO) static -ERL_NIF_TERM ngetopt_lvl_sock_sndtimeo(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_sock_sndtimeo(ErlNifEnv* env, + ESockDescriptor* descP) { - return ngetopt_timeval_opt(env, descP, SOL_SOCKET, SO_SNDTIMEO); + return esock_getopt_timeval_opt(env, descP, SOL_SOCKET, SO_SNDTIMEO); } #endif #if defined(SO_TIMESTAMP) static -ERL_NIF_TERM ngetopt_lvl_sock_timestamp(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_sock_timestamp(ErlNifEnv* env, + ESockDescriptor* descP) { - return ngetopt_bool_opt(env, descP, SOL_SOCKET, SO_TIMESTAMP); + return esock_getopt_bool_opt(env, descP, SOL_SOCKET, SO_TIMESTAMP); } #endif #if defined(SO_TYPE) static -ERL_NIF_TERM ngetopt_lvl_sock_type(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_sock_type(ErlNifEnv* env, + ESockDescriptor* descP) { ERL_NIF_TERM result, reason; int val; @@ -11907,174 +12318,174 @@ ERL_NIF_TERM ngetopt_lvl_sock_type(ErlNifEnv* env, #endif -/* ngetopt_lvl_ip - Level *IP* option(s) +/* esock_getopt_lvl_ip - Level *IP* option(s) */ static -ERL_NIF_TERM ngetopt_lvl_ip(ErlNifEnv* env, - ESockDescriptor* descP, - int eOpt) +ERL_NIF_TERM esock_getopt_lvl_ip(ErlNifEnv* env, + ESockDescriptor* descP, + int eOpt) { ERL_NIF_TERM result; SSDBG( descP, - ("SOCKET", "ngetopt_lvl_ip -> entry with" + ("SOCKET", "esock_getopt_lvl_ip -> entry with" "\r\n eOpt: %d" "\r\n", eOpt) ); switch (eOpt) { #if defined(IP_FREEBIND) - case SOCKET_OPT_IP_FREEBIND: - result = ngetopt_lvl_ip_freebind(env, descP); + case ESOCK_OPT_IP_FREEBIND: + result = esock_getopt_lvl_ip_freebind(env, descP); break; #endif #if defined(IP_HDRINCL) - case SOCKET_OPT_IP_HDRINCL: - result = ngetopt_lvl_ip_hdrincl(env, descP); + case ESOCK_OPT_IP_HDRINCL: + result = esock_getopt_lvl_ip_hdrincl(env, descP); break; #endif #if defined(IP_MINTTL) - case SOCKET_OPT_IP_MINTTL: - result = ngetopt_lvl_ip_minttl(env, descP); + case ESOCK_OPT_IP_MINTTL: + result = esock_getopt_lvl_ip_minttl(env, descP); break; #endif #if defined(IP_MTU) - case SOCKET_OPT_IP_MTU: - result = ngetopt_lvl_ip_mtu(env, descP); + case ESOCK_OPT_IP_MTU: + result = esock_getopt_lvl_ip_mtu(env, descP); break; #endif #if defined(IP_MTU_DISCOVER) - case SOCKET_OPT_IP_MTU_DISCOVER: - result = ngetopt_lvl_ip_mtu_discover(env, descP); + case ESOCK_OPT_IP_MTU_DISCOVER: + result = esock_getopt_lvl_ip_mtu_discover(env, descP); break; #endif #if defined(IP_MULTICAST_ALL) - case SOCKET_OPT_IP_MULTICAST_ALL: - result = ngetopt_lvl_ip_multicast_all(env, descP); + case ESOCK_OPT_IP_MULTICAST_ALL: + result = esock_getopt_lvl_ip_multicast_all(env, descP); break; #endif #if defined(IP_MULTICAST_IF) - case SOCKET_OPT_IP_MULTICAST_IF: - result = ngetopt_lvl_ip_multicast_if(env, descP); + case ESOCK_OPT_IP_MULTICAST_IF: + result = esock_getopt_lvl_ip_multicast_if(env, descP); break; #endif #if defined(IP_MULTICAST_LOOP) - case SOCKET_OPT_IP_MULTICAST_LOOP: - result = ngetopt_lvl_ip_multicast_loop(env, descP); + case ESOCK_OPT_IP_MULTICAST_LOOP: + result = esock_getopt_lvl_ip_multicast_loop(env, descP); break; #endif #if defined(IP_MULTICAST_TTL) - case SOCKET_OPT_IP_MULTICAST_TTL: - result = ngetopt_lvl_ip_multicast_ttl(env, descP); + case ESOCK_OPT_IP_MULTICAST_TTL: + result = esock_getopt_lvl_ip_multicast_ttl(env, descP); break; #endif #if defined(IP_NODEFRAG) - case SOCKET_OPT_IP_NODEFRAG: - result = ngetopt_lvl_ip_nodefrag(env, descP); + case ESOCK_OPT_IP_NODEFRAG: + result = esock_getopt_lvl_ip_nodefrag(env, descP); break; #endif #if defined(IP_PKTINFO) - case SOCKET_OPT_IP_PKTINFO: - result = ngetopt_lvl_ip_pktinfo(env, descP); + case ESOCK_OPT_IP_PKTINFO: + result = esock_getopt_lvl_ip_pktinfo(env, descP); break; #endif #if defined(IP_RECVDSTADDR) - case SOCKET_OPT_IP_RECVDSTADDR: - result = ngetopt_lvl_ip_recvdstaddr(env, descP); + case ESOCK_OPT_IP_RECVDSTADDR: + result = esock_getopt_lvl_ip_recvdstaddr(env, descP); break; #endif #if defined(IP_RECVERR) - case SOCKET_OPT_IP_RECVERR: - result = ngetopt_lvl_ip_recverr(env, descP); + case ESOCK_OPT_IP_RECVERR: + result = esock_getopt_lvl_ip_recverr(env, descP); break; #endif #if defined(IP_RECVIF) - case SOCKET_OPT_IP_RECVIF: - result = ngetopt_lvl_ip_recvif(env, descP); + case ESOCK_OPT_IP_RECVIF: + result = esock_getopt_lvl_ip_recvif(env, descP); break; #endif #if defined(IP_RECVOPTS) - case SOCKET_OPT_IP_RECVOPTS: - result = ngetopt_lvl_ip_recvopts(env, descP); + case ESOCK_OPT_IP_RECVOPTS: + result = esock_getopt_lvl_ip_recvopts(env, descP); break; #endif #if defined(IP_RECVORIGDSTADDR) - case SOCKET_OPT_IP_RECVORIGDSTADDR: - result = ngetopt_lvl_ip_recvorigdstaddr(env, descP); + case ESOCK_OPT_IP_RECVORIGDSTADDR: + result = esock_getopt_lvl_ip_recvorigdstaddr(env, descP); break; #endif #if defined(IP_RECVTOS) - case SOCKET_OPT_IP_RECVTOS: - result = ngetopt_lvl_ip_recvtos(env, descP); + case ESOCK_OPT_IP_RECVTOS: + result = esock_getopt_lvl_ip_recvtos(env, descP); break; #endif #if defined(IP_RECVTTL) - case SOCKET_OPT_IP_RECVTTL: - result = ngetopt_lvl_ip_recvttl(env, descP); + case ESOCK_OPT_IP_RECVTTL: + result = esock_getopt_lvl_ip_recvttl(env, descP); break; #endif #if defined(IP_RETOPTS) - case SOCKET_OPT_IP_RETOPTS: - result = ngetopt_lvl_ip_retopts(env, descP); + case ESOCK_OPT_IP_RETOPTS: + result = esock_getopt_lvl_ip_retopts(env, descP); break; #endif #if defined(IP_ROUTER_ALERT) - case SOCKET_OPT_IP_ROUTER_ALERT: - result = ngetopt_lvl_ip_router_alert(env, descP); + case ESOCK_OPT_IP_ROUTER_ALERT: + result = esock_getopt_lvl_ip_router_alert(env, descP); break; #endif #if defined(IP_SENDSRCADDR) - case SOCKET_OPT_IP_SENDSRCADDR: - result = ngetopt_lvl_ip_sendsrcaddr(env, descP); + case ESOCK_OPT_IP_SENDSRCADDR: + result = esock_getopt_lvl_ip_sendsrcaddr(env, descP); break; #endif #if defined(IP_TOS) - case SOCKET_OPT_IP_TOS: - result = ngetopt_lvl_ip_tos(env, descP); + case ESOCK_OPT_IP_TOS: + result = esock_getopt_lvl_ip_tos(env, descP); break; #endif #if defined(IP_TRANSPARENT) - case SOCKET_OPT_IP_TRANSPARENT: - result = ngetopt_lvl_ip_transparent(env, descP); + case ESOCK_OPT_IP_TRANSPARENT: + result = esock_getopt_lvl_ip_transparent(env, descP); break; #endif #if defined(IP_TTL) - case SOCKET_OPT_IP_TTL: - result = ngetopt_lvl_ip_ttl(env, descP); + case ESOCK_OPT_IP_TTL: + result = esock_getopt_lvl_ip_ttl(env, descP); break; #endif default: SSDBG( descP, - ("SOCKET", "ngetopt_lvl_ip -> unknown opt %d\r\n", eOpt) ); + ("SOCKET", "esock_getopt_lvl_ip -> unknown opt %d\r\n", eOpt) ); result = esock_make_error(env, esock_atom_einval); break; } SSDBG( descP, - ("SOCKET", "ngetopt_lvl_ip -> done when" + ("SOCKET", "esock_getopt_lvl_ip -> done when" "\r\n result: %T" "\r\n", result) ); @@ -12082,12 +12493,12 @@ ERL_NIF_TERM ngetopt_lvl_ip(ErlNifEnv* env, } -/* ngetopt_lvl_ip_minttl - Level IP MINTTL option +/* esock_getopt_lvl_ip_minttl - Level IP MINTTL option */ #if defined(IP_MINTTL) static -ERL_NIF_TERM ngetopt_lvl_ip_minttl(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ip_minttl(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IP) int level = SOL_IP; @@ -12095,17 +12506,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_minttl(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return ngetopt_int_opt(env, descP, level, IP_MINTTL); + return esock_getopt_int_opt(env, descP, level, IP_MINTTL); } #endif -/* ngetopt_lvl_ip_freebind - Level IP FREEBIND option +/* esock_getopt_lvl_ip_freebind - Level IP FREEBIND option */ #if defined(IP_FREEBIND) static -ERL_NIF_TERM ngetopt_lvl_ip_freebind(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ip_freebind(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IP) int level = SOL_IP; @@ -12113,17 +12524,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_freebind(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return ngetopt_bool_opt(env, descP, level, IP_FREEBIND); + return esock_getopt_bool_opt(env, descP, level, IP_FREEBIND); } #endif -/* ngetopt_lvl_ip_hdrincl - Level IP HDRINCL option +/* esock_getopt_lvl_ip_hdrincl - Level IP HDRINCL option */ #if defined(IP_HDRINCL) static -ERL_NIF_TERM ngetopt_lvl_ip_hdrincl(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ip_hdrincl(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IP) int level = SOL_IP; @@ -12131,17 +12542,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_hdrincl(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return ngetopt_bool_opt(env, descP, level, IP_HDRINCL); + return esock_getopt_bool_opt(env, descP, level, IP_HDRINCL); } #endif -/* ngetopt_lvl_ip_mtu - Level IP MTU option +/* esock_getopt_lvl_ip_mtu - Level IP MTU option */ #if defined(IP_MTU) static -ERL_NIF_TERM ngetopt_lvl_ip_mtu(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ip_mtu(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IP) int level = SOL_IP; @@ -12149,17 +12560,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_mtu(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return ngetopt_int_opt(env, descP, level, IP_MTU); + return esock_getopt_int_opt(env, descP, level, IP_MTU); } #endif -/* ngetopt_lvl_ip_mtu_discover - Level IP MTU_DISCOVER option +/* esock_getopt_lvl_ip_mtu_discover - Level IP MTU_DISCOVER option */ #if defined(IP_MTU_DISCOVER) static -ERL_NIF_TERM ngetopt_lvl_ip_mtu_discover(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ip_mtu_discover(ErlNifEnv* env, + ESockDescriptor* descP) { ERL_NIF_TERM result; ERL_NIF_TERM eMtuDisc; @@ -12188,12 +12599,12 @@ ERL_NIF_TERM ngetopt_lvl_ip_mtu_discover(ErlNifEnv* env, #endif -/* ngetopt_lvl_ip_multicast_all - Level IP MULTICAST_ALL option +/* esock_getopt_lvl_ip_multicast_all - Level IP MULTICAST_ALL option */ #if defined(IP_MULTICAST_ALL) static -ERL_NIF_TERM ngetopt_lvl_ip_multicast_all(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ip_multicast_all(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IP) int level = SOL_IP; @@ -12201,17 +12612,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_multicast_all(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return ngetopt_bool_opt(env, descP, level, IP_MULTICAST_ALL); + return esock_getopt_bool_opt(env, descP, level, IP_MULTICAST_ALL); } #endif -/* ngetopt_lvl_ip_multicast_if - Level IP MULTICAST_IF option +/* esock_getopt_lvl_ip_multicast_if - Level IP MULTICAST_IF option */ #if defined(IP_MULTICAST_IF) static -ERL_NIF_TERM ngetopt_lvl_ip_multicast_if(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ip_multicast_if(ErlNifEnv* env, + ESockDescriptor* descP) { ERL_NIF_TERM result; ERL_NIF_TERM eAddr; @@ -12243,12 +12654,12 @@ ERL_NIF_TERM ngetopt_lvl_ip_multicast_if(ErlNifEnv* env, #endif -/* ngetopt_lvl_ip_multicast_loop - Level IP MULTICAST_LOOP option +/* esock_getopt_lvl_ip_multicast_loop - Level IP MULTICAST_LOOP option */ #if defined(IP_MULTICAST_LOOP) static -ERL_NIF_TERM ngetopt_lvl_ip_multicast_loop(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ip_multicast_loop(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IP) int level = SOL_IP; @@ -12256,17 +12667,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_multicast_loop(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return ngetopt_bool_opt(env, descP, level, IP_MULTICAST_LOOP); + return esock_getopt_bool_opt(env, descP, level, IP_MULTICAST_LOOP); } #endif -/* ngetopt_lvl_ip_multicast_ttl - Level IP MULTICAST_TTL option +/* esock_getopt_lvl_ip_multicast_ttl - Level IP MULTICAST_TTL option */ #if defined(IP_MULTICAST_TTL) static -ERL_NIF_TERM ngetopt_lvl_ip_multicast_ttl(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ip_multicast_ttl(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IP) int level = SOL_IP; @@ -12274,17 +12685,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_multicast_ttl(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return ngetopt_int_opt(env, descP, level, IP_MULTICAST_TTL); + return esock_getopt_int_opt(env, descP, level, IP_MULTICAST_TTL); } #endif -/* ngetopt_lvl_ip_nodefrag - Level IP NODEFRAG option +/* esock_getopt_lvl_ip_nodefrag - Level IP NODEFRAG option */ #if defined(IP_NODEFRAG) static -ERL_NIF_TERM ngetopt_lvl_ip_nodefrag(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ip_nodefrag(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IP) int level = SOL_IP; @@ -12292,17 +12703,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_nodefrag(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return ngetopt_bool_opt(env, descP, level, IP_NODEFRAG); + return esock_getopt_bool_opt(env, descP, level, IP_NODEFRAG); } #endif -/* ngetopt_lvl_ip_pktinfo - Level IP PKTINFO option +/* esock_getopt_lvl_ip_pktinfo - Level IP PKTINFO option */ #if defined(IP_PKTINFO) static -ERL_NIF_TERM ngetopt_lvl_ip_pktinfo(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ip_pktinfo(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IP) int level = SOL_IP; @@ -12310,17 +12721,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_pktinfo(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return ngetopt_bool_opt(env, descP, level, IP_PKTINFO); + return esock_getopt_bool_opt(env, descP, level, IP_PKTINFO); } #endif -/* ngetopt_lvl_ip_recvtos - Level IP RECVTOS option +/* esock_getopt_lvl_ip_recvtos - Level IP RECVTOS option */ #if defined(IP_RECVTOS) static -ERL_NIF_TERM ngetopt_lvl_ip_recvtos(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ip_recvtos(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IP) int level = SOL_IP; @@ -12328,17 +12739,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_recvtos(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return ngetopt_bool_opt(env, descP, level, IP_RECVTOS); + return esock_getopt_bool_opt(env, descP, level, IP_RECVTOS); } #endif -/* ngetopt_lvl_ip_recvdstaddr - Level IP RECVDSTADDR option +/* esock_getopt_lvl_ip_recvdstaddr - Level IP RECVDSTADDR option */ #if defined(IP_RECVDSTADDR) static -ERL_NIF_TERM ngetopt_lvl_ip_recvdstaddr(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ip_recvdstaddr(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IP) int level = SOL_IP; @@ -12346,17 +12757,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_recvdstaddr(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return ngetopt_bool_opt(env, descP, level, IP_RECVDSTADDR); + return esock_getopt_bool_opt(env, descP, level, IP_RECVDSTADDR); } #endif -/* ngetopt_lvl_ip_recverr - Level IP RECVERR option +/* esock_getopt_lvl_ip_recverr - Level IP RECVERR option */ #if defined(IP_RECVERR) static -ERL_NIF_TERM ngetopt_lvl_ip_recverr(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ip_recverr(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IP) int level = SOL_IP; @@ -12364,17 +12775,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_recverr(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return ngetopt_bool_opt(env, descP, level, IP_RECVERR); + return esock_getopt_bool_opt(env, descP, level, IP_RECVERR); } #endif -/* ngetopt_lvl_ip_recvif - Level IP RECVIF option +/* esock_getopt_lvl_ip_recvif - Level IP RECVIF option */ #if defined(IP_RECVIF) static -ERL_NIF_TERM ngetopt_lvl_ip_recvif(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ip_recvif(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IP) int level = SOL_IP; @@ -12382,17 +12793,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_recvif(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return ngetopt_bool_opt(env, descP, level, IP_RECVIF); + return esock_getopt_bool_opt(env, descP, level, IP_RECVIF); } #endif -/* ngetopt_lvl_ip_recvopt - Level IP RECVOPTS option +/* esock_getopt_lvl_ip_recvopt - Level IP RECVOPTS option */ #if defined(IP_RECVOPTS) static -ERL_NIF_TERM ngetopt_lvl_ip_recvopts(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ip_recvopts(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IP) int level = SOL_IP; @@ -12400,17 +12811,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_recvopts(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return ngetopt_bool_opt(env, descP, level, IP_RECVOPTS); + return esock_getopt_bool_opt(env, descP, level, IP_RECVOPTS); } #endif -/* ngetopt_lvl_ip_recvorigdstaddr - Level IP RECVORIGDSTADDR option +/* esock_getopt_lvl_ip_recvorigdstaddr - Level IP RECVORIGDSTADDR option */ #if defined(IP_RECVORIGDSTADDR) static -ERL_NIF_TERM ngetopt_lvl_ip_recvorigdstaddr(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ip_recvorigdstaddr(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IP) int level = SOL_IP; @@ -12418,17 +12829,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_recvorigdstaddr(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return ngetopt_bool_opt(env, descP, level, IP_RECVORIGDSTADDR); + return esock_getopt_bool_opt(env, descP, level, IP_RECVORIGDSTADDR); } #endif -/* ngetopt_lvl_ip_recvttl - Level IP RECVTTL option +/* esock_getopt_lvl_ip_recvttl - Level IP RECVTTL option */ #if defined(IP_RECVTTL) static -ERL_NIF_TERM ngetopt_lvl_ip_recvttl(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ip_recvttl(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IP) int level = SOL_IP; @@ -12436,17 +12847,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_recvttl(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return ngetopt_bool_opt(env, descP, level, IP_RECVTTL); + return esock_getopt_bool_opt(env, descP, level, IP_RECVTTL); } #endif -/* ngetopt_lvl_ip_retopts - Level IP RETOPTS option +/* esock_getopt_lvl_ip_retopts - Level IP RETOPTS option */ #if defined(IP_RETOPTS) static -ERL_NIF_TERM ngetopt_lvl_ip_retopts(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ip_retopts(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IP) int level = SOL_IP; @@ -12454,17 +12865,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_retopts(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return ngetopt_bool_opt(env, descP, level, IP_RETOPTS); + return esock_getopt_bool_opt(env, descP, level, IP_RETOPTS); } #endif -/* ngetopt_lvl_ip_router_alert - Level IP ROUTER_ALERT option +/* esock_getopt_lvl_ip_router_alert - Level IP ROUTER_ALERT option */ #if defined(IP_ROUTER_ALERT) static -ERL_NIF_TERM ngetopt_lvl_ip_router_alert(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ip_router_alert(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IP) int level = SOL_IP; @@ -12472,17 +12883,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_router_alert(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return ngetopt_int_opt(env, descP, level, IP_ROUTER_ALERT); + return esock_getopt_int_opt(env, descP, level, IP_ROUTER_ALERT); } #endif -/* ngetopt_lvl_ip_sendsrcaddr - Level IP SENDSRCADDR option +/* esock_getopt_lvl_ip_sendsrcaddr - Level IP SENDSRCADDR option */ #if defined(IP_SENDSRCADDR) static -ERL_NIF_TERM ngetopt_lvl_ip_sendsrcaddr(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ip_sendsrcaddr(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IP) int level = SOL_IP; @@ -12490,17 +12901,17 @@ ERL_NIF_TERM ngetopt_lvl_ip_sendsrcaddr(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return ngetopt_bool_opt(env, descP, level, IP_SENDSRCADDR); + return esock_getopt_bool_opt(env, descP, level, IP_SENDSRCADDR); } #endif -/* ngetopt_lvl_ip_tos - Level IP TOS option +/* esock_getopt_lvl_ip_tos - Level IP TOS option */ #if defined(IP_TOS) static -ERL_NIF_TERM ngetopt_lvl_ip_tos(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ip_tos(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IP) int level = SOL_IP; @@ -12525,12 +12936,12 @@ ERL_NIF_TERM ngetopt_lvl_ip_tos(ErlNifEnv* env, #endif -/* ngetopt_lvl_ip_transparent - Level IP TRANSPARENT option +/* esock_getopt_lvl_ip_transparent - Level IP TRANSPARENT option */ #if defined(IP_TRANSPARENT) static -ERL_NIF_TERM ngetopt_lvl_ip_transparent(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ip_transparent(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IP) int level = SOL_IP; @@ -12538,18 +12949,18 @@ ERL_NIF_TERM ngetopt_lvl_ip_transparent(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return ngetopt_bool_opt(env, descP, level, IP_TRANSPARENT); + return esock_getopt_bool_opt(env, descP, level, IP_TRANSPARENT); } #endif -/* ngetopt_lvl_ip_ttl - Level IP TTL option +/* esock_getopt_lvl_ip_ttl - Level IP TTL option */ #if defined(IP_TTL) static -ERL_NIF_TERM ngetopt_lvl_ip_ttl(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ip_ttl(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IP) int level = SOL_IP; @@ -12557,121 +12968,121 @@ ERL_NIF_TERM ngetopt_lvl_ip_ttl(ErlNifEnv* env, int level = IPPROTO_IP; #endif - return ngetopt_int_opt(env, descP, level, IP_TTL); + return esock_getopt_int_opt(env, descP, level, IP_TTL); } #endif -/* ngetopt_lvl_ipv6 - Level *IPv6* option(s) +/* esock_getopt_lvl_ipv6 - Level *IPv6* option(s) */ #if defined(HAVE_IPV6) static -ERL_NIF_TERM ngetopt_lvl_ipv6(ErlNifEnv* env, - ESockDescriptor* descP, - int eOpt) +ERL_NIF_TERM esock_getopt_lvl_ipv6(ErlNifEnv* env, + ESockDescriptor* descP, + int eOpt) { ERL_NIF_TERM result; SSDBG( descP, - ("SOCKET", "ngetopt_lvl_ipv6 -> entry with" + ("SOCKET", "esock_getopt_lvl_ipv6 -> entry with" "\r\n eOpt: %d" "\r\n", eOpt) ); switch (eOpt) { #if defined(IPV6_AUTHHDR) - case SOCKET_OPT_IPV6_AUTHHDR: - result = ngetopt_lvl_ipv6_authhdr(env, descP); + case ESOCK_OPT_IPV6_AUTHHDR: + result = esock_getopt_lvl_ipv6_authhdr(env, descP); break; #endif #if defined(IPV6_DSTOPTS) - case SOCKET_OPT_IPV6_DSTOPTS: - result = ngetopt_lvl_ipv6_dstopts(env, descP); + case ESOCK_OPT_IPV6_DSTOPTS: + result = esock_getopt_lvl_ipv6_dstopts(env, descP); break; #endif #if defined(IPV6_FLOWINFO) - case SOCKET_OPT_IPV6_FLOWINFO: - result = ngetopt_lvl_ipv6_flowinfo(env, descP); + case ESOCK_OPT_IPV6_FLOWINFO: + result = esock_getopt_lvl_ipv6_flowinfo(env, descP); break; #endif #if defined(IPV6_HOPLIMIT) - case SOCKET_OPT_IPV6_HOPLIMIT: - result = ngetopt_lvl_ipv6_hoplimit(env, descP); + case ESOCK_OPT_IPV6_HOPLIMIT: + result = esock_getopt_lvl_ipv6_hoplimit(env, descP); break; #endif #if defined(IPV6_HOPOPTS) - case SOCKET_OPT_IPV6_HOPOPTS: - result = ngetopt_lvl_ipv6_hopopts(env, descP); + case ESOCK_OPT_IPV6_HOPOPTS: + result = esock_getopt_lvl_ipv6_hopopts(env, descP); break; #endif #if defined(IPV6_MTU) - case SOCKET_OPT_IPV6_MTU: - result = ngetopt_lvl_ipv6_mtu(env, descP); + case ESOCK_OPT_IPV6_MTU: + result = esock_getopt_lvl_ipv6_mtu(env, descP); break; #endif #if defined(IPV6_MTU_DISCOVER) - case SOCKET_OPT_IPV6_MTU_DISCOVER: - result = ngetopt_lvl_ipv6_mtu_discover(env, descP); + case ESOCK_OPT_IPV6_MTU_DISCOVER: + result = esock_getopt_lvl_ipv6_mtu_discover(env, descP); break; #endif #if defined(IPV6_MULTICAST_HOPS) - case SOCKET_OPT_IPV6_MULTICAST_HOPS: - result = ngetopt_lvl_ipv6_multicast_hops(env, descP); + case ESOCK_OPT_IPV6_MULTICAST_HOPS: + result = esock_getopt_lvl_ipv6_multicast_hops(env, descP); break; #endif #if defined(IPV6_MULTICAST_IF) - case SOCKET_OPT_IPV6_MULTICAST_IF: - result = ngetopt_lvl_ipv6_multicast_if(env, descP); + case ESOCK_OPT_IPV6_MULTICAST_IF: + result = esock_getopt_lvl_ipv6_multicast_if(env, descP); break; #endif #if defined(IPV6_MULTICAST_LOOP) - case SOCKET_OPT_IPV6_MULTICAST_LOOP: - result = ngetopt_lvl_ipv6_multicast_loop(env, descP); + case ESOCK_OPT_IPV6_MULTICAST_LOOP: + result = esock_getopt_lvl_ipv6_multicast_loop(env, descP); break; #endif #if defined(IPV6_RECVERR) - case SOCKET_OPT_IPV6_RECVERR: - result = ngetopt_lvl_ipv6_recverr(env, descP); + case ESOCK_OPT_IPV6_RECVERR: + result = esock_getopt_lvl_ipv6_recverr(env, descP); break; #endif #if defined(IPV6_RECVPKTINFO) || defined(IPV6_PKTINFO) - case SOCKET_OPT_IPV6_RECVPKTINFO: - result = ngetopt_lvl_ipv6_recvpktinfo(env, descP); + case ESOCK_OPT_IPV6_RECVPKTINFO: + result = esock_getopt_lvl_ipv6_recvpktinfo(env, descP); break; #endif #if defined(IPV6_ROUTER_ALERT) - case SOCKET_OPT_IPV6_ROUTER_ALERT: - result = ngetopt_lvl_ipv6_router_alert(env, descP); + case ESOCK_OPT_IPV6_ROUTER_ALERT: + result = esock_getopt_lvl_ipv6_router_alert(env, descP); break; #endif #if defined(IPV6_RTHDR) - case SOCKET_OPT_IPV6_RTHDR: - result = ngetopt_lvl_ipv6_rthdr(env, descP); + case ESOCK_OPT_IPV6_RTHDR: + result = esock_getopt_lvl_ipv6_rthdr(env, descP); break; #endif #if defined(IPV6_UNICAST_HOPS) - case SOCKET_OPT_IPV6_UNICAST_HOPS: - result = ngetopt_lvl_ipv6_unicast_hops(env, descP); + case ESOCK_OPT_IPV6_UNICAST_HOPS: + result = esock_getopt_lvl_ipv6_unicast_hops(env, descP); break; #endif #if defined(IPV6_V6ONLY) - case SOCKET_OPT_IPV6_V6ONLY: - result = ngetopt_lvl_ipv6_v6only(env, descP); + case ESOCK_OPT_IPV6_V6ONLY: + result = esock_getopt_lvl_ipv6_v6only(env, descP); break; #endif @@ -12681,7 +13092,7 @@ ERL_NIF_TERM ngetopt_lvl_ipv6(ErlNifEnv* env, } SSDBG( descP, - ("SOCKET", "ngetopt_lvl_ipv6 -> done when" + ("SOCKET", "esock_getopt_lvl_ipv6 -> done when" "\r\n result: %T" "\r\n", result) ); @@ -12691,33 +13102,33 @@ ERL_NIF_TERM ngetopt_lvl_ipv6(ErlNifEnv* env, #if defined(IPV6_AUTHHDR) static -ERL_NIF_TERM ngetopt_lvl_ipv6_authhdr(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ipv6_authhdr(ErlNifEnv* env, + ESockDescriptor* descP) { - return ngetopt_bool_opt(env, descP, SOL_IPV6, IPV6_AUTHHDR); + return esock_getopt_bool_opt(env, descP, SOL_IPV6, IPV6_AUTHHDR); } #endif #if defined(IPV6_DSTOPTS) static -ERL_NIF_TERM ngetopt_lvl_ipv6_dstopts(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ipv6_dstopts(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IPV6) int level = SOL_IPV6; #else int level = IPPROTO_IPV6; #endif - return ngetopt_bool_opt(env, descP, level, IPV6_DSTOPTS); + return esock_getopt_bool_opt(env, descP, level, IPV6_DSTOPTS); } #endif #if defined(IPV6_FLOWINFO) static -ERL_NIF_TERM ngetopt_lvl_ipv6_flowinfo(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ipv6_flowinfo(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IPV6) int level = SOL_IPV6; @@ -12725,15 +13136,15 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_flowinfo(ErlNifEnv* env, int level = IPPROTO_IPV6; #endif - return ngetopt_bool_opt(env, descP, level, IPV6_FLOWINFO); + return esock_getopt_bool_opt(env, descP, level, IPV6_FLOWINFO); } #endif #if defined(IPV6_HOPLIMIT) static -ERL_NIF_TERM ngetopt_lvl_ipv6_hoplimit(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ipv6_hoplimit(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IPV6) int level = SOL_IPV6; @@ -12741,15 +13152,15 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_hoplimit(ErlNifEnv* env, int level = IPPROTO_IPV6; #endif - return ngetopt_bool_opt(env, descP, level, IPV6_HOPLIMIT); + return esock_getopt_bool_opt(env, descP, level, IPV6_HOPLIMIT); } #endif #if defined(IPV6_HOPOPTS) static -ERL_NIF_TERM ngetopt_lvl_ipv6_hopopts(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ipv6_hopopts(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IPV6) int level = SOL_IPV6; @@ -12757,15 +13168,15 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_hopopts(ErlNifEnv* env, int level = IPPROTO_IPV6; #endif - return ngetopt_bool_opt(env, descP, level, IPV6_HOPOPTS); + return esock_getopt_bool_opt(env, descP, level, IPV6_HOPOPTS); } #endif #if defined(IPV6_MTU) static -ERL_NIF_TERM ngetopt_lvl_ipv6_mtu(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ipv6_mtu(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IPV6) int level = SOL_IPV6; @@ -12773,17 +13184,17 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_mtu(ErlNifEnv* env, int level = IPPROTO_IPV6; #endif - return ngetopt_int_opt(env, descP, level, IPV6_MTU); + return esock_getopt_int_opt(env, descP, level, IPV6_MTU); } #endif -/* ngetopt_lvl_ipv6_mtu_discover - Level IPv6 MTU_DISCOVER option +/* esock_getopt_lvl_ipv6_mtu_discover - Level IPv6 MTU_DISCOVER option */ #if defined(IPV6_MTU_DISCOVER) static -ERL_NIF_TERM ngetopt_lvl_ipv6_mtu_discover(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ipv6_mtu_discover(ErlNifEnv* env, + ESockDescriptor* descP) { ERL_NIF_TERM result; ERL_NIF_TERM eMtuDisc; @@ -12814,8 +13225,8 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_mtu_discover(ErlNifEnv* env, #if defined(IPV6_MULTICAST_HOPS) static -ERL_NIF_TERM ngetopt_lvl_ipv6_multicast_hops(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ipv6_multicast_hops(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IPV6) int level = SOL_IPV6; @@ -12823,15 +13234,15 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_multicast_hops(ErlNifEnv* env, int level = IPPROTO_IPV6; #endif - return ngetopt_int_opt(env, descP, level, IPV6_MULTICAST_HOPS); + return esock_getopt_int_opt(env, descP, level, IPV6_MULTICAST_HOPS); } #endif #if defined(IPV6_MULTICAST_IF) static -ERL_NIF_TERM ngetopt_lvl_ipv6_multicast_if(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ipv6_multicast_if(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IPV6) int level = SOL_IPV6; @@ -12839,15 +13250,15 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_multicast_if(ErlNifEnv* env, int level = IPPROTO_IPV6; #endif - return ngetopt_int_opt(env, descP, level, IPV6_MULTICAST_IF); + return esock_getopt_int_opt(env, descP, level, IPV6_MULTICAST_IF); } #endif #if defined(IPV6_MULTICAST_LOOP) static -ERL_NIF_TERM ngetopt_lvl_ipv6_multicast_loop(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ipv6_multicast_loop(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IPV6) int level = SOL_IPV6; @@ -12855,15 +13266,15 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_multicast_loop(ErlNifEnv* env, int level = IPPROTO_IPV6; #endif - return ngetopt_bool_opt(env, descP, level, IPV6_MULTICAST_LOOP); + return esock_getopt_bool_opt(env, descP, level, IPV6_MULTICAST_LOOP); } #endif #if defined(IPV6_RECVERR) static -ERL_NIF_TERM ngetopt_lvl_ipv6_recverr(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ipv6_recverr(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IPV6) int level = SOL_IPV6; @@ -12871,15 +13282,15 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_recverr(ErlNifEnv* env, int level = IPPROTO_IPV6; #endif - return ngetopt_bool_opt(env, descP, level, IPV6_RECVERR); + return esock_getopt_bool_opt(env, descP, level, IPV6_RECVERR); } #endif #if defined(IPV6_RECVPKTINFO) || defined(IPV6_PKTINFO) static -ERL_NIF_TERM ngetopt_lvl_ipv6_recvpktinfo(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ipv6_recvpktinfo(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IPV6) int level = SOL_IPV6; @@ -12892,15 +13303,15 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_recvpktinfo(ErlNifEnv* env, int opt = IPV6_PKTINFO; #endif - return ngetopt_bool_opt(env, descP, level, opt); + return esock_getopt_bool_opt(env, descP, level, opt); } #endif #if defined(IPV6_ROUTER_ALERT) static -ERL_NIF_TERM ngetopt_lvl_ipv6_router_alert(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ipv6_router_alert(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IPV6) int level = SOL_IPV6; @@ -12908,15 +13319,15 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_router_alert(ErlNifEnv* env, int level = IPPROTO_IPV6; #endif - return ngetopt_int_opt(env, descP, level, IPV6_ROUTER_ALERT); + return esock_getopt_int_opt(env, descP, level, IPV6_ROUTER_ALERT); } #endif #if defined(IPV6_RTHDR) static -ERL_NIF_TERM ngetopt_lvl_ipv6_rthdr(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ipv6_rthdr(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IPV6) int level = SOL_IPV6; @@ -12924,15 +13335,15 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_rthdr(ErlNifEnv* env, int level = IPPROTO_IPV6; #endif - return ngetopt_bool_opt(env, descP, level, IPV6_RTHDR); + return esock_getopt_bool_opt(env, descP, level, IPV6_RTHDR); } #endif #if defined(IPV6_UNICAST_HOPS) static -ERL_NIF_TERM ngetopt_lvl_ipv6_unicast_hops(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ipv6_unicast_hops(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IPV6) int level = SOL_IPV6; @@ -12940,15 +13351,15 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_unicast_hops(ErlNifEnv* env, int level = IPPROTO_IPV6; #endif - return ngetopt_int_opt(env, descP, level, IPV6_UNICAST_HOPS); + return esock_getopt_int_opt(env, descP, level, IPV6_UNICAST_HOPS); } #endif #if defined(IPV6_V6ONLY) static -ERL_NIF_TERM ngetopt_lvl_ipv6_v6only(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_ipv6_v6only(ErlNifEnv* env, + ESockDescriptor* descP) { #if defined(SOL_IPV6) int level = SOL_IPV6; @@ -12956,7 +13367,7 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_v6only(ErlNifEnv* env, int level = IPPROTO_IPV6; #endif - return ngetopt_bool_opt(env, descP, level, IPV6_V6ONLY); + return esock_getopt_bool_opt(env, descP, level, IPV6_V6ONLY); } #endif @@ -12965,31 +13376,31 @@ ERL_NIF_TERM ngetopt_lvl_ipv6_v6only(ErlNifEnv* env, -/* ngetopt_lvl_tcp - Level *TCP* option(s) +/* esock_getopt_lvl_tcp - Level *TCP* option(s) */ static -ERL_NIF_TERM ngetopt_lvl_tcp(ErlNifEnv* env, - ESockDescriptor* descP, - int eOpt) +ERL_NIF_TERM esock_getopt_lvl_tcp(ErlNifEnv* env, + ESockDescriptor* descP, + int eOpt) { ERL_NIF_TERM result; switch (eOpt) { #if defined(TCP_CONGESTION) - case SOCKET_OPT_TCP_CONGESTION: - result = ngetopt_lvl_tcp_congestion(env, descP); + case ESOCK_OPT_TCP_CONGESTION: + result = esock_getopt_lvl_tcp_congestion(env, descP); break; #endif #if defined(TCP_MAXSEG) - case SOCKET_OPT_TCP_MAXSEG: - result = ngetopt_lvl_tcp_maxseg(env, descP); + case ESOCK_OPT_TCP_MAXSEG: + result = esock_getopt_lvl_tcp_maxseg(env, descP); break; #endif #if defined(TCP_NODELAY) - case SOCKET_OPT_TCP_NODELAY: - result = ngetopt_lvl_tcp_nodelay(env, descP); + case ESOCK_OPT_TCP_NODELAY: + result = esock_getopt_lvl_tcp_nodelay(env, descP); break; #endif @@ -13002,58 +13413,58 @@ ERL_NIF_TERM ngetopt_lvl_tcp(ErlNifEnv* env, } -/* ngetopt_lvl_tcp_congestion - Level TCP CONGESTION option +/* esock_getopt_lvl_tcp_congestion - Level TCP CONGESTION option */ #if defined(TCP_CONGESTION) static -ERL_NIF_TERM ngetopt_lvl_tcp_congestion(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_tcp_congestion(ErlNifEnv* env, + ESockDescriptor* descP) { - int max = SOCKET_OPT_TCP_CONGESTION_NAME_MAX+1; + int max = ESOCK_OPT_TCP_CONGESTION_NAME_MAX+1; - return ngetopt_str_opt(env, descP, IPPROTO_TCP, TCP_CONGESTION, max); + return esock_getopt_str_opt(env, descP, IPPROTO_TCP, TCP_CONGESTION, max); } #endif -/* ngetopt_lvl_tcp_maxseg - Level TCP MAXSEG option +/* esock_getopt_lvl_tcp_maxseg - Level TCP MAXSEG option */ #if defined(TCP_MAXSEG) static -ERL_NIF_TERM ngetopt_lvl_tcp_maxseg(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_tcp_maxseg(ErlNifEnv* env, + ESockDescriptor* descP) { - return ngetopt_int_opt(env, descP, IPPROTO_TCP, TCP_MAXSEG); + return esock_getopt_int_opt(env, descP, IPPROTO_TCP, TCP_MAXSEG); } #endif -/* ngetopt_lvl_tcp_nodelay - Level TCP NODELAY option +/* esock_getopt_lvl_tcp_nodelay - Level TCP NODELAY option */ #if defined(TCP_NODELAY) static -ERL_NIF_TERM ngetopt_lvl_tcp_nodelay(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_tcp_nodelay(ErlNifEnv* env, + ESockDescriptor* descP) { - return ngetopt_bool_opt(env, descP, IPPROTO_TCP, TCP_NODELAY); + return esock_getopt_bool_opt(env, descP, IPPROTO_TCP, TCP_NODELAY); } #endif -/* ngetopt_lvl_udp - Level *UDP* option(s) +/* esock_getopt_lvl_udp - Level *UDP* option(s) */ static -ERL_NIF_TERM ngetopt_lvl_udp(ErlNifEnv* env, - ESockDescriptor* descP, - int eOpt) +ERL_NIF_TERM esock_getopt_lvl_udp(ErlNifEnv* env, + ESockDescriptor* descP, + int eOpt) { ERL_NIF_TERM result; switch (eOpt) { #if defined(UDP_CORK) - case SOCKET_OPT_UDP_CORK: - result = ngetopt_lvl_udp_cork(env, descP); + case ESOCK_OPT_UDP_CORK: + result = esock_getopt_lvl_udp_cork(env, descP); break; #endif @@ -13066,74 +13477,74 @@ ERL_NIF_TERM ngetopt_lvl_udp(ErlNifEnv* env, } -/* ngetopt_lvl_udp_cork - Level UDP CORK option +/* esock_getopt_lvl_udp_cork - Level UDP CORK option */ #if defined(UDP_CORK) static -ERL_NIF_TERM ngetopt_lvl_udp_cork(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_udp_cork(ErlNifEnv* env, + ESockDescriptor* descP) { - return ngetopt_bool_opt(env, descP, IPPROTO_UDP, UDP_CORK); + return esock_getopt_bool_opt(env, descP, IPPROTO_UDP, UDP_CORK); } #endif -/* ngetopt_lvl_sctp - Level *SCTP* option(s) +/* esock_getopt_lvl_sctp - Level *SCTP* option(s) */ #if defined(HAVE_SCTP) static -ERL_NIF_TERM ngetopt_lvl_sctp(ErlNifEnv* env, - ESockDescriptor* descP, - int eOpt) +ERL_NIF_TERM esock_getopt_lvl_sctp(ErlNifEnv* env, + ESockDescriptor* descP, + int eOpt) { ERL_NIF_TERM result; SSDBG( descP, - ("SOCKET", "ngetopt_lvl_sctp -> entry with" + ("SOCKET", "esock_getopt_lvl_sctp -> entry with" "\r\n opt: %d" "\r\n", eOpt) ); switch (eOpt) { #if defined(SCTP_ASSOCINFO) - case SOCKET_OPT_SCTP_ASSOCINFO: - result = ngetopt_lvl_sctp_associnfo(env, descP); + case ESOCK_OPT_SCTP_ASSOCINFO: + result = esock_getopt_lvl_sctp_associnfo(env, descP); break; #endif #if defined(SCTP_AUTOCLOSE) - case SOCKET_OPT_SCTP_AUTOCLOSE: - result = ngetopt_lvl_sctp_autoclose(env, descP); + case ESOCK_OPT_SCTP_AUTOCLOSE: + result = esock_getopt_lvl_sctp_autoclose(env, descP); break; #endif #if defined(SCTP_DISABLE_FRAGMENTS) - case SOCKET_OPT_SCTP_DISABLE_FRAGMENTS: - result = ngetopt_lvl_sctp_disable_fragments(env, descP); + case ESOCK_OPT_SCTP_DISABLE_FRAGMENTS: + result = esock_getopt_lvl_sctp_disable_fragments(env, descP); break; #endif #if defined(SCTP_INITMSG) - case SOCKET_OPT_SCTP_INITMSG: - result = ngetopt_lvl_sctp_initmsg(env, descP); + case ESOCK_OPT_SCTP_INITMSG: + result = esock_getopt_lvl_sctp_initmsg(env, descP); break; #endif #if defined(SCTP_MAXSEG) - case SOCKET_OPT_SCTP_MAXSEG: - result = ngetopt_lvl_sctp_maxseg(env, descP); + case ESOCK_OPT_SCTP_MAXSEG: + result = esock_getopt_lvl_sctp_maxseg(env, descP); break; #endif #if defined(SCTP_NODELAY) - case SOCKET_OPT_SCTP_NODELAY: - result = ngetopt_lvl_sctp_nodelay(env, descP); + case ESOCK_OPT_SCTP_NODELAY: + result = esock_getopt_lvl_sctp_nodelay(env, descP); break; #endif #if defined(SCTP_RTOINFO) - case SOCKET_OPT_SCTP_RTOINFO: - result = ngetopt_lvl_sctp_rtoinfo(env, descP); + case ESOCK_OPT_SCTP_RTOINFO: + result = esock_getopt_lvl_sctp_rtoinfo(env, descP); break; #endif @@ -13143,7 +13554,7 @@ ERL_NIF_TERM ngetopt_lvl_sctp(ErlNifEnv* env, } SSDBG( descP, - ("SOCKET", "ngetopt_lvl_sctp -> done when" + ("SOCKET", "esock_getopt_lvl_sctp -> done when" "\r\n result: %T" "\r\n", result) ); @@ -13151,7 +13562,7 @@ ERL_NIF_TERM ngetopt_lvl_sctp(ErlNifEnv* env, } -/* ngetopt_lvl_sctp_associnfo - Level SCTP ASSOCINFO option +/* esock_getopt_lvl_sctp_associnfo - Level SCTP ASSOCINFO option * * <KOLLA> * @@ -13166,15 +13577,15 @@ ERL_NIF_TERM ngetopt_lvl_sctp(ErlNifEnv* env, */ #if defined(SCTP_ASSOCINFO) static -ERL_NIF_TERM ngetopt_lvl_sctp_associnfo(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_sctp_associnfo(ErlNifEnv* env, + ESockDescriptor* descP) { ERL_NIF_TERM result; struct sctp_assocparams val; SOCKOPTLEN_T valSz = sizeof(val); int res; - SSDBG( descP, ("SOCKET", "ngetopt_lvl_sctp_associnfo -> entry\r\n") ); + SSDBG( descP, ("SOCKET", "esock_getopt_lvl_sctp_associnfo -> entry\r\n") ); sys_memzero((char*) &val, valSz); res = sock_getopt(descP->sock, IPPROTO_SCTP, SCTP_ASSOCINFO, &val, &valSz); @@ -13203,7 +13614,7 @@ ERL_NIF_TERM ngetopt_lvl_sctp_associnfo(ErlNifEnv* env, } SSDBG( descP, - ("SOCKET", "ngetopt_lvl_sctp_associnfo -> done with" + ("SOCKET", "esock_getopt_lvl_sctp_associnfo -> done with" "\r\n res: %d" "\r\n result: %T" "\r\n", res, result) ); @@ -13213,44 +13624,45 @@ ERL_NIF_TERM ngetopt_lvl_sctp_associnfo(ErlNifEnv* env, #endif -/* ngetopt_lvl_sctp_autoclose - Level SCTP AUTOCLOSE option +/* esock_getopt_lvl_sctp_autoclose - Level SCTP AUTOCLOSE option */ #if defined(SCTP_AUTOCLOSE) static -ERL_NIF_TERM ngetopt_lvl_sctp_autoclose(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_sctp_autoclose(ErlNifEnv* env, + ESockDescriptor* descP) { - return ngetopt_int_opt(env, descP, IPPROTO_SCTP, SCTP_AUTOCLOSE); + return esock_getopt_int_opt(env, descP, IPPROTO_SCTP, SCTP_AUTOCLOSE); } #endif -/* ngetopt_lvl_sctp_disable_fragments - Level SCTP DISABLE:FRAGMENTS option +/* esock_getopt_lvl_sctp_disable_fragments - Level SCTP DISABLE:FRAGMENTS option */ #if defined(SCTP_DISABLE_FRAGMENTS) static -ERL_NIF_TERM ngetopt_lvl_sctp_disable_fragments(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_sctp_disable_fragments(ErlNifEnv* env, + ESockDescriptor* descP) { - return ngetopt_bool_opt(env, descP, IPPROTO_SCTP, SCTP_DISABLE_FRAGMENTS); + return esock_getopt_bool_opt(env, descP, + IPPROTO_SCTP, SCTP_DISABLE_FRAGMENTS); } #endif -/* ngetopt_lvl_sctp_initmsg - Level SCTP INITMSG option +/* esock_getopt_lvl_sctp_initmsg - Level SCTP INITMSG option * */ #if defined(SCTP_INITMSG) static -ERL_NIF_TERM ngetopt_lvl_sctp_initmsg(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_sctp_initmsg(ErlNifEnv* env, + ESockDescriptor* descP) { ERL_NIF_TERM result; struct sctp_initmsg val; SOCKOPTLEN_T valSz = sizeof(val); int res; - SSDBG( descP, ("SOCKET", "ngetopt_lvl_sctp_initmsg -> entry\r\n") ); + SSDBG( descP, ("SOCKET", "esock_getopt_lvl_sctp_initmsg -> entry\r\n") ); sys_memzero((char*) &val, valSz); res = sock_getopt(descP->sock, IPPROTO_SCTP, SCTP_INITMSG, &val, &valSz); @@ -13277,7 +13689,7 @@ ERL_NIF_TERM ngetopt_lvl_sctp_initmsg(ErlNifEnv* env, } SSDBG( descP, - ("SOCKET", "ngetopt_lvl_sctp_initmsg -> done with" + ("SOCKET", "esock_getopt_lvl_sctp_initmsg -> done with" "\r\n res: %d" "\r\n result: %T" "\r\n", res, result) ); @@ -13287,31 +13699,31 @@ ERL_NIF_TERM ngetopt_lvl_sctp_initmsg(ErlNifEnv* env, #endif -/* ngetopt_lvl_sctp_maxseg - Level SCTP MAXSEG option +/* esock_getopt_lvl_sctp_maxseg - Level SCTP MAXSEG option */ #if defined(SCTP_MAXSEG) static -ERL_NIF_TERM ngetopt_lvl_sctp_maxseg(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_sctp_maxseg(ErlNifEnv* env, + ESockDescriptor* descP) { - return ngetopt_int_opt(env, descP, IPPROTO_SCTP, SCTP_MAXSEG); + return esock_getopt_int_opt(env, descP, IPPROTO_SCTP, SCTP_MAXSEG); } #endif -/* ngetopt_lvl_sctp_nodelay - Level SCTP NODELAY option +/* esock_getopt_lvl_sctp_nodelay - Level SCTP NODELAY option */ #if defined(SCTP_NODELAY) static -ERL_NIF_TERM ngetopt_lvl_sctp_nodelay(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_sctp_nodelay(ErlNifEnv* env, + ESockDescriptor* descP) { - return ngetopt_bool_opt(env, descP, IPPROTO_SCTP, SCTP_NODELAY); + return esock_getopt_bool_opt(env, descP, IPPROTO_SCTP, SCTP_NODELAY); } #endif -/* ngetopt_lvl_sctp_associnfo - Level SCTP ASSOCINFO option +/* esock_getopt_lvl_sctp_associnfo - Level SCTP ASSOCINFO option * * <KOLLA> * @@ -13326,15 +13738,15 @@ ERL_NIF_TERM ngetopt_lvl_sctp_nodelay(ErlNifEnv* env, */ #if defined(SCTP_RTOINFO) static -ERL_NIF_TERM ngetopt_lvl_sctp_rtoinfo(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_getopt_lvl_sctp_rtoinfo(ErlNifEnv* env, + ESockDescriptor* descP) { ERL_NIF_TERM result; struct sctp_rtoinfo val; SOCKOPTLEN_T valSz = sizeof(val); int res; - SSDBG( descP, ("SOCKET", "ngetopt_lvl_sctp_rtoinfo -> entry\r\n") ); + SSDBG( descP, ("SOCKET", "esock_getopt_lvl_sctp_rtoinfo -> entry\r\n") ); sys_memzero((char*) &val, valSz); res = sock_getopt(descP->sock, IPPROTO_SCTP, SCTP_RTOINFO, &val, &valSz); @@ -13360,7 +13772,7 @@ ERL_NIF_TERM ngetopt_lvl_sctp_rtoinfo(ErlNifEnv* env, } SSDBG( descP, - ("SOCKET", "ngetopt_lvl_sctp_rtoinfo -> done with" + ("SOCKET", "esock_getopt_lvl_sctp_rtoinfo -> done with" "\r\n res: %d" "\r\n result: %T" "\r\n", res, result) ); @@ -13375,13 +13787,13 @@ ERL_NIF_TERM ngetopt_lvl_sctp_rtoinfo(ErlNifEnv* env, -/* ngetopt_bool_opt - get an (integer) bool option +/* esock_getopt_bool_opt - get an (integer) bool option */ static -ERL_NIF_TERM ngetopt_bool_opt(ErlNifEnv* env, - ESockDescriptor* descP, - int level, - int opt) +ERL_NIF_TERM esock_getopt_bool_opt(ErlNifEnv* env, + ESockDescriptor* descP, + int level, + int opt) { ERL_NIF_TERM result; int val; @@ -13389,7 +13801,7 @@ ERL_NIF_TERM ngetopt_bool_opt(ErlNifEnv* env, int res; /* - SSDBG( descP, ("SOCKET", "ngetopt_bool_opt -> entry with" + SSDBG( descP, ("SOCKET", "esock_getopt_bool_opt -> entry with" "\r\n: level: %d" "\r\n: opt: %d" "\r\n", level, opt) ); @@ -13406,7 +13818,7 @@ ERL_NIF_TERM ngetopt_bool_opt(ErlNifEnv* env, } /* - SSDBG( descP, ("SOCKET", "ngetopt_bool_opt -> done when" + SSDBG( descP, ("SOCKET", "esock_getopt_bool_opt -> done when" "\r\n: res: %d" "\r\n: result: %T" "\r\n", res, result) ); @@ -13416,13 +13828,13 @@ ERL_NIF_TERM ngetopt_bool_opt(ErlNifEnv* env, } -/* ngetopt_int_opt - get an integer option +/* esock_getopt_int_opt - get an integer option */ static -ERL_NIF_TERM ngetopt_int_opt(ErlNifEnv* env, - ESockDescriptor* descP, - int level, - int opt) +ERL_NIF_TERM esock_getopt_int_opt(ErlNifEnv* env, + ESockDescriptor* descP, + int level, + int opt) { ERL_NIF_TERM result; int val; @@ -13442,13 +13854,13 @@ ERL_NIF_TERM ngetopt_int_opt(ErlNifEnv* env, -/* ngetopt_timeval_opt - get an timeval option +/* esock_getopt_timeval_opt - get an timeval option */ static -ERL_NIF_TERM ngetopt_timeval_opt(ErlNifEnv* env, - ESockDescriptor* descP, - int level, - int opt) +ERL_NIF_TERM esock_getopt_timeval_opt(ErlNifEnv* env, + ESockDescriptor* descP, + int level, + int opt) { ERL_NIF_TERM result; struct timeval val; @@ -13456,7 +13868,7 @@ ERL_NIF_TERM ngetopt_timeval_opt(ErlNifEnv* env, int res; SSDBG( descP, - ("SOCKET", "ngetopt_timeval_opt -> entry with" + ("SOCKET", "esock_getopt_timeval_opt -> entry with" "\r\n level: %d" "\r\n opt: %d" "\r\n", level, opt) ); @@ -13477,7 +13889,7 @@ ERL_NIF_TERM ngetopt_timeval_opt(ErlNifEnv* env, } SSDBG( descP, - ("SOCKET", "ngetopt_timeval_opt -> done when" + ("SOCKET", "esock_getopt_timeval_opt -> done when" "\r\n result: %T" "\r\n", result) ); @@ -13486,7 +13898,7 @@ ERL_NIF_TERM ngetopt_timeval_opt(ErlNifEnv* env, -/* ngetopt_str_opt - get an string option +/* esock_getopt_str_opt - get an string option * * We provide the max size of the string. This is the * size of the buffer we allocate for the value. @@ -13495,11 +13907,11 @@ ERL_NIF_TERM ngetopt_timeval_opt(ErlNifEnv* env, */ #if defined(USE_GETOPT_STR_OPT) static -ERL_NIF_TERM ngetopt_str_opt(ErlNifEnv* env, - ESockDescriptor* descP, - int level, - int opt, - int max) +ERL_NIF_TERM esock_getopt_str_opt(ErlNifEnv* env, + ESockDescriptor* descP, + int level, + int opt, + int max) { ERL_NIF_TERM result; char* val = MALLOC(max); @@ -13507,7 +13919,7 @@ ERL_NIF_TERM ngetopt_str_opt(ErlNifEnv* env, int res; SSDBG( descP, - ("SOCKET", "ngetopt_str_opt -> entry with" + ("SOCKET", "esock_getopt_str_opt -> entry with" "\r\n level: %d" "\r\n opt: %d" "\r\n max: %d" @@ -13524,7 +13936,7 @@ ERL_NIF_TERM ngetopt_str_opt(ErlNifEnv* env, } SSDBG( descP, - ("SOCKET", "ngetopt_str_opt -> done when" + ("SOCKET", "esock_getopt_str_opt -> done when" "\r\n result: %T" "\r\n", result) ); @@ -13563,7 +13975,7 @@ ERL_NIF_TERM nif_sockname(ErlNifEnv* env, /* Extract arguments and perform preliminary validation */ if ((argc != 1) || - !enif_get_resource(env, argv[0], sockets, (void**) &descP)) { + !ESOCK_GET_RESOURCE(env, argv[0], (void**) &descP)) { return enif_make_badarg(env); } @@ -13575,7 +13987,7 @@ ERL_NIF_TERM nif_sockname(ErlNifEnv* env, "\r\n Socket: %T" "\r\n", descP->sock, argv[0]) ); - res = nsockname(env, descP); + res = esock_sockname(env, descP); SSDBG( descP, ("SOCKET", "nif_sockname -> done with res = %T\r\n", res) ); @@ -13587,8 +13999,8 @@ ERL_NIF_TERM nif_sockname(ErlNifEnv* env, #if !defined(__WIN32__) static -ERL_NIF_TERM nsockname(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_sockname(ErlNifEnv* env, + ESockDescriptor* descP) { ESockAddress sa; ESockAddress* saP = &sa; @@ -13637,7 +14049,7 @@ ERL_NIF_TERM nif_peername(ErlNifEnv* env, /* Extract arguments and perform preliminary validation */ if ((argc != 1) || - !enif_get_resource(env, argv[0], sockets, (void**) &descP)) { + !ESOCK_GET_RESOURCE(env, argv[0], (void**) &descP)) { return enif_make_badarg(env); } @@ -13649,7 +14061,7 @@ ERL_NIF_TERM nif_peername(ErlNifEnv* env, "\r\n Socket: %T" "\r\n", descP->sock, argv[0]) ); - res = npeername(env, descP); + res = esock_peername(env, descP); SSDBG( descP, ("SOCKET", "nif_peername -> done with res = %T\r\n", res) ); @@ -13661,8 +14073,8 @@ ERL_NIF_TERM nif_peername(ErlNifEnv* env, #if !defined(__WIN32__) static -ERL_NIF_TERM npeername(ErlNifEnv* env, - ESockDescriptor* descP) +ERL_NIF_TERM esock_peername(ErlNifEnv* env, + ESockDescriptor* descP) { ESockAddress sa; ESockAddress* saP = &sa; @@ -13713,7 +14125,7 @@ ERL_NIF_TERM nif_cancel(ErlNifEnv* env, sockRef = argv[0]; if ((argc != 3) || - !enif_get_resource(env, sockRef, sockets, (void**) &descP)) { + !ESOCK_GET_RESOURCE(env, sockRef, (void**) &descP)) { return enif_make_badarg(env); } op = argv[1]; @@ -13728,7 +14140,7 @@ ERL_NIF_TERM nif_cancel(ErlNifEnv* env, "\r\n opRef: %T" "\r\n", descP->sock, op, opRef) ); - result = ncancel(env, descP, op, sockRef, opRef); + result = esock_cancel(env, descP, op, sockRef, opRef); SSDBG( descP, ("SOCKET", "nif_cancel -> done with result: " @@ -13742,11 +14154,11 @@ ERL_NIF_TERM nif_cancel(ErlNifEnv* env, #if !defined(__WIN32__) static -ERL_NIF_TERM ncancel(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM op, - ERL_NIF_TERM sockRef, - ERL_NIF_TERM opRef) +ERL_NIF_TERM esock_cancel(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM op, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM opRef) { /* <KOLLA> * @@ -13757,21 +14169,21 @@ ERL_NIF_TERM ncancel(ErlNifEnv* env, * </KOLLA> */ if (COMPARE(op, esock_atom_connect) == 0) { - return ncancel_connect(env, descP, opRef); + return esock_cancel_connect(env, descP, opRef); } else if (COMPARE(op, esock_atom_accept) == 0) { - return ncancel_accept(env, descP, sockRef, opRef); + return esock_cancel_accept(env, descP, sockRef, opRef); } else if (COMPARE(op, esock_atom_send) == 0) { - return ncancel_send(env, descP, sockRef, opRef); + return esock_cancel_send(env, descP, sockRef, opRef); } else if (COMPARE(op, esock_atom_sendto) == 0) { - return ncancel_send(env, descP, sockRef, opRef); + return esock_cancel_send(env, descP, sockRef, opRef); } else if (COMPARE(op, esock_atom_sendmsg) == 0) { - return ncancel_send(env, descP, sockRef, opRef); + return esock_cancel_send(env, descP, sockRef, opRef); } else if (COMPARE(op, esock_atom_recv) == 0) { - return ncancel_recv(env, descP, sockRef, opRef); + return esock_cancel_recv(env, descP, sockRef, opRef); } else if (COMPARE(op, esock_atom_recvfrom) == 0) { - return ncancel_recv(env, descP, sockRef, opRef); + return esock_cancel_recv(env, descP, sockRef, opRef); } else if (COMPARE(op, esock_atom_recvmsg) == 0) { - return ncancel_recv(env, descP, sockRef, opRef); + return esock_cancel_recv(env, descP, sockRef, opRef); } else { return esock_make_error(env, esock_atom_einval); } @@ -13779,20 +14191,20 @@ ERL_NIF_TERM ncancel(ErlNifEnv* env, -/* *** ncancel_connect *** +/* *** esock_cancel_connect *** * * */ static -ERL_NIF_TERM ncancel_connect(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM opRef) +ERL_NIF_TERM esock_cancel_connect(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM opRef) { - return ncancel_write_select(env, descP, opRef); + return esock_cancel_write_select(env, descP, opRef); } -/* *** ncancel_accept *** +/* *** esock_cancel_accept *** * * We have two different cases: * *) Its the current acceptor @@ -13803,15 +14215,15 @@ ERL_NIF_TERM ncancel_connect(ErlNifEnv* env, * */ static -ERL_NIF_TERM ncancel_accept(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - ERL_NIF_TERM opRef) +ERL_NIF_TERM esock_cancel_accept(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM opRef) { ERL_NIF_TERM res; SSDBG( descP, - ("SOCKET", "ncancel_accept -> entry with" + ("SOCKET", "esock_cancel_accept -> entry with" "\r\n opRef: %T" "\r\n %s" "\r\n", opRef, @@ -13821,9 +14233,9 @@ ERL_NIF_TERM ncancel_accept(ErlNifEnv* env, if (descP->currentAcceptorP != NULL) { if (COMPARE(opRef, descP->currentAcceptor.ref) == 0) { - res = ncancel_accept_current(env, descP, sockRef); + res = esock_cancel_accept_current(env, descP, sockRef); } else { - res = ncancel_accept_waiting(env, descP, opRef); + res = esock_cancel_accept_waiting(env, descP, opRef); } } else { /* Or badarg? */ @@ -13833,7 +14245,7 @@ ERL_NIF_TERM ncancel_accept(ErlNifEnv* env, MUNLOCK(descP->accMtx); SSDBG( descP, - ("SOCKET", "ncancel_accept -> done with result:" + ("SOCKET", "esock_cancel_accept -> done with result:" "\r\n %T" "\r\n", res) ); @@ -13846,27 +14258,27 @@ ERL_NIF_TERM ncancel_accept(ErlNifEnv* env, * in the acceptor queue). */ static -ERL_NIF_TERM ncancel_accept_current(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef) +ERL_NIF_TERM esock_cancel_accept_current(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef) { ERL_NIF_TERM res; - SSDBG( descP, ("SOCKET", "ncancel_accept_current -> entry\r\n") ); + SSDBG( descP, ("SOCKET", "esock_cancel_accept_current -> entry\r\n") ); - DEMONP("ncancel_accept_current -> current acceptor", + DEMONP("esock_cancel_accept_current -> current acceptor", env, descP, &descP->currentAcceptor.mon); - res = ncancel_read_select(env, descP, descP->currentAcceptor.ref); + res = esock_cancel_read_select(env, descP, descP->currentAcceptor.ref); SSDBG( descP, ("SOCKET", - "ncancel_accept_current -> cancel res: %T\r\n", res) ); + "esock_cancel_accept_current -> cancel res: %T\r\n", res) ); if (!activate_next_acceptor(env, descP, sockRef)) { SSDBG( descP, - ("SOCKET", "ncancel_accept_current -> no more writers\r\n") ); + ("SOCKET", "esock_cancel_accept_current -> no more writers\r\n") ); - descP->state = SOCKET_STATE_LISTENING; + descP->state = ESOCK_STATE_LISTENING; descP->currentAcceptorP = NULL; descP->currentAcceptor.ref = esock_atom_undefined; @@ -13874,7 +14286,7 @@ ERL_NIF_TERM ncancel_accept_current(ErlNifEnv* env, esock_monitor_init(&descP->currentAcceptor.mon); } - SSDBG( descP, ("SOCKET", "ncancel_accept_current -> done with result:" + SSDBG( descP, ("SOCKET", "esock_cancel_accept_current -> done with result:" "\r\n %T" "\r\n", res) ); @@ -13886,9 +14298,9 @@ ERL_NIF_TERM ncancel_accept_current(ErlNifEnv* env, * remove them from the acceptor queue. */ static -ERL_NIF_TERM ncancel_accept_waiting(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM opRef) +ERL_NIF_TERM esock_cancel_accept_waiting(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM opRef) { ErlNifPid caller; @@ -13907,23 +14319,23 @@ ERL_NIF_TERM ncancel_accept_waiting(ErlNifEnv* env, -/* *** ncancel_send *** +/* *** esock_cancel_send *** * * Cancel a send operation. * Its either the current writer or one of the waiting writers. */ static -ERL_NIF_TERM ncancel_send(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - ERL_NIF_TERM opRef) +ERL_NIF_TERM esock_cancel_send(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM opRef) { ERL_NIF_TERM res; MLOCK(descP->writeMtx); SSDBG( descP, - ("SOCKET", "ncancel_send -> entry with" + ("SOCKET", "esock_cancel_send -> entry with" "\r\n opRef: %T" "\r\n %s" "\r\n", opRef, @@ -13931,9 +14343,9 @@ ERL_NIF_TERM ncancel_send(ErlNifEnv* env, if (descP->currentWriterP != NULL) { if (COMPARE(opRef, descP->currentWriter.ref) == 0) { - res = ncancel_send_current(env, descP, sockRef); + res = esock_cancel_send_current(env, descP, sockRef); } else { - res = ncancel_send_waiting(env, descP, opRef); + res = esock_cancel_send_waiting(env, descP, opRef); } } else { /* Or badarg? */ @@ -13943,7 +14355,7 @@ ERL_NIF_TERM ncancel_send(ErlNifEnv* env, MUNLOCK(descP->writeMtx); SSDBG( descP, - ("SOCKET", "ncancel_send -> done with result:" + ("SOCKET", "esock_cancel_send -> done with result:" "\r\n %T" "\r\n", res) ); @@ -13957,31 +14369,31 @@ ERL_NIF_TERM ncancel_send(ErlNifEnv* env, * in the writer queue). */ static -ERL_NIF_TERM ncancel_send_current(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef) +ERL_NIF_TERM esock_cancel_send_current(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef) { ERL_NIF_TERM res; - SSDBG( descP, ("SOCKET", "ncancel_send_current -> entry\r\n") ); + SSDBG( descP, ("SOCKET", "esock_cancel_send_current -> entry\r\n") ); - DEMONP("ncancel_send_current -> current writer", + DEMONP("esock_cancel_send_current -> current writer", env, descP, &descP->currentWriter.mon); - res = ncancel_write_select(env, descP, descP->currentWriter.ref); + res = esock_cancel_write_select(env, descP, descP->currentWriter.ref); SSDBG( descP, - ("SOCKET", "ncancel_send_current -> cancel res: %T\r\n", res) ); + ("SOCKET", "esock_cancel_send_current -> cancel res: %T\r\n", res) ); if (!activate_next_writer(env, descP, sockRef)) { SSDBG( descP, - ("SOCKET", "ncancel_send_current -> no more writers\r\n") ); + ("SOCKET", "esock_cancel_send_current -> no more writers\r\n") ); descP->currentWriterP = NULL; descP->currentWriter.ref = esock_atom_undefined; enif_set_pid_undefined(&descP->currentWriter.pid); esock_monitor_init(&descP->currentWriter.mon); } - SSDBG( descP, ("SOCKET", "ncancel_send_current -> done with result:" + SSDBG( descP, ("SOCKET", "esock_cancel_send_current -> done with result:" "\r\n %T" "\r\n", res) ); @@ -13993,9 +14405,9 @@ ERL_NIF_TERM ncancel_send_current(ErlNifEnv* env, * remove them from the writer queue. */ static -ERL_NIF_TERM ncancel_send_waiting(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM opRef) +ERL_NIF_TERM esock_cancel_send_waiting(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM opRef) { ErlNifPid caller; @@ -14014,23 +14426,23 @@ ERL_NIF_TERM ncancel_send_waiting(ErlNifEnv* env, -/* *** ncancel_recv *** +/* *** esock_cancel_recv *** * * Cancel a read operation. * Its either the current reader or one of the waiting readers. */ static -ERL_NIF_TERM ncancel_recv(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - ERL_NIF_TERM opRef) +ERL_NIF_TERM esock_cancel_recv(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM opRef) { ERL_NIF_TERM res; MLOCK(descP->readMtx); SSDBG( descP, - ("SOCKET", "ncancel_recv -> entry with" + ("SOCKET", "esock_cancel_recv -> entry with" "\r\n opRef: %T" "\r\n %s" "\r\n", opRef, @@ -14038,9 +14450,9 @@ ERL_NIF_TERM ncancel_recv(ErlNifEnv* env, if (descP->currentReaderP != NULL) { if (COMPARE(opRef, descP->currentReader.ref) == 0) { - res = ncancel_recv_current(env, descP, sockRef); + res = esock_cancel_recv_current(env, descP, sockRef); } else { - res = ncancel_recv_waiting(env, descP, opRef); + res = esock_cancel_recv_waiting(env, descP, opRef); } } else { /* Or badarg? */ @@ -14050,7 +14462,7 @@ ERL_NIF_TERM ncancel_recv(ErlNifEnv* env, MUNLOCK(descP->readMtx); SSDBG( descP, - ("SOCKET", "ncancel_recv -> done with result:" + ("SOCKET", "esock_cancel_recv -> done with result:" "\r\n %T" "\r\n", res) ); @@ -14063,31 +14475,31 @@ ERL_NIF_TERM ncancel_recv(ErlNifEnv* env, * in the reader queue). */ static -ERL_NIF_TERM ncancel_recv_current(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef) +ERL_NIF_TERM esock_cancel_recv_current(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef) { ERL_NIF_TERM res; - SSDBG( descP, ("SOCKET", "ncancel_recv_current -> entry\r\n") ); + SSDBG( descP, ("SOCKET", "esock_cancel_recv_current -> entry\r\n") ); - DEMONP("ncancel_recv_current -> current reader", + DEMONP("esock_cancel_recv_current -> current reader", env, descP, &descP->currentReader.mon); - res = ncancel_read_select(env, descP, descP->currentReader.ref); + res = esock_cancel_read_select(env, descP, descP->currentReader.ref); SSDBG( descP, - ("SOCKET", "ncancel_recv_current -> cancel res: %T\r\n", res) ); + ("SOCKET", "esock_cancel_recv_current -> cancel res: %T\r\n", res) ); if (!activate_next_reader(env, descP, sockRef)) { SSDBG( descP, - ("SOCKET", "ncancel_recv_current -> no more readers\r\n") ); + ("SOCKET", "esock_cancel_recv_current -> no more readers\r\n") ); descP->currentReaderP = NULL; descP->currentReader.ref = esock_atom_undefined; enif_set_pid_undefined(&descP->currentReader.pid); esock_monitor_init(&descP->currentReader.mon); } - SSDBG( descP, ("SOCKET", "ncancel_recv_current -> done with result:" + SSDBG( descP, ("SOCKET", "esock_cancel_recv_current -> done with result:" "\r\n %T" "\r\n", res) ); @@ -14099,9 +14511,9 @@ ERL_NIF_TERM ncancel_recv_current(ErlNifEnv* env, * remove them from the reader queue. */ static -ERL_NIF_TERM ncancel_recv_waiting(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM opRef) +ERL_NIF_TERM esock_cancel_recv_waiting(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM opRef) { ErlNifPid caller; @@ -14121,33 +14533,33 @@ ERL_NIF_TERM ncancel_recv_waiting(ErlNifEnv* env, static -ERL_NIF_TERM ncancel_read_select(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM opRef) +ERL_NIF_TERM esock_cancel_read_select(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM opRef) { - return ncancel_mode_select(env, descP, opRef, - ERL_NIF_SELECT_READ, - ERL_NIF_SELECT_READ_CANCELLED); + return esock_cancel_mode_select(env, descP, opRef, + ERL_NIF_SELECT_READ, + ERL_NIF_SELECT_READ_CANCELLED); } static -ERL_NIF_TERM ncancel_write_select(ErlNifEnv* env, +ERL_NIF_TERM esock_cancel_write_select(ErlNifEnv* env, ESockDescriptor* descP, ERL_NIF_TERM opRef) { - return ncancel_mode_select(env, descP, opRef, - ERL_NIF_SELECT_WRITE, - ERL_NIF_SELECT_WRITE_CANCELLED); + return esock_cancel_mode_select(env, descP, opRef, + ERL_NIF_SELECT_WRITE, + ERL_NIF_SELECT_WRITE_CANCELLED); } static -ERL_NIF_TERM ncancel_mode_select(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM opRef, - int smode, - int rmode) +ERL_NIF_TERM esock_cancel_mode_select(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM opRef, + int smode, + int rmode) { int selectRes = esock_select_cancel(env, descP->sock, smode, descP); @@ -14159,7 +14571,8 @@ ERL_NIF_TERM ncancel_mode_select(ErlNifEnv* env, return esock_make_error(env, esock_atom_select_sent); } else { /* Stopped? */ - SSDBG( descP, ("SOCKET", "ncancel_mode_select -> failed: %d (0x%lX)" + SSDBG( descP, ("SOCKET", + "esock_cancel_mode_select -> failed: %d (0x%lX)" "\r\n", selectRes, selectRes) ); return esock_make_error(env, esock_atom_einval); } @@ -14311,8 +14724,12 @@ ERL_NIF_TERM send_check_ok(ErlNifEnv* env, ssize_t dataSize, ERL_NIF_TERM sockRef) { - cnt_inc(&descP->writePkgCnt, 1); - cnt_inc(&descP->writeByteCnt, written); + // cnt_inc(&descP->writePkgCnt, 1); + SOCK_CNT_INC(env, descP, sockRef, + atom_write_pkg, &descP->writePkgCnt, 1); + // cnt_inc(&descP->writeByteCnt, written); + SOCK_CNT_INC(env, descP, sockRef, + atom_write_byte, &descP->writeByteCnt, written); if (descP->currentWriterP != NULL) { DEMONP("send_check_ok -> current writer", @@ -14358,7 +14775,8 @@ ERL_NIF_TERM send_check_fail(ErlNifEnv* env, ERL_NIF_TERM reason; req.env = NULL; - cnt_inc(&descP->writeFails, 1); + // cnt_inc(&descP->writeFails, 1); + SOCK_CNT_INC(env, descP, sockRef, atom_write_fails, &descP->writeFails, 1); SSDBG( descP, ("SOCKET", "send_check_fail -> error: %d\r\n", saveErrno) ); @@ -14423,7 +14841,8 @@ ERL_NIF_TERM send_check_retry(ErlNifEnv* env, } } - cnt_inc(&descP->writeWaits, 1); + // cnt_inc(&descP->writeWaits, 1); + SOCK_CNT_INC(env, descP, sockRef, atom_write_waits, &descP->writeWaits, 1); sres = esock_select_write(env, descP->sock, descP, NULL, sockRef, sendRef); @@ -14685,6 +15104,8 @@ ERL_NIF_TERM recv_check_result(ErlNifEnv* env, res = esock_make_error(env, atom_closed); + SOCK_CNT_INC(env, descP, sockRef, atom_read_fails, &descP->readFails, 1); + /* * When a stream socket peer has performed an orderly shutdown, * the return value will be 0 (the traditional "end-of-file" return). @@ -14831,7 +15252,8 @@ ERL_NIF_TERM recv_check_full_maybe_done(ErlNifEnv* env, { char* xres; - cnt_inc(&descP->readByteCnt, read); + // cnt_inc(&descP->readByteCnt, read); + SOCK_CNT_INC(env, descP, sockRef, atom_read_byte, &descP->readByteCnt, read); if (descP->rNum > 0) { @@ -14840,7 +15262,8 @@ ERL_NIF_TERM recv_check_full_maybe_done(ErlNifEnv* env, descP->rNumCnt = 0; - cnt_inc(&descP->readPkgCnt, 1); + // cnt_inc(&descP->readPkgCnt, 1); + SOCK_CNT_INC(env, descP, sockRef, atom_read_pkg, &descP->readPkgCnt, 1); recv_update_current_reader(env, descP, sockRef); @@ -14888,8 +15311,10 @@ ERL_NIF_TERM recv_check_full_done(ErlNifEnv* env, { ERL_NIF_TERM data; - cnt_inc(&descP->readPkgCnt, 1); - cnt_inc(&descP->readByteCnt, read); + // cnt_inc(&descP->readPkgCnt, 1); + SOCK_CNT_INC(env, descP, sockRef, atom_read_pkg, &descP->readPkgCnt, 1); + // cnt_inc(&descP->readByteCnt, read); + SOCK_CNT_INC(env, descP, sockRef, atom_read_byte, &descP->readByteCnt, read); recv_update_current_reader(env, descP, sockRef); @@ -14926,6 +15351,10 @@ ERL_NIF_TERM recv_check_fail(ErlNifEnv* env, SSDBG( descP, ("SOCKET", "recv_check_fail -> closed\r\n") ); + // This is a bit overkill (to count here), but just in case... + // cnt_inc(&descP->readFails, 1); + SOCK_CNT_INC(env, descP, sockRef, atom_read_fails, &descP->readFails, 1); + res = recv_check_fail_closed(env, descP, sockRef, recvRef); } else if ((saveErrno == ERRNO_BLOCK) || @@ -14940,6 +15369,9 @@ ERL_NIF_TERM recv_check_fail(ErlNifEnv* env, SSDBG( descP, ("SOCKET", "recv_check_fail -> errno: %d\r\n", saveErrno) ); + // cnt_inc(&descP->readFails, 1); + SOCK_CNT_INC(env, descP, sockRef, atom_read_fails, &descP->readFails, 1); + res = recv_check_fail_gen(env, descP, saveErrno, sockRef); } @@ -14978,7 +15410,7 @@ ERL_NIF_TERM recv_check_fail_closed(ErlNifEnv* env, */ descP->closeLocal = FALSE; - descP->state = SOCKET_STATE_CLOSING; + descP->state = ESOCK_STATE_CLOSING; recv_error_current_reader(env, descP, sockRef, res); @@ -15103,8 +15535,10 @@ ERL_NIF_TERM recv_check_partial_done(ErlNifEnv* env, ERL_NIF_TERM data; descP->rNumCnt = 0; - cnt_inc(&descP->readPkgCnt, 1); - cnt_inc(&descP->readByteCnt, read); + // cnt_inc(&descP->readPkgCnt, 1); + SOCK_CNT_INC(env, descP, sockRef, atom_read_pkg, &descP->readPkgCnt, 1); + // cnt_inc(&descP->readByteCnt, read); + SOCK_CNT_INC(env, descP, sockRef, atom_read_byte, &descP->readByteCnt, read); recv_update_current_reader(env, descP, sockRef); @@ -15147,7 +15581,8 @@ ERL_NIF_TERM recv_check_partial_part(ErlNifEnv* env, data = MKBIN(env, bufP); data = MKSBIN(env, data, 0, read); - cnt_inc(&descP->readByteCnt, read); + // cnt_inc(&descP->readByteCnt, read); + SOCK_CNT_INC(env, descP, sockRef, atom_read_byte, &descP->readByteCnt, read); /* SELECT for more data */ @@ -15234,6 +15669,12 @@ ERL_NIF_TERM recvfrom_check_result(ErlNifEnv* env, data = MKSBIN(env, data, 0, read); } + // cnt_inc(&descP->readPkgCnt, 1); + SOCK_CNT_INC(env, descP, sockRef, atom_read_pkg, &descP->readPkgCnt, 1); + // cnt_inc(&descP->readByteCnt, read); + SOCK_CNT_INC(env, descP, sockRef, atom_read_byte, + &descP->readByteCnt, read); + recv_update_current_reader(env, descP, sockRef); res = esock_make_ok2(env, MKT2(env, eSockAddr, data)); @@ -15291,6 +15732,7 @@ ERL_NIF_TERM recvmsg_check_result(ErlNifEnv* env, * *We* do never actually try to read 0 bytes from a stream socket! */ + SOCK_CNT_INC(env, descP, sockRef, atom_read_fails, &descP->readFails, 1); FREE_BIN(dataBufP); FREE_BIN(ctrlBufP); @@ -15361,6 +15803,21 @@ ERL_NIF_TERM recvmsg_check_msg(ErlNifEnv* env, "recvmsg_check_result -> " "(msghdr) encode failed: %s\r\n", xres) ); + /* So this is a bit strange. We did "successfully" read 'read' bytes, + * but then we fail to process the message header. So what counters + * shall we increment? + * Only failure? + * Or only success (pkg and byte), since the read was "ok" (or was it?) + * Or all of them? + * + * For now, we increment all three... + */ + + SOCK_CNT_INC(env, descP, sockRef, atom_read_fails, &descP->readFails, 1); + SOCK_CNT_INC(env, descP, sockRef, atom_read_pkg, &descP->readPkgCnt, 1); + SOCK_CNT_INC(env, descP, sockRef, atom_read_byte, + &descP->readByteCnt, read); + recv_update_current_reader(env, descP, sockRef); FREE_BIN(dataBufP); FREE_BIN(ctrlBufP); @@ -15372,6 +15829,10 @@ ERL_NIF_TERM recvmsg_check_msg(ErlNifEnv* env, SSDBG( descP, ("SOCKET", "recvmsg_check_result -> (msghdr) encode ok\r\n") ); + SOCK_CNT_INC(env, descP, sockRef, atom_read_pkg, &descP->readPkgCnt, 1); + SOCK_CNT_INC(env, descP, sockRef, atom_read_byte, + &descP->readByteCnt, read); + recv_update_current_reader(env, descP, sockRef); res = esock_make_ok2(env, eMsgHdr); @@ -16969,11 +17430,11 @@ BOOLEAN_T decode_native_get_opt(ErlNifEnv* env, ERL_NIF_TERM eVal, if (COMPARE(nativeOptT[1], atom_int) == 0) { SGDBG( ("SOCKET", "decode_native_get_opt -> int\r\n") ); - *valueType = SOCKET_OPT_VALUE_TYPE_INT; + *valueType = ESOCK_OPT_VALUE_TYPE_INT; *valueSz = sizeof(int); // Just to be sure } else if (COMPARE(nativeOptT[1], atom_bool) == 0) { SGDBG( ("SOCKET", "decode_native_get_opt -> bool\r\n") ); - *valueType = SOCKET_OPT_VALUE_TYPE_BOOL; + *valueType = ESOCK_OPT_VALUE_TYPE_BOOL; *valueSz = sizeof(int); // Just to be sure } else { return FALSE; @@ -16981,7 +17442,7 @@ BOOLEAN_T decode_native_get_opt(ErlNifEnv* env, ERL_NIF_TERM eVal, } else if (IS_NUM(env, nativeOptT[1])) { if (GET_INT(env, nativeOptT[1], valueSz)) { SGDBG( ("SOCKET", "decode_native_get_opt -> unspec\r\n") ); - *valueType = SOCKET_OPT_VALUE_TYPE_UNSPEC; + *valueType = ESOCK_OPT_VALUE_TYPE_UNSPEC; } else { return FALSE; } @@ -17048,7 +17509,7 @@ ESockDescriptor* alloc_descriptor(SOCKET sock, HANDLE event) { ESockDescriptor* descP; - if ((descP = enif_alloc_resource(sockets, sizeof(ESockDescriptor))) != NULL) { + if ((descP = enif_alloc_resource(esocks, sizeof(ESockDescriptor))) != NULL) { char buf[64]; /* Buffer used for building the mutex name */ descP->pattern = ESOCK_DESC_PATTERN_CREATED; @@ -17086,6 +17547,7 @@ ESockDescriptor* alloc_descriptor(SOCKET sock, HANDLE event) descP->readByteCnt = 0; descP->readTries = 0; descP->readWaits = 0; + descP->readFails = 0; sprintf(buf, "esock[acc,%d]", sock); descP->accMtx = MCREATE(buf); @@ -17106,13 +17568,13 @@ ESockDescriptor* alloc_descriptor(SOCKET sock, HANDLE event) sprintf(buf, "esock[cfg,%d]", sock); descP->cfgMtx = MCREATE(buf); - descP->rBufSz = SOCKET_RECV_BUFFER_SIZE_DEFAULT; + descP->rBufSz = ESOCK_RECV_BUFFER_SIZE_DEFAULT; descP->rNum = 0; descP->rNumCnt = 0; - descP->rCtrlSz = SOCKET_RECV_CTRL_BUFFER_SIZE_DEFAULT; - descP->wCtrlSz = SOCKET_SEND_CTRL_BUFFER_SIZE_DEFAULT; + descP->rCtrlSz = ESOCK_RECV_CTRL_BUFFER_SIZE_DEFAULT; + descP->wCtrlSz = ESOCK_SEND_CTRL_BUFFER_SIZE_DEFAULT; descP->iow = FALSE; - descP->dbg = SOCKET_DEBUG_DEFAULT; + descP->dbg = ESOCK_DEBUG_DEFAULT; descP->sock = sock; descP->event = event; @@ -17239,17 +17701,17 @@ static BOOLEAN_T edomain2domain(int edomain, int* domain) { switch (edomain) { - case SOCKET_DOMAIN_INET: + case ESOCK_DOMAIN_INET: *domain = AF_INET; break; #if defined(HAVE_IN6) && defined(AF_INET6) - case SOCKET_DOMAIN_INET6: + case ESOCK_DOMAIN_INET6: *domain = AF_INET6; break; #endif #ifdef HAVE_SYS_UN_H - case SOCKET_DOMAIN_LOCAL: + case ESOCK_DOMAIN_LOCAL: *domain = AF_UNIX; break; #endif @@ -17271,20 +17733,20 @@ static BOOLEAN_T etype2type(int etype, int* type) { switch (etype) { - case SOCKET_TYPE_STREAM: + case ESOCK_TYPE_STREAM: *type = SOCK_STREAM; break; - case SOCKET_TYPE_DGRAM: + case ESOCK_TYPE_DGRAM: *type = SOCK_DGRAM; break; - case SOCKET_TYPE_RAW: + case ESOCK_TYPE_RAW: *type = SOCK_RAW; break; #ifdef HAVE_SCTP - case SOCKET_TYPE_SEQPACKET: + case ESOCK_TYPE_SEQPACKET: *type = SOCK_SEQPACKET; break; #endif @@ -17316,33 +17778,33 @@ BOOLEAN_T eproto2proto(ErlNifEnv* env, } switch (ep) { - case SOCKET_PROTOCOL_DEFAULT: + case ESOCK_PROTOCOL_DEFAULT: *proto = 0; // default - note that _IP also has the value 0... break; - case SOCKET_PROTOCOL_IP: + case ESOCK_PROTOCOL_IP: *proto = IPPROTO_IP; break; - case SOCKET_PROTOCOL_TCP: + case ESOCK_PROTOCOL_TCP: *proto = IPPROTO_TCP; break; - case SOCKET_PROTOCOL_UDP: + case ESOCK_PROTOCOL_UDP: *proto = IPPROTO_UDP; break; #if defined(HAVE_SCTP) - case SOCKET_PROTOCOL_SCTP: + case ESOCK_PROTOCOL_SCTP: *proto = IPPROTO_SCTP; break; #endif - case SOCKET_PROTOCOL_ICMP: + case ESOCK_PROTOCOL_ICMP: *proto = IPPROTO_ICMP; break; - case SOCKET_PROTOCOL_IGMP: + case ESOCK_PROTOCOL_IGMP: *proto = IPPROTO_IGMP; break; @@ -17451,47 +17913,47 @@ BOOLEAN_T esendflags2sendflags(unsigned int eflags, int* flags) return TRUE; } - for (ef = SOCKET_SEND_FLAG_LOW; ef <= SOCKET_SEND_FLAG_HIGH; ef++) { + for (ef = ESOCK_SEND_FLAG_LOW; ef <= ESOCK_SEND_FLAG_HIGH; ef++) { switch (ef) { #if defined(MSG_CONFIRM) - case SOCKET_SEND_FLAG_CONFIRM: - if ((1 << SOCKET_SEND_FLAG_CONFIRM) & eflags) + case ESOCK_SEND_FLAG_CONFIRM: + if ((1 << ESOCK_SEND_FLAG_CONFIRM) & eflags) tmp |= MSG_CONFIRM; break; #endif #if defined(MSG_DONTROUTE) - case SOCKET_SEND_FLAG_DONTROUTE: - if ((1 << SOCKET_SEND_FLAG_DONTROUTE) & eflags) + case ESOCK_SEND_FLAG_DONTROUTE: + if ((1 << ESOCK_SEND_FLAG_DONTROUTE) & eflags) tmp |= MSG_DONTROUTE; break; #endif #if defined(MSG_EOR) - case SOCKET_SEND_FLAG_EOR: - if ((1 << SOCKET_SEND_FLAG_EOR) & eflags) + case ESOCK_SEND_FLAG_EOR: + if ((1 << ESOCK_SEND_FLAG_EOR) & eflags) tmp |= MSG_EOR; break; #endif #if defined(MSG_MORE) - case SOCKET_SEND_FLAG_MORE: - if ((1 << SOCKET_SEND_FLAG_MORE) & eflags) + case ESOCK_SEND_FLAG_MORE: + if ((1 << ESOCK_SEND_FLAG_MORE) & eflags) tmp |= MSG_MORE; break; #endif #if defined(MSG_NOSIGNAL) - case SOCKET_SEND_FLAG_NOSIGNAL: - if ((1 << SOCKET_SEND_FLAG_NOSIGNAL) & eflags) + case ESOCK_SEND_FLAG_NOSIGNAL: + if ((1 << ESOCK_SEND_FLAG_NOSIGNAL) & eflags) tmp |= MSG_NOSIGNAL; break; #endif #if defined(MSG_OOB) - case SOCKET_SEND_FLAG_OOB: - if ((1 << SOCKET_SEND_FLAG_OOB) & eflags) + case ESOCK_SEND_FLAG_OOB: + if ((1 << ESOCK_SEND_FLAG_OOB) & eflags) tmp |= MSG_OOB; break; #endif @@ -17527,7 +17989,7 @@ BOOLEAN_T erecvflags2recvflags(unsigned int eflags, int* flags) return TRUE; } - for (ef = SOCKET_RECV_FLAG_LOW; ef <= SOCKET_RECV_FLAG_HIGH; ef++) { + for (ef = ESOCK_RECV_FLAG_LOW; ef <= ESOCK_RECV_FLAG_HIGH; ef++) { SGDBG( ("SOCKET", "erecvflags2recvflags -> iteration" "\r\n ef: %d" @@ -17536,22 +17998,22 @@ BOOLEAN_T erecvflags2recvflags(unsigned int eflags, int* flags) switch (ef) { #if defined(MSG_CMSG_CLOEXEC) - case SOCKET_RECV_FLAG_CMSG_CLOEXEC: - if ((1 << SOCKET_RECV_FLAG_CMSG_CLOEXEC) & eflags) + case ESOCK_RECV_FLAG_CMSG_CLOEXEC: + if ((1 << ESOCK_RECV_FLAG_CMSG_CLOEXEC) & eflags) tmp |= MSG_CMSG_CLOEXEC; break; #endif #if defined(MSG_ERRQUEUE) - case SOCKET_RECV_FLAG_ERRQUEUE: - if ((1 << SOCKET_RECV_FLAG_ERRQUEUE) & eflags) + case ESOCK_RECV_FLAG_ERRQUEUE: + if ((1 << ESOCK_RECV_FLAG_ERRQUEUE) & eflags) tmp |= MSG_ERRQUEUE; break; #endif #if defined(MSG_OOB) - case SOCKET_RECV_FLAG_OOB: - if ((1 << SOCKET_RECV_FLAG_OOB) & eflags) + case ESOCK_RECV_FLAG_OOB: + if ((1 << ESOCK_RECV_FLAG_OOB) & eflags) tmp |= MSG_OOB; break; #endif @@ -17564,15 +18026,15 @@ BOOLEAN_T erecvflags2recvflags(unsigned int eflags, int* flags) * </KOLLA> */ #if defined(MSG_PEEK) - case SOCKET_RECV_FLAG_PEEK: - if ((1 << SOCKET_RECV_FLAG_PEEK) & eflags) + case ESOCK_RECV_FLAG_PEEK: + if ((1 << ESOCK_RECV_FLAG_PEEK) & eflags) tmp |= MSG_PEEK; break; #endif #if defined(MSG_TRUNC) - case SOCKET_RECV_FLAG_TRUNC: - if ((1 << SOCKET_RECV_FLAG_TRUNC) & eflags) + case ESOCK_RECV_FLAG_TRUNC: + if ((1 << ESOCK_RECV_FLAG_TRUNC) & eflags) tmp |= MSG_TRUNC; break; #endif @@ -17598,15 +18060,15 @@ static BOOLEAN_T ehow2how(unsigned int ehow, int* how) { switch (ehow) { - case SOCKET_SHUTDOWN_HOW_RD: + case ESOCK_SHUTDOWN_HOW_RD: *how = SHUT_RD; break; - case SOCKET_SHUTDOWN_HOW_WR: + case ESOCK_SHUTDOWN_HOW_WR: *how = SHUT_WR; break; - case SOCKET_SHUTDOWN_HOW_RDWR: + case ESOCK_SHUTDOWN_HOW_RDWR: *how = SHUT_RDWR; break; @@ -17619,6 +18081,59 @@ BOOLEAN_T ehow2how(unsigned int ehow, int* how) +/* ecommand2command - convert erlang command to "native" command (and data) + */ +static +BOOLEAN_T ecommand2command(ErlNifEnv* env, + ERL_NIF_TERM ecommand, + Uint16* command, + ERL_NIF_TERM* edata) +{ + size_t sz; + ERL_NIF_TERM ecmd; + + if (!IS_MAP(env, ecommand)) { + SGDBG( ("SOCKET", "ecommand2command -> (e)command not a map\r\n") ); + return FALSE; + } + + /* The map shall have exactly two attrbutes: + * 'command' and 'data' + */ + if (!enif_get_map_size(env, ecommand, &sz) || (sz != 2)) { + SGDBG( ("SOCKET", "ecommand2command -> comamnd map size invalid\r\n") ); + return FALSE; + } + + /* Get the command value, and transform into integer + * (might as well do that, since theer is no point in + * extracting the data if command is invalid). + */ + if (!GET_MAP_VAL(env, ecommand, esock_atom_command, &ecmd)) { + SGDBG( ("SOCKET", "ecommand2command -> command attribute not found\r\n") ); + return FALSE; + } + if (COMPARE(ecmd, esock_atom_debug) == 0) { + *command = ESOCK_CMD_DEBUG; + } else { + SGDBG( ("SOCKET", "ecommand2command -> unknown command %T\r\n", ecmd) ); + return FALSE; + } + + /* Get the command data value, we do *not* convert it to + * the native form (here) since it may "in theory" be complex. + */ + if (!GET_MAP_VAL(env, ecommand, esock_atom_data, edata)) { + SGDBG( ("SOCKET", "ecommand2command -> (command) data not found\r\n") ); + return FALSE; + } + + return TRUE; +} + + + + #if defined(HAVE_SYS_UN_H) || defined(SO_BINDTODEVICE) /* strnlen doesn't exist everywhere */ /* @@ -17634,6 +18149,25 @@ size_t my_strnlen(const char *s, size_t maxlen) #endif +/* Send an counter wrap message to the controlling process: + * A message in the form: + * + * {'$socket', Socket, counter_wrap, Counter :: atom()} + * + * This message will only be sent if the iow (Inform On Wrap) is TRUE. + */ +static +char* esock_send_wrap_msg(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM cnt) +{ + ERL_NIF_TERM msg = mk_wrap_msg(env, sockRef, cnt); + + return esock_send_msg(env, &descP->ctrlPid, msg, NULL); +} + + /* Send an close message to the specified process: * A message in the form: * @@ -17731,6 +18265,22 @@ ERL_NIF_TERM mk_abort_msg(ErlNifEnv* env, } +/* *** mk_wrap_msg *** + * + * Construct a counter wrap (socket) message. It has the form: + * + * {'$socket', Socket, counter_wrap, Counter} + * + */ +static +ERL_NIF_TERM mk_wrap_msg(ErlNifEnv* env, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM cnt) +{ + return mk_socket_msg(env, sockRef, atom_counter_wrap, cnt); +} + + /* *** mk_close_msg *** * * Construct a close (socket) message. It has the form: @@ -18386,11 +18936,11 @@ static void free_request_queue(ESockRequestQueue* q) } /* ========================================================================= - * socket_dtor - Callback function for resource destructor + * esock_dtor - Callback function for resource destructor * */ static -void socket_dtor(ErlNifEnv* env, void* obj) +void esock_dtor(ErlNifEnv* env, void* obj) { #if !defined(__WIN32__) ESockDescriptor* descP = (ESockDescriptor*) obj; @@ -18417,14 +18967,14 @@ void socket_dtor(ErlNifEnv* env, void* obj) free_request_queue(&descP->writersQ); free_request_queue(&descP->acceptorsQ); - descP->state = SOCKET_STATE_DTOR; + descP->state = ESOCK_STATE_DTOR; descP->pattern = ESOCK_DESC_PATTERN_DTOR; #endif } /* ========================================================================= - * socket_stop - Callback function for resource stop + * esock_stop - Callback function for resource stop * * When the socket is stopped, we need to inform: * @@ -18439,14 +18989,14 @@ void socket_dtor(ErlNifEnv* env, void* obj) * */ static -void socket_stop(ErlNifEnv* env, void* obj, int fd, int is_direct_call) +void esock_stop(ErlNifEnv* env, void* obj, int fd, int is_direct_call) { #if !defined(__WIN32__) ESockDescriptor* descP = (ESockDescriptor*) obj; ERL_NIF_TERM sockRef; SSDBG( descP, - ("SOCKET", "socket_stop -> entry when %s" + ("SOCKET", "esock_stop -> entry when %s" "\r\n sock: %d (%d)" "\r\n", ((is_direct_call) ? "called" : "scheduled"), descP->sock, fd) ); @@ -18459,7 +19009,7 @@ void socket_stop(ErlNifEnv* env, void* obj, int fd, int is_direct_call) MLOCK(descP->cfgMtx); if (!is_direct_call) MLOCK(descP->closeMtx); - SSDBG( descP, ("SOCKET", "socket_stop -> " + SSDBG( descP, ("SOCKET", "esock_stop -> " "[%d, %T] all mutex(s) locked when counters:" "\r\n writePkgCnt: %u" "\r\n writeByteCnt: %u" @@ -18483,7 +19033,7 @@ void socket_stop(ErlNifEnv* env, void* obj, int fd, int is_direct_call) descP->readWaits) ); sockRef = enif_make_resource(env, descP); - descP->state = SOCKET_STATE_CLOSING; // Just in case...??? + descP->state = ESOCK_STATE_CLOSING; // Just in case...??? descP->isReadable = FALSE; descP->isWritable = FALSE; @@ -18494,7 +19044,7 @@ void socket_stop(ErlNifEnv* env, void* obj, int fd, int is_direct_call) * there is no point to demonitor. Also, we do not actually * have a monitor in that case... */ - DEMONP("socket_stop -> ctrl", env, descP, &descP->ctrlMon); + DEMONP("esock_stop -> ctrl", env, descP, &descP->ctrlMon); @@ -18511,12 +19061,12 @@ void socket_stop(ErlNifEnv* env, void* obj, int fd, int is_direct_call) * writers waiting. */ - socket_stop_handle_current(env, - "writer", - descP, sockRef, &descP->currentWriter); + esock_stop_handle_current(env, + "writer", + descP, sockRef, &descP->currentWriter); /* And also deal with the waiting writers (in the same way) */ - SSDBG( descP, ("SOCKET", "socket_stop -> handle waiting writer(s)\r\n") ); + SSDBG( descP, ("SOCKET", "esock_stop -> handle waiting writer(s)\r\n") ); inform_waiting_procs(env, "writer", descP, sockRef, &descP->writersQ, TRUE, atom_closed); } @@ -18535,12 +19085,12 @@ void socket_stop(ErlNifEnv* env, void* obj, int fd, int is_direct_call) * readers waiting. */ - socket_stop_handle_current(env, - "reader", - descP, sockRef, &descP->currentReader); + esock_stop_handle_current(env, + "reader", + descP, sockRef, &descP->currentReader); /* And also deal with the waiting readers (in the same way) */ - SSDBG( descP, ("SOCKET", "socket_stop -> handle waiting reader(s)\r\n") ); + SSDBG( descP, ("SOCKET", "esock_stop -> handle waiting reader(s)\r\n") ); inform_waiting_procs(env, "reader", descP, sockRef, &descP->readersQ, TRUE, atom_closed); } @@ -18560,12 +19110,12 @@ void socket_stop(ErlNifEnv* env, void* obj, int fd, int is_direct_call) * acceptors waiting. */ - socket_stop_handle_current(env, - "acceptor", - descP, sockRef, &descP->currentAcceptor); - + esock_stop_handle_current(env, + "acceptor", + descP, sockRef, &descP->currentAcceptor); + /* And also deal with the waiting acceptors (in the same way) */ - SSDBG( descP, ("SOCKET", "socket_stop -> handle waiting acceptor(s)\r\n") ); + SSDBG( descP, ("SOCKET", "esock_stop -> handle waiting acceptor(s)\r\n") ); inform_waiting_procs(env, "acceptor", descP, sockRef, &descP->acceptorsQ, TRUE, atom_closed); } @@ -18589,7 +19139,7 @@ void socket_stop(ErlNifEnv* env, void* obj, int fd, int is_direct_call) esock_send_close_msg(env, descP, &descP->closerPid); - DEMONP("socket_stop -> closer", env, descP, &descP->closerMon); + DEMONP("esock_stop -> closer", env, descP, &descP->closerMon); } else { @@ -18598,14 +19148,14 @@ void socket_stop(ErlNifEnv* env, void* obj, int fd, int is_direct_call) */ if (descP->closeEnv != NULL) - esock_free_env("socket_stop - close-env", descP->closeEnv); + esock_free_env("esock_stop - close-env", descP->closeEnv); } } } - SSDBG( descP, ("SOCKET", "socket_stop -> unlock all mutex(s)\r\n") ); + SSDBG( descP, ("SOCKET", "esock_stop -> unlock all mutex(s)\r\n") ); if (!is_direct_call) MUNLOCK(descP->closeMtx); MUNLOCK(descP->cfgMtx); @@ -18614,33 +19164,33 @@ void socket_stop(ErlNifEnv* env, void* obj, int fd, int is_direct_call) MUNLOCK(descP->writeMtx); SSDBG( descP, - ("SOCKET", "socket_stop -> done (%d, %d)\r\n", descP->sock, fd) ); + ("SOCKET", "esock_stop -> done (%d, %d)\r\n", descP->sock, fd) ); #endif // if !defined(__WIN32__) } -/* *** socket_stop_handle_current *** +/* *** esock_stop_handle_current *** * * Handle current requestor (reader, writer or acceptor) during * socket stop. */ #if !defined(__WIN32__) static -void socket_stop_handle_current(ErlNifEnv* env, - const char* role, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - ESockRequestor* reqP) +void esock_stop_handle_current(ErlNifEnv* env, + const char* role, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ESockRequestor* reqP) { - SSDBG( descP, ("SOCKET", "socket_stop -> handle current %s\r\n", role) ); + SSDBG( descP, ("SOCKET", "esock_stop -> handle current %s\r\n", role) ); - DEMONP("socket_stop_handle_current", env, descP, &reqP->mon); + DEMONP("esock_stop_handle_current", env, descP, &reqP->mon); if (COMPARE_PIDS(&descP->closerPid, &reqP->pid) != 0) { - SSDBG( descP, ("SOCKET", "socket_stop_handle_current -> " + SSDBG( descP, ("SOCKET", "esock_stop_handle_current -> " "send abort message to current %s %T\r\n", role, reqP->pid) ); @@ -18725,21 +19275,21 @@ void inform_waiting_procs(ErlNifEnv* env, /* ========================================================================= - * socket_down - Callback function for resource down (monitored processes) + * esock_down - Callback function for resource down (monitored processes) * */ static -void socket_down(ErlNifEnv* env, - void* obj, - const ErlNifPid* pid, - const ErlNifMonitor* mon) +void esock_down(ErlNifEnv* env, + void* obj, + const ErlNifPid* pid, + const ErlNifMonitor* mon) { #if !defined(__WIN32__) ESockDescriptor* descP = (ESockDescriptor*) obj; int sres; ERL_NIF_TERM sockRef; - SSDBG( descP, ("SOCKET", "socket_down -> entry with" + SSDBG( descP, ("SOCKET", "esock_down -> entry with" "\r\n sock: %d" "\r\n pid: %T" "\r\n Close: %s (%s)" @@ -18757,9 +19307,9 @@ void socket_down(ErlNifEnv* env, */ SSDBG( descP, - ("SOCKET", "socket_down -> controlling process exit\r\n") ); + ("SOCKET", "esock_down -> controlling process exit\r\n") ); - descP->state = SOCKET_STATE_CLOSING; + descP->state = ESOCK_STATE_CLOSING; descP->closeLocal = TRUE; descP->closerPid = *pid; MON_INIT(&descP->closerMon); @@ -18771,10 +19321,10 @@ void socket_down(ErlNifEnv* env, /* We are done - we can finalize (socket close) directly */ SSDBG( descP, ("SOCKET", - "socket_down -> [%d] stop called\r\n", descP->sock) ); + "esock_down -> [%d] stop called\r\n", descP->sock) ); dec_socket(descP->domain, descP->type, descP->protocol); - descP->state = SOCKET_STATE_CLOSED; + descP->state = ESOCK_STATE_CLOSED; /* And finally close the socket. * Since we close the socket because of an exiting owner, @@ -18797,7 +19347,7 @@ void socket_down(ErlNifEnv* env, descP->sock = INVALID_SOCKET; descP->event = INVALID_EVENT; - descP->state = SOCKET_STATE_CLOSED; + descP->state = ESOCK_STATE_CLOSED; } else if (sres & ERL_NIF_SELECT_STOP_SCHEDULED) { @@ -18808,7 +19358,7 @@ void socket_down(ErlNifEnv* env, */ SSDBG( descP, ("SOCKET", - "socket_down -> [%d] stop scheduled\r\n", + "esock_down -> [%d] stop scheduled\r\n", descP->sock) ); dec_socket(descP->domain, descP->type, descP->protocol); @@ -18848,9 +19398,9 @@ void socket_down(ErlNifEnv* env, * The same goes for the monitor (connMon). */ - descP->state = SOCKET_STATE_OPEN; /* restore state */ + descP->state = ESOCK_STATE_OPEN; /* restore state */ enif_set_pid_undefined(&descP->connPid); - DEMONP("socket_down -> connector", + DEMONP("esock_down -> connector", env, descP, &descP->connMon); } else { @@ -18861,43 +19411,43 @@ void socket_down(ErlNifEnv* env, * */ - SSDBG( descP, ("SOCKET", "socket_down -> other process term\r\n") ); + SSDBG( descP, ("SOCKET", "esock_down -> other process term\r\n") ); sockRef = enif_make_resource(env, descP); MLOCK(descP->accMtx); if (descP->currentAcceptorP != NULL) - socket_down_acceptor(env, descP, sockRef, pid); + esock_down_acceptor(env, descP, sockRef, pid); MUNLOCK(descP->accMtx); MLOCK(descP->writeMtx); if (descP->currentWriterP != NULL) - socket_down_writer(env, descP, sockRef, pid); + esock_down_writer(env, descP, sockRef, pid); MUNLOCK(descP->writeMtx); MLOCK(descP->readMtx); if (descP->currentReaderP != NULL) - socket_down_reader(env, descP, sockRef, pid); + esock_down_reader(env, descP, sockRef, pid); MUNLOCK(descP->readMtx); } } - SSDBG( descP, ("SOCKET", "socket_down -> done\r\n") ); + SSDBG( descP, ("SOCKET", "esock_down -> done\r\n") ); #endif // if !defined(__WIN32__) } -/* *** socket_down_acceptor *** +/* *** esock_down_acceptor *** * * Check and then handle a downed acceptor process. * */ #if !defined(__WIN32__) static -void socket_down_acceptor(ErlNifEnv* env, +void esock_down_acceptor(ErlNifEnv* env, ESockDescriptor* descP, ERL_NIF_TERM sockRef, const ErlNifPid* pid) @@ -18905,15 +19455,15 @@ void socket_down_acceptor(ErlNifEnv* env, if (COMPARE_PIDS(&descP->currentAcceptor.pid, pid) == 0) { SSDBG( descP, ("SOCKET", - "socket_down_acceptor -> " + "esock_down_acceptor -> " "current acceptor - try activate next\r\n") ); if (!activate_next_acceptor(env, descP, sockRef)) { SSDBG( descP, - ("SOCKET", "socket_down_acceptor -> no more writers\r\n") ); + ("SOCKET", "esock_down_acceptor -> no more writers\r\n") ); - descP->state = SOCKET_STATE_LISTENING; + descP->state = ESOCK_STATE_LISTENING; descP->currentAcceptorP = NULL; descP->currentAcceptor.ref = esock_atom_undefined; @@ -18926,7 +19476,7 @@ void socket_down_acceptor(ErlNifEnv* env, /* Maybe unqueue one of the waiting acceptors */ SSDBG( descP, ("SOCKET", - "socket_down_acceptor -> " + "esock_down_acceptor -> " "not current acceptor - maybe a waiting acceptor\r\n") ); acceptor_unqueue(env, descP, pid); @@ -18936,13 +19486,13 @@ void socket_down_acceptor(ErlNifEnv* env, -/* *** socket_down_writer *** +/* *** esock_down_writer *** * * Check and then handle a downed writer process. * */ static -void socket_down_writer(ErlNifEnv* env, +void esock_down_writer(ErlNifEnv* env, ESockDescriptor* descP, ERL_NIF_TERM sockRef, const ErlNifPid* pid) @@ -18950,12 +19500,12 @@ void socket_down_writer(ErlNifEnv* env, if (COMPARE_PIDS(&descP->currentWriter.pid, pid) == 0) { SSDBG( descP, ("SOCKET", - "socket_down_writer -> " + "esock_down_writer -> " "current writer - try activate next\r\n") ); if (!activate_next_writer(env, descP, sockRef)) { SSDBG( descP, ("SOCKET", - "socket_down_writer -> no active writer\r\n") ); + "esock_down_writer -> no active writer\r\n") ); descP->currentWriterP = NULL; descP->currentWriter.ref = esock_atom_undefined; enif_set_pid_undefined(&descP->currentWriter.pid); @@ -18967,7 +19517,7 @@ void socket_down_writer(ErlNifEnv* env, /* Maybe unqueue one of the waiting writer(s) */ SSDBG( descP, ("SOCKET", - "socket_down_writer -> " + "esock_down_writer -> " "not current writer - maybe a waiting writer\r\n") ); writer_unqueue(env, descP, pid); @@ -18977,13 +19527,13 @@ void socket_down_writer(ErlNifEnv* env, -/* *** socket_down_reader *** +/* *** esock_down_reader *** * * Check and then handle a downed reader process. * */ static -void socket_down_reader(ErlNifEnv* env, +void esock_down_reader(ErlNifEnv* env, ESockDescriptor* descP, ERL_NIF_TERM sockRef, const ErlNifPid* pid) @@ -18991,12 +19541,13 @@ void socket_down_reader(ErlNifEnv* env, if (COMPARE_PIDS(&descP->currentReader.pid, pid) == 0) { SSDBG( descP, ("SOCKET", - "socket_down_reader -> " + "esock_down_reader -> " "current reader - try activate next\r\n") ); if (!activate_next_reader(env, descP, sockRef)) { SSDBG( descP, - ("SOCKET", "ncancel_recv_current -> no more readers\r\n") ); + ("SOCKET", + "esock_down_reader -> no more readers\r\n") ); descP->currentReaderP = NULL; descP->currentReader.ref = esock_atom_undefined; enif_set_pid_undefined(&descP->currentReader.pid); @@ -19008,7 +19559,7 @@ void socket_down_reader(ErlNifEnv* env, /* Maybe unqueue one of the waiting reader(s) */ SSDBG( descP, ("SOCKET", - "socket_down_reader -> " + "esock_down_reader -> " "not current reader - maybe a waiting reader\r\n") ); reader_unqueue(env, descP, pid); @@ -19024,16 +19575,16 @@ void socket_down_reader(ErlNifEnv* env, */ static -ErlNifFunc socket_funcs[] = +ErlNifFunc esock_funcs[] = { // Some utility and support functions {"nif_info", 0, nif_info, 0}, + {"nif_info", 1, nif_info, 0}, {"nif_supports", 1, nif_supports, 0}, - // {"nif_debug", 1, nif_debug, 0}, - // {"nif_command", 1, nif_command, 0}, + {"nif_command", 1, nif_command, 0}, // The proper "socket" interface - // nif_open/1 is used when we already have a file descriptor + // nif_open/1 is (supposed to be) used when we already have a file descriptor // {"nif_open", 1, nif_open, 0}, {"nif_open", 4, nif_open, 0}, {"nif_bind", 2, nif_bind, 0}, @@ -19076,7 +19627,7 @@ BOOLEAN_T extract_debug(ErlNifEnv* env, */ ERL_NIF_TERM debug = MKA(env, "debug"); - return esock_extract_bool_from_map(env, map, debug, SOCKET_GLOBAL_DEBUG_DEFAULT); + return esock_extract_bool_from_map(env, map, debug, ESOCK_GLOBAL_DEBUG_DEFAULT); } static @@ -19089,7 +19640,7 @@ BOOLEAN_T extract_iow(ErlNifEnv* env, */ ERL_NIF_TERM iow = MKA(env, "iow"); - return esock_extract_bool_from_map(env, map, iow, SOCKET_NIF_IOW_DEFAULT); + return esock_extract_bool_from_map(env, map, iow, ESOCK_NIF_IOW_DEFAULT); } #endif // if !defined(__WIN32__) @@ -19110,7 +19661,7 @@ int on_load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) data.iow = extract_iow(env, load_info); /* +++ Global Counters +++ */ - data.cntMtx = MCREATE("socket[gcnt]"); + data.cntMtx = MCREATE("esock[gcnt]"); data.numSockets = 0; data.numTypeDGrams = 0; data.numTypeStreams = 0; @@ -19137,13 +19688,21 @@ GLOBAL_ERROR_REASON_ATOMS #undef GLOBAL_ATOM_DECL esock_atom_socket_tag = MKA(env, "$socket"); - sockets = enif_open_resource_type_x(env, - "sockets", - &socketInit, - ERL_NIF_RT_CREATE, - NULL); + esocks = enif_open_resource_type_x(env, + "sockets", + &esockInit, + ERL_NIF_RT_CREATE, + NULL); - return !sockets; + return !esocks; } -ERL_NIF_INIT(socket, socket_funcs, on_load, NULL, NULL, NULL) +/* + * MODULE: socket (the erlang API/interface module) + * funcs: esock_funcs (defines the API of this nif) + * load: on_load (load this nif) + * upgrade: NULL (not used) + * NULL: THIS IS NOT USED + * unload: NULL (not used) + */ +ERL_NIF_INIT(socket, esock_funcs, on_load, NULL, NULL, NULL) diff --git a/erts/emulator/nifs/common/socket_util.c b/erts/emulator/nifs/common/socket_util.c index 2740cb51ef..54c310ecc7 100644 --- a/erts/emulator/nifs/common/socket_util.c +++ b/erts/emulator/nifs/common/socket_util.c @@ -741,16 +741,24 @@ char* esock_decode_ip4_address(ErlNifEnv* env, "\r\n", eAddr) ); if (IS_ATOM(env, eAddr)) { - /* This is either 'any' or 'loopback' */ + + /* This is either 'any' | 'broadcast' | 'loopback' */ if (COMPARE(esock_atom_loopback, eAddr) == 0) { - UDBG( ("SUTIL", "esock_decode_ip4_address -> address: lookback\r\n") ); + UDBG( ("SUTIL", + "esock_decode_ip4_address -> address: lookback\r\n") ); addr.s_addr = htonl(INADDR_LOOPBACK); } else if (COMPARE(esock_atom_any, eAddr) == 0) { - UDBG( ("SUTIL", "esock_decode_ip4_address -> address: any\r\n") ); - addr.s_addr = htonl(INADDR_ANY); + UDBG( ("SUTIL", + "esock_decode_ip4_address -> address: any\r\n") ); + addr.s_addr = htonl(INADDR_ANY); + } else if (COMPARE(esock_atom_broadcast, eAddr) == 0) { + UDBG( ("SUTIL", + "esock_decode_ip4_address -> address: broadcast\r\n") ); + addr.s_addr = htonl(INADDR_BROADCAST); } else { - UDBG( ("SUTIL", "esock_decode_ip4_address -> address: unknown\r\n") ); + UDBG( ("SUTIL", + "esock_decode_ip4_address -> address: unknown\r\n") ); return ESOCK_STR_EINVAL; } diff --git a/erts/emulator/nifs/unix/unix_prim_file.c b/erts/emulator/nifs/unix/unix_prim_file.c index 20021b9358..176a9318b2 100644 --- a/erts/emulator/nifs/unix/unix_prim_file.c +++ b/erts/emulator/nifs/unix/unix_prim_file.c @@ -627,6 +627,33 @@ int efile_truncate(efile_data_t *d) { return 1; } +static void build_file_info(struct stat *data, efile_fileinfo_t *result) { + if(S_ISCHR(data->st_mode) || S_ISBLK(data->st_mode)) { + result->type = EFILE_FILETYPE_DEVICE; + } else if(S_ISDIR(data->st_mode)) { + result->type = EFILE_FILETYPE_DIRECTORY; + } else if(S_ISREG(data->st_mode)) { + result->type = EFILE_FILETYPE_REGULAR; + } else if(S_ISLNK(data->st_mode)) { + result->type = EFILE_FILETYPE_SYMLINK; + } else { + result->type = EFILE_FILETYPE_OTHER; + } + + result->a_time = (Sint64)data->st_atime; + result->m_time = (Sint64)data->st_mtime; + result->c_time = (Sint64)data->st_ctime; + result->size = data->st_size; + + result->major_device = data->st_dev; + result->minor_device = data->st_rdev; + result->links = data->st_nlink; + result->inode = data->st_ino; + result->mode = data->st_mode; + result->uid = data->st_uid; + result->gid = data->st_gid; +} + posix_errno_t efile_read_info(const efile_path_t *path, int follow_links, efile_fileinfo_t *result) { struct stat data; @@ -640,30 +667,7 @@ posix_errno_t efile_read_info(const efile_path_t *path, int follow_links, efile_ } } - if(S_ISCHR(data.st_mode) || S_ISBLK(data.st_mode)) { - result->type = EFILE_FILETYPE_DEVICE; - } else if(S_ISDIR(data.st_mode)) { - result->type = EFILE_FILETYPE_DIRECTORY; - } else if(S_ISREG(data.st_mode)) { - result->type = EFILE_FILETYPE_REGULAR; - } else if(S_ISLNK(data.st_mode)) { - result->type = EFILE_FILETYPE_SYMLINK; - } else { - result->type = EFILE_FILETYPE_OTHER; - } - - result->a_time = (Sint64)data.st_atime; - result->m_time = (Sint64)data.st_mtime; - result->c_time = (Sint64)data.st_ctime; - result->size = data.st_size; - - result->major_device = data.st_dev; - result->minor_device = data.st_rdev; - result->links = data.st_nlink; - result->inode = data.st_ino; - result->mode = data.st_mode; - result->uid = data.st_uid; - result->gid = data.st_gid; + build_file_info(&data, result); #ifndef NO_ACCESS result->access = EFILE_ACCESS_NONE; @@ -682,6 +686,56 @@ posix_errno_t efile_read_info(const efile_path_t *path, int follow_links, efile_ return 0; } +static int check_access(struct stat *st) { + int ret = EFILE_ACCESS_NONE; + + if(st->st_uid == getuid()) { + if(st->st_mode & S_IRUSR) { + ret |= EFILE_ACCESS_READ; + } + if(st->st_mode & S_IWUSR) { + ret |= EFILE_ACCESS_WRITE; + } + return ret; + } + + if(st->st_gid == getgid()) { + if(st->st_mode & S_IRGRP) { + ret |= EFILE_ACCESS_READ; + } + if(st->st_mode & S_IWGRP) { + ret |= EFILE_ACCESS_WRITE; + } + return ret; + } + + if(st->st_mode & S_IROTH) { + ret |= EFILE_ACCESS_READ; + } + if(st->st_mode & S_IWOTH) { + ret |= EFILE_ACCESS_WRITE; + } + return ret; +} + +posix_errno_t efile_read_handle_info(efile_data_t *d, efile_fileinfo_t *result) { + struct stat data; + efile_unix_t *u = (efile_unix_t*)d; + +#ifdef HAVE_FSTAT + if(fstat(u->fd, &data) < 0) { + return errno; + } + + build_file_info(&data, result); + result->access = check_access(&data); + + return 0; +#else + return ENOTSUP; +#endif +} + posix_errno_t efile_set_permissions(const efile_path_t *path, Uint32 permissions) { const mode_t MUTABLE_MODES = (S_ISUID | S_ISGID | S_IRWXU | S_IRWXG | S_IRWXO); mode_t new_modes = permissions & MUTABLE_MODES; diff --git a/erts/emulator/nifs/win32/win_prim_file.c b/erts/emulator/nifs/win32/win_prim_file.c index 13306104c0..839ac3ea6e 100644 --- a/erts/emulator/nifs/win32/win_prim_file.c +++ b/erts/emulator/nifs/win32/win_prim_file.c @@ -773,6 +773,71 @@ static int is_name_surrogate(const efile_path_t *path) { return result; } +static void build_file_info(BY_HANDLE_FILE_INFORMATION *native_file_info, const efile_path_t *path, int is_link, efile_fileinfo_t *result) { + DWORD attributes; + + attributes = native_file_info->dwFileAttributes; + + if(is_link) { + result->type = EFILE_FILETYPE_SYMLINK; + /* This should be _S_IFLNK, but the old driver always set + * non-directories to _S_IFREG. */ + result->mode |= _S_IFREG; + } else if(attributes & FILE_ATTRIBUTE_DIRECTORY) { + result->type = EFILE_FILETYPE_DIRECTORY; + result->mode |= _S_IFDIR | _S_IEXEC; + } else { + if(is_executable_file(path)) { + result->mode |= _S_IEXEC; + } + + result->type = EFILE_FILETYPE_REGULAR; + result->mode |= _S_IFREG; + } + + if(!(attributes & FILE_ATTRIBUTE_READONLY)) { + result->access = EFILE_ACCESS_READ | EFILE_ACCESS_WRITE; + result->mode |= _S_IREAD | _S_IWRITE; + } else { + result->access = EFILE_ACCESS_READ; + result->mode |= _S_IREAD; + } + + /* Propagate user mode-bits to group/other fields */ + result->mode |= (result->mode & 0700) >> 3; + result->mode |= (result->mode & 0700) >> 6; + + result->size = + ((Uint64)native_file_info->nFileSizeHigh << 32ull) | + (Uint64)native_file_info->nFileSizeLow; + result->links = MAX(1, native_file_info->nNumberOfLinks); + + result->major_device = get_drive_number(path); + result->minor_device = 0; + result->inode = 0; + result->uid = 0; + result->gid = 0; +} + +static void build_file_info_times(BY_HANDLE_FILE_INFORMATION *native_file_info, efile_fileinfo_t *result) { + FILETIME_TO_EPOCH(result->m_time, native_file_info->ftLastWriteTime); + FILETIME_TO_EPOCH(result->a_time, native_file_info->ftLastAccessTime); + FILETIME_TO_EPOCH(result->c_time, native_file_info->ftCreationTime); + + if(result->m_time == -EPOCH_DIFFERENCE) { + /* Default to 1970 just like the old driver. */ + result->m_time = 0; + } + + if(result->a_time == -EPOCH_DIFFERENCE) { + result->a_time = result->m_time; + } + + if(result->c_time == -EPOCH_DIFFERENCE) { + result->c_time = result->m_time; + } +} + posix_errno_t efile_read_info(const efile_path_t *path, int follow_links, efile_fileinfo_t *result) { BY_HANDLE_FILE_INFORMATION native_file_info; DWORD attributes; @@ -792,23 +857,41 @@ posix_errno_t efile_read_info(const efile_path_t *path, int follow_links, efile_ return windows_to_posix_errno(last_error); } - attributes = FILE_ATTRIBUTE_DIRECTORY; + native_file_info.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY; } else if(is_path_root(path)) { /* Local (or mounted) roots can be queried with GetFileAttributesW but * lack support for GetFileInformationByHandle, so we'll skip that * part. */ + native_file_info.dwFileAttributes = attributes; } else { HANDLE handle; + DWORD last_error; + DWORD flags; if(attributes & FILE_ATTRIBUTE_REPARSE_POINT) { is_link = is_name_surrogate(path); } + flags = FILE_FLAG_BACKUP_SEMANTICS; + if(!follow_links && is_link) { + flags |= FILE_FLAG_OPEN_REPARSE_POINT; + } + + handle = CreateFileW((const WCHAR*)path->data, GENERIC_READ, + FILE_SHARE_FLAGS, NULL, OPEN_EXISTING, flags, NULL); + last_error = GetLastError(); + + if(handle == INVALID_HANDLE_VALUE) { + return windows_to_posix_errno(last_error); + } + if(follow_links && is_link) { posix_errno_t posix_errno; efile_path_t resolved_path; - posix_errno = internal_read_link(path, &resolved_path); + posix_errno = internal_read_link(handle, &resolved_path); + + CloseHandle(handle); if(posix_errno != 0) { return posix_errno; @@ -817,74 +900,43 @@ posix_errno_t efile_read_info(const efile_path_t *path, int follow_links, efile_ return efile_read_info(&resolved_path, 0, result); } - handle = CreateFileW((const WCHAR*)path->data, GENERIC_READ, - FILE_SHARE_FLAGS, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, - NULL); - - /* The old driver never cared whether this succeeded. */ - if(handle != INVALID_HANDLE_VALUE) { - GetFileInformationByHandle(handle, &native_file_info); - CloseHandle(handle); - } + GetFileInformationByHandle(handle, &native_file_info); + CloseHandle(handle); - FILETIME_TO_EPOCH(result->m_time, native_file_info.ftLastWriteTime); - FILETIME_TO_EPOCH(result->a_time, native_file_info.ftLastAccessTime); - FILETIME_TO_EPOCH(result->c_time, native_file_info.ftCreationTime); + build_file_info_times(&native_file_info, result); + } - if(result->m_time == -EPOCH_DIFFERENCE) { - /* Default to 1970 just like the old driver. */ - result->m_time = 0; - } + build_file_info(&native_file_info, path, is_link, result); - if(result->a_time == -EPOCH_DIFFERENCE) { - result->a_time = result->m_time; - } + return 0; +} - if(result->c_time == -EPOCH_DIFFERENCE) { - result->c_time = result->m_time; - } - } +posix_errno_t efile_read_handle_info(efile_data_t *d, efile_fileinfo_t *result) { + efile_win_t *w = (efile_win_t*)d; + HANDLE handle; + BY_HANDLE_FILE_INFORMATION native_file_info; + posix_errno_t posix_errno; + efile_path_t path; + int length; - if(is_link) { - result->type = EFILE_FILETYPE_SYMLINK; - /* This should be _S_IFLNK, but the old driver always set - * non-directories to _S_IFREG. */ - result->mode |= _S_IFREG; - } else if(attributes & FILE_ATTRIBUTE_DIRECTORY) { - result->type = EFILE_FILETYPE_DIRECTORY; - result->mode |= _S_IFDIR | _S_IEXEC; - } else { - if(is_executable_file(path)) { - result->mode |= _S_IEXEC; - } + sys_memset(&native_file_info, 0, sizeof(native_file_info)); - result->type = EFILE_FILETYPE_REGULAR; - result->mode |= _S_IFREG; + posix_errno = internal_read_link(w->handle, &path); + if(posix_errno != 0) { + return posix_errno; } - if(!(attributes & FILE_ATTRIBUTE_READONLY)) { - result->access = EFILE_ACCESS_READ | EFILE_ACCESS_WRITE; - result->mode |= _S_IREAD | _S_IWRITE; + if(GetFileInformationByHandle(w->handle, &native_file_info)) { + build_file_info_times(&native_file_info, result); + } else if(is_path_root(&path)) { + /* GetFileInformationByHandle is not supported on path roots, so + * fall back to efile_read_info. */ + return efile_read_info(&path, 0, result); } else { - result->access = EFILE_ACCESS_READ; - result->mode |= _S_IREAD; + return windows_to_posix_errno(GetLastError()); } - /* Propagate user mode-bits to group/other fields */ - result->mode |= (result->mode & 0700) >> 3; - result->mode |= (result->mode & 0700) >> 6; - - result->size = - ((Uint64)native_file_info.nFileSizeHigh << 32ull) | - (Uint64)native_file_info.nFileSizeLow; - - result->links = MAX(1, native_file_info.nNumberOfLinks); - - result->major_device = get_drive_number(path); - result->minor_device = 0; - result->inode = 0; - result->uid = 0; - result->gid = 0; + build_file_info(&native_file_info, &path, 0, result); return 0; } @@ -963,31 +1015,20 @@ posix_errno_t efile_set_time(const efile_path_t *path, Sint64 a_time, Sint64 m_t return windows_to_posix_errno(last_error); } -static posix_errno_t internal_read_link(const efile_path_t *path, efile_path_t *result) { +static posix_errno_t internal_read_link(HANDLE link_handle, efile_path_t *result) { DWORD required_length, actual_length; - HANDLE link_handle; DWORD last_error; - link_handle = CreateFileW((WCHAR*)path->data, GENERIC_READ, - FILE_SHARE_FLAGS, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); - last_error = GetLastError(); - - if(link_handle == INVALID_HANDLE_VALUE) { - return windows_to_posix_errno(last_error); - } - required_length = GetFinalPathNameByHandleW(link_handle, NULL, 0, 0); last_error = GetLastError(); if(required_length <= 0) { - CloseHandle(link_handle); return windows_to_posix_errno(last_error); } /* Unlike many other path functions (eg. GetFullPathNameW), this one * includes the NUL terminator in its required length. */ if(!enif_alloc_binary(required_length * sizeof(WCHAR), result)) { - CloseHandle(link_handle); return ENOMEM; } @@ -995,8 +1036,6 @@ static posix_errno_t internal_read_link(const efile_path_t *path, efile_path_t * (WCHAR*)result->data, required_length, 0); last_error = GetLastError(); - CloseHandle(link_handle); - if(actual_length == 0 || actual_length >= required_length) { enif_release_binary(result); return windows_to_posix_errno(last_error); @@ -1014,6 +1053,8 @@ posix_errno_t efile_read_link(ErlNifEnv *env, const efile_path_t *path, ERL_NIF_ posix_errno_t posix_errno; ErlNifBinary result_bin; DWORD attributes; + HANDLE handle; + DWORD last_error; ASSERT_PATH_FORMAT(path); @@ -1029,7 +1070,17 @@ posix_errno_t efile_read_link(ErlNifEnv *env, const efile_path_t *path, ERL_NIF_ return EINVAL; } - posix_errno = internal_read_link(path, &result_bin); + handle = CreateFileW((WCHAR*)path->data, GENERIC_READ, + FILE_SHARE_FLAGS, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, + NULL); + last_error = GetLastError(); + + if(handle == INVALID_HANDLE_VALUE) { + return windows_to_posix_errno(last_error); + } + posix_errno = internal_read_link(handle, &result_bin); + + CloseHandle(handle); if(posix_errno == 0) { if(!normalize_path_result(&result_bin)) { diff --git a/erts/emulator/pcre/LICENCE b/erts/emulator/pcre/LICENCE index f6ef7fd766..760a6666b6 100644 --- a/erts/emulator/pcre/LICENCE +++ b/erts/emulator/pcre/LICENCE @@ -25,7 +25,7 @@ Email domain: cam.ac.uk University of Cambridge Computing Service, Cambridge, England. -Copyright (c) 1997-2018 University of Cambridge +Copyright (c) 1997-2019 University of Cambridge All rights reserved. @@ -34,9 +34,9 @@ PCRE JUST-IN-TIME COMPILATION SUPPORT Written by: Zoltan Herczeg Email local part: hzmester -Emain domain: freemail.hu +Email domain: freemail.hu -Copyright(c) 2010-2018 Zoltan Herczeg +Copyright(c) 2010-2019 Zoltan Herczeg All rights reserved. @@ -45,9 +45,9 @@ STACK-LESS JUST-IN-TIME COMPILER Written by: Zoltan Herczeg Email local part: hzmester -Emain domain: freemail.hu +Email domain: freemail.hu -Copyright(c) 2009-2018 Zoltan Herczeg +Copyright(c) 2009-2019 Zoltan Herczeg All rights reserved. diff --git a/erts/emulator/pcre/pcre-8.42.tar.bz2 b/erts/emulator/pcre/pcre-8.42.tar.bz2 Binary files differdeleted file mode 100644 index 61bfa38970..0000000000 --- a/erts/emulator/pcre/pcre-8.42.tar.bz2 +++ /dev/null diff --git a/erts/emulator/pcre/pcre-8.43.tar.bz2 b/erts/emulator/pcre/pcre-8.43.tar.bz2 Binary files differnew file mode 100644 index 0000000000..e20c601f71 --- /dev/null +++ b/erts/emulator/pcre/pcre-8.43.tar.bz2 diff --git a/erts/emulator/pcre/pcre.h b/erts/emulator/pcre/pcre.h index 505e2ccce0..49c9fc6dc8 100644 --- a/erts/emulator/pcre/pcre.h +++ b/erts/emulator/pcre/pcre.h @@ -43,9 +43,9 @@ POSSIBILITY OF SUCH DAMAGE. /* The current PCRE version information. */ #define PCRE_MAJOR 8 -#define PCRE_MINOR 42 +#define PCRE_MINOR 43 #define PCRE_PRERELEASE -#define PCRE_DATE 2018-03-20 +#define PCRE_DATE 2019-02-23 /* When an application links to a PCRE DLL in Windows, the symbols that are imported have to be identified as such. When building PCRE, the appropriate diff --git a/erts/emulator/pcre/pcre_compile.c b/erts/emulator/pcre/pcre_compile.c index ae7f6e2a2a..6ac222b27e 100644 --- a/erts/emulator/pcre/pcre_compile.c +++ b/erts/emulator/pcre/pcre_compile.c @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2016 University of Cambridge + Copyright (c) 1997-2018 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -3300,7 +3300,7 @@ for(;;) if ((*xclass_flags & XCL_MAP) == 0) { /* No bits are set for characters < 256. */ - if (list[1] == 0) return TRUE; + if (list[1] == 0) return (*xclass_flags & XCL_NOT) == 0; /* Might be an empty repeat. */ continue; } @@ -7643,6 +7643,8 @@ for (;; ptr++) /* Can't determine a first byte now */ if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE; + zerofirstchar = firstchar; + zerofirstcharflags = firstcharflags; continue; @@ -8683,10 +8685,18 @@ do { if (!is_anchored(scode, new_map, cd, atomcount)) return FALSE; } - /* Positive forward assertions and conditions */ + /* Positive forward assertion */ - else if (op == OP_ASSERT || op == OP_COND) + else if (op == OP_ASSERT) + { + if (!is_anchored(scode, bracket_map, cd, atomcount)) return FALSE; + } + + /* Condition; not anchored if no second branch */ + + else if (op == OP_COND) { + if (scode[GET(scode,1)] != OP_ALT) return FALSE; if (!is_anchored(scode, bracket_map, cd, atomcount)) return FALSE; } diff --git a/erts/emulator/pcre/pcre_jit_compile.c b/erts/emulator/pcre/pcre_jit_compile.c index 926e40f6d3..2d2288f81e 100644 --- a/erts/emulator/pcre/pcre_jit_compile.c +++ b/erts/emulator/pcre/pcre_jit_compile.c @@ -9002,7 +9002,7 @@ if (exact > 1) #ifdef SUPPORT_UTF && !common->utf #endif - ) + && type != OP_ANYNL && type != OP_EXTUNI) { OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(exact)); add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_GREATER, TMP1, 0, STR_END, 0)); diff --git a/erts/emulator/sys/unix/sys_drivers.c b/erts/emulator/sys/unix/sys_drivers.c index 664d677ebd..92020c6f35 100644 --- a/erts/emulator/sys/unix/sys_drivers.c +++ b/erts/emulator/sys/unix/sys_drivers.c @@ -785,15 +785,15 @@ static ErlDrvSSizeT spawn_control(ErlDrvData e, unsigned int cmd, char *buf, static int fd_get_window_size(int fd, Uint32 *width, Uint32 *height) { -#ifdef TIOCGWINSZ +#ifdef TIOCGWINSZ struct winsize ws; if (ioctl(fd,TIOCGWINSZ,&ws) == 0) { *width = (Uint32) ws.ws_col; *height = (Uint32) ws.ws_row; - return 0; + return 1; } #endif - return -1; + return 0; } static ErlDrvSSizeT fd_control(ErlDrvData drv_data, @@ -801,16 +801,28 @@ static ErlDrvSSizeT fd_control(ErlDrvData drv_data, char *buf, ErlDrvSizeT len, char **rbuf, ErlDrvSizeT rlen) { - int fd = (int)(long)drv_data; char resbuff[2*sizeof(Uint32)]; - + ErtsSysDriverData* dd = (ErtsSysDriverData*)drv_data; command -= ERTS_TTYSL_DRV_CONTROL_MAGIC_NUMBER; switch (command) { case FD_CTRL_OP_GET_WINSIZE: { Uint32 w,h; - if (fd_get_window_size(fd,&w,&h)) - return 0; + int success = 0; + if (dd->ofd != NULL) { + /* Try with output file descriptor */ + int out_fd = dd->ofd->fd; + success = fd_get_window_size(out_fd,&w,&h); + } + if (!success && dd->ifd != NULL) { + /* Try with input file descriptor */ + int in_fd = dd->ifd->fd; + success = fd_get_window_size(in_fd,&w,&h); + } + if (!success) { + return -1; + } + /* Succeeded */ memcpy(resbuff,&w,sizeof(Uint32)); memcpy(resbuff+sizeof(Uint32),&h,sizeof(Uint32)); } diff --git a/erts/emulator/test/binary_SUITE.erl b/erts/emulator/test/binary_SUITE.erl index 4fb339926e..fbd1325c3a 100644 --- a/erts/emulator/test/binary_SUITE.erl +++ b/erts/emulator/test/binary_SUITE.erl @@ -1438,7 +1438,8 @@ sleeper() -> gc_test(Config) when is_list(Config) -> %% Note: This test is only relevant for REFC binaries. %% Therefore, we take care that all binaries are REFC binaries. - B = list_to_binary(lists:seq(0, ?heap_binary_size)), + true = 192 > ?heap_binary_size, + B = list_to_binary(lists:seq(1, 192)), Self = self(), F1 = fun() -> gc(), @@ -1447,22 +1448,22 @@ gc_test(Config) when is_list(Config) -> end, F = fun() -> receive go -> ok end, - {binary,[{_,65,1}]} = process_info(self(), binary), + {binary,[{_,192,1}]} = process_info(self(), binary), gc(), - {B1,B2} = my_split_binary(B, 4), + {B1,B2} = my_split_binary(B, 68), gc(), gc(), {binary,L1} = process_info(self(), binary), [Binfo1,Binfo2,Binfo3] = L1, - {_,65,3} = Binfo1 = Binfo2 = Binfo3, - 65 = size(B), - 4 = size(B1), - 61 = size(B2), + {_,192,3} = Binfo1 = Binfo2 = Binfo3, + 192 = size(B), + 68 = size(B1), + 124 = size(B2), F1() end, gc(), gc(), - 65 = size(B), + 192 = size(B), gc_test1(spawn_opt(erlang, apply, [F,[]], [link,{fullsweep_after,0}])). gc_test1(Pid) -> diff --git a/erts/emulator/test/distribution_SUITE.erl b/erts/emulator/test/distribution_SUITE.erl index 7885d35d9d..9dcdd60060 100644 --- a/erts/emulator/test/distribution_SUITE.erl +++ b/erts/emulator/test/distribution_SUITE.erl @@ -1400,6 +1400,10 @@ get_conflicting_unicode_atoms(CIX, N) -> %% The message_latency_large tests that small distribution messages are %% not blocked by other large distribution messages. Basically it tests %% that fragmentation of distribution messages works. +%% +%% Because of large problems to get reliable values from these testcases +%% they no longer fail when the latency is incorrect. However, they are +%% kept as they continue to find bugs in the distribution implementation. message_latency_large_message(Config) when is_list(Config) -> measure_latency_large_message(?FUNCTION_NAME, fun(Dropper, Payload) -> Dropper ! Payload end). @@ -1484,7 +1488,11 @@ measure_latency_large_message(Nodename, DataFun) -> case {lists:max(Times), lists:min(Times)} of {Max, Min} when Max * 0.25 > Min, BuildType =:= opt -> - ct:fail({incorrect_latency, IndexTimes}); + %% We only issue a comment for this failure as the + %% testcases proved very difficult to run successfully + %% on many platforms. + ct:comment({incorrect_latency, IndexTimes}), + ok; _ -> ok end. @@ -1503,10 +1511,7 @@ measure_latency(DataFun, Dropper, Echo, Payload) -> end end) || _ <- lists:seq(1,2)], - [receive - {monitor, _Sender, busy_dist_port, _Info} -> - ok - end || _ <- lists:seq(1,10)], + wait_for_busy_dist(2 * 60 * 1000, 10), {TS, Times} = timer:tc(fun() -> @@ -1530,6 +1535,18 @@ measure_latency(DataFun, Dropper, Echo, Payload) -> end || {Sender, Ref} <- Senders], TS. +wait_for_busy_dist(_Tmo, 0) -> + ok; +wait_for_busy_dist(Tmo, N) -> + T0 = erlang:monotonic_time(millisecond), + receive + {monitor, _Sender, busy_dist_port, _Info} -> + wait_for_busy_dist(Tmo - (erlang:monotonic_time(millisecond) - T0), N - 1) + after Tmo -> + ct:log("Timed out waiting for busy_dist, ~p left",[N]), + timeout + end. + flush() -> receive _ -> @@ -2600,7 +2617,7 @@ verify_nc(Node) -> demonitor(MonRef,[flush]), ok; {Ref, Error} -> - ct:log("~p",[Error]), + ct:log("~s",[Error]), ct:fail(failed_nc_refc_check); {'DOWN', MonRef, _, _, _} = Down -> ct:log("~p",[Down]), diff --git a/erts/emulator/test/dump_SUITE.erl b/erts/emulator/test/dump_SUITE.erl index 9f8ac42fa9..6133b82756 100644 --- a/erts/emulator/test/dump_SUITE.erl +++ b/erts/emulator/test/dump_SUITE.erl @@ -68,12 +68,14 @@ signal_abort(Config) -> {ok, Node} = start_node(Config), - _P1 = spawn(Node, ?MODULE, load, []), - _P2 = spawn(Node, ?MODULE, load, []), - _P3 = spawn(Node, ?MODULE, load, []), - _P4 = spawn(Node, ?MODULE, load, []), - _P5 = spawn(Node, ?MODULE, load, []), - _P6 = spawn(Node, ?MODULE, load, []), + SO = rpc:call(Node, erlang, system_info, [schedulers_online]), + + _P1 = spawn_opt(Node, ?MODULE, load, [], [{scheduler, (0 rem SO) + 1}]), + _P2 = spawn_opt(Node, ?MODULE, load, [], [{scheduler, (1 rem SO) + 1}]), + _P3 = spawn_opt(Node, ?MODULE, load, [], [{scheduler, (2 rem SO) + 1}]), + _P4 = spawn_opt(Node, ?MODULE, load, [], [{scheduler, (3 rem SO) + 1}]), + _P5 = spawn_opt(Node, ?MODULE, load, [], [{scheduler, (4 rem SO) + 1}]), + _P6 = spawn_opt(Node, ?MODULE, load, [], [{scheduler, (5 rem SO) + 1}]), timer:sleep(500), @@ -140,13 +142,13 @@ free_dump(Config) when is_list(Config) -> {ok, NodeA} = start_node(Config), {ok, NodeB} = start_node(Config), - Self = self(), PidA = spawn_link( NodeA, fun() -> Self ! ready, + Reason = lists:duplicate(1000000,100), receive ok -> spawn(fun() -> @@ -154,24 +156,29 @@ free_dump(Config) when is_list(Config) -> timer:sleep(5), receive M -> - io:format("~p",[M]), - erlang:halt("dump") - end + io:format("~p",[M]) +%% We may want to add this timeout here in-case no busy condition is triggered +%% after 60 * 1000 -> +%% io:format("Timeout") + end, + erlang:halt("dump") end), - exit(lists:duplicate(1000000,100)) + exit(Reason) end end), - spawn_link(NodeB, - fun() -> - [erlang:monitor(process, PidA) || _ <- lists:seq(1,10000)], - Self ! done, - receive _ -> ok end - end), + PidB = spawn_link(NodeB, + fun() -> + [erlang:monitor(process, PidA) || _ <- lists:seq(1,10000)], + Self ! done, + receive _ -> ok end + end), receive done -> ok end, true = rpc:call(NodeA, os, putenv, ["ERL_CRASH_DUMP",Dump]), - ct:pal("~p",[rpc:call(NodeA, distribution_SUITE, make_busy, [NodeB, 1000])]), + %% Make the node busy towards NodeB for 10 seconds. + BusyPid = rpc:call(NodeA, distribution_SUITE, make_busy, [NodeB,10000]), + ct:pal("~p",[BusyPid]), receive ready -> unlink(PidA), PidA ! ok end, @@ -185,6 +192,10 @@ free_dump(Config) when is_list(Config) -> file:delete(Dump), + unlink(PidB), + + rpc:call(NodeB, erlang, halt, [0]), + ok. diff --git a/erts/emulator/test/esock_ttest/esock-ttest b/erts/emulator/test/esock_ttest/esock-ttest index 9adc51fc8b..2ded557484 100755 --- a/erts/emulator/test/esock_ttest/esock-ttest +++ b/erts/emulator/test/esock_ttest/esock-ttest @@ -203,7 +203,7 @@ process_client_args(["--max-outstanding", Max|Args], State) -> end; process_client_args(["--scon", Server|Args], State) -> - case string:tokens(Server, [$:]) of + case string:split(Server, ":", trailing) of [AddrStr,PortStr] -> Addr = case inet:parse_address(AddrStr) of {ok, A} -> @@ -343,9 +343,9 @@ exec(#{role := client, runtime := RunTime}) -> case socket_test_ttest_tcp_client_socket:start(true, Async, + Active, Method, ServerInfo, - Active, MsgID, MaxOutstanding, RunTime) of {ok, Pid} -> diff --git a/erts/emulator/test/esock_ttest/esock-ttest-client b/erts/emulator/test/esock_ttest/esock-ttest-client index 7c90ae6391..5ae05d03b8 100755 --- a/erts/emulator/test/esock_ttest/esock-ttest-client +++ b/erts/emulator/test/esock_ttest/esock-ttest-client @@ -20,23 +20,30 @@ # %CopyrightEnd% # +# +# This is just a simple convenience wrapper to the esock-ttest. +# That means that there are some options not available here. +# + EMU=$ERL_TOP/erts/emulator EMU_TEST=$EMU/test ESOCK_TTEST=$EMU_TEST/esock_ttest RUNTIME=30 +# RUNTIME=60 +# RUNTIME=600 if [ $# = 3 ]; then MSGID=$1 SERVER_INFO=$2:$3 ITERATIONS="\ - gen false $MSGID - gen true $MSGID - gen once $MSGID - sock false $MSGID - sock true $MSGID - sock once $MSGID" + gen false $MSGID + gen true $MSGID + gen once $MSGID + sock false $MSGID --async + sock true $MSGID --async + sock once $MSGID --async" else if [ $# = 2 ]; then @@ -44,9 +51,9 @@ else SERVER_INFO=$2 ITERATIONS="\ - sock false $MSGID - sock true $MSGID - sock once $MSGID" + sock false $MSGID --async + sock true $MSGID --async + sock once $MSGID --async" else echo "Invalid number of args" @@ -70,14 +77,14 @@ fi # --------------------------------------------------------------------------- echo "$ITERATIONS" | - while read TRANSPORT ACTIVE MSG_ID; do + while read TRANSPORT ACTIVE MSG_ID ASYNC; do echo "" echo "=========== transport = $TRANSPORT, active = $ACTIVE, msg-id = $MSG_ID ===========" # The /dev/null at the end is necessary because erlang "does things" with stdin # and this case would cause the 'while read' to "fail" so that we only would # loop one time - $ESOCK_TTEST/esock-ttest --client --transport $TRANSPORT --active $ACTIVE --msg-id $MSG_ID --scon $SERVER_INFO --runtime $RUNTIME </dev/null + $ESOCK_TTEST/esock-ttest --client --transport $TRANSPORT $ASYNC --active $ACTIVE --msg-id $MSG_ID --scon $SERVER_INFO --runtime $RUNTIME </dev/null echo "" done diff --git a/erts/emulator/test/esock_ttest/esock-ttest-server-sock b/erts/emulator/test/esock_ttest/esock-ttest-server-sock index fc87499f09..c443d42e64 100755 --- a/erts/emulator/test/esock_ttest/esock-ttest-server-sock +++ b/erts/emulator/test/esock_ttest/esock-ttest-server-sock @@ -24,9 +24,10 @@ EMU=$ERL_TOP/erts/emulator EMU_TEST=$EMU/test ESOCK_TTEST=$EMU_TEST/esock_ttest -# $1 - async - boolean() -# $2 - active - once | boolean() -if [ $# = 2 ]; then +# $1 - async - boolean() +# $2 - active - once | boolean() +# [$3 - domain - inet (default) | inet6 | local] +if [ $# -ge 2 ]; then async=$1 active=$2 @@ -39,6 +40,11 @@ if [ $# = 2 ]; then ACTIVE="--active $active" + if [ $# = 3 ]; then + DOMAIN="--domain $3" + fi + + else echo "<ERROR> Missing args: async and active" echo "" @@ -46,5 +52,5 @@ else fi -$ESOCK_TTEST/esock-ttest --server $ASYNC --transport sock $ACTIVE +$ESOCK_TTEST/esock-ttest --server $DOMAIN $ASYNC --transport sock $ACTIVE diff --git a/erts/emulator/test/fun_SUITE.erl b/erts/emulator/test/fun_SUITE.erl index 2cbde621ce..ad8ef0feff 100644 --- a/erts/emulator/test/fun_SUITE.erl +++ b/erts/emulator/test/fun_SUITE.erl @@ -27,7 +27,7 @@ fun_to_port/1,t_phash/1,t_phash2/1,md5/1, refc/1,refc_ets/1,refc_dist/1, const_propagation/1,t_arity/1,t_is_function2/1, - t_fun_info/1,t_fun_info_mfa/1]). + t_fun_info/1,t_fun_info_mfa/1,t_fun_to_list/1]). -export([nothing/0]). @@ -44,7 +44,7 @@ all() -> equality, ordering, fun_to_port, t_phash, t_phash2, md5, refc, refc_ets, refc_dist, const_propagation, t_arity, t_is_function2, t_fun_info, - t_fun_info_mfa]. + t_fun_info_mfa,t_fun_to_list]. %% Test that the correct EXIT code is returned for all types of bad funs. bad_apply(Config) when is_list(Config) -> @@ -802,6 +802,12 @@ t_fun_info_mfa(Config) when is_list(Config) -> {'EXIT',_} = (catch erlang:fun_info_mfa(id(d))), ok. +t_fun_to_list(Config) when is_list(Config) -> + "fun a:b/1" = erlang:fun_to_list(fun a:b/1), + "fun 'a-esc':'b-esc'/1" = erlang:fun_to_list(fun 'a-esc':'b-esc'/1), + "fun 'a-esc':b/1" = erlang:fun_to_list(fun 'a-esc':b/1), + "fun a:'b-esc'/1" = erlang:fun_to_list(fun a:'b-esc'/1), + ok. bad_info(Term) -> try erlang:fun_info(Term, module) of diff --git a/erts/emulator/test/multi_load_SUITE.erl b/erts/emulator/test/multi_load_SUITE.erl index edf3205812..c79e2b6dcd 100644 --- a/erts/emulator/test/multi_load_SUITE.erl +++ b/erts/emulator/test/multi_load_SUITE.erl @@ -30,7 +30,15 @@ all() -> [many,on_load,errors]. many(_Config) -> - Ms = make_modules(100, fun many_module/1), + + N = case erlang:system_info(build_type) of + valgrind -> + 10; + _ -> + 100 + end, + + Ms = make_modules(N, fun many_module/1), io:put_chars("Light load\n" "=========="), diff --git a/erts/emulator/test/net_SUITE.erl b/erts/emulator/test/net_SUITE.erl index 6111fc76a5..c6e77a5373 100644 --- a/erts/emulator/test/net_SUITE.erl +++ b/erts/emulator/test/net_SUITE.erl @@ -20,6 +20,8 @@ %% %% This test suite is basically a "placeholder" for a proper test suite... +%% Also we should really call prim_net directly, and not net (since that does +%% not even reside here). %% %% Run the entire test suite: @@ -127,6 +129,7 @@ api_basic_cases() -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% init_per_suite(Config) -> + %% We test on the socket module for simplicity case lists:member(socket, erlang:loaded()) of true -> case os:type() of diff --git a/erts/emulator/test/node_container_SUITE.erl b/erts/emulator/test/node_container_SUITE.erl index ef4635a6f5..c44693f8d9 100644 --- a/erts/emulator/test/node_container_SUITE.erl +++ b/erts/emulator/test/node_container_SUITE.erl @@ -51,7 +51,8 @@ unique_pid/1, iter_max_procs/1, magic_ref/1, - dist_entry_gc/1]). + dist_entry_gc/1, + persistent_term/1]). suite() -> [{ct_hooks,[ts_install_cth]}, @@ -63,7 +64,8 @@ all() -> node_table_gc, dist_link_refc, dist_monitor_refc, node_controller_refc, ets_refc, match_spec_refc, timer_refc, pid_wrap, port_wrap, bad_nc, - unique_pid, iter_max_procs, magic_ref]. + unique_pid, iter_max_procs, + magic_ref, persistent_term]. init_per_suite(Config) -> Config. @@ -570,7 +572,17 @@ node_controller_refc(Config) when is_list(Config) -> wait_until(fun () -> not is_process_alive(P) end), lists:foreach(fun (Proc) -> garbage_collect(Proc) end, processes()), false = get_node_references({Node,Creation}), - false = get_dist_references(Node), + wait_until(fun () -> + case get_dist_references(Node) of + false -> + true; + [{{system,thread_progress_delete_timer}, + [{system,1}]}] -> + false; + Other -> + ct:fail(Other) + end + end), false = lists:member(Node, nodes(known)), nc_refc_check(node()), erts_debug:set_internal_state(node_tab_delayed_delete, -1), %% restore original value @@ -871,7 +883,22 @@ magic_ref(Config) when is_list(Config) -> {'DOWN', Mon, process, Pid, _} -> ok end, - {Addr0, 2, true} = erts_debug:get_internal_state({magic_ref,MRef0}), + MaxTime = erlang:monotonic_time(millisecond) + 1000, + %% The DOWN signal is sent before heap is cleaned up, + %% so we might need to wait some time after the DOWN + %% signal has been received before the heap actually + %% has been cleaned up... + wait_until(fun () -> + case erts_debug:get_internal_state({magic_ref,MRef0}) of + {Addr0, 2, true} -> + true; + {Addr0, 3, true} -> + true = MaxTime >= erlang:monotonic_time(millisecond), + false; + Error -> + ct:fail(Error) + end + end), id(MRef0), id(MRef1), MRefExt = term_to_binary(erts_debug:set_internal_state(make, magic_ref)), @@ -881,6 +908,44 @@ magic_ref(Config) when is_list(Config) -> true = erts_debug:get_internal_state({magic_ref,MRef2}), ok. +persistent_term(Config) when is_list(Config) -> + {ok, Node} = start_node(get_nodefirstname()), + Self = self(), + NcData = make_ref(), + RPid = spawn_link(Node, + fun () -> + Self ! {NcData, self(), hd(erlang:ports()), erlang:make_ref()} + end), + Data = receive + {NcData, RPid, RPort, RRef} -> + {RPid, RPort, RRef} + end, + unlink(RPid), + stop_node(Node), + Stuff = lists:foldl(fun (N, Acc) -> + persistent_term:put({?MODULE, N}, Data), + persistent_term:erase({?MODULE, N-1}), + node_container_refc_check(node()), + Data = persistent_term:get({?MODULE, N}), + try + persistent_term:get({?MODULE, N-1}) + catch + error:badarg -> + ok + end, + case N rem 4 of + 0 -> [persistent_term:get({?MODULE, N})|Acc]; + _ -> Acc + end + end, + [], + lists:seq(1, 100)), + persistent_term:erase({?MODULE, 100}), + receive after 2000 -> ok end, %% give literal gc some time to run... + node_container_refc_check(node()), + id(Stuff), + ok. + lost_pending_connection(Node) -> _ = (catch erts_internal:new_connection(Node)), diff --git a/erts/emulator/test/nofrag_SUITE.erl b/erts/emulator/test/nofrag_SUITE.erl index 8b1519ae36..d4c74579e2 100644 --- a/erts/emulator/test/nofrag_SUITE.erl +++ b/erts/emulator/test/nofrag_SUITE.erl @@ -22,6 +22,11 @@ -include_lib("common_test/include/ct.hrl"). +%% This suite alters the return values of functions which breaks certain +%% assumptions made by the compiler, so we have to turn off module-level type +%% optimization to be safe. +-compile(no_module_opt). + -export([all/0, suite/0, error_handler/1,error_handler_apply/1, error_handler_fixed_apply/1,error_handler_fun/1, diff --git a/erts/emulator/test/process_SUITE.erl b/erts/emulator/test/process_SUITE.erl index 3684cde8d4..13dde12e69 100644 --- a/erts/emulator/test/process_SUITE.erl +++ b/erts/emulator/test/process_SUITE.erl @@ -2600,14 +2600,20 @@ garb_other_running(Config) when is_list(Config) -> no_priority_inversion(Config) when is_list(Config) -> Prio = process_flag(priority, max), - HTLs = lists:map(fun (_) -> + Master = self(), + Executing = make_ref(), + HTLs = lists:map(fun (Sched) -> spawn_opt(fun () -> + Master ! {self(), Executing}, tok_loop() end, - [{priority, high}, monitor, link]) + [{priority, high}, + {scheduler, Sched}, + monitor, + link]) end, - lists:seq(1, 2*erlang:system_info(schedulers))), - receive after 500 -> ok end, + lists:seq(1, erlang:system_info(schedulers_online))), + lists:foreach(fun ({P, _}) -> receive {P,Executing} -> ok end end, HTLs), LTL = spawn_opt(fun () -> tok_loop() end, @@ -2629,14 +2635,19 @@ no_priority_inversion(Config) when is_list(Config) -> no_priority_inversion2(Config) when is_list(Config) -> Prio = process_flag(priority, max), - MTLs = lists:map(fun (_) -> + Master = self(), + Executing = make_ref(), + MTLs = lists:map(fun (Sched) -> spawn_opt(fun () -> + Master ! {self(), Executing}, tok_loop() end, - [{priority, max}, monitor, link]) + [{priority, max}, + {scheduler, Sched}, + monitor, link]) end, - lists:seq(1, 2*erlang:system_info(schedulers))), - receive after 2000 -> ok end, + lists:seq(1, erlang:system_info(schedulers_online))), + lists:foreach(fun ({P, _}) -> receive {P,Executing} -> ok end end, MTLs), {PL, ML} = spawn_opt(fun () -> tok_loop() end, diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index c82e2efad9..4980ea2a82 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -58,6 +58,7 @@ -include_lib("common_test/include/ct.hrl"). -include_lib("common_test/include/ct_event.hrl"). +-include("socket_test_evaluator.hrl"). %% Suite exports -export([suite/0, all/0, groups/0]). @@ -67,6 +68,9 @@ %% Test cases -export([ + %% *** API Misc *** + api_m_debug/1, + %% *** API Basic *** api_b_open_and_close_udp4/1, api_b_open_and_close_tcp4/1, @@ -83,26 +87,52 @@ %% *** API async *** api_a_connect_tcp4/1, + api_a_connect_tcp6/1, api_a_sendto_and_recvfrom_udp4/1, + api_a_sendto_and_recvfrom_udp6/1, api_a_sendmsg_and_recvmsg_udp4/1, + api_a_sendmsg_and_recvmsg_udp6/1, api_a_send_and_recv_tcp4/1, + api_a_send_and_recv_tcp6/1, api_a_sendmsg_and_recvmsg_tcp4/1, + api_a_sendmsg_and_recvmsg_tcp6/1, api_a_recvfrom_cancel_udp4/1, + api_a_recvfrom_cancel_udp6/1, api_a_recvmsg_cancel_udp4/1, + api_a_recvmsg_cancel_udp6/1, api_a_accept_cancel_tcp4/1, + api_a_accept_cancel_tcp6/1, api_a_recv_cancel_tcp4/1, + api_a_recv_cancel_tcp6/1, api_a_recvmsg_cancel_tcp4/1, + api_a_recvmsg_cancel_tcp6/1, api_a_mrecvfrom_cancel_udp4/1, + api_a_mrecvfrom_cancel_udp6/1, api_a_mrecvmsg_cancel_udp4/1, + api_a_mrecvmsg_cancel_udp6/1, api_a_maccept_cancel_tcp4/1, + api_a_maccept_cancel_tcp6/1, api_a_mrecv_cancel_tcp4/1, + api_a_mrecv_cancel_tcp6/1, api_a_mrecvmsg_cancel_tcp4/1, + api_a_mrecvmsg_cancel_tcp6/1, %% *** API Options *** api_opt_simple_otp_options/1, api_opt_simple_otp_rcvbuf_option/1, api_opt_simple_otp_controlling_process/1, + api_opt_sock_acceptconn_udp/1, + api_opt_sock_acceptconn_tcp/1, + api_opt_sock_acceptfilter/1, + api_opt_sock_bindtodevice/1, + api_opt_sock_broadcast/1, + api_opt_sock_debug/1, + api_opt_sock_domain/1, + api_opt_sock_dontroute/1, + api_opt_sock_error/1, + api_opt_sock_keepalive/1, + api_opt_sock_linger/1, api_opt_ip_add_drop_membership/1, %% *** API Operation Timeout *** @@ -168,6 +198,19 @@ sc_rs_recvmsg_send_shutdown_receive_tcpL/1, %% *** Traffic *** + traffic_send_and_recv_counters_tcp4/1, + traffic_send_and_recv_counters_tcp6/1, + traffic_send_and_recv_counters_tcpL/1, + traffic_sendmsg_and_recvmsg_counters_tcp4/1, + traffic_sendmsg_and_recvmsg_counters_tcp6/1, + traffic_sendmsg_and_recvmsg_counters_tcpL/1, + traffic_sendto_and_recvfrom_counters_udp4/1, + traffic_sendto_and_recvfrom_counters_udp6/1, + traffic_sendto_and_recvfrom_counters_udpL/1, + traffic_sendmsg_and_recvmsg_counters_udp4/1, + traffic_sendmsg_and_recvmsg_counters_udp6/1, + traffic_sendmsg_and_recvmsg_counters_udpL/1, + traffic_send_and_recv_chunks_tcp4/1, traffic_send_and_recv_chunks_tcp6/1, traffic_send_and_recv_chunks_tcpL/1, @@ -514,30 +557,31 @@ ]). --include("socket_test_evaluator.hrl"). - %% Internal exports %% -export([]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --define(BASIC_REQ, <<"hejsan">>). --define(BASIC_REP, <<"hoppsan">>). +-define(LIB, socket_test_lib). +-define(TTEST_LIB, socket_test_ttest_lib). +-define(LOGGER, socket_test_logger). --define(DATA, <<"HOPPSAN">>). % Temporary --define(FAIL(R), exit(R)). +-define(BASIC_REQ, <<"hejsan">>). +-define(BASIC_REP, <<"hoppsan">>). --define(SLEEP(T), receive after T -> ok end). +-define(DATA, <<"HOPPSAN">>). % Temporary +-define(FAIL(R), exit(R)). --define(MINS(M), timer:minutes(M)). --define(SECS(S), timer:seconds(S)). +-define(SLEEP(T), receive after T -> ok end). --define(TT(T), ct:timetrap(T)). +-define(MINS(M), timer:minutes(M)). +-define(SECS(S), timer:seconds(S)). + +-define(TT(T), ct:timetrap(T)). + +-define(F(F, A), ?LIB:f(F, A)). --define(LIB, socket_test_lib). --define(TTEST_LIB, socket_test_ttest_lib). --define(LOGGER, socket_test_logger). -define(TPP_SMALL, lists:seq(1, 8)). -define(TPP_MEDIUM, lists:flatten(lists:duplicate(1024, ?TPP_SMALL))). @@ -557,10 +601,10 @@ suite() -> {timetrap,{minutes,1}}]. all() -> - Groups = [{api, "ESOCK_TEST_API", include}, - {socket_closure, "ESOCK_TEST_SOCK_CLOSE", include}, - {traffic, "ESOCK_TEST_TRAFFIC", include}, - {ttest, "ESOCK_TEST_TTEST", exclude}], + Groups = [{api, "ESOCK_TEST_API", include}, + {socket_close, "ESOCK_TEST_SOCK_CLOSE", include}, + {traffic, "ESOCK_TEST_TRAFFIC", include}, + {ttest, "ESOCK_TEST_TTEST", exclude}], [use_group(Group, Env, Default) || {Group, Env, Default} <- Groups]. use_group(Group, Env, Default) -> @@ -582,90 +626,104 @@ use_group(Group, Env, Default) -> groups() -> - [{api, [], api_cases()}, - {api_basic, [], api_basic_cases()}, - {api_async, [], api_async_cases()}, - {api_options, [], api_options_cases()}, - {api_options_otp, [], api_options_otp_cases()}, - {api_options_ip, [], api_options_ip_cases()}, - {api_op_with_timeout, [], api_op_with_timeout_cases()}, - {socket_closure, [], socket_closure_cases()}, - {sc_ctrl_proc_exit, [], sc_cp_exit_cases()}, - {sc_local_close, [], sc_lc_cases()}, - {sc_remote_close, [], sc_rc_cases()}, - {sc_remote_shutdown, [], sc_rs_cases()}, - {traffic, [], traffic_cases()}, - {traffic_chunks, [], traffic_chunks_cases()}, - {traffic_pp_send_recv, [], traffic_pp_send_recv_cases()}, - {traffic_pp_sendto_recvfrom, [], traffic_pp_sendto_recvfrom_cases()}, - {traffic_pp_sendmsg_recvmsg, [], traffic_pp_sendmsg_recvmsg_cases()}, - {ttest, [], ttest_cases()}, - {ttest_sgenf, [], ttest_sgenf_cases()}, - {ttest_sgenf_cgen, [], ttest_sgenf_cgen_cases()}, - {ttest_sgenf_cgenf, [], ttest_sgenf_cgenf_cases()}, - {ttest_sgenf_cgeno, [], ttest_sgenf_cgeno_cases()}, - {ttest_sgenf_cgent, [], ttest_sgenf_cgent_cases()}, - {ttest_sgenf_csock, [], ttest_sgenf_csock_cases()}, - {ttest_sgenf_csockf, [], ttest_sgenf_csockf_cases()}, - {ttest_sgenf_csocko, [], ttest_sgenf_csocko_cases()}, - {ttest_sgenf_csockt, [], ttest_sgenf_csockt_cases()}, - {ttest_sgeno, [], ttest_sgeno_cases()}, - {ttest_sgeno_cgen, [], ttest_sgeno_cgen_cases()}, - {ttest_sgeno_cgenf, [], ttest_sgeno_cgenf_cases()}, - {ttest_sgeno_cgeno, [], ttest_sgeno_cgeno_cases()}, - {ttest_sgeno_cgent, [], ttest_sgeno_cgent_cases()}, - {ttest_sgeno_csock, [], ttest_sgeno_csock_cases()}, - {ttest_sgeno_csockf, [], ttest_sgeno_csockf_cases()}, - {ttest_sgeno_csocko, [], ttest_sgeno_csocko_cases()}, - {ttest_sgeno_csockt, [], ttest_sgeno_csockt_cases()}, - {ttest_sgent, [], ttest_sgent_cases()}, - {ttest_sgent_cgen, [], ttest_sgent_cgen_cases()}, - {ttest_sgent_cgenf, [], ttest_sgent_cgenf_cases()}, - {ttest_sgent_cgeno, [], ttest_sgent_cgeno_cases()}, - {ttest_sgent_cgent, [], ttest_sgent_cgent_cases()}, - {ttest_sgent_csock, [], ttest_sgent_csock_cases()}, - {ttest_sgent_csockf, [], ttest_sgent_csockf_cases()}, - {ttest_sgent_csocko, [], ttest_sgent_csocko_cases()}, - {ttest_sgent_csockt, [], ttest_sgent_csockt_cases()}, - {ttest_ssockf, [], ttest_ssockf_cases()}, - {ttest_ssockf_cgen, [], ttest_ssockf_cgen_cases()}, - {ttest_ssockf_cgenf, [], ttest_ssockf_cgenf_cases()}, - {ttest_ssockf_cgeno, [], ttest_ssockf_cgeno_cases()}, - {ttest_ssockf_cgent, [], ttest_ssockf_cgent_cases()}, - {ttest_ssockf_csock, [], ttest_ssockf_csock_cases()}, - {ttest_ssockf_csockf, [], ttest_ssockf_csockf_cases()}, - {ttest_ssockf_csocko, [], ttest_ssockf_csocko_cases()}, - {ttest_ssockf_csockt, [], ttest_ssockf_csockt_cases()}, - {ttest_ssocko, [], ttest_ssocko_cases()}, - {ttest_ssocko_cgen, [], ttest_ssocko_cgen_cases()}, - {ttest_ssocko_cgenf, [], ttest_ssocko_cgenf_cases()}, - {ttest_ssocko_cgeno, [], ttest_ssocko_cgeno_cases()}, - {ttest_ssocko_cgent, [], ttest_ssocko_cgent_cases()}, - {ttest_ssocko_csock, [], ttest_ssocko_csock_cases()}, - {ttest_ssocko_csockf, [], ttest_ssocko_csockf_cases()}, - {ttest_ssocko_csocko, [], ttest_ssocko_csocko_cases()}, - {ttest_ssocko_csockt, [], ttest_ssocko_csockt_cases()}, - {ttest_ssockt, [], ttest_ssockt_cases()}, - {ttest_ssockt_cgen, [], ttest_ssockt_cgen_cases()}, - {ttest_ssockt_cgenf, [], ttest_ssockt_cgenf_cases()}, - {ttest_ssockt_cgeno, [], ttest_ssockt_cgeno_cases()}, - {ttest_ssockt_cgent, [], ttest_ssockt_cgent_cases()}, - {ttest_ssockt_csock, [], ttest_ssockt_csock_cases()}, - {ttest_ssockt_csockf, [], ttest_ssockt_csockf_cases()}, - {ttest_ssockt_csocko, [], ttest_ssockt_csocko_cases()}, - {ttest_ssockt_csockt, [], ttest_ssockt_csockt_cases()} + [{api, [], api_cases()}, + {api_misc, [], api_misc_cases()}, + {api_basic, [], api_basic_cases()}, + {api_async, [], api_async_cases()}, + {api_options, [], api_options_cases()}, + {api_options_otp, [], api_options_otp_cases()}, + {api_options_socket, [], api_options_socket_cases()}, + {api_option_sock_acceptconn, [], api_option_sock_acceptconn_cases()}, + {api_options_ip, [], api_options_ip_cases()}, + %% {api_options_ipv6, [], api_options_ipv6_cases()}, + %% {api_options_tcp, [], api_options_tcp_cases()}, + %% {api_options_udp, [], api_options_udp_cases()}, + %% {api_options_sctp, [], api_options_sctp_cases()}, + {api_op_with_timeout, [], api_op_with_timeout_cases()}, + {socket_close, [], socket_close_cases()}, + {sc_ctrl_proc_exit, [], sc_cp_exit_cases()}, + {sc_local_close, [], sc_lc_cases()}, + {sc_remote_close, [], sc_rc_cases()}, + {sc_remote_shutdown, [], sc_rs_cases()}, + {traffic, [], traffic_cases()}, + {traffic_counters, [], traffic_counters_cases()}, + {traffic_chunks, [], traffic_chunks_cases()}, + {traffic_pp_send_recv, [], traffic_pp_send_recv_cases()}, + {traffic_pp_sendto_recvfrom, [], traffic_pp_sendto_recvfrom_cases()}, + {traffic_pp_sendmsg_recvmsg, [], traffic_pp_sendmsg_recvmsg_cases()}, + {ttest, [], ttest_cases()}, + {ttest_sgenf, [], ttest_sgenf_cases()}, + {ttest_sgenf_cgen, [], ttest_sgenf_cgen_cases()}, + {ttest_sgenf_cgenf, [], ttest_sgenf_cgenf_cases()}, + {ttest_sgenf_cgeno, [], ttest_sgenf_cgeno_cases()}, + {ttest_sgenf_cgent, [], ttest_sgenf_cgent_cases()}, + {ttest_sgenf_csock, [], ttest_sgenf_csock_cases()}, + {ttest_sgenf_csockf, [], ttest_sgenf_csockf_cases()}, + {ttest_sgenf_csocko, [], ttest_sgenf_csocko_cases()}, + {ttest_sgenf_csockt, [], ttest_sgenf_csockt_cases()}, + {ttest_sgeno, [], ttest_sgeno_cases()}, + {ttest_sgeno_cgen, [], ttest_sgeno_cgen_cases()}, + {ttest_sgeno_cgenf, [], ttest_sgeno_cgenf_cases()}, + {ttest_sgeno_cgeno, [], ttest_sgeno_cgeno_cases()}, + {ttest_sgeno_cgent, [], ttest_sgeno_cgent_cases()}, + {ttest_sgeno_csock, [], ttest_sgeno_csock_cases()}, + {ttest_sgeno_csockf, [], ttest_sgeno_csockf_cases()}, + {ttest_sgeno_csocko, [], ttest_sgeno_csocko_cases()}, + {ttest_sgeno_csockt, [], ttest_sgeno_csockt_cases()}, + {ttest_sgent, [], ttest_sgent_cases()}, + {ttest_sgent_cgen, [], ttest_sgent_cgen_cases()}, + {ttest_sgent_cgenf, [], ttest_sgent_cgenf_cases()}, + {ttest_sgent_cgeno, [], ttest_sgent_cgeno_cases()}, + {ttest_sgent_cgent, [], ttest_sgent_cgent_cases()}, + {ttest_sgent_csock, [], ttest_sgent_csock_cases()}, + {ttest_sgent_csockf, [], ttest_sgent_csockf_cases()}, + {ttest_sgent_csocko, [], ttest_sgent_csocko_cases()}, + {ttest_sgent_csockt, [], ttest_sgent_csockt_cases()}, + {ttest_ssockf, [], ttest_ssockf_cases()}, + {ttest_ssockf_cgen, [], ttest_ssockf_cgen_cases()}, + {ttest_ssockf_cgenf, [], ttest_ssockf_cgenf_cases()}, + {ttest_ssockf_cgeno, [], ttest_ssockf_cgeno_cases()}, + {ttest_ssockf_cgent, [], ttest_ssockf_cgent_cases()}, + {ttest_ssockf_csock, [], ttest_ssockf_csock_cases()}, + {ttest_ssockf_csockf, [], ttest_ssockf_csockf_cases()}, + {ttest_ssockf_csocko, [], ttest_ssockf_csocko_cases()}, + {ttest_ssockf_csockt, [], ttest_ssockf_csockt_cases()}, + {ttest_ssocko, [], ttest_ssocko_cases()}, + {ttest_ssocko_cgen, [], ttest_ssocko_cgen_cases()}, + {ttest_ssocko_cgenf, [], ttest_ssocko_cgenf_cases()}, + {ttest_ssocko_cgeno, [], ttest_ssocko_cgeno_cases()}, + {ttest_ssocko_cgent, [], ttest_ssocko_cgent_cases()}, + {ttest_ssocko_csock, [], ttest_ssocko_csock_cases()}, + {ttest_ssocko_csockf, [], ttest_ssocko_csockf_cases()}, + {ttest_ssocko_csocko, [], ttest_ssocko_csocko_cases()}, + {ttest_ssocko_csockt, [], ttest_ssocko_csockt_cases()}, + {ttest_ssockt, [], ttest_ssockt_cases()}, + {ttest_ssockt_cgen, [], ttest_ssockt_cgen_cases()}, + {ttest_ssockt_cgenf, [], ttest_ssockt_cgenf_cases()}, + {ttest_ssockt_cgeno, [], ttest_ssockt_cgeno_cases()}, + {ttest_ssockt_cgent, [], ttest_ssockt_cgent_cases()}, + {ttest_ssockt_csock, [], ttest_ssockt_csock_cases()}, + {ttest_ssockt_csockf, [], ttest_ssockt_csockf_cases()}, + {ttest_ssockt_csocko, [], ttest_ssockt_csocko_cases()}, + {ttest_ssockt_csockt, [], ttest_ssockt_csockt_cases()} %% {tickets, [], ticket_cases()} ]. api_cases() -> [ + {group, api_misc}, {group, api_basic}, {group, api_async}, {group, api_options}, {group, api_op_with_timeout} ]. +api_misc_cases() -> + [ + api_m_debug + ]. + api_basic_cases() -> [ api_b_open_and_close_udp4, @@ -685,26 +743,46 @@ api_basic_cases() -> api_async_cases() -> [ api_a_connect_tcp4, + api_a_connect_tcp6, api_a_sendto_and_recvfrom_udp4, + api_a_sendto_and_recvfrom_udp6, api_a_sendmsg_and_recvmsg_udp4, + api_a_sendmsg_and_recvmsg_udp6, api_a_send_and_recv_tcp4, + api_a_send_and_recv_tcp6, api_a_sendmsg_and_recvmsg_tcp4, + api_a_sendmsg_and_recvmsg_tcp6, api_a_recvfrom_cancel_udp4, + api_a_recvfrom_cancel_udp6, api_a_recvmsg_cancel_udp4, + api_a_recvmsg_cancel_udp6, api_a_accept_cancel_tcp4, + api_a_accept_cancel_tcp6, api_a_recv_cancel_tcp4, + api_a_recv_cancel_tcp6, api_a_recvmsg_cancel_tcp4, + api_a_recvmsg_cancel_tcp6, api_a_mrecvfrom_cancel_udp4, + api_a_mrecvfrom_cancel_udp6, api_a_mrecvmsg_cancel_udp4, + api_a_mrecvmsg_cancel_udp6, api_a_maccept_cancel_tcp4, + api_a_maccept_cancel_tcp6, api_a_mrecv_cancel_tcp4, - api_a_mrecvmsg_cancel_tcp4 + api_a_mrecv_cancel_tcp6, + api_a_mrecvmsg_cancel_tcp4, + api_a_mrecvmsg_cancel_tcp6 ]. api_options_cases() -> [ {group, api_options_otp}, - {group, api_options_ip} + {group, api_options_socket}, + {group, api_options_ip}% , + %% {group, api_options_ipv6}, + %% {group, api_options_tcp}, + %% {group, api_options_udp}, + %% {group, api_options_sctp} ]. api_options_otp_cases() -> @@ -714,11 +792,35 @@ api_options_otp_cases() -> api_opt_simple_otp_controlling_process ]. +api_options_socket_cases() -> + [ + {group, api_option_sock_acceptconn}, + api_opt_sock_acceptfilter, + api_opt_sock_bindtodevice, + api_opt_sock_broadcast, + api_opt_sock_debug, + api_opt_sock_domain, + api_opt_sock_dontroute, + api_opt_sock_error, + api_opt_sock_keepalive, + api_opt_sock_linger + ]. + +api_option_sock_acceptconn_cases() -> + [ + api_opt_sock_acceptconn_udp, + api_opt_sock_acceptconn_tcp + ]. + api_options_ip_cases() -> [ api_opt_ip_add_drop_membership ]. +%% api_options_ipv6_cases() -> +%% [ +%% ]. + api_op_with_timeout_cases() -> [ api_to_connect_tcp4, @@ -747,7 +849,7 @@ api_op_with_timeout_cases() -> %% These cases tests what happens when the socket is closed/shutdown, %% locally or remotely. -socket_closure_cases() -> +socket_close_cases() -> [ {group, sc_ctrl_proc_exit}, {group, sc_local_close}, @@ -818,12 +920,29 @@ sc_rs_cases() -> traffic_cases() -> [ + {group, traffic_counters}, {group, traffic_chunks}, {group, traffic_pp_send_recv}, {group, traffic_pp_sendto_recvfrom}, {group, traffic_pp_sendmsg_recvmsg} ]. +traffic_counters_cases() -> + [ + traffic_send_and_recv_counters_tcp4, + traffic_send_and_recv_counters_tcp6, + traffic_send_and_recv_counters_tcpL, + traffic_sendmsg_and_recvmsg_counters_tcp4, + traffic_sendmsg_and_recvmsg_counters_tcp6, + traffic_sendmsg_and_recvmsg_counters_tcpL, + traffic_sendto_and_recvfrom_counters_udp4, + traffic_sendto_and_recvfrom_counters_udp6, + traffic_sendto_and_recvfrom_counters_udpL, + traffic_sendmsg_and_recvmsg_counters_udp4, + traffic_sendmsg_and_recvmsg_counters_udp6, + traffic_sendmsg_and_recvmsg_counters_udpL + ]. + traffic_chunks_cases() -> [ traffic_send_and_recv_chunks_tcp4, @@ -1650,6 +1769,80 @@ quiet_mode(Config) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% +%% API MISC %% +%% %% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% A simple test case that tests that the global debug can be channged. +%% At the same time, it will test the info function (since it uses it +%% for verification). + +api_m_debug(suite) -> + []; +api_m_debug(doc) -> + []; +api_m_debug(_Config) when is_list(_Config) -> + ?TT(?SECS(5)), + tc_try(api_m_debug, + fun() -> has_bugfree_gcc() end, + fun() -> + ok = api_m_debug() + end). + +%% For some reason this test case triggers a gcc bug, which causes +%% a segfault, on an ancient Fedora 16 VM. So, check the version of gcc... +%% Not pretty, but the simplest way to skip (without actually testing for the host). +has_bugfree_gcc() -> + has_bugfree_gcc(os:type()). + +%% Make sure we are on linux +has_bugfree_gcc({unix, linux}) -> + has_bugfree_gcc2(string:trim(os:cmd("cat /etc/issue"))); +has_bugfree_gcc(_) -> + ok. + +%% Make sure we are on Fedora 16 +has_bugfree_gcc2("Fedora release 16 " ++ _) -> + has_bugfree_gcc3(os:cmd("gcc --version")); +has_bugfree_gcc2("Welcome to SUSE Linux " ++ _) -> + has_bugfree_gcc4(os:cmd("gcc --version")); +has_bugfree_gcc2(_) -> + ok. + +has_bugfree_gcc3("gcc (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2" ++ _) -> + skip("Buggy GCC"); +has_bugfree_gcc3(_) -> + ok. + +has_bugfree_gcc4("gcc (SUSE Linux) 4.3.2" ++ _) -> + skip("Buggy GCC"); +has_bugfree_gcc4(_) -> + ok. + +api_m_debug() -> + i("get initial info"), + #{debug := D0} = socket:info(), + D1 = not D0, + i("set new debug (~w => ~w)", [D0, D1]), + ok = socket:debug(D1), + i("get updated info (~w)", [D1]), + #{debug := D1} = socket:info(), + D2 = not D1, + i("set new debug (~w => ~w)", [D1, D2]), + ok = socket:debug(D2), + i("get updated info (~w)", [D2]), + #{debug := D2} = socket:info(), + i("ok"), + ok. + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% %% %% API BASIC %% %% %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -2669,7 +2862,7 @@ api_b_send_and_recv_tcp(InitState) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Basically establish a TCP connection via an async connect. +%% Basically establish a TCP connection via an async connect. IPv4. api_a_connect_tcp4(suite) -> []; @@ -2679,25 +2872,48 @@ api_a_connect_tcp4(_Config) when is_list(_Config) -> ?TT(?SECS(10)), tc_try(api_a_connect_tcp4, fun() -> - Connect = fun(Sock, SockAddr) -> - socket:connect(Sock, SockAddr, nowait) - end, - Send = fun(Sock, Data) -> - socket:send(Sock, Data) - end, - Recv = fun(Sock) -> - socket:recv(Sock) - end, - InitState = #{domain => inet, - connect => Connect, - send => Send, - recv => Recv}, - ok = api_a_connect_tcp(InitState) + ok = api_a_connect_tcpD(inet) + end). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% Basically establish a TCP connection via an async connect. IPv6. + +api_a_connect_tcp6(suite) -> + []; +api_a_connect_tcp6(doc) -> + []; +api_a_connect_tcp6(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), + tc_try(api_a_connect_tcp6, + fun() -> has_support_ipv6() end, + fun() -> + ok = api_a_connect_tcpD(inet6) end). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +api_a_connect_tcpD(Domain) -> + Connect = fun(Sock, SockAddr) -> + socket:connect(Sock, SockAddr, nowait) + end, + Send = fun(Sock, Data) -> + socket:send(Sock, Data) + end, + Recv = fun(Sock) -> + socket:recv(Sock) + end, + InitState = #{domain => Domain, + connect => Connect, + send => Send, + recv => Recv}, + api_a_connect_tcp(InitState). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + api_a_connect_tcp(InitState) -> process_flag(trap_exit, true), ServerSeq = @@ -3197,6 +3413,37 @@ api_a_sendto_and_recvfrom_udp4(_Config) when is_list(_Config) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Basically send and receive on an IPv6 UDP (dgram) socket using +%% sendto and recvfrom. But we try to be async. That is, we use +%% the 'nowait' value for the Timeout argument (and await the eventual +%% select message). Note that we only do this for the recvfrom, +%% since its much more difficult to "arrange" for sendto. +%% +api_a_sendto_and_recvfrom_udp6(suite) -> + []; +api_a_sendto_and_recvfrom_udp6(doc) -> + []; +api_a_sendto_and_recvfrom_udp6(_Config) when is_list(_Config) -> + ?TT(?SECS(5)), + tc_try(api_a_sendto_and_recvfrom_udp6, + fun() -> has_support_ipv6() end, + fun() -> + Send = fun(Sock, Data, Dest) -> + socket:sendto(Sock, Data, Dest) + end, + Recv = fun(Sock) -> + socket:recvfrom(Sock, 0, nowait) + end, + InitState = #{domain => inet6, + send => Send, + recv => Recv}, + ok = api_a_send_and_recv_udp(InitState) + end). + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %% Basically send and receive on an IPv4 UDP (dgram) socket using %% sendto and recvfrom. But we try to be async. That is, we use %% the 'nowait' value for the Timeout argument (and await the eventual @@ -3240,6 +3487,50 @@ api_a_sendmsg_and_recvmsg_udp4(_Config) when is_list(_Config) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Basically send and receive on an IPv6 UDP (dgram) socket using +%% sendto and recvfrom. But we try to be async. That is, we use +%% the 'nowait' value for the Timeout argument (and await the eventual +%% select message). Note that we only do this for the recvmsg, +%% since its much more difficult to "arrange" for sendmsg. +%% +api_a_sendmsg_and_recvmsg_udp6(suite) -> + []; +api_a_sendmsg_and_recvmsg_udp6(doc) -> + []; +api_a_sendmsg_and_recvmsg_udp6(_Config) when is_list(_Config) -> + ?TT(?SECS(5)), + tc_try(api_a_sendmsg_and_recvmsg_udp6, + fun() -> has_support_ipv6() end, + fun() -> + Send = fun(Sock, Data, Dest) -> + MsgHdr = #{addr => Dest, + %% ctrl => CMsgHdrs, + iov => [Data]}, + socket:sendmsg(Sock, MsgHdr) + end, + Recv = fun(Sock) -> + case socket:recvmsg(Sock, nowait) of + {ok, #{addr := Source, + iov := [Data]}} -> + {ok, {Source, Data}}; + {ok, _} = OK -> + OK; + {select, _} = SELECT -> + SELECT; + {error, _} = ERROR -> + ERROR + end + end, + InitState = #{domain => inet6, + send => Send, + recv => Recv}, + ok = api_a_send_and_recv_udp(InitState) + end). + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + api_a_send_and_recv_udp(InitState) -> ServerSeq = [ @@ -3689,6 +3980,37 @@ api_a_send_and_recv_tcp4(_Config) when is_list(_Config) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Basically send and receive using the "common" functions (send and recv) +%% on an IPv6 TCP (stream) socket. But we try to be async. That is, we use +%% the 'nowait' value for the Timeout argument (and await the eventual +%% select message). Note that we only do this for the recv, +%% since its much more difficult to "arrange" for send. +%% We *also* test async for accept. +api_a_send_and_recv_tcp6(suite) -> + []; +api_a_send_and_recv_tcp6(doc) -> + []; +api_a_send_and_recv_tcp6(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), + tc_try(api_a_send_and_recv_tcp6, + fun() -> has_support_ipv6() end, + fun() -> + Send = fun(Sock, Data) -> + socket:send(Sock, Data) + end, + Recv = fun(Sock) -> + socket:recv(Sock, 0, nowait) + end, + InitState = #{domain => inet6, + send => Send, + recv => Recv}, + ok = api_a_send_and_recv_tcp(InitState) + end). + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %% Basically send and receive using the msg functions (sendmsg and recvmsg) %% on an IPv4 TCP (stream) socket. But we try to be async. That is, we use %% the 'nowait' value for the Timeout argument (and await the eventual @@ -3716,7 +4038,7 @@ api_a_sendmsg_and_recvmsg_tcp4(_Config) when is_list(_Config) -> OK; {select, _} = SELECT -> SELECT; - {error, _} = ERROR -> + {error, _} = ERROR -> ERROR end end, @@ -3727,6 +4049,49 @@ api_a_sendmsg_and_recvmsg_tcp4(_Config) when is_list(_Config) -> end). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% Basically send and receive using the msg functions (sendmsg and recvmsg) +%% on an IPv6 TCP (stream) socket. But we try to be async. That is, we use +%% the 'nowait' value for the Timeout argument (and await the eventual +%% select message). Note that we only do this for the recvmsg, +%% since its much more difficult to "arrange" for sendmsg. +%% We *also* test async for accept. +api_a_sendmsg_and_recvmsg_tcp6(suite) -> + []; +api_a_sendmsg_and_recvmsg_tcp6(doc) -> + []; +api_a_sendmsg_and_recvmsg_tcp6(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), + tc_try(api_a_sendmsg_and_recvmsg_tcp6, + fun() -> has_support_ipv6() end, + fun() -> + Send = fun(Sock, Data) -> + MsgHdr = #{iov => [Data]}, + socket:sendmsg(Sock, MsgHdr) + end, + Recv = fun(Sock) -> + case socket:recvmsg(Sock, nowait) of + {ok, #{addr := undefined, + iov := [Data]}} -> + {ok, Data}; + {ok, _} = OK -> + OK; + {select, _} = SELECT -> + SELECT; + {error, _} = ERROR -> + ERROR + end + end, + InitState = #{domain => inet6, + send => Send, + recv => Recv}, + ok = api_a_send_and_recv_tcp(InitState) + end). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% api_a_send_and_recv_tcp(InitState) -> @@ -4227,7 +4592,7 @@ api_a_send_and_recv_tcp(InitState) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Basically we make an async (Timeout = nowait) call to recvfrom, -%% wait some time and then cancel. +%% wait some time and then cancel. IPv4 %% api_a_recvfrom_cancel_udp4(suite) -> []; @@ -4256,8 +4621,39 @@ api_a_recvfrom_cancel_udp4(_Config) when is_list(_Config) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Basically we make an async (Timeout = nowait) call to recvfrom, +%% wait some time and then cancel. IPv6 +%% +api_a_recvfrom_cancel_udp6(suite) -> + []; +api_a_recvfrom_cancel_udp6(doc) -> + []; +api_a_recvfrom_cancel_udp6(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), + tc_try(api_a_recvfrom_cancel_udp6, + fun() -> has_support_ipv6() end, + fun() -> + Recv = fun(Sock) -> + case socket:recvfrom(Sock, 0, nowait) of + {ok, _} = OK -> + OK; + {select, _} = SELECT -> + SELECT; + {error, _} = ERROR -> + ERROR + end + end, + InitState = #{domain => inet6, + recv => Recv}, + ok = api_a_recv_cancel_udp(InitState) + end). + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %% Basically we make an async (Timeout = nowait) call to recvmsg, -%% wait some time and then cancel. +%% wait some time and then cancel. IPv4 %% api_a_recvmsg_cancel_udp4(suite) -> []; @@ -4286,6 +4682,37 @@ api_a_recvmsg_cancel_udp4(_Config) when is_list(_Config) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Basically we make an async (Timeout = nowait) call to recvmsg, +%% wait some time and then cancel. IPv6 +%% +api_a_recvmsg_cancel_udp6(suite) -> + []; +api_a_recvmsg_cancel_udp6(doc) -> + []; +api_a_recvmsg_cancel_udp6(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), + tc_try(api_a_recvmsg_cancel_udp6, + fun() -> has_support_ipv6() end, + fun() -> + Recv = fun(Sock) -> + case socket:recvmsg(Sock, nowait) of + {ok, _} = OK -> + OK; + {select, _} = SELECT -> + SELECT; + {error, _} = ERROR -> + ERROR + end + end, + InitState = #{domain => inet6, + recv => Recv}, + ok = api_a_recv_cancel_udp(InitState) + end). + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + api_a_recv_cancel_udp(InitState) -> ServerSeq = [ @@ -4491,7 +4918,7 @@ api_a_recv_cancel_udp(InitState) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Basically we make an async (Timeout = nowait) call to accept, -%% wait some time and then cancel. +%% wait some time and then cancel. IPv4 %% api_a_accept_cancel_tcp4(suite) -> []; @@ -4521,6 +4948,38 @@ api_a_accept_cancel_tcp4(_Config) when is_list(_Config) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Basically we make an async (Timeout = nowait) call to accept, +%% wait some time and then cancel. IPv6 +%% +api_a_accept_cancel_tcp6(suite) -> + []; +api_a_accept_cancel_tcp6(doc) -> + []; +api_a_accept_cancel_tcp6(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), + tc_try(api_a_accept_cancel_tcp6, + fun() -> has_support_ipv6() end, + fun() -> + Accept = fun(Sock) -> + case socket:accept(Sock, nowait) of + {ok, _} = OK -> + OK; + {select, _} = SELECT -> + SELECT; + {error, _} = ERROR -> + ERROR + end + end, + InitState = #{domain => inet6, + accept => Accept}, + ok = api_a_accept_cancel_tcp(InitState) + end). + + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + api_a_accept_cancel_tcp(InitState) -> process_flag(trap_exit, true), ServerSeq = @@ -4721,7 +5180,7 @@ api_a_accept_cancel_tcp(InitState) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Basically we make an async (Timeout = nowait) call to recv, -%% wait some time and then cancel. +%% wait some time and then cancel. IPv4 %% api_a_recv_cancel_tcp4(suite) -> []; @@ -4743,8 +5202,32 @@ api_a_recv_cancel_tcp4(_Config) when is_list(_Config) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Basically we make an async (Timeout = nowait) call to recv, +%% wait some time and then cancel. IPv6 +%% +api_a_recv_cancel_tcp6(suite) -> + []; +api_a_recv_cancel_tcp6(doc) -> + []; +api_a_recv_cancel_tcp6(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), + tc_try(api_a_recv_cancel_tcp6, + fun() -> has_support_ipv6() end, + fun() -> + Recv = fun(Sock) -> + socket:recv(Sock, 0, nowait) + end, + InitState = #{domain => inet6, + recv => Recv}, + ok = api_a_recv_cancel_tcp(InitState) + end). + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %% Basically we make an async (Timeout = nowait) call to recvmsg, -%% wait some time and then cancel. +%% wait some time and then cancel. IPv4 %% api_a_recvmsg_cancel_tcp4(suite) -> []; @@ -4766,6 +5249,30 @@ api_a_recvmsg_cancel_tcp4(_Config) when is_list(_Config) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Basically we make an async (Timeout = nowait) call to recvmsg, +%% wait some time and then cancel. IPv6 +%% +api_a_recvmsg_cancel_tcp6(suite) -> + []; +api_a_recvmsg_cancel_tcp6(doc) -> + []; +api_a_recvmsg_cancel_tcp6(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), + tc_try(api_a_recvmsg_cancel_tcp6, + fun() -> has_support_ipv6() end, + fun() -> + Recv = fun(Sock) -> + socket:recvmsg(Sock, nowait) + end, + InitState = #{domain => inet6, + recv => Recv}, + ok = api_a_recv_cancel_tcp(InitState) + end). + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + api_a_recv_cancel_tcp(InitState) -> process_flag(trap_exit, true), ServerSeq = @@ -5119,7 +5626,7 @@ api_a_recv_cancel_tcp(InitState) -> %% Basically we make multiple async (Timeout = nowait) call(s) to recvfrom %% (from *several* processes), wait some time and then cancel. -%% This should result in abort messages to the 'other' processes. +%% This should result in abort messages to the 'other' processes. IPv4 %% api_a_mrecvfrom_cancel_udp4(suite) -> []; @@ -5148,9 +5655,41 @@ api_a_mrecvfrom_cancel_udp4(_Config) when is_list(_Config) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Basically we make multiple async (Timeout = nowait) call(s) to recvfrom +%% (from *several* processes), wait some time and then cancel. +%% This should result in abort messages to the 'other' processes. IPv6 +%% +api_a_mrecvfrom_cancel_udp6(suite) -> + []; +api_a_mrecvfrom_cancel_udp6(doc) -> + []; +api_a_mrecvfrom_cancel_udp6(_Config) when is_list(_Config) -> + ?TT(?SECS(20)), + tc_try(api_a_mrecvfrom_cancel_udp6, + fun() -> has_support_ipv6() end, + fun() -> + Recv = fun(Sock) -> + case socket:recvfrom(Sock, 0, nowait) of + {ok, _} = OK -> + OK; + {select, _} = SELECT -> + SELECT; + {error, _} = ERROR -> + ERROR + end + end, + InitState = #{domain => inet6, + recv => Recv}, + ok = api_a_mrecv_cancel_udp(InitState) + end). + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %% Basically we make multiple async (Timeout = nowait) call(s) to recvmsg %% (from *several* processes), wait some time and then cancel. -%% This should result in abort messages to the 'other' processes. +%% This should result in abort messages to the 'other' processes. IPv4 %% api_a_mrecvmsg_cancel_udp4(suite) -> []; @@ -5179,6 +5718,38 @@ api_a_mrecvmsg_cancel_udp4(_Config) when is_list(_Config) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Basically we make multiple async (Timeout = nowait) call(s) to recvmsg +%% (from *several* processes), wait some time and then cancel. +%% This should result in abort messages to the 'other' processes. IPv6 +%% +api_a_mrecvmsg_cancel_udp6(suite) -> + []; +api_a_mrecvmsg_cancel_udp6(doc) -> + []; +api_a_mrecvmsg_cancel_udp6(_Config) when is_list(_Config) -> + ?TT(?SECS(20)), + tc_try(api_a_mrecvmsg_cancel_udp6, + fun() -> has_support_ipv6() end, + fun() -> + Recv = fun(Sock) -> + case socket:recvmsg(Sock, nowait) of + {ok, _} = OK -> + OK; + {select, _} = SELECT -> + SELECT; + {error, _} = ERROR -> + ERROR + end + end, + InitState = #{domain => inet6, + recv => Recv}, + ok = api_a_mrecv_cancel_udp(InitState) + end). + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + api_a_mrecv_cancel_udp(InitState) -> ServerSeq = [ @@ -5550,7 +6121,7 @@ api_a_mrecv_cancel_udp(InitState) -> %% Basically we make multiple async (Timeout = nowait) call(s) to accept %% (from *several* processes), wait some time and then cancel, -%% This should result in abort messages to the 'other' processes. +%% This should result in abort messages to the 'other' processes. IPv4 %% api_a_maccept_cancel_tcp4(suite) -> []; @@ -5580,6 +6151,39 @@ api_a_maccept_cancel_tcp4(_Config) when is_list(_Config) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Basically we make multiple async (Timeout = nowait) call(s) to accept +%% (from *several* processes), wait some time and then cancel, +%% This should result in abort messages to the 'other' processes. IPv6 +%% +api_a_maccept_cancel_tcp6(suite) -> + []; +api_a_maccept_cancel_tcp6(doc) -> + []; +api_a_maccept_cancel_tcp6(_Config) when is_list(_Config) -> + ?TT(?SECS(20)), + tc_try(api_a_maccept_cancel_tcp6, + fun() -> has_support_ipv6() end, + fun() -> + Accept = fun(Sock) -> + case socket:accept(Sock, nowait) of + {ok, _} = OK -> + OK; + {select, _} = SELECT -> + SELECT; + {error, _} = ERROR -> + ERROR + end + end, + InitState = #{domain => inet6, + accept => Accept}, + ok = api_a_maccept_cancel_tcp(InitState) + end). + + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + api_a_maccept_cancel_tcp(InitState) -> process_flag(trap_exit, true), ServerSeq = @@ -5948,7 +6552,7 @@ api_a_maccept_cancel_tcp(InitState) -> %% Basically we make multiple async (Timeout = nowait) call(s) to recv %% (from *several* processes), wait some time and then cancel, -%% This should result in abort messages to the 'other' processes. +%% This should result in abort messages to the 'other' processes. IPv4 %% api_a_mrecv_cancel_tcp4(suite) -> []; @@ -5970,9 +6574,34 @@ api_a_mrecv_cancel_tcp4(_Config) when is_list(_Config) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Basically we make multiple async (Timeout = nowait) call(s) to recv +%% (from *several* processes), wait some time and then cancel, +%% This should result in abort messages to the 'other' processes. IPv6 +%% +api_a_mrecv_cancel_tcp6(suite) -> + []; +api_a_mrecv_cancel_tcp6(doc) -> + []; +api_a_mrecv_cancel_tcp6(_Config) when is_list(_Config) -> + ?TT(?SECS(20)), + tc_try(api_a_mrecv_cancel_tcp6, + fun() -> has_support_ipv6() end, + fun() -> + Recv = fun(Sock) -> + socket:recv(Sock, 0, nowait) + end, + InitState = #{domain => inet6, + recv => Recv}, + ok = api_a_mrecv_cancel_tcp(InitState) + end). + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %% Basically we make multiple async (Timeout = nowait) call(s) to recvmsg %% (from *several* processes), wait some time and then cancel, -%% This should result in abort messages to the 'other' processes. +%% This should result in abort messages to the 'other' processes. IPv4 %% api_a_mrecvmsg_cancel_tcp4(suite) -> []; @@ -5994,6 +6623,31 @@ api_a_mrecvmsg_cancel_tcp4(_Config) when is_list(_Config) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Basically we make multiple async (Timeout = nowait) call(s) to recvmsg +%% (from *several* processes), wait some time and then cancel, +%% This should result in abort messages to the 'other' processes. IPv6 +%% +api_a_mrecvmsg_cancel_tcp6(suite) -> + []; +api_a_mrecvmsg_cancel_tcp6(doc) -> + []; +api_a_mrecvmsg_cancel_tcp6(_Config) when is_list(_Config) -> + ?TT(?SECS(20)), + tc_try(api_a_mrecvmsg_cancel_tcp6, + fun() -> has_support_ipv6() end, + fun() -> + Recv = fun(Sock) -> + socket:recvmsg(Sock, nowait) + end, + InitState = #{domain => inet6, + recv => Recv}, + ok = api_a_mrecv_cancel_tcp(InitState) + end). + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + api_a_mrecv_cancel_tcp(InitState) -> process_flag(trap_exit, true), ServerSeq = @@ -7735,6 +8389,1695 @@ api_opt_simple_otp_controlling_process() -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Tests the socket option acceptconn for UDP. +%% This should be possible to get but not set. + +api_opt_sock_acceptconn_udp(suite) -> + []; +api_opt_sock_acceptconn_udp(doc) -> + []; +api_opt_sock_acceptconn_udp(_Config) when is_list(_Config) -> + ?TT(?SECS(30)), + tc_try(api_opt_sock_acceptconn_udp, + fun() -> + has_support_sock_acceptconn() + end, + fun() -> api_opt_sock_acceptconn_udp() end). + + + +api_opt_sock_acceptconn_udp() -> + Opt = acceptconn, + Set = fun(S, Val) -> + socket:setopt(S, socket, Opt, Val) + end, + Get = fun(S) -> + socket:getopt(S, socket, Opt) + end, + + TesterSeq = + [ + #{desc => "which local address", + cmd => fun(#{domain := Domain} = State) -> + LSA = which_local_socket_addr(Domain), + {ok, State#{local_sa => LSA}} + end}, + #{desc => "create socket", + cmd => fun(#{domain := Domain} = State) -> + case socket:open(Domain, dgram, udp) of + {ok, Sock} -> + {ok, State#{sock => Sock}}; + {error, _} = ERROR -> + ERROR + end + end}, + + #{desc => "[get] verify socket (before bind)", + cmd => fun(#{sock := Sock} = _State) -> + case Get(Sock) of + {ok, false} -> + ?SEV_IPRINT("Expected Success: " + "Not accepting connections"), + ok; + {ok, true} -> + ?SEV_EPRINT("Unexpected Success: " + "Accepting connections"), + {error, {unexpected_success, {Opt, true}}}; + {error, enoprotoopt = Reason} -> + %% On some platforms this is not accepted + %% for UDP, so skip this part (UDP). + ?SEV_EPRINT("Expected Failure: " + "~p => SKIP", [Reason]), + (catch socket:close(Sock)), + {skip, Reason}; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", + [Reason]), + ERROR + end + end}, + #{desc => "[set] verify socket (before bind)", + cmd => fun(#{sock := Sock} = _State) -> + case Set(Sock, true) of + {error, Reason} -> + ?SEV_IPRINT("Expected Failure: ~p", + [Reason]), + ok; + ok -> + ?SEV_EPRINT("Unexpected Success: " + "Set acceptconn (=true)"), + {error, unexpected_success} + end + end}, + + #{desc => "bind socket to local address", + cmd => fun(#{sock := Sock, local_sa := LSA} = _State) -> + case socket:bind(Sock, LSA) of + {ok, _} -> + ok; + {error, _} = ERROR -> + ERROR + end + end}, + + ?SEV_SLEEP(?SECS(1)), + + #{desc => "[get] verify socket (after bind)", + cmd => fun(#{sock := Sock} = _State) -> + case Get(Sock) of + {ok, false} -> + ?SEV_IPRINT("Expected Success: " + "Not accepting connections"), + ok; + {ok, true} -> + ?SEV_EPRINT("Unexpected Success: " + "Accepting connections"), + {error, {unexpected_success, {Opt, true}}}; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", + [Reason]), + ERROR + end + end}, + #{desc => "[set] verify socket (after bind)", + cmd => fun(#{sock := Sock} = _State) -> + case Set(Sock, true) of + {error, Reason} -> + ?SEV_IPRINT("Expected Failure: ~p", + [Reason]), + ok; + ok -> + ?SEV_EPRINT("Unexpected Success: " + "Set acceptconn (=true)"), + {error, unexpected_success} + end + end}, + + %% *** Termination *** + #{desc => "close socket", + cmd => fun(#{sock := Sock} = State) -> + socket:close(Sock), + {ok, maps:remove(sock, State)} + end}, + + %% *** We are done *** + ?SEV_FINISH_NORMAL + ], + + Domain = inet, + + i("start tester evaluator"), + InitState = #{domain => Domain}, + Tester = ?SEV_START("tester", TesterSeq, InitState), + + i("await evaluator(s)"), + ok = ?SEV_AWAIT_FINISH([Tester]). + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% Tests the socket option acceptconn for TCP. +%% This should be possible to get but not set. + +api_opt_sock_acceptconn_tcp(suite) -> + []; +api_opt_sock_acceptconn_tcp(doc) -> + []; +api_opt_sock_acceptconn_tcp(_Config) when is_list(_Config) -> + ?TT(?SECS(30)), + tc_try(api_opt_sock_acceptconn_tcp, + fun() -> + has_support_sock_acceptconn() + end, + fun() -> api_opt_sock_acceptconn_tcp() end). + + + +api_opt_sock_acceptconn_tcp() -> + Opt = acceptconn, + Set = fun(S, Val) -> + socket:setopt(S, socket, Opt, Val) + end, + Get = fun(S) -> + socket:getopt(S, socket, Opt) + end, + + TesterSeq = + [ + #{desc => "which local address", + cmd => fun(#{domain := Domain} = State) -> + LSA = which_local_socket_addr(Domain), + {ok, State#{local_sa => LSA}} + end}, + + #{desc => "create listen socket", + cmd => fun(#{domain := Domain} = State) -> + case socket:open(Domain, stream, tcp) of + {ok, Sock} -> + {ok, State#{lsock => Sock}}; + {error, _} = ERROR -> + ERROR + end + end}, + + #{desc => "[get] verify listen socket (before bind)", + cmd => fun(#{lsock := Sock} = _State) -> + case Get(Sock) of + {ok, false} -> + ?SEV_IPRINT("Expected Success: " + "Not accepting connections"), + ok; + {ok, true} -> + ?SEV_EPRINT("Unexpected Success: " + "Accepting connections"), + {error, {unexpected_success, {Opt, true}}}; + {error, enoprotoopt = Reason} -> + ?SEV_EPRINT("Expected Failure: " + "~p => SKIP", [Reason]), + (catch socket:close(Sock)), + {skip, Reason}; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", + [Reason]), + ERROR + end + end}, + #{desc => "[set] verify listen socket (before bind)", + cmd => fun(#{lsock := Sock} = _State) -> + case Set(Sock, true) of + {error, Reason} -> + ?SEV_IPRINT("Expected Failure: ~p", [Reason]), + ok; + ok -> + ?SEV_EPRINT("Unexpected Success: " + "Set acceptconn (=true)"), + {error, unexpected_success} + end + end}, + + ?SEV_SLEEP(?SECS(1)), + + #{desc => "bind listen socket to local address", + cmd => fun(#{lsock := Sock, local_sa := LSA} = State) -> + case socket:bind(Sock, LSA) of + {ok, Port} -> + {ok, State#{server_sa => LSA#{port => Port}}}; + {error, _} = ERROR -> + ERROR + end + end}, + + #{desc => "[get] verify listen socket (after bind)", + cmd => fun(#{lsock := Sock} = _State) -> + case Get(Sock) of + {ok, false} -> + ?SEV_IPRINT("Expected Success: " + "Not accepting connections"), + ok; + {ok, true} -> + ?SEV_EPRINT("Unexpected Success: " + "Accepting connections"), + {error, {unexpected_success, {Opt, true}}}; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]), + ERROR + end + end}, + #{desc => "[set] verify listen socket (after bind)", + cmd => fun(#{lsock := Sock} = _State) -> + case Set(Sock, true) of + {error, Reason} -> + ?SEV_IPRINT("Expected Failure: ~p", [Reason]), + ok; + ok -> + ?SEV_EPRINT("Unexpected Success: " + "Set acceptconn (=true)"), + {error, unexpected_success} + end + end}, + + ?SEV_SLEEP(?SECS(1)), + + #{desc => "make listen socket accept connections", + cmd => fun(#{lsock := Sock} = _State) -> + case socket:listen(Sock) of + ok -> + ok; + {error, _} = ERROR -> + ERROR + end + end}, + + #{desc => "[get] verify listen socket (after listen)", + cmd => fun(#{lsock := Sock} = _State) -> + case Get(Sock) of + {ok, true} -> + ?SEV_IPRINT("Expected Success: " + "Accepting connections"), + ok; + {ok, false} -> + ?SEV_EPRINT("Unexpected Success: " + "Not accepting connections"), + {error, {unexpected_success, {Opt, false}}}; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]), + ERROR + end + end}, + #{desc => "[set] verify listen socket (after listen)", + cmd => fun(#{lsock := Sock} = _State) -> + case Set(Sock, false) of + {error, Reason} -> + ?SEV_IPRINT("Expected Failure: ~p", [Reason]), + ok; + ok -> + ?SEV_EPRINT("Unexpected Success: " + "Set acceptconn (=false)"), + {error, unexpected_success} + end + end}, + + ?SEV_SLEEP(?SECS(1)), + + #{desc => "create (connecting) socket", + cmd => fun(#{domain := Domain} = State) -> + case socket:open(Domain, stream, tcp) of + {ok, Sock} -> + {ok, State#{csockc => Sock}}; + {error, _} = ERROR -> + ERROR + end + end}, + + #{desc => "bind connecting socket to local address", + cmd => fun(#{csockc := Sock, local_sa := LSA} = _State) -> + case socket:bind(Sock, LSA) of + {ok, _Port} -> + ok; + {error, _} = ERROR -> + ERROR + end + end}, + + ?SEV_SLEEP(?SECS(1)), + + #{desc => "[get] verify connecting socket (before connect)", + cmd => fun(#{csockc := Sock} = _State) -> + case Get(Sock) of + {ok, false} -> + ?SEV_IPRINT("Expected Success: " + "Not accepting connections"), + ok; + {ok, true} -> + ?SEV_EPRINT("Unexpected Success: " + "Accepting connections"), + {error, {unexpected_success, {Opt, true}}}; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]), + ERROR + end + end}, + #{desc => "[set] verify connecting socket (before connect)", + cmd => fun(#{csockc := Sock} = _State) -> + case Set(Sock, true) of + {error, Reason} -> + ?SEV_IPRINT("Expected Failure: ~p", [Reason]), + ok; + ok -> + ?SEV_EPRINT("Unexpected Success: " + "Set acceptconn (=true)"), + {error, unexpected_success} + end + end}, + + ?SEV_SLEEP(?SECS(1)), + + #{desc => "connect to server", + cmd => fun(#{csockc := Sock, server_sa := SSA} = _State) -> + case socket:connect(Sock, SSA) of + ok -> + ok; + {error, _} = ERROR -> + ERROR + end + end}, + + #{desc => "accept connection", + cmd => fun(#{lsock := Sock} = State) -> + case socket:accept(Sock) of + {ok, CSock} -> + {ok, State#{csocks => CSock}}; + {error, _} = ERROR -> + ERROR + end + end}, + + #{desc => "[get] verify connecting socket (after connect)", + cmd => fun(#{csockc := Sock} = _State) -> + case Get(Sock) of + {ok, false} -> + ?SEV_IPRINT("Expected Success: " + "Not accepting connections"), + ok; + {ok, true} -> + ?SEV_EPRINT("Unexpected Success: " + "Accepting connections"), + {error, {unexpected_success, {Opt, true}}}; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]), + ERROR + end + end}, + #{desc => "[set] verify connecting socket (after connect)", + cmd => fun(#{csockc := Sock} = _State) -> + case Set(Sock, true) of + {error, Reason} -> + ?SEV_IPRINT("Expected Failure: ~p", [Reason]), + ok; + ok -> + ?SEV_EPRINT("Unexpected Success: " + "Set acceptconn (=true)"), + {error, unexpected_success} + end + end}, + + #{desc => "[get] verify connected socket", + cmd => fun(#{csocks := Sock} = _State) -> + case Get(Sock) of + {ok, false} -> + ?SEV_IPRINT("Expected Success: " + "Not accepting connections"), + ok; + {ok, true} -> + ?SEV_EPRINT("Unexpected Success: " + "Accepting connections"), + {error, {unexpected_success, {Opt, true}}}; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]), + ERROR + end + end}, + #{desc => "[set] verify connected socket", + cmd => fun(#{csocks := Sock} = _State) -> + case Set(Sock, true) of + {error, Reason} -> + ?SEV_IPRINT("Expected Failure: ~p", [Reason]), + ok; + ok -> + ?SEV_EPRINT("Unexpected Success: " + "Set acceptconn (=true)"), + {error, unexpected_success} + end + end}, + + #{desc => "[get] verify listen socket (after connect)", + cmd => fun(#{lsock := Sock} = _State) -> + case Get(Sock) of + {ok, true} -> + ?SEV_IPRINT("Expected Success: " + "Accepting connections"), + ok; + {ok, false} -> + ?SEV_EPRINT("Unexpected Success: " + "Not accepting connections"), + {error, {unexpected_success, {Opt, false}}}; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]), + ERROR + end + end}, + #{desc => "[set] verify listen socket (after connect)", + cmd => fun(#{lsock := Sock} = _State) -> + case Set(Sock, false) of + {error, Reason} -> + ?SEV_IPRINT("Expected Failure: ~p", [Reason]), + ok; + ok -> + ?SEV_EPRINT("Unexpected Success: " + "Set acceptconn (=false)"), + {error, unexpected_success} + end + end}, + + %% *** Termination *** + #{desc => "close connecting socket(s)", + cmd => fun(#{csockc := Sock} = State0) -> + socket:close(Sock), + State1 = maps:remove(csockc, State0), + State2 = maps:remove(csocks, State1), %% Auto-close + {ok, maps:remove(csockc, State2)} + end}, + #{desc => "close listen socket", + cmd => fun(#{lsock := Sock} = State) -> + socket:close(Sock), + {ok, maps:remove(lsock, State)} + end}, + + %% *** We are done *** + ?SEV_FINISH_NORMAL + ], + + + Domain = inet, + + i("start tester evaluator"), + InitState = #{domain => Domain}, + Tester = ?SEV_START("tester", TesterSeq, InitState), + + i("await evaluator(s)"), + ok = ?SEV_AWAIT_FINISH([Tester]). + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% Tests the socket option acceptfilter. PLACEHOLDER! + +api_opt_sock_acceptfilter(suite) -> + []; +api_opt_sock_acceptfilter(doc) -> + []; +api_opt_sock_acceptfilter(_Config) when is_list(_Config) -> + ?TT(?SECS(30)), + tc_try(api_opt_sock_acceptfilter, + fun() -> not_yet_implemented() end, + fun() -> ok end). + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% Tests the socket option bindtodevice. +%% It has not always been possible to 'get' this option +%% (atleast on linux). + +api_opt_sock_bindtodevice(suite) -> + []; +api_opt_sock_bindtodevice(doc) -> + []; +api_opt_sock_bindtodevice(_Config) when is_list(_Config) -> + ?TT(?SECS(30)), + tc_try(api_opt_sock_bindtodevice, + fun() -> has_support_sock_bindtodevice() end, + fun() -> api_opt_sock_bindtodevice() end). + + +api_opt_sock_bindtodevice() -> + Opt = bindtodevice, + Set = fun(S, Val) -> + socket:setopt(S, socket, Opt, Val) + end, + Get = fun(S) -> + socket:getopt(S, socket, Opt) + end, + + TesterSeq = + [ + #{desc => "which local address", + cmd => fun(#{domain := Domain} = State) -> + case ?LIB:which_local_host_info(Domain) of + {ok, #{name := Name, addr := Addr}} -> + ?SEV_IPRINT("local host info (~p): " + "~n Name: ~p" + "~n Addr: ~p", + [Domain, Name, Addr]), + LSA = #{family => Domain, + addr => Addr}, + {ok, State#{dev => Name, + local_sa => LSA}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "create UDP socket 1", + cmd => fun(#{domain := Domain} = State) -> + case socket:open(Domain, dgram, udp) of + {ok, Sock} -> + {ok, State#{usock1 => Sock}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "create UDP socket 2", + cmd => fun(#{domain := Domain} = State) -> + case socket:open(Domain, dgram, udp) of + {ok, Sock} -> + {ok, State#{usock2 => Sock}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "create TCP socket 1", + cmd => fun(#{domain := Domain} = State) -> + case socket:open(Domain, stream, tcp) of + {ok, Sock} -> + {ok, State#{tsock1 => Sock}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "create TCP socket 2", + cmd => fun(#{domain := Domain} = State) -> + case socket:open(Domain, stream, tcp) of + {ok, Sock} -> + {ok, State#{tsock2 => Sock}}; + {error, _} = ERROR -> + ERROR + end + end}, + + #{desc => "[get] verify UDP socket 1 (before bindtodevice)", + cmd => fun(#{usock1 := Sock} = _State) -> + case Get(Sock) of + {ok, Dev} -> + ?SEV_IPRINT("Expected Success: ~p", [Dev]), + ok; + {error, enoprotoopt = Reason} -> + ?SEV_EPRINT("Unexpected Failure: ~p => SKIP", + [Reason]), + {skip, Reason}; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", + [Reason]), + ERROR + end + end}, + #{desc => "[get] verify UDP socket 2 (before bind)", + cmd => fun(#{usock2 := Sock} = _State) -> + case Get(Sock) of + {ok, Dev} -> + ?SEV_IPRINT("Expected Success: ~p", [Dev]), + ok; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]), + ERROR + end + end}, + #{desc => "[get] verify TCP socket 1 (before bindtodevice)", + cmd => fun(#{tsock1 := Sock} = _State) -> + case Get(Sock) of + {ok, Dev} -> + ?SEV_IPRINT("Expected Success: ~p", [Dev]), + ok; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]), + ERROR + end + end}, + #{desc => "[get] verify TCP socket 2 (before bind)", + cmd => fun(#{tsock2 := Sock} = _State) -> + case Get(Sock) of + {ok, Dev} -> + ?SEV_IPRINT("Expected Success: ~p", [Dev]), + ok; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]), + ERROR + end + end}, + + ?SEV_SLEEP(?SECS(1)), + + #{desc => "Bind UDP socket 1 to device", + cmd => fun(#{usock1 := Sock, dev := Dev} = State) -> + case Set(Sock, Dev) of + ok -> + ?SEV_IPRINT("Expected Success"), + ok; + {error, eperm = Reason} -> + ?SEV_IPRINT("Expected Failure: ~p", [Reason]), + (catch socket:close(Sock)), + {ok, State#{usock1 => skip}}; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]), + ERROR + end + end}, + #{desc => "Bind UDP socket 2 to local address", + cmd => fun(#{usock2 := Sock, local_sa := LSA} = _State) -> + case socket:bind(Sock, LSA) of + {ok, _Port} -> + ?SEV_IPRINT("Expected Success"), + ok; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]), + ERROR + end + end}, + #{desc => "Bind TCP socket 1 to device", + cmd => fun(#{usock1 := USock1, + tsock1 := Sock, dev := Dev} = State) -> + case Set(Sock, Dev) of + ok -> + ?SEV_IPRINT("Expected Success"), + ok; + {error, eperm = Reason} when (USock1 =:= skip) -> + ?SEV_IPRINT("Expected Failure: ~p", [Reason]), + {skip, Reason}; + {error, eperm = Reason} -> + ?SEV_IPRINT("Expected Failure: ~p", [Reason]), + (catch socket:close(Sock)), + {ok, State#{tsock1 => skip}}; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]), + ERROR + end + end}, + #{desc => "Bind TCP socket 2 to local address", + cmd => fun(#{tsock2 := Sock, local_sa := LSA} = _State) -> + case socket:bind(Sock, LSA) of + {ok, _Port} -> + ?SEV_IPRINT("Expected Success"), + ok; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]), + ERROR + end + end}, + + ?SEV_SLEEP(?SECS(1)), + + #{desc => "[get] verify UDP socket 1 (after bindtodevice)", + cmd => fun(#{usock1 := skip} = _State) -> + ?SEV_IPRINT("SKIP'ed (previous eperm)"), + ok; + (#{usock1 := Sock} = _State) -> + case Get(Sock) of + {ok, Dev} -> + ?SEV_IPRINT("Expected Success: ~p", [Dev]), + ok; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]), + ERROR + end + end}, + #{desc => "[get] verify UDP socket 2 (after bind)", + cmd => fun(#{usock2 := Sock} = _State) -> + case Get(Sock) of + {ok, Dev} -> + ?SEV_IPRINT("Expected Success: ~p", [Dev]), + ok; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]), + ERROR + end + end}, + #{desc => "[get] verify TCP socket 1 (after bindtodevice)", + cmd => fun(#{tsock1 := skip} = _State) -> + ?SEV_IPRINT("SKIP'ed (previous eperm)"), + ok; + (#{tsock1 := Sock} = _State) -> + case Get(Sock) of + {ok, Dev} -> + ?SEV_IPRINT("Expected Success: ~p", [Dev]), + ok; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]), + ERROR + end + end}, + #{desc => "[get] verify TCP socket 2 (after bind)", + cmd => fun(#{tsock2 := Sock} = _State) -> + case Get(Sock) of + {ok, Dev} -> + ?SEV_IPRINT("Expected Success: ~p", [Dev]), + ok; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", [Reason]), + ERROR + end + end}, + + ?SEV_SLEEP(?SECS(1)), + + %% *** Termination *** + #{desc => "close UDP socket 1", + cmd => fun(#{usock1 := skip} = State) -> + ?SEV_IPRINT("SKIP'ed (already closed)"), + {ok, maps:remove(usock1, State)}; + (#{usock1 := Sock} = State) -> + socket:close(Sock), + {ok, maps:remove(usock1, State)} + end}, + #{desc => "close UDP socket 2", + cmd => fun(#{usock2 := Sock} = State) -> + socket:close(Sock), + {ok, maps:remove(usock2, State)} + end}, + #{desc => "close TCP socket 1", + cmd => fun(#{tsock1 := skip} = State) -> + ?SEV_IPRINT("SKIP'ed (already closed)"), + {ok, maps:remove(tsock1, State)}; + (#{tsock1 := Sock} = State) -> + socket:close(Sock), + {ok, maps:remove(tsock1, State)} + end}, + #{desc => "close TCP socket 2", + cmd => fun(#{tsock2 := Sock} = State) -> + socket:close(Sock), + {ok, maps:remove(tsock2, State)} + end}, + + %% *** We are done *** + ?SEV_FINISH_NORMAL + ], + + Domain = inet, + + i("start tester evaluator"), + InitState = #{domain => Domain}, + Tester = ?SEV_START("tester", TesterSeq, InitState), + + i("await evaluator(s)"), + ok = ?SEV_AWAIT_FINISH([Tester]). + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% Tests the socket option broadcast. +%% Make it possible for datagram sockets to send packets to a broadcast +%% address (IPv4 only). + +api_opt_sock_broadcast(suite) -> + []; +api_opt_sock_broadcast(doc) -> + []; +api_opt_sock_broadcast(_Config) when is_list(_Config) -> + ?TT(?SECS(30)), + tc_try(api_opt_sock_broadcast, + fun() -> has_support_sock_broadcast() end, + fun() -> api_opt_sock_broadcast() end). + + +api_opt_sock_broadcast() -> + Opt = broadcast, + Set = fun(S, Val) when is_boolean(Val) -> + socket:setopt(S, socket, Opt, Val) + end, + Get = fun(S) -> + socket:getopt(S, socket, Opt) + end, + + TesterSeq = + [ + #{desc => "which local address", + cmd => fun(#{domain := Domain} = State) -> + case ?LIB:which_local_host_info(Domain) of + {ok, #{name := Name, + addr := Addr, + broadaddr := BAddr}} -> + ?SEV_IPRINT("local host info: " + "~n Name: ~p" + "~n Addr: ~p" + "~n Broadcast Addr: ~p", + [Name, Addr, BAddr]), + LSA = #{family => Domain, + addr => Addr}, + BSA = #{family => Domain, + addr => BAddr}, + {ok, State#{lsa => LSA, + bsa => BSA}}; + {error, _} = ERROR -> + ERROR + end + end}, + + #{desc => "[socket 1] create UDP socket (listening 1)", + cmd => fun(#{domain := Domain} = State) -> + case socket:open(Domain, dgram, udp) of + {ok, Sock} -> + {ok, State#{sock1 => Sock}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "[socket 1] Bind UDP socket (to limited broadcast address)", + cmd => fun(#{sock1 := Sock} = State) -> + BSA = #{family => inet, + addr => broadcast}, + ?SEV_IPRINT("Try bind (socket 1) to: " + "~n ~p", [BSA]), + case socket:bind(Sock, BSA) of + {ok, Port} -> + ?SEV_IPRINT("Expected Success (bound): ~p", + [Port]), + {ok, State#{sa1 => BSA#{port => Port}}}; + {error, eaddrnotavail = Reason} -> + ?SEV_IPRINT("~p => " + "SKIP limited broadcast test", + [Reason]), + {ok, State#{sa1 => skip}}; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", + [Reason]), + ERROR + end + end}, + #{desc => "[socket 1] UDP socket sockname", + cmd => fun(#{sa1 := skip} = _State) -> + ?SEV_IPRINT("SKIP limited broadcast test"), + ok; + (#{sock1 := Sock} = _State) -> + case socket:sockname(Sock) of + {ok, SA} -> + ?SEV_IPRINT("SA: ~p", [SA]), + ok; + {error, _} = ERROR -> + ERROR + end + end}, + + ?SEV_SLEEP(?SECS(1)), + + #{desc => "[socket 2] create UDP socket (listening 2)", + cmd => fun(#{domain := Domain} = State) -> + case socket:open(Domain, dgram, udp) of + {ok, Sock} -> + {ok, State#{sock2 => Sock}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "[socket 2] Bind UDP socket (to subnet-directed broadcast address)", + cmd => fun(#{sock2 := Sock, + bsa := BSA} = State) -> + ?SEV_IPRINT("Try bind (socket 1) to: " + "~n ~p", [BSA]), + case socket:bind(Sock, BSA) of + {ok, Port} -> + ?SEV_IPRINT("Expected Success (bound): ~p", + [Port]), + {ok, State#{sa2 => BSA#{port => Port}}}; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", + [Reason]), + ERROR + end + end}, + #{desc => "[socket 2] UDP socket sockname", + cmd => fun(#{sock2 := Sock} = _State) -> + case socket:sockname(Sock) of + {ok, SA} -> + ?SEV_IPRINT("SA: ~p", [SA]), + ok; + {error, _} = ERROR -> + ERROR + end + end}, + + ?SEV_SLEEP(?SECS(1)), + + #{desc => "[socket 3] create UDP socket (sender)", + cmd => fun(#{domain := Domain} = State) -> + case socket:open(Domain, dgram, udp) of + {ok, Sock} -> + {ok, State#{sock3 => Sock}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "[socket 3][get] verify UDP socket (before bind and set)", + cmd => fun(#{sock3 := Sock} = _State) -> + case Get(Sock) of + {ok, false} -> + ?SEV_IPRINT("Expected Success: " + "broadcast not allowed"), + ok; + {ok, true} -> + ?SEV_IPRINT("Unexpected Success result: " + "broadcast already allowed"), + ok; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", + [Reason]), + ERROR + end + end}, + #{desc => "[socket 3] Try make broadcast allowed", + cmd => fun(#{sock3 := Sock} = _State) -> + case Set(Sock, true) of + ok -> + ?SEV_IPRINT("Expected Success: " + "broadcast now allowed"), + ok; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", + [Reason]), + ERROR + end + end}, + #{desc => "[socket 3] verify UDP socket broadcast allowed", + cmd => fun(#{sock3 := Sock} = _State) -> + case Get(Sock) of + {ok, true} -> + ?SEV_IPRINT("Expected Success: " + "broadcast allowed"), + ok; + {ok, false} -> + ?SEV_IPRINT("Unexpected Success result: " + "broadcast *not* allowed"), + ok; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", + [Reason]), + ERROR + end + end}, + #{desc => "[socket 3] Bind UDP socket (to local address)", + cmd => fun(#{sock3 := Sock, lsa := LSA} = State) -> + ?SEV_IPRINT("Try bind (socket 2) to: " + "~n ~p", [LSA]), + case socket:bind(Sock, LSA) of + {ok, Port} -> + ?SEV_IPRINT("Expected Success (bound): ~p", + [Port]), + {ok, State#{sa3 => LSA#{port => Port}}}; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", + [Reason]), + ERROR + end + end}, + #{desc => "[socket 3] verify UDP socket (after set)", + cmd => fun(#{sock3 := Sock} = _State) -> + case Get(Sock) of + {ok, true} -> + ?SEV_IPRINT("Expected Success: " + "broadcast allowed"), + ok; + {ok, false} -> + ?SEV_IPRINT("Unexpected Success result: " + "broadcast not allowed"), + {error, not_allowed}; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", + [Reason]), + ERROR + end + end}, + + ?SEV_SLEEP(?SECS(1)), + + #{desc => "[socket 3] try send to limited broadcast address", + cmd => fun(#{sa1 := skip} = _State) -> + ?SEV_IPRINT("SKIP limited broadcast test"), + ok; + (#{sock3 := Sock, + sa1 := Dest} = _State) -> + Data = list_to_binary("hejsan"), + ?SEV_IPRINT("try send to bradcast address: " + "~n ~p", [Dest]), + case socket:sendto(Sock, Data, Dest) of + ok -> + ?SEV_IPRINT("Expected Success: " + "broadcast message sent"), + ok; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", + [Reason]), + ERROR + end + end}, + #{desc => "[socket 1] try recv", + cmd => fun(#{sa1 := skip} = _State) -> + ?SEV_IPRINT("SKIP limited broadcast test"), + ok; + (#{sock1 := Sock} = State) -> + case socket:recvfrom(Sock, 0, 5000) of + {ok, _} -> + ?SEV_IPRINT("Expected Success: " + "received message"), + ok; + {error, timeout = Reason} -> + %% Some platforms seem to balk at this. + %% It spossible to bind to this, and + %% send to it, but no data is received. + %% At some point we should investigate... + %% For now, we just skip this part of + %% the test... + ?SEV_IPRINT("Unexpected Failure: ~p", + [Reason]), + {ok, State#{sa1 => skip}}; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", + [Reason]), + ERROR + end + end}, + + ?SEV_SLEEP(?SECS(1)), + + #{desc => "[socket 3] try send to subnet-directed broadcast address", + cmd => fun(#{sock3 := Sock, + sa2 := Dest} = _State) -> + Data = list_to_binary("hejsan"), + ?SEV_IPRINT("try send to bradcast address: " + "~n ~p", [Dest]), + case socket:sendto(Sock, Data, Dest) of + ok -> + ?SEV_IPRINT("Expected Success: " + "broadcast message sent"), + ok; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", + [Reason]), + ERROR + end + end}, + #{desc => "[socket 2] try recv", + cmd => fun(#{sock2 := Sock, sa1 := SA1} = _State) -> + case socket:recvfrom(Sock, 0, 5000) of + {ok, _} -> + ?SEV_IPRINT("Expected Success: " + "received message"), + ok; + {error, timeout = Reason} when (SA1 =:= skip) -> + ?SEV_IPRINT("Unexpected Failure: ~p", + [Reason]), + {skip, "receive timeout"}; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", + [Reason]), + ERROR + end + end}, + + %% *** Termination *** + #{desc => "[socket 3] close UDP socket (sender)", + cmd => fun(#{sock3 := Sock} = State0) -> + socket:close(Sock), + State1 = maps:remove(sock3, State0), + State2 = maps:remove(sa3, State1), + {ok, State2} + end}, + #{desc => "[socket 2] close UDP socket (listener 2)", + cmd => fun(#{sock2 := Sock} = State0) -> + socket:close(Sock), + State1 = maps:remove(sock2, State0), + State2 = maps:remove(sa2, State1), + {ok, State2} + end}, + #{desc => "[socket 1] close UDP socket (listener 1)", + cmd => fun(#{sock1 := Sock} = State0) -> + socket:close(Sock), + State1 = maps:remove(sock1, State0), + State2 = maps:remove(sa1, State1), + {ok, State2} + end}, + + %% *** We are done *** + ?SEV_FINISH_NORMAL + ], + + Domain = inet, + + i("start tester evaluator"), + InitState = #{domain => Domain}, + Tester = ?SEV_START("tester", TesterSeq, InitState), + + i("await evaluator(s)"), + ok = ?SEV_AWAIT_FINISH([Tester]). + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% Tests the socket option debug. +%% On linux, this test requires that the user running the test to have +%% CAP_NET_ADMIN capabilities or be root (effective user ID of 0), +%% therefor we explicitly test for the result eacces when attempting to +%% set, and skip if we get it. + +api_opt_sock_debug(suite) -> + []; +api_opt_sock_debug(doc) -> + []; +api_opt_sock_debug(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), + tc_try(api_opt_sock_debug, + fun() -> has_support_sock_debug() end, + fun() -> api_opt_sock_debug() end). + + +api_opt_sock_debug() -> + Opt = debug, + Set = fun(S, Val) when is_integer(Val) -> + socket:setopt(S, socket, Opt, Val) + end, + Get = fun(S) -> + socket:getopt(S, socket, Opt) + end, + + TesterSeq = + [ + #{desc => "which local address", + cmd => fun(#{domain := Domain} = State) -> + case ?LIB:which_local_host_info(Domain) of + {ok, #{name := Name, + addr := Addr, + broadaddr := BAddr}} -> + ?SEV_IPRINT("local host info: " + "~n Name: ~p" + "~n Addr: ~p" + "~n Broadcast Addr: ~p", + [Name, Addr, BAddr]), + LSA = #{family => Domain, + addr => Addr}, + BSA = #{family => Domain, + addr => BAddr}, + {ok, State#{lsa => LSA, + bsa => BSA}}; + {error, _} = ERROR -> + ERROR + end + end}, + + #{desc => "create UDP socket", + cmd => fun(#{domain := Domain} = State) -> + case socket:open(Domain, dgram, udp) of + {ok, Sock} -> + {ok, State#{sock => Sock}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "Get current debug value", + cmd => fun(#{sock := Sock} = State) -> + case Get(Sock) of + {ok, Debug} when is_integer(Debug) -> + ?SEV_IPRINT("Success: ~p", [Debug]), + {ok, State#{debug => Debug}}; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected failure: ~p", + [Reason]), + ERROR + end + end}, + #{desc => "Try enable socket debug", + cmd => fun(#{sock := Sock, debug := Debug} = State) -> + NewDebug = Debug + 1, + case Set(Sock, NewDebug) of + ok -> + ?SEV_IPRINT("Expected Success"), + {ok, State#{debug => NewDebug}}; + {error, eacces = Reason} -> + ?SEV_EPRINT("NO ACCESS => SKIP"), + {skip, Reason}; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", + [Reason]), + ERROR + end + end}, + #{desc => "Get current (new) debug value", + cmd => fun(#{sock := Sock, debug := Debug} = _State) -> + case Get(Sock) of + {ok, Debug} when is_integer(Debug) -> + ?SEV_IPRINT("Success: ~p", [Debug]), + ok; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected failure: ~p", + [Reason]), + ERROR + end + end}, + + %% *** Termination *** + #{desc => "close UDP socket", + cmd => fun(#{sock := Sock} = State0) -> + socket:close(Sock), + State1 = maps:remove(sock, State0), + {ok, State1} + end}, + + %% *** We are done *** + ?SEV_FINISH_NORMAL + ], + + Domain = inet, + + i("start tester evaluator"), + InitState = #{domain => Domain}, + Tester = ?SEV_START("tester", TesterSeq, InitState), + + i("await evaluator(s)"), + ok = ?SEV_AWAIT_FINISH([Tester]). + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% Tests the socket option domain. +%% This is a read only option. Also not available on all platforms. + +api_opt_sock_domain(suite) -> + []; +api_opt_sock_domain(doc) -> + []; +api_opt_sock_domain(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), + tc_try(api_opt_sock_domain, + fun() -> has_support_sock_domain() end, + fun() -> api_opt_sock_domain() end). + + +api_opt_sock_domain() -> + Opt = domain, + Get = fun(S) -> + socket:getopt(S, socket, Opt) + end, + + TesterSeq = + [ + #{desc => "which local address", + cmd => fun(#{domain := Domain} = State) -> + case ?LIB:which_local_host_info(Domain) of + {ok, #{name := Name, + addr := Addr, + broadaddr := BAddr}} -> + ?SEV_IPRINT("local host info: " + "~n Name: ~p" + "~n Addr: ~p" + "~n Broadcast Addr: ~p", + [Name, Addr, BAddr]), + LSA = #{family => Domain, + addr => Addr}, + BSA = #{family => Domain, + addr => BAddr}, + {ok, State#{lsa => LSA, + bsa => BSA}}; + {error, _} = ERROR -> + ERROR + end + end}, + + #{desc => "create IPv4 UDP socket", + cmd => fun(#{domain := Domain} = State) -> + case socket:open(Domain, dgram, udp) of + {ok, Sock} -> + {ok, State#{usock => Sock}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "Get domain for the UDP socket", + cmd => fun(#{domain := Domain, usock := Sock} = _State) -> + case Get(Sock) of + {ok, Domain} -> + ?SEV_IPRINT("Success: ~p", [Domain]), + ok; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected failure: ~p", + [Reason]), + ERROR + end + end}, + #{desc => "create TCP socket", + cmd => fun(#{domain := Domain} = State) -> + case socket:open(Domain, stream, tcp) of + {ok, Sock} -> + {ok, State#{tsock => Sock}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "Get domain for the TCP socket", + cmd => fun(#{domain := Domain, tsock := Sock} = _State) -> + case Get(Sock) of + {ok, Domain} -> + ?SEV_IPRINT("Success: ~p", [Domain]), + ok; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected failure: ~p", + [Reason]), + ERROR + end + end}, + + %% *** Termination *** + #{desc => "close UDP socket", + cmd => fun(#{usock := Sock} = State0) -> + socket:close(Sock), + State1 = maps:remove(usock, State0), + {ok, State1} + end}, + #{desc => "close TCP socket", + cmd => fun(#{tsock := Sock} = State0) -> + socket:close(Sock), + State1 = maps:remove(tsock, State0), + {ok, State1} + end}, + + %% *** We are done *** + ?SEV_FINISH_NORMAL + ], + + Domain = inet, + + i("start tester evaluator"), + InitState = #{domain => Domain}, + Tester = ?SEV_START("tester", TesterSeq, InitState), + + i("await evaluator(s)"), + ok = ?SEV_AWAIT_FINISH([Tester]). + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% Tests the socket option dontroute. +%% The man page has the following to say: +%% "Don't send via a gateway, send only to directly connected hosts. +%% The same effect can be achieved by setting the MSG_DONTROUTE +%% flag on a socket send(2) operation." +%% Since its "kind of" difficult to check if it actually takes an +%% effect (you would need a gateway for that and a machine "on the +%% other side"), we only test if we can set and get the value. +%% Better then nothing. + +api_opt_sock_dontroute(suite) -> + []; +api_opt_sock_dontroute(doc) -> + []; +api_opt_sock_dontroute(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), + tc_try(api_opt_sock_dontroute, + fun() -> has_support_sock_dontroute() end, + fun() -> api_opt_sock_dontroute() end). + + +api_opt_sock_dontroute() -> + Opt = dontroute, + Set = fun(S, Val) when is_boolean(Val) -> + socket:setopt(S, socket, Opt, Val) + end, + Get = fun(S) -> + socket:getopt(S, socket, Opt) + end, + + TesterSeq = + [ + #{desc => "which local address", + cmd => fun(#{domain := Domain} = State) -> + case ?LIB:which_local_host_info(Domain) of + {ok, #{name := Name, + addr := Addr, + broadaddr := BAddr}} -> + ?SEV_IPRINT("local host info: " + "~n Name: ~p" + "~n Addr: ~p" + "~n Broadcast Addr: ~p", + [Name, Addr, BAddr]), + LSA = #{family => Domain, + addr => Addr}, + BSA = #{family => Domain, + addr => BAddr}, + {ok, State#{lsa => LSA, + bsa => BSA}}; + {error, _} = ERROR -> + ERROR + end + end}, + + #{desc => "create UDP socket", + cmd => fun(#{domain := Domain} = State) -> + case socket:open(Domain, dgram, udp) of + {ok, Sock} -> + {ok, State#{sock => Sock}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "Get current value", + cmd => fun(#{sock := Sock} = State) -> + case Get(Sock) of + {ok, Val} when is_boolean(Val) -> + ?SEV_IPRINT("Success: ~p", [Val]), + {ok, State#{dontroute => Val}}; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected failure: ~p", + [Reason]), + ERROR + end + end}, + #{desc => "Try change value", + cmd => fun(#{sock := Sock, dontroute := Current} = State) -> + New = not Current, + ?SEV_IPRINT("Change from ~p to ~p", [Current, New]), + case Set(Sock, New) of + ok -> + ?SEV_IPRINT("Expected Success"), + {ok, State#{dontroute => New}}; + {error, eopnotsupp = Reason} -> + ?SEV_EPRINT("Expected Failure: ~p", + [Reason]), + {skip, Reason}; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", + [Reason]), + ERROR + end + end}, + #{desc => "Verify changed value", + cmd => fun(#{sock := Sock, dontroute := Val} = _State) -> + case Get(Sock) of + {ok, Val} -> + ?SEV_IPRINT("Expected Success"), + ok; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected failure: ~p", + [Reason]), + ERROR + end + end}, + + %% *** Termination *** + #{desc => "close UDP socket", + cmd => fun(#{sock := Sock} = State0) -> + socket:close(Sock), + State1 = maps:remove(sock, State0), + {ok, State1} + end}, + + %% *** We are done *** + ?SEV_FINISH_NORMAL + ], + + Domain = inet, + + i("start tester evaluator"), + InitState = #{domain => Domain}, + Tester = ?SEV_START("tester", TesterSeq, InitState), + + i("await evaluator(s)"), + ok = ?SEV_AWAIT_FINISH([Tester]). + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% Tests the socket option error. PLACEHOLDER! + +api_opt_sock_error(suite) -> + []; +api_opt_sock_error(doc) -> + []; +api_opt_sock_error(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), + tc_try(api_opt_sock_error, + fun() -> not_yet_implemented() end, + fun() -> ok end). + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% Tests the socket option keepalive. +%% This is bit tricky to test, partly because we have no control over +%% the underlying TCP timeouts. So, for now, we just test that we can +%% change the value. + +api_opt_sock_keepalive(suite) -> + []; +api_opt_sock_keepalive(doc) -> + []; +api_opt_sock_keepalive(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), + tc_try(api_opt_sock_keepalive, + fun() -> has_support_sock_keepalive() end, + fun() -> api_opt_sock_keepalive() end). + + +api_opt_sock_keepalive() -> + Opt = keepalive, + Set = fun(S, Val) when is_boolean(Val) -> + socket:setopt(S, socket, Opt, Val) + end, + Get = fun(S) -> + socket:getopt(S, socket, Opt) + end, + + TesterSeq = + [ + #{desc => "which local address", + cmd => fun(#{domain := Domain} = State) -> + case ?LIB:which_local_host_info(Domain) of + {ok, #{name := Name, + addr := Addr, + broadaddr := BAddr}} -> + ?SEV_IPRINT("local host info: " + "~n Name: ~p" + "~n Addr: ~p" + "~n Broadcast Addr: ~p", + [Name, Addr, BAddr]), + LSA = #{family => Domain, + addr => Addr}, + BSA = #{family => Domain, + addr => BAddr}, + {ok, State#{lsa => LSA, + bsa => BSA}}; + {error, _} = ERROR -> + ERROR + end + end}, + + #{desc => "create TCP socket", + cmd => fun(#{domain := Domain} = State) -> + case socket:open(Domain, stream, tcp) of + {ok, Sock} -> + {ok, State#{sock => Sock}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "Get current value", + cmd => fun(#{sock := Sock} = State) -> + case Get(Sock) of + {ok, Val} when is_boolean(Val) -> + ?SEV_IPRINT("Success: ~p", [Val]), + {ok, State#{keepalive => Val}}; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected failure: ~p", + [Reason]), + ERROR + end + end}, + #{desc => "Try change the value", + cmd => fun(#{sock := Sock, keepalive := Current} = State) -> + New = not Current, + ?SEV_IPRINT("Try change value from ~p to ~p", + [Current, New]), + case Set(Sock, New) of + ok -> + ?SEV_IPRINT("Expected Success"), + {ok, State#{keepalive => New}}; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected Failure: ~p", + [Reason]), + ERROR + end + end}, + #{desc => "Verify (new) current value", + cmd => fun(#{sock := Sock, keepalive := Val} = _State) -> + case Get(Sock) of + {ok, Val} -> + ?SEV_IPRINT("Expected Success (~p)", [Val]), + ok; + {ok, OtherVal} -> + ?SEV_IPRINT("Unexpected Success: ~p", + [OtherVal]), + {error, {unexpected_success_value, + Val, OtherVal}}; + {error, Reason} = ERROR -> + ?SEV_EPRINT("Unexpected failure: ~p", + [Reason]), + ERROR + end + end}, + + %% *** Termination *** + #{desc => "close UDP socket", + cmd => fun(#{sock := Sock} = State0) -> + socket:close(Sock), + State1 = maps:remove(sock, State0), + {ok, State1} + end}, + + %% *** We are done *** + ?SEV_FINISH_NORMAL + ], + + Domain = inet, + + i("start tester evaluator"), + InitState = #{domain => Domain}, + Tester = ?SEV_START("tester", TesterSeq, InitState), + + i("await evaluator(s)"), + ok = ?SEV_AWAIT_FINISH([Tester]). + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% Tests the socket option linger. PLACEHOLDER! + +api_opt_sock_linger(suite) -> + []; +api_opt_sock_linger(doc) -> + []; +api_opt_sock_linger(_Config) when is_list(_Config) -> + ?TT(?SECS(10)), + tc_try(api_opt_sock_linger, + fun() -> not_yet_implemented() end, + fun() -> ok end). + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %% Tests that the add_mambership and drop_membership ip options work. %% We create one server and two clients. The server only send messages, %% the clients only receives messages. @@ -7754,9 +10097,9 @@ api_opt_ip_add_drop_membership(_Config) when is_list(_Config) -> ?TT(?SECS(30)), tc_try(api_opt_ip_add_drop_membership, fun() -> - has_ip_add_membership_support(), - has_ip_drop_membership_support(), - has_ip_multicast_support() + has_support_ip_add_membership(), + has_support_ip_drop_membership(), + has_support_ip_multicast() end, fun() -> api_opt_ip_add_drop_membership() end). @@ -7973,8 +10316,8 @@ api_opt_ip_add_drop_membership() -> ], - i("get multicast address"), Domain = inet, + i("get multicast address"), MAddr = which_ip_multicast_address(), MSA = #{family => Domain, addr => MAddr}, @@ -8007,6 +10350,7 @@ which_multicast_address(Domain) -> which_multicast_address2(Domain, WhichMAddr); Type -> + %% Actually, what is "not supported". is netstat! not_supported({multicast, Type}) end. @@ -8015,13 +10359,30 @@ which_multicast_address(Domain) -> %% SunOS: IfName - Group - RefCnt which_multicast_address2(Domain, WhichMAddr) -> - IfName = which_local_host_ifname(Domain), - NetstatGroupsStr = os:cmd("netstat -g | grep " ++ IfName), - NetstatGroups0 = string:tokens(NetstatGroupsStr, [$\n]), - NetstatGroups = [string:tokens(G, [$ ]) || G <- NetstatGroups0], - MAddrs = [WhichMAddr(NetstatGroup) || NetstatGroup <- - NetstatGroups], - which_multicast_address3(Domain, MAddrs). + IfName = which_local_host_ifname(Domain), + %% On some platforms the netstat barfs out some crap on stderr + %% before the actual info... + case os:cmd("netstat -g 2>/dev/null | grep " ++ IfName) of + [] -> + %% Can't figure out if we support multicast or not... + not_supported(no_netstat); + NetstatGroupsStr -> + try + begin + NetstatGroups0 = string:tokens(NetstatGroupsStr, [$\n]), + NetstatGroups = [string:tokens(G, [$ ]) || + G <- NetstatGroups0], + MAddrs = [WhichMAddr(NetstatGroup) || + NetstatGroup <- NetstatGroups], + which_multicast_address3(Domain, MAddrs) + end + catch + throw:E:_ -> + throw(E); + C:E:S -> + not_supported({multicast, {C,E,S}}) + end + end. which_multicast_address3(_Domain, []) -> not_supported({multicast, no_valid_addrs}); @@ -8038,8 +10399,8 @@ which_multicast_address3(Domain, [MAddrStr|MAddrs]) -> end. which_local_host_ifname(Domain) -> - case which_local_host_info(Domain) of - {ok, {Name, _Addr, _Flags}} -> + case ?LIB:which_local_host_info(Domain) of + {ok, #{name := Name}} -> Name; {error, Reason} -> not_supported({multicast, Reason}) @@ -9114,6 +11475,7 @@ api_to_send_tcp6(doc) -> []; api_to_send_tcp6(_Config) when is_list(_Config) -> tc_try(api_to_send_tcp6, + fun() -> has_support_ipv6() end, fun() -> not_yet_implemented()%% , %% ok = api_to_send_tcp(inet6) @@ -9146,6 +11508,7 @@ api_to_sendto_udp6(doc) -> []; api_to_sendto_udp6(_Config) when is_list(_Config) -> tc_try(api_to_sendto_udp6, + fun() -> has_support_ipv6() end, fun() -> not_yet_implemented()%% , %% ok = api_to_sendto_to_udp(inet6) @@ -9178,6 +11541,7 @@ api_to_sendmsg_tcp6(doc) -> []; api_to_sendmsg_tcp6(_Config) when is_list(_Config) -> tc_try(api_to_sendmsg_tcp6, + fun() -> has_support_ipv6() end, fun() -> not_yet_implemented()%% , %% ok = api_to_sendmsg_tcp(inet6) @@ -9212,6 +11576,7 @@ api_to_recv_udp6(doc) -> []; api_to_recv_udp6(_Config) when is_list(_Config) -> tc_try(api_to_recv_udp6, + fun() -> has_support_ipv6() end, fun() -> not_yet_implemented()%% , %% ok = api_to_recv_udp(inet6) @@ -9791,7 +12156,7 @@ sc_cpe_socket_cleanup_tcp4(suite) -> sc_cpe_socket_cleanup_tcp4(doc) -> []; sc_cpe_socket_cleanup_tcp4(_Config) when is_list(_Config) -> - ?TT(?SECS(5)), + ?TT(?SECS(30)), tc_try(sc_cpe_socket_cleanup_tcp4, fun() -> InitState = #{domain => inet, @@ -9811,7 +12176,7 @@ sc_cpe_socket_cleanup_tcp6(suite) -> sc_cpe_socket_cleanup_tcp6(doc) -> []; sc_cpe_socket_cleanup_tcp6(_Config) when is_list(_Config) -> - ?TT(?SECS(5)), + ?TT(?SECS(30)), tc_try(sc_cpe_socket_cleanup_tcp6, fun() -> has_support_ipv6() end, fun() -> @@ -9832,7 +12197,7 @@ sc_cpe_socket_cleanup_tcpL(suite) -> sc_cpe_socket_cleanup_tcpL(doc) -> []; sc_cpe_socket_cleanup_tcpL(_Config) when is_list(_Config) -> - ?TT(?SECS(5)), + ?TT(?SECS(30)), tc_try(sc_cpe_socket_cleanup_tcpL, fun() -> has_support_unix_domain_socket() end, fun() -> @@ -9853,7 +12218,7 @@ sc_cpe_socket_cleanup_udp4(suite) -> sc_cpe_socket_cleanup_udp4(doc) -> []; sc_cpe_socket_cleanup_udp4(_Config) when is_list(_Config) -> - ?TT(?SECS(5)), + ?TT(?SECS(30)), tc_try(sc_cpe_socket_cleanup_udp4, fun() -> InitState = #{domain => inet, @@ -9874,7 +12239,7 @@ sc_cpe_socket_cleanup_udp6(suite) -> sc_cpe_socket_cleanup_udp6(doc) -> []; sc_cpe_socket_cleanup_udp6(_Config) when is_list(_Config) -> - ?TT(?SECS(5)), + ?TT(?SECS(30)), tc_try(sc_cpe_socket_cleanup_udp6, fun() -> has_support_ipv6() end, fun() -> @@ -9895,7 +12260,7 @@ sc_cpe_socket_cleanup_udpL(suite) -> sc_cpe_socket_cleanup_udpL(doc) -> []; sc_cpe_socket_cleanup_udpL(_Config) when is_list(_Config) -> - ?TT(?SECS(5)), + ?TT(?SECS(30)), tc_try(sc_cpe_socket_cleanup_udpL, fun() -> has_support_unix_domain_socket() end, fun() -> @@ -10001,8 +12366,15 @@ sc_cpe_socket_cleanup(InitState) -> ERROR end end}, + + ?SEV_SLEEP(?SECS(5)), + %% The reason we get closed, is that as long as there is a ref to %% the resource (socket), then it will not be garbage collected. + %% Note that its still a race that the nif has processed that the + %% "controlling process" has terminated. There really is no + %% proper timeout for this, but the 5 seconds "should" be enough... + %% We should really have some way to subscribe to socket events... #{desc => "verify no socket (closed)", cmd => fun(#{owner := Pid, sock := Sock} = _State) -> case socket:getopt(Sock, otp, controlling_process) of @@ -13819,6 +16191,2044 @@ sc_rs_recvmsg_send_shutdown_receive_tcpL(_Config) when is_list(_Config) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case is intended to (simply) test that the counters +%% for both read and write. +%% So that its easy to extend, we use fun's for read and write. +%% We use TCP on IPv4. + +traffic_send_and_recv_counters_tcp4(suite) -> + []; +traffic_send_and_recv_counters_tcp4(doc) -> + []; +traffic_send_and_recv_counters_tcp4(_Config) when is_list(_Config) -> + ?TT(?SECS(15)), + tc_try(traffic_send_and_recv_counters_tcp4, + fun() -> + InitState = #{domain => inet, + proto => tcp, + recv => fun(S) -> socket:recv(S) end, + send => fun(S, D) -> socket:send(S, D) end}, + ok = traffic_send_and_recv_tcp(InitState) + end). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case is intended to (simply) test that the counters +%% for both read and write. +%% So that its easy to extend, we use fun's for read and write. +%% We use TCP on IPv6. + +traffic_send_and_recv_counters_tcp6(suite) -> + []; +traffic_send_and_recv_counters_tcp6(doc) -> + []; +traffic_send_and_recv_counters_tcp6(_Config) when is_list(_Config) -> + ?TT(?SECS(15)), + tc_try(traffic_send_and_recv_counters_tcp6, + fun() -> has_support_ipv6() end, + fun() -> + InitState = #{domain => inet6, + proto => tcp, + recv => fun(S) -> socket:recv(S) end, + send => fun(S, D) -> socket:send(S, D) end}, + ok = traffic_send_and_recv_tcp(InitState) + end). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case is intended to (simply) test that the counters +%% for both read and write. +%% So that its easy to extend, we use fun's for read and write. +%% We use default (TCP) on local. + +traffic_send_and_recv_counters_tcpL(suite) -> + []; +traffic_send_and_recv_counters_tcpL(doc) -> + []; +traffic_send_and_recv_counters_tcpL(_Config) when is_list(_Config) -> + ?TT(?SECS(15)), + tc_try(traffic_send_and_recv_counters_tcpL, + fun() -> has_support_unix_domain_socket() end, + fun() -> + InitState = #{domain => local, + proto => default, + recv => fun(S) -> socket:recv(S) end, + send => fun(S, D) -> socket:send(S, D) end}, + ok = traffic_send_and_recv_tcp(InitState) + end). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case is intended to (simply) test that the counters +%% for both read and write. +%% So that its easy to extend, we use fun's for read and write. +%% We use TCP on IPv4. + +traffic_sendmsg_and_recvmsg_counters_tcp4(suite) -> + []; +traffic_sendmsg_and_recvmsg_counters_tcp4(doc) -> + []; +traffic_sendmsg_and_recvmsg_counters_tcp4(_Config) when is_list(_Config) -> + ?TT(?SECS(15)), + tc_try(traffic_sendmsg_and_recvmsg_counters_tcp4, + fun() -> + InitState = #{domain => inet, + proto => tcp, + recv => fun(S) -> + case socket:recvmsg(S) of + {ok, #{addr := _Source, + iov := [Data]}} -> + {ok, Data}; + {error, _} = ERROR -> + ERROR + end + end, + send => fun(S, Data) -> + MsgHdr = #{iov => [Data]}, + socket:sendmsg(S, MsgHdr) + end}, + ok = traffic_send_and_recv_tcp(InitState) + end). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case is intended to (simply) test that the counters +%% for both read and write. +%% So that its easy to extend, we use fun's for read and write. +%% We use TCP on IPv6. + +traffic_sendmsg_and_recvmsg_counters_tcp6(suite) -> + []; +traffic_sendmsg_and_recvmsg_counters_tcp6(doc) -> + []; +traffic_sendmsg_and_recvmsg_counters_tcp6(_Config) when is_list(_Config) -> + ?TT(?SECS(15)), + tc_try(traffic_sendmsg_and_recvmsg_counters_tcp6, + fun() -> has_support_ipv6() end, + fun() -> + InitState = #{domain => inet6, + proto => tcp, + recv => fun(S) -> + case socket:recvmsg(S) of + {ok, #{addr := _Source, + iov := [Data]}} -> + {ok, Data}; + {error, _} = ERROR -> + ERROR + end + end, + send => fun(S, Data) -> + MsgHdr = #{iov => [Data]}, + socket:sendmsg(S, MsgHdr) + end}, + ok = traffic_send_and_recv_tcp(InitState) + end). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case is intended to (simply) test that the counters +%% for both read and write. +%% So that its easy to extend, we use fun's for read and write. +%% We use default (TCP) on local. + +traffic_sendmsg_and_recvmsg_counters_tcpL(suite) -> + []; +traffic_sendmsg_and_recvmsg_counters_tcpL(doc) -> + []; +traffic_sendmsg_and_recvmsg_counters_tcpL(_Config) when is_list(_Config) -> + ?TT(?SECS(15)), + tc_try(traffic_sendmsg_and_recvmsg_counters_tcpL, + fun() -> has_support_unix_domain_socket() end, + fun() -> + InitState = #{domain => local, + proto => default, + recv => fun(S) -> + case socket:recvmsg(S) of + {ok, #{addr := _Source, + iov := [Data]}} -> + {ok, Data}; + {error, _} = ERROR -> + ERROR + end + end, + send => fun(S, Data) -> + MsgHdr = #{iov => [Data]}, + socket:sendmsg(S, MsgHdr) + end}, + ok = traffic_send_and_recv_tcp(InitState) + end). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +traffic_send_and_recv_tcp(InitState) -> + ServerSeq = + [ + %% *** Wait for start order part *** + #{desc => "await start", + cmd => fun(State) -> + Tester = ?SEV_AWAIT_START(), + {ok, State#{tester => Tester}} + end}, + #{desc => "monitor tester", + cmd => fun(#{tester := Tester} = _State) -> + _MRef = erlang:monitor(process, Tester), + ok + end}, + + %% *** Init part *** + #{desc => "which local address", + cmd => fun(#{domain := Domain} = State) -> + LSA = which_local_socket_addr(Domain), + {ok, State#{local_sa => LSA}} + end}, + #{desc => "create listen socket", + cmd => fun(#{domain := Domain, proto := Proto} = State) -> + case socket:open(Domain, stream, Proto) of + {ok, Sock} -> + {ok, State#{lsock => Sock}}; + {error, eafnosupport = Reason} -> + {skip, Reason}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "bind to local address", + cmd => fun(#{domain := local, + lsock := LSock, + local_sa := LSA} = _State) -> + case socket:bind(LSock, LSA) of + {ok, _Port} -> + ok; % We do not care about the port for local + {error, _} = ERROR -> + ERROR + end; + (#{lsock := LSock, + local_sa := LSA} = State) -> + case socket:bind(LSock, LSA) of + {ok, Port} -> + {ok, State#{lport => Port}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "make listen socket", + cmd => fun(#{lsock := LSock}) -> + socket:listen(LSock) + end}, + #{desc => "announce ready (init)", + cmd => fun(#{domain := local, + tester := Tester, + local_sa := #{path := Path}}) -> + ?SEV_ANNOUNCE_READY(Tester, init, Path), + ok; + (#{tester := Tester, + lport := Port}) -> + ?SEV_ANNOUNCE_READY(Tester, init, Port), + ok + end}, + + %% The actual test + #{desc => "await continue (accept)", + cmd => fun(#{tester := Tester} = _State) -> + ?SEV_AWAIT_CONTINUE(Tester, tester, accept) + end}, + #{desc => "accept", + cmd => fun(#{lsock := LSock} = State) -> + case socket:accept(LSock) of + {ok, Sock} -> + {ok, State#{csock => Sock}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "initial counter validation (=zero)", + cmd => fun(#{csock := Sock} = _State) -> + try socket:info(Sock) of + #{counters := Counters} -> + ?SEV_IPRINT("Validate initial counters: " + "~n ~p", [Counters]), + traffic_sar_counters_validation(Counters) + catch + C:E:S -> + ?SEV_EPRINT("Failed get socket info: " + "~n Class: ~p" + "~n Error: ~p" + "~n Stack: ~p", [C, E, S]), + {error, {socket_info_failed, {C, E, S}}} + end + end}, + #{desc => "announce ready (accept)", + cmd => fun(#{tester := Tester}) -> + ?SEV_ANNOUNCE_READY(Tester, accept), + ok + end}, + + #{desc => "await continue (recv_and_validate 1)", + cmd => fun(#{tester := Tester} = _State) -> + ?SEV_AWAIT_CONTINUE(Tester, tester, recv_and_validate) + end}, + #{desc => "recv (1)", + cmd => fun(#{csock := Sock, + recv := Recv} = State) -> + case Recv(Sock) of + {ok, Data} -> + ?SEV_IPRINT("recv ~p bytes", [size(Data)]), + {ok, State#{read_pkg => 1, + read_byte => size(Data)}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "validate (recv 1)", + cmd => fun(#{csock := Sock, + read_pkg := Pkg, + read_byte := Byte} = _State) -> + try socket:info(Sock) of + #{counters := Counters} -> + ?SEV_IPRINT("validate counters: " + "~n ~p", [Counters]), + traffic_sar_counters_validation( + Counters, + [{read_pkg, Pkg}, + {read_byte, Byte}, + {read_tries, any}]) + catch + C:E:S -> + ?SEV_EPRINT("Failed get socket info: " + "~n Class: ~p" + "~n Error: ~p" + "~n Stack: ~p", [C, E, S]), + {error, {socket_info_failed, {C, E, S}}} + end + end}, + #{desc => "announce ready (recv_and_validate 1)", + cmd => fun(#{tester := Tester}) -> + ?SEV_ANNOUNCE_READY(Tester, recv_and_validate), + ok + end}, + + #{desc => "await continue (send_and_validate 1)", + cmd => fun(#{tester := Tester} = _State) -> + ?SEV_AWAIT_CONTINUE(Tester, tester, send_and_validate) + end}, + #{desc => "send (1)", + cmd => fun(#{csock := Sock, + send := Send} = State) -> + Data = ?DATA, + case Send(Sock, Data) of + ok -> + ?SEV_IPRINT("sent ~p bytes", [size(Data)]), + {ok, State#{write_pkg => 1, + write_byte => size(Data)}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "validate (send 1)", + cmd => fun(#{csock := Sock, + read_pkg := RPkg, + read_byte := RByte, + write_pkg := SPkg, + write_byte := SByte} = _State) -> + try socket:info(Sock) of + #{counters := Counters} -> + ?SEV_IPRINT("validate counters: " + "~n ~p", [Counters]), + traffic_sar_counters_validation( + Counters, + [{read_pkg, RPkg}, + {read_byte, RByte}, + {write_pkg, SPkg}, + {write_byte, SByte}, + {read_tries, any}, + {write_tries, any}]) + catch + C:E:S -> + ?SEV_EPRINT("Failed get socket info: " + "~n Class: ~p" + "~n Error: ~p" + "~n Stack: ~p", [C, E, S]), + {error, {socket_info_failed, {C, E, S}}} + end + end}, + #{desc => "announce ready (send_and_validate 1)", + cmd => fun(#{tester := Tester}) -> + ?SEV_ANNOUNCE_READY(Tester, send_and_validate), + ok + end}, + + #{desc => "await continue (recv_and_validate 2)", + cmd => fun(#{tester := Tester} = _State) -> + ?SEV_AWAIT_CONTINUE(Tester, tester, recv_and_validate) + end}, + #{desc => "recv (2)", + cmd => fun(#{csock := Sock, + recv := Recv, + read_pkg := Pkg, + read_byte := Byte} = State) -> + case Recv(Sock) of + {ok, Data} -> + ?SEV_IPRINT("recv ~p bytes", [size(Data)]), + {ok, State#{read_pkg => Pkg + 1, + read_byte => Byte + size(Data)}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "validate (recv 2)", + cmd => fun(#{csock := Sock, + read_pkg := RPkg, + read_byte := RByte, + write_pkg := SPkg, + write_byte := SByte} = _State) -> + try socket:info(Sock) of + #{counters := Counters} -> + ?SEV_IPRINT("validate counters: " + "~n ~p", [Counters]), + traffic_sar_counters_validation( + Counters, + [{read_pkg, RPkg}, + {read_byte, RByte}, + {write_pkg, SPkg}, + {write_byte, SByte}, + {read_tries, any}, + {write_tries, any}]) + catch + C:E:S -> + ?SEV_EPRINT("Failed get socket info: " + "~n Class: ~p" + "~n Error: ~p" + "~n Stack: ~p", [C, E, S]), + {error, {socket_info_failed, {C, E, S}}} + end + end}, + #{desc => "announce ready (recv_and_validate 2)", + cmd => fun(#{tester := Tester}) -> + ?SEV_ANNOUNCE_READY(Tester, recv_and_validate), + ok + end}, + + #{desc => "await continue (send_and_validate 2)", + cmd => fun(#{tester := Tester} = _State) -> + ?SEV_AWAIT_CONTINUE(Tester, tester, send_and_validate) + end}, + #{desc => "send (2)", + cmd => fun(#{csock := Sock, + send := Send, + write_pkg := Pkg, + write_byte := Byte} = State) -> + Data = ?DATA, + case Send(Sock, Data) of + ok -> + ?SEV_IPRINT("sent ~p bytes", [size(Data)]), + {ok, State#{write_pkg => Pkg + 1, + write_byte => Byte + size(Data)}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "validate (send 2)", + cmd => fun(#{csock := Sock, + read_pkg := RPkg, + read_byte := RByte, + write_pkg := SPkg, + write_byte := SByte} = _State) -> + try socket:info(Sock) of + #{counters := Counters} -> + ?SEV_IPRINT("validate counters: " + "~n ~p", [Counters]), + traffic_sar_counters_validation( + Counters, + [{read_pkg, RPkg}, + {read_byte, RByte}, + {write_pkg, SPkg}, + {write_byte, SByte}, + {read_tries, any}, + {write_tries, any}]) + catch + C:E:S -> + ?SEV_EPRINT("Failed get socket info: " + "~n Class: ~p" + "~n Error: ~p" + "~n Stack: ~p", [C, E, S]), + {error, {socket_info_failed, {C, E, S}}} + end + end}, + #{desc => "announce ready (send_and_validate 2)", + cmd => fun(#{tester := Tester}) -> + ?SEV_ANNOUNCE_READY(Tester, send_and_validate), + ok + end}, + + + %% Termination + #{desc => "await terminate (from tester)", + cmd => fun(#{tester := Tester} = State) -> + case ?SEV_AWAIT_TERMINATE(Tester, tester) of + ok -> + {ok, maps:remove(tester, State)}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "close connection socket (just in case)", + cmd => fun(#{csock := Sock} = State) -> + (catch socket:close(Sock)), + {ok, maps:remove(csock, State)} + end}, + #{desc => "close listen socket", + cmd => fun(#{domain := local, + lsock := Sock, + local_sa := #{path := Path}} = State) -> + ok = socket:close(Sock), + State1 = + unlink_path(Path, + fun() -> + maps:remove(local_sa, State) + end, + fun() -> State end), + {ok, maps:remove(lsock, State1)}; + (#{lsock := Sock} = State) -> + (catch socket:close(Sock)), + {ok, maps:remove(lsock, State)} + end}, + + %% *** We are done *** + ?SEV_FINISH_NORMAL + ], + + ClientSeq = + [ + %% *** Wait for start order part *** + #{desc => "await start (from tester)", + cmd => fun(#{domain := local} = State) -> + {Tester, Path} = ?SEV_AWAIT_START(), + {ok, State#{tester => Tester, server_path => Path}}; + (State) -> + {Tester, Port} = ?SEV_AWAIT_START(), + {ok, State#{tester => Tester, server_port => Port}} + end}, + #{desc => "monitor tester", + cmd => fun(#{tester := Tester} = _State) -> + _MRef = erlang:monitor(process, Tester), + ok + end}, + + %% *** Init part *** + #{desc => "which server (local) address", + cmd => fun(#{domain := local = Domain, + server_path := Path} = State) -> + LSA = which_local_socket_addr(Domain), + SSA = #{family => Domain, path => Path}, + {ok, State#{local_sa => LSA, server_sa => SSA}}; + (#{domain := Domain, server_port := Port} = State) -> + LSA = which_local_socket_addr(Domain), + SSA = LSA#{port => Port}, + {ok, State#{local_sa => LSA, server_sa => SSA}} + end}, + #{desc => "create socket", + cmd => fun(#{domain := Domain, + proto := Proto} = State) -> + case socket:open(Domain, stream, Proto) of + {ok, Sock} -> + {ok, State#{sock => Sock}}; + {error, eafnosupport = Reason} -> + {skip, Reason}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "bind to local address", + cmd => fun(#{sock := Sock, local_sa := LSA} = _State) -> + case socket:bind(Sock, LSA) of + {ok, _Port} -> + ok; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "announce ready (init)", + cmd => fun(#{tester := Tester}) -> + ?SEV_ANNOUNCE_READY(Tester, init), + ok + end}, + + %% The actual test + #{desc => "await continue (connect)", + cmd => fun(#{tester := Tester} = _State) -> + ?SEV_AWAIT_CONTINUE(Tester, tester, connect), + ok + end}, + #{desc => "connect to server", + cmd => fun(#{sock := Sock, server_sa := SSA}) -> + socket:connect(Sock, SSA) + end}, + #{desc => "announce ready (connect)", + cmd => fun(#{tester := Tester}) -> + ?SEV_ANNOUNCE_READY(Tester, connect), + ok + end}, + + #{desc => "await continue (send_and_validate 1)", + cmd => fun(#{tester := Tester} = _State) -> + ?SEV_AWAIT_CONTINUE(Tester, tester, send_and_validate) + end}, + #{desc => "send (1)", + cmd => fun(#{sock := Sock, + send := Send} = State) -> + Data = ?DATA, + case Send(Sock, Data) of + ok -> + ?SEV_IPRINT("sent ~p bytes", [size(Data)]), + {ok, State#{write_pkg => 1, + write_byte => size(Data)}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "validate (send 1)", + cmd => fun(#{sock := Sock, + write_pkg := SPkg, + write_byte := SByte} = _State) -> + try socket:info(Sock) of + #{counters := Counters} -> + ?SEV_IPRINT("validate counters: " + "~n ~p", [Counters]), + traffic_sar_counters_validation( + Counters, + [{write_pkg, SPkg}, + {write_byte, SByte}, + {write_tries, any}]) + catch + C:E:S -> + ?SEV_EPRINT("Failed get socket info: " + "~n Class: ~p" + "~n Error: ~p" + "~n Stack: ~p", [C, E, S]), + {error, {socket_info_failed, {C, E, S}}} + end + end}, + #{desc => "announce ready (send_and_validate 1)", + cmd => fun(#{tester := Tester}) -> + ?SEV_ANNOUNCE_READY(Tester, send_and_validate), + ok + end}, + + #{desc => "await continue (recv_and_validate 1)", + cmd => fun(#{tester := Tester} = _State) -> + ?SEV_AWAIT_CONTINUE(Tester, tester, recv_and_validate) + end}, + #{desc => "recv (1)", + cmd => fun(#{sock := Sock, + recv := Recv} = State) -> + case Recv(Sock) of + {ok, Data} -> + ?SEV_IPRINT("recv ~p bytes", [size(Data)]), + {ok, State#{read_pkg => 1, + read_byte => size(Data)}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "validate (recv 1)", + cmd => fun(#{sock := Sock, + read_pkg := RPkg, + read_byte := RByte, + write_pkg := SPkg, + write_byte := SByte} = _State) -> + try socket:info(Sock) of + #{counters := Counters} -> + ?SEV_IPRINT("validate counters: " + "~n ~p", [Counters]), + traffic_sar_counters_validation( + Counters, + [{read_pkg, RPkg}, + {read_byte, RByte}, + {write_pkg, SPkg}, + {write_byte, SByte}, + {read_tries, any}, + {write_tries, any}]) + catch + C:E:S -> + ?SEV_EPRINT("Failed get socket info: " + "~n Class: ~p" + "~n Error: ~p" + "~n Stack: ~p", [C, E, S]), + {error, {socket_info_failed, {C, E, S}}} + end + end}, + #{desc => "announce ready (recv_and_validate 1)", + cmd => fun(#{tester := Tester}) -> + ?SEV_ANNOUNCE_READY(Tester, recv_and_validate), + ok + end}, + + #{desc => "await continue (send_and_validate 2)", + cmd => fun(#{tester := Tester} = _State) -> + ?SEV_AWAIT_CONTINUE(Tester, tester, send_and_validate) + end}, + #{desc => "send (2)", + cmd => fun(#{sock := Sock, + send := Send, + write_pkg := SPkg, + write_byte := SByte} = State) -> + Data = ?DATA, + case Send(Sock, Data) of + ok -> + ?SEV_IPRINT("sent ~p bytes", [size(Data)]), + {ok, State#{write_pkg => SPkg + 1, + write_byte => SByte + size(Data)}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "validate (send 2)", + cmd => fun(#{sock := Sock, + read_pkg := RPkg, + read_byte := RByte, + write_pkg := SPkg, + write_byte := SByte} = _State) -> + try socket:info(Sock) of + #{counters := Counters} -> + ?SEV_IPRINT("validate counters: " + "~n ~p", [Counters]), + traffic_sar_counters_validation( + Counters, + [{read_pkg, RPkg}, + {read_byte, RByte}, + {write_pkg, SPkg}, + {write_byte, SByte}, + {read_tries, any}, + {write_tries, any}]) + catch + C:E:S -> + ?SEV_EPRINT("Failed get socket info: " + "~n Class: ~p" + "~n Error: ~p" + "~n Stack: ~p", [C, E, S]), + {error, {socket_info_failed, {C, E, S}}} + end + end}, + #{desc => "announce ready (send_and_validate 2)", + cmd => fun(#{tester := Tester}) -> + ?SEV_ANNOUNCE_READY(Tester, send_and_validate), + ok + end}, + + #{desc => "await continue (recv_and_validate 2)", + cmd => fun(#{tester := Tester} = _State) -> + ?SEV_AWAIT_CONTINUE(Tester, tester, recv_and_validate) + end}, + #{desc => "recv (2)", + cmd => fun(#{sock := Sock, + recv := Recv, + read_pkg := RPkg, + read_byte := RByte} = State) -> + case Recv(Sock) of + {ok, Data} -> + ?SEV_IPRINT("recv ~p bytes", [size(Data)]), + {ok, State#{read_pkg => RPkg + 1, + read_byte => RByte + size(Data)}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "validate (recv 2)", + cmd => fun(#{sock := Sock, + read_pkg := RPkg, + read_byte := RByte, + write_pkg := SPkg, + write_byte := SByte} = _State) -> + try socket:info(Sock) of + #{counters := Counters} -> + ?SEV_IPRINT("validate counters: " + "~n ~p", [Counters]), + traffic_sar_counters_validation( + Counters, + [{read_pkg, RPkg}, + {read_byte, RByte}, + {write_pkg, SPkg}, + {write_byte, SByte}, + {read_tries, any}, + {write_tries, any}]) + catch + C:E:S -> + ?SEV_EPRINT("Failed get socket info: " + "~n Class: ~p" + "~n Error: ~p" + "~n Stack: ~p", [C, E, S]), + {error, {socket_info_failed, {C, E, S}}} + end + end}, + #{desc => "announce ready (recv_and_validate 2)", + cmd => fun(#{tester := Tester}) -> + ?SEV_ANNOUNCE_READY(Tester, recv_and_validate), + ok + end}, + + %% Termination + #{desc => "await terminate (from tester)", + cmd => fun(#{tester := Tester} = State) -> + case ?SEV_AWAIT_TERMINATE(Tester, tester) of + ok -> + {ok, maps:remove(tester, State)}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "close connection socket", + cmd => fun(#{domain := local, + sock := Sock, + local_sa := #{path := Path}} = State) -> + ok = socket:close(Sock), + State1 = + unlink_path(Path, + fun() -> + maps:remove(local_sa, State) + end, + fun() -> State end), + {ok, maps:remove(sock, State1)}; + (#{sock := Sock} = State) -> + socket:close(Sock), + {ok, maps:remove(sock, State)} + end}, + + %% *** We are done *** + ?SEV_FINISH_NORMAL + ], + + + TesterSeq = + [ + %% *** Init part *** + #{desc => "monitor server", + cmd => fun(#{server := Pid} = _State) -> + _MRef = erlang:monitor(process, Pid), + ok + end}, + #{desc => "monitor client", + cmd => fun(#{client := Pid} = _State) -> + _MRef = erlang:monitor(process, Pid), + ok + end}, + + %% Start the server + #{desc => "order server start", + cmd => fun(#{server := Pid} = _State) -> + ?SEV_ANNOUNCE_START(Pid), + ok + end}, + #{desc => "await server ready (init)", + cmd => fun(#{domain := local, + server := Pid} = State) -> + {ok, Path} = ?SEV_AWAIT_READY(Pid, server, init), + {ok, State#{path => Path}}; + (#{server := Pid} = State) -> + {ok, Port} = ?SEV_AWAIT_READY(Pid, server, init), + {ok, State#{port => Port}} + end}, + + %% Start the client + #{desc => "order client start", + cmd => fun(#{domain := local, + client := Pid, + path := Path} = _State) -> + ?SEV_ANNOUNCE_START(Pid, Path), + ok; + (#{client := Pid, + port := Port} = _State) -> + ?SEV_ANNOUNCE_START(Pid, Port), + ok + end}, + #{desc => "await client ready (init)", + cmd => fun(#{client := Pid} = _State) -> + ok = ?SEV_AWAIT_READY(Pid, client, init) + end}, + + %% *** The actual test *** + + #{desc => "order server to continue (with accept)", + cmd => fun(#{server := Server} = _State) -> + ?SEV_ANNOUNCE_CONTINUE(Server, accept), + ok + end}, + + ?SEV_SLEEP(?SECS(1)), + + #{desc => "order client to continue (with connect)", + cmd => fun(#{client := Client} = _State) -> + ?SEV_ANNOUNCE_CONTINUE(Client, connect), + ok + end}, + #{desc => "await client ready (connect)", + cmd => fun(#{client := Client} = _State) -> + ?SEV_AWAIT_READY(Client, client, connect) + end}, + #{desc => "await server ready (accept)", + cmd => fun(#{server := Server} = _State) -> + ?SEV_AWAIT_READY(Server, server, accept) + end}, + + ?SEV_SLEEP(?SECS(1)), + + #{desc => "order server to continue (recv_and_validate 1)", + cmd => fun(#{server := Server} = _State) -> + ?SEV_ANNOUNCE_CONTINUE(Server, recv_and_validate), + ok + end}, + #{desc => "order client to continue (send_and_validate 1)", + cmd => fun(#{client := Client} = _State) -> + ?SEV_ANNOUNCE_CONTINUE(Client, send_and_validate), + ok + end}, + #{desc => "await client ready (send_and_validate 1)", + cmd => fun(#{client := Client} = _State) -> + ?SEV_AWAIT_READY(Client, client, send_and_validate) + end}, + #{desc => "await server ready (recv_and_validate 1)", + cmd => fun(#{server := Server} = _State) -> + ?SEV_AWAIT_READY(Server, server, recv_and_validate) + end}, + + ?SEV_SLEEP(?SECS(1)), + + #{desc => "order client to continue (recv_and_validate 1)", + cmd => fun(#{client := Client} = _State) -> + ?SEV_ANNOUNCE_CONTINUE(Client, recv_and_validate), + ok + end}, + #{desc => "order server to continue (send_and_validate 1)", + cmd => fun(#{server := Server} = _State) -> + ?SEV_ANNOUNCE_CONTINUE(Server, send_and_validate), + ok + end}, + #{desc => "await server ready (send_and_validate 1)", + cmd => fun(#{server := Server} = _State) -> + ?SEV_AWAIT_READY(Server, server, send_and_validate) + end}, + #{desc => "await client ready (recv_and_validate 1)", + cmd => fun(#{client := Client} = _State) -> + ?SEV_AWAIT_READY(Client, client, recv_and_validate) + end}, + + ?SEV_SLEEP(?SECS(1)), + + #{desc => "order server to continue (recv_and_validate 2)", + cmd => fun(#{server := Server} = _State) -> + ?SEV_ANNOUNCE_CONTINUE(Server, recv_and_validate), + ok + end}, + #{desc => "order client to continue (send_and_validate 2)", + cmd => fun(#{client := Client} = _State) -> + ?SEV_ANNOUNCE_CONTINUE(Client, send_and_validate), + ok + end}, + #{desc => "await client ready (send_and_validate 2)", + cmd => fun(#{client := Client} = _State) -> + ?SEV_AWAIT_READY(Client, client, send_and_validate) + end}, + #{desc => "await server ready (recv_and_validate 2)", + cmd => fun(#{server := Server} = _State) -> + ?SEV_AWAIT_READY(Server, server, recv_and_validate) + end}, + + ?SEV_SLEEP(?SECS(1)), + + #{desc => "order client to continue (recv_and_validate 2)", + cmd => fun(#{client := Client} = _State) -> + ?SEV_ANNOUNCE_CONTINUE(Client, recv_and_validate), + ok + end}, + #{desc => "order server to continue (send_and_validate 2)", + cmd => fun(#{server := Server} = _State) -> + ?SEV_ANNOUNCE_CONTINUE(Server, send_and_validate), + ok + end}, + #{desc => "await server ready (send_and_validate 2)", + cmd => fun(#{server := Server} = _State) -> + ?SEV_AWAIT_READY(Server, server, send_and_validate) + end}, + #{desc => "await client ready (recv_and_validate 2)", + cmd => fun(#{client := Client} = _State) -> + ?SEV_AWAIT_READY(Client, client, recv_and_validate) + end}, + + %% *** Termination *** + #{desc => "order client to terminate", + cmd => fun(#{client := Client} = _State) -> + ?SEV_ANNOUNCE_TERMINATE(Client), + ok + end}, + #{desc => "await client termination", + cmd => fun(#{client := Client} = State) -> + ?SEV_AWAIT_TERMINATION(Client), + State1 = maps:remove(client, State), + {ok, State1} + end}, + #{desc => "order server to terminate", + cmd => fun(#{server := Server} = _State) -> + ?SEV_ANNOUNCE_TERMINATE(Server), + ok + end}, + #{desc => "await server termination", + cmd => fun(#{server := Server} = State) -> + ?SEV_AWAIT_TERMINATION(Server), + State1 = maps:remove(server, State), + {ok, State1} + end}, + + %% *** We are done *** + ?SEV_FINISH_NORMAL + ], + + i("start server evaluator"), + ServerInitState = InitState#{host => local_host()}, + Server = ?SEV_START("server", ServerSeq, ServerInitState), + + i("start client evaluator(s)"), + ClientInitState = InitState#{host => local_host()}, + Client = ?SEV_START("client", ClientSeq, ClientInitState), + + i("start 'tester' evaluator"), + TesterInitState = #{server => Server#ev.pid, + client => Client#ev.pid}, + Tester = ?SEV_START("tester", TesterSeq, TesterInitState), + + i("await evaluator"), + ok = ?SEV_AWAIT_FINISH([Server, Client, Tester]). + + + +traffic_sar_counters_validation(Counters) -> + traffic_sar_counters_validation(Counters, []). + +traffic_sar_counters_validation(Counters, []) -> + (catch lists:foreach( + fun({_Cnt, 0}) -> ok; + ({Cnt, Val}) -> throw({error, {invalid_counter, Cnt, Val}}) + end, + Counters)); +traffic_sar_counters_validation(Counters, [{Cnt, Val}|ValidateCounters]) -> + case lists:keysearch(Cnt, 1, Counters) of + {value, {Cnt, Val}} -> + Counters2 = lists:keydelete(Cnt, 1, Counters), + traffic_sar_counters_validation(Counters2, ValidateCounters); + {value, {Cnt, _Val}} when (Val =:= any) -> + Counters2 = lists:keydelete(Cnt, 1, Counters), + traffic_sar_counters_validation(Counters2, ValidateCounters); + {value, {Cnt, InvVal}} -> + {error, {invalid_counter, Cnt, InvVal, Val}}; + false -> + {error, {unknown_counter, Cnt, Counters}} + end. + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case is intended to (simply) test that the counters +%% for both read and write. +%% So that its easy to extend, we use fun's for read and write. +%% We use UDP on IPv4. + +traffic_sendto_and_recvfrom_counters_udp4(suite) -> + []; +traffic_sendto_and_recvfrom_counters_udp4(doc) -> + []; +traffic_sendto_and_recvfrom_counters_udp4(_Config) when is_list(_Config) -> + ?TT(?SECS(15)), + tc_try(traffic_sendto_and_recvfrom_counters_udp4, + fun() -> + InitState = #{domain => inet, + proto => udp, + recv => fun(S) -> + socket:recvfrom(S) + end, + send => fun(S, Data, Dest) -> + socket:sendto(S, Data, Dest) + end}, + ok = traffic_send_and_recv_udp(InitState) + end). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case is intended to (simply) test that the counters +%% for both read and write. +%% So that its easy to extend, we use fun's for read and write. +%% We use UDP on IPv6. + +traffic_sendto_and_recvfrom_counters_udp6(suite) -> + []; +traffic_sendto_and_recvfrom_counters_udp6(doc) -> + []; +traffic_sendto_and_recvfrom_counters_udp6(_Config) when is_list(_Config) -> + ?TT(?SECS(15)), + tc_try(traffic_sendto_and_recvfrom_counters_udp6, + fun() -> has_support_ipv6() end, + fun() -> + InitState = #{domain => inet6, + proto => udp, + recv => fun(S) -> + socket:recvfrom(S) + end, + send => fun(S, Data, Dest) -> + socket:sendto(S, Data, Dest) + end}, + ok = traffic_send_and_recv_udp(InitState) + end). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case is intended to (simply) test that the counters +%% for both read and write. +%% So that its easy to extend, we use fun's for read and write. +%% We use default (UDP) on local. + +traffic_sendto_and_recvfrom_counters_udpL(suite) -> + []; +traffic_sendto_and_recvfrom_counters_udpL(doc) -> + []; +traffic_sendto_and_recvfrom_counters_udpL(_Config) when is_list(_Config) -> + ?TT(?SECS(15)), + tc_try(traffic_sendto_and_recvfrom_counters_udp4, + fun() -> has_support_unix_domain_socket() end, + fun() -> + InitState = #{domain => local, + proto => default, + recv => fun(S) -> + socket:recvfrom(S) + end, + send => fun(S, Data, Dest) -> + socket:sendto(S, Data, Dest) + end}, + ok = traffic_send_and_recv_udp(InitState) + end). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case is intended to (simply) test that the counters +%% for both read and write. +%% So that its easy to extend, we use fun's for read and write. +%% We use UDP on IPv4. + +traffic_sendmsg_and_recvmsg_counters_udp4(suite) -> + []; +traffic_sendmsg_and_recvmsg_counters_udp4(doc) -> + []; +traffic_sendmsg_and_recvmsg_counters_udp4(_Config) when is_list(_Config) -> + ?TT(?SECS(15)), + tc_try(traffic_sendmsg_and_recvmsg_counters_udp4, + fun() -> + InitState = #{domain => inet, + proto => udp, + recv => fun(S) -> + case socket:recvmsg(S) of + {ok, #{addr := Source, + iov := [Data]}} -> + {ok, {Source, Data}}; + {error, _} = ERROR -> + ERROR + end + end, + send => fun(S, Data, Dest) -> + MsgHdr = #{addr => Dest, + iov => [Data]}, + socket:sendmsg(S, MsgHdr) + end}, + ok = traffic_send_and_recv_udp(InitState) + end). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case is intended to (simply) test that the counters +%% for both read and write. +%% So that its easy to extend, we use fun's for read and write. +%% We use UDP on IPv6. + +traffic_sendmsg_and_recvmsg_counters_udp6(suite) -> + []; +traffic_sendmsg_and_recvmsg_counters_udp6(doc) -> + []; +traffic_sendmsg_and_recvmsg_counters_udp6(_Config) when is_list(_Config) -> + ?TT(?SECS(15)), + tc_try(traffic_sendmsg_and_recvmsg_counters_udp6, + fun() -> has_support_ipv6() end, + fun() -> + InitState = #{domain => inet6, + proto => udp, + recv => fun(S) -> + case socket:recvmsg(S) of + {ok, #{addr := Source, + iov := [Data]}} -> + {ok, {Source, Data}}; + {error, _} = ERROR -> + ERROR + end + end, + send => fun(S, Data, Dest) -> + MsgHdr = #{addr => Dest, + iov => [Data]}, + socket:sendmsg(S, MsgHdr) + end}, + ok = traffic_send_and_recv_udp(InitState) + end). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test case is intended to (simply) test that the counters +%% for both read and write. +%% So that its easy to extend, we use fun's for read and write. +%% We use default (UDP) on local. + +traffic_sendmsg_and_recvmsg_counters_udpL(suite) -> + []; +traffic_sendmsg_and_recvmsg_counters_udpL(doc) -> + []; +traffic_sendmsg_and_recvmsg_counters_udpL(_Config) when is_list(_Config) -> + ?TT(?SECS(15)), + tc_try(traffic_sendmsg_and_recvmsg_counters_udpL, + fun() -> has_support_unix_domain_socket() end, + fun() -> + InitState = #{domain => local, + proto => default, + recv => fun(S) -> + case socket:recvmsg(S) of + {ok, #{addr := Source, + iov := [Data]}} -> + {ok, {Source, Data}}; + {error, _} = ERROR -> + ERROR + end + end, + send => fun(S, Data, Dest) -> + MsgHdr = #{addr => Dest, + iov => [Data]}, + socket:sendmsg(S, MsgHdr) + end}, + ok = traffic_send_and_recv_udp(InitState) + end). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +traffic_send_and_recv_udp(InitState) -> + ServerSeq = + [ + %% *** Wait for start order part *** + #{desc => "await start", + cmd => fun(State) -> + Tester = ?SEV_AWAIT_START(), + {ok, State#{tester => Tester}} + end}, + #{desc => "monitor tester", + cmd => fun(#{tester := Tester} = _State) -> + _MRef = erlang:monitor(process, Tester), + ok + end}, + + %% *** Init part *** + #{desc => "which local address", + cmd => fun(#{domain := Domain} = State) -> + LSA = which_local_socket_addr(Domain), + {ok, State#{local_sa => LSA}} + end}, + #{desc => "create socket", + cmd => fun(#{domain := Domain, proto := Proto} = State) -> + case socket:open(Domain, dgram, Proto) of + {ok, Sock} -> + {ok, State#{sock => Sock}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "bind to local address", + cmd => fun(#{domain := local, + sock := Sock, + local_sa := LSA} = _State) -> + case socket:bind(Sock, LSA) of + {ok, _Port} -> + ok; % We do not care about the port for local + {error, _} = ERROR -> + ERROR + end; + (#{sock := LSock, + local_sa := LSA} = State) -> + case socket:bind(LSock, LSA) of + {ok, Port} -> + {ok, State#{lport => Port}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "initial counter validation (=zero)", + cmd => fun(#{sock := Sock} = _State) -> + try socket:info(Sock) of + #{counters := Counters} -> + ?SEV_IPRINT("Validate initial counters: " + "~n ~p", [Counters]), + traffic_sar_counters_validation(Counters) + catch + C:E:S -> + ?SEV_EPRINT("Failed get socket info: " + "~n Class: ~p" + "~n Error: ~p" + "~n Stack: ~p", [C, E, S]), + {error, {socket_info_failed, {C, E, S}}} + end + end}, + #{desc => "announce ready (init)", + cmd => fun(#{domain := local, + tester := Tester, + local_sa := #{path := Path}}) -> + ?SEV_ANNOUNCE_READY(Tester, init, Path), + ok; + (#{tester := Tester, + lport := Port}) -> + ?SEV_ANNOUNCE_READY(Tester, init, Port), + ok + end}, + + %% The actual test + #{desc => "await continue (recv_and_validate 1)", + cmd => fun(#{tester := Tester} = _State) -> + ?SEV_AWAIT_CONTINUE(Tester, tester, recv_and_validate) + end}, + #{desc => "recv (1)", + cmd => fun(#{sock := Sock, + recv := Recv} = State) -> + case Recv(Sock) of + {ok, {ClientSA, Data}} -> + ?SEV_IPRINT("recv ~p bytes", [size(Data)]), + {ok, State#{client_sa => ClientSA, + read_pkg => 1, + read_byte => size(Data)}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "validate (recv 1)", + cmd => fun(#{sock := Sock, + read_pkg := Pkg, + read_byte := Byte} = _State) -> + try socket:info(Sock) of + #{counters := Counters} -> + ?SEV_IPRINT("validate counters: " + "~n ~p", [Counters]), + traffic_sar_counters_validation( + Counters, + [{read_pkg, Pkg}, + {read_byte, Byte}, + {read_tries, any}]) + catch + C:E:S -> + ?SEV_EPRINT("Failed get socket info: " + "~n Class: ~p" + "~n Error: ~p" + "~n Stack: ~p", [C, E, S]), + {error, {socket_info_failed, {C, E, S}}} + end + end}, + #{desc => "announce ready (recv_and_validate 1)", + cmd => fun(#{tester := Tester}) -> + ?SEV_ANNOUNCE_READY(Tester, recv_and_validate), + ok + end}, + + #{desc => "await continue (send_and_validate 1)", + cmd => fun(#{tester := Tester} = _State) -> + ?SEV_AWAIT_CONTINUE(Tester, tester, send_and_validate) + end}, + #{desc => "send (1)", + cmd => fun(#{sock := Sock, + send := Send, + client_sa := ClientSA} = State) -> + Data = ?DATA, + case Send(Sock, Data, ClientSA) of + ok -> + ?SEV_IPRINT("sent ~p bytes", [size(Data)]), + {ok, State#{write_pkg => 1, + write_byte => size(Data)}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "validate (send 1)", + cmd => fun(#{sock := Sock, + read_pkg := RPkg, + read_byte := RByte, + write_pkg := SPkg, + write_byte := SByte} = _State) -> + try socket:info(Sock) of + #{counters := Counters} -> + ?SEV_IPRINT("validate counters: " + "~n ~p", [Counters]), + traffic_sar_counters_validation( + Counters, + [{read_pkg, RPkg}, + {read_byte, RByte}, + {write_pkg, SPkg}, + {write_byte, SByte}, + {read_tries, any}, + {write_tries, any}]) + catch + C:E:S -> + ?SEV_EPRINT("Failed get socket info: " + "~n Class: ~p" + "~n Error: ~p" + "~n Stack: ~p", [C, E, S]), + {error, {socket_info_failed, {C, E, S}}} + end + end}, + #{desc => "announce ready (send_and_validate 1)", + cmd => fun(#{tester := Tester}) -> + ?SEV_ANNOUNCE_READY(Tester, send_and_validate), + ok + end}, + + #{desc => "await continue (recv_and_validate 2)", + cmd => fun(#{tester := Tester} = _State) -> + ?SEV_AWAIT_CONTINUE(Tester, tester, recv_and_validate) + end}, + #{desc => "recv (2)", + cmd => fun(#{sock := Sock, + recv := Recv, + read_pkg := Pkg, + read_byte := Byte} = State) -> + case Recv(Sock) of + {ok, {Source, Data}} -> + ?SEV_IPRINT("recv ~p bytes", [size(Data)]), + {ok, State#{client_sa => Source, + read_pkg => Pkg + 1, + read_byte => Byte + size(Data)}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "validate (recv 2)", + cmd => fun(#{sock := Sock, + read_pkg := RPkg, + read_byte := RByte, + write_pkg := SPkg, + write_byte := SByte} = _State) -> + try socket:info(Sock) of + #{counters := Counters} -> + ?SEV_IPRINT("validate counters: " + "~n ~p", [Counters]), + traffic_sar_counters_validation( + Counters, + [{read_pkg, RPkg}, + {read_byte, RByte}, + {write_pkg, SPkg}, + {write_byte, SByte}, + {read_tries, any}, + {write_tries, any}]) + catch + C:E:S -> + ?SEV_EPRINT("Failed get socket info: " + "~n Class: ~p" + "~n Error: ~p" + "~n Stack: ~p", [C, E, S]), + {error, {socket_info_failed, {C, E, S}}} + end + end}, + #{desc => "announce ready (recv_and_validate 2)", + cmd => fun(#{tester := Tester}) -> + ?SEV_ANNOUNCE_READY(Tester, recv_and_validate), + ok + end}, + + #{desc => "await continue (send_and_validate 2)", + cmd => fun(#{tester := Tester} = _State) -> + ?SEV_AWAIT_CONTINUE(Tester, tester, send_and_validate) + end}, + #{desc => "send (2)", + cmd => fun(#{sock := Sock, + client_sa := ClientSA, + send := Send, + write_pkg := Pkg, + write_byte := Byte} = State) -> + Data = ?DATA, + case Send(Sock, Data, ClientSA) of + ok -> + ?SEV_IPRINT("sent ~p bytes", [size(Data)]), + {ok, State#{write_pkg => Pkg + 1, + write_byte => Byte + size(Data)}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "validate (send 2)", + cmd => fun(#{sock := Sock, + read_pkg := RPkg, + read_byte := RByte, + write_pkg := SPkg, + write_byte := SByte} = _State) -> + try socket:info(Sock) of + #{counters := Counters} -> + ?SEV_IPRINT("validate counters: " + "~n ~p", [Counters]), + traffic_sar_counters_validation( + Counters, + [{read_pkg, RPkg}, + {read_byte, RByte}, + {write_pkg, SPkg}, + {write_byte, SByte}, + {read_tries, any}, + {write_tries, any}]) + catch + C:E:S -> + ?SEV_EPRINT("Failed get socket info: " + "~n Class: ~p" + "~n Error: ~p" + "~n Stack: ~p", [C, E, S]), + {error, {socket_info_failed, {C, E, S}}} + end + end}, + #{desc => "announce ready (send_and_validate 2)", + cmd => fun(#{tester := Tester}) -> + ?SEV_ANNOUNCE_READY(Tester, send_and_validate), + ok + end}, + + + %% Termination + #{desc => "await terminate (from tester)", + cmd => fun(#{tester := Tester} = State) -> + case ?SEV_AWAIT_TERMINATE(Tester, tester) of + ok -> + {ok, maps:remove(tester, State)}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "close socket (just in case)", + cmd => fun(#{domain := local, + sock := Sock, + local_sa := #{path := Path}} = State) -> + ok = socket:close(Sock), + State1 = + unlink_path(Path, + fun() -> + maps:remove(local_sa, State) + end, + fun() -> State end), + {ok, maps:remove(lsock, State1)}; + (#{sock := Sock} = State) -> + (catch socket:close(Sock)), + {ok, maps:remove(sock, State)} + end}, + + %% *** We are done *** + ?SEV_FINISH_NORMAL + ], + + ClientSeq = + [ + %% *** Wait for start order part *** + #{desc => "await start (from tester)", + cmd => fun(#{domain := local} = State) -> + {Tester, Path} = ?SEV_AWAIT_START(), + {ok, State#{tester => Tester, server_path => Path}}; + (State) -> + {Tester, Port} = ?SEV_AWAIT_START(), + {ok, State#{tester => Tester, server_port => Port}} + end}, + #{desc => "monitor tester", + cmd => fun(#{tester := Tester} = _State) -> + _MRef = erlang:monitor(process, Tester), + ok + end}, + + %% *** Init part *** + #{desc => "which server (local) address", + cmd => fun(#{domain := local = Domain, + server_path := Path} = State) -> + LSA = which_local_socket_addr(Domain), + SSA = #{family => Domain, path => Path}, + {ok, State#{local_sa => LSA, server_sa => SSA}}; + (#{domain := Domain, server_port := Port} = State) -> + LSA = which_local_socket_addr(Domain), + SSA = LSA#{port => Port}, + {ok, State#{local_sa => LSA, server_sa => SSA}} + end}, + #{desc => "create socket", + cmd => fun(#{domain := Domain, + proto := Proto} = State) -> + case socket:open(Domain, dgram, Proto) of + {ok, Sock} -> + {ok, State#{sock => Sock}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "bind to local address", + cmd => fun(#{sock := Sock, local_sa := LSA} = _State) -> + case socket:bind(Sock, LSA) of + {ok, _Port} -> + ok; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "initial counter validation (=zero)", + cmd => fun(#{sock := Sock} = _State) -> + try socket:info(Sock) of + #{counters := Counters} -> + ?SEV_IPRINT("Validate initial counters: " + "~n ~p", [Counters]), + traffic_sar_counters_validation(Counters) + catch + C:E:S -> + ?SEV_EPRINT("Failed get socket info: " + "~n Class: ~p" + "~n Error: ~p" + "~n Stack: ~p", [C, E, S]), + {error, {socket_info_failed, {C, E, S}}} + end + end}, + #{desc => "announce ready (init)", + cmd => fun(#{tester := Tester}) -> + ?SEV_ANNOUNCE_READY(Tester, init), + ok + end}, + + %% The actual test + #{desc => "await continue (send_and_validate 1)", + cmd => fun(#{tester := Tester} = _State) -> + ?SEV_AWAIT_CONTINUE(Tester, tester, send_and_validate) + end}, + #{desc => "send (1)", + cmd => fun(#{sock := Sock, + send := Send, + server_sa := ServerSA} = State) -> + Data = ?DATA, + case Send(Sock, Data, ServerSA) of + ok -> + ?SEV_IPRINT("sent ~p bytes", [size(Data)]), + {ok, State#{write_pkg => 1, + write_byte => size(Data)}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "validate (send 1)", + cmd => fun(#{sock := Sock, + write_pkg := SPkg, + write_byte := SByte} = _State) -> + try socket:info(Sock) of + #{counters := Counters} -> + ?SEV_IPRINT("validate counters: " + "~n ~p", [Counters]), + traffic_sar_counters_validation( + Counters, + [{write_pkg, SPkg}, + {write_byte, SByte}, + {write_tries, any}]) + catch + C:E:S -> + ?SEV_EPRINT("Failed get socket info: " + "~n Class: ~p" + "~n Error: ~p" + "~n Stack: ~p", [C, E, S]), + {error, {socket_info_failed, {C, E, S}}} + end + end}, + #{desc => "announce ready (send_and_validate 1)", + cmd => fun(#{tester := Tester}) -> + ?SEV_ANNOUNCE_READY(Tester, send_and_validate), + ok + end}, + + #{desc => "await continue (recv_and_validate 1)", + cmd => fun(#{tester := Tester} = _State) -> + ?SEV_AWAIT_CONTINUE(Tester, tester, recv_and_validate) + end}, + #{desc => "recv (1)", + cmd => fun(#{sock := Sock, + recv := Recv, + server_sa := #{family := local} = ServerSA} = State) -> + case Recv(Sock) of + {ok, {ServerSA, Data}} -> + ?SEV_IPRINT("recv ~p bytes", [size(Data)]), + {ok, State#{read_pkg => 1, + read_byte => size(Data)}}; + {error, _} = ERROR -> + ERROR + end; + (#{sock := Sock, + recv := Recv, + server_sa := #{addr := Addr, port := Port}} = State) -> + case Recv(Sock) of + {ok, {#{addr := Addr, port := Port}, Data}} -> + ?SEV_IPRINT("recv ~p bytes", [size(Data)]), + {ok, State#{read_pkg => 1, + read_byte => size(Data)}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "validate (recv 1)", + cmd => fun(#{sock := Sock, + read_pkg := RPkg, + read_byte := RByte, + write_pkg := SPkg, + write_byte := SByte} = _State) -> + try socket:info(Sock) of + #{counters := Counters} -> + ?SEV_IPRINT("validate counters: " + "~n ~p", [Counters]), + traffic_sar_counters_validation( + Counters, + [{read_pkg, RPkg}, + {read_byte, RByte}, + {write_pkg, SPkg}, + {write_byte, SByte}, + {read_tries, any}, + {write_tries, any}]) + catch + C:E:S -> + ?SEV_EPRINT("Failed get socket info: " + "~n Class: ~p" + "~n Error: ~p" + "~n Stack: ~p", [C, E, S]), + {error, {socket_info_failed, {C, E, S}}} + end + end}, + #{desc => "announce ready (recv_and_validate 1)", + cmd => fun(#{tester := Tester}) -> + ?SEV_ANNOUNCE_READY(Tester, recv_and_validate), + ok + end}, + + #{desc => "await continue (send_and_validate 2)", + cmd => fun(#{tester := Tester} = _State) -> + ?SEV_AWAIT_CONTINUE(Tester, tester, send_and_validate) + end}, + #{desc => "send (2)", + cmd => fun(#{sock := Sock, + send := Send, + server_sa := ServerSA, + write_pkg := SPkg, + write_byte := SByte} = State) -> + Data = ?DATA, + case Send(Sock, Data, ServerSA) of + ok -> + ?SEV_IPRINT("sent ~p bytes", [size(Data)]), + {ok, State#{write_pkg => SPkg + 1, + write_byte => SByte + size(Data)}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "validate (send 2)", + cmd => fun(#{sock := Sock, + read_pkg := RPkg, + read_byte := RByte, + write_pkg := SPkg, + write_byte := SByte} = _State) -> + try socket:info(Sock) of + #{counters := Counters} -> + ?SEV_IPRINT("validate counters: " + "~n ~p", [Counters]), + traffic_sar_counters_validation( + Counters, + [{read_pkg, RPkg}, + {read_byte, RByte}, + {write_pkg, SPkg}, + {write_byte, SByte}, + {read_tries, any}, + {write_tries, any}]) + catch + C:E:S -> + ?SEV_EPRINT("Failed get socket info: " + "~n Class: ~p" + "~n Error: ~p" + "~n Stack: ~p", [C, E, S]), + {error, {socket_info_failed, {C, E, S}}} + end + end}, + #{desc => "announce ready (send_and_validate 2)", + cmd => fun(#{tester := Tester}) -> + ?SEV_ANNOUNCE_READY(Tester, send_and_validate), + ok + end}, + + #{desc => "await continue (recv_and_validate 2)", + cmd => fun(#{tester := Tester} = _State) -> + ?SEV_AWAIT_CONTINUE(Tester, tester, recv_and_validate) + end}, + #{desc => "recv (2)", + cmd => fun(#{sock := Sock, + server_sa := #{family := local} = ServerSA, + recv := Recv, + read_pkg := RPkg, + read_byte := RByte} = State) -> + case Recv(Sock) of + {ok, {ServerSA, Data}} -> + ?SEV_IPRINT("recv ~p bytes", [size(Data)]), + {ok, State#{read_pkg => RPkg + 1, + read_byte => RByte + size(Data)}}; + {error, _} = ERROR -> + ERROR + end; + (#{sock := Sock, + server_sa := #{addr := Addr, port := Port}, + recv := Recv, + read_pkg := RPkg, + read_byte := RByte} = State) -> + case Recv(Sock) of + {ok, {#{addr := Addr, port := Port}, Data}} -> + ?SEV_IPRINT("recv ~p bytes", [size(Data)]), + {ok, State#{read_pkg => RPkg + 1, + read_byte => RByte + size(Data)}}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "validate (recv 2)", + cmd => fun(#{sock := Sock, + read_pkg := RPkg, + read_byte := RByte, + write_pkg := SPkg, + write_byte := SByte} = _State) -> + try socket:info(Sock) of + #{counters := Counters} -> + ?SEV_IPRINT("validate counters: " + "~n ~p", [Counters]), + traffic_sar_counters_validation( + Counters, + [{read_pkg, RPkg}, + {read_byte, RByte}, + {write_pkg, SPkg}, + {write_byte, SByte}, + {read_tries, any}, + {write_tries, any}]) + catch + C:E:S -> + ?SEV_EPRINT("Failed get socket info: " + "~n Class: ~p" + "~n Error: ~p" + "~n Stack: ~p", [C, E, S]), + {error, {socket_info_failed, {C, E, S}}} + end + end}, + #{desc => "announce ready (recv_and_validate 2)", + cmd => fun(#{tester := Tester}) -> + ?SEV_ANNOUNCE_READY(Tester, recv_and_validate), + ok + end}, + + %% Termination + #{desc => "await terminate (from tester)", + cmd => fun(#{tester := Tester} = State) -> + case ?SEV_AWAIT_TERMINATE(Tester, tester) of + ok -> + {ok, maps:remove(tester, State)}; + {error, _} = ERROR -> + ERROR + end + end}, + #{desc => "close connection socket", + cmd => fun(#{domain := local, + sock := Sock, + local_sa := #{path := Path}} = State) -> + ok = socket:close(Sock), + State1 = + unlink_path(Path, + fun() -> + maps:remove(local_sa, State) + end, + fun() -> State end), + {ok, maps:remove(sock, State1)}; + (#{sock := Sock} = State) -> + socket:close(Sock), + {ok, maps:remove(sock, State)} + end}, + + %% *** We are done *** + ?SEV_FINISH_NORMAL + ], + + + TesterSeq = + [ + %% *** Init part *** + #{desc => "monitor server", + cmd => fun(#{server := Pid} = _State) -> + _MRef = erlang:monitor(process, Pid), + ok + end}, + #{desc => "monitor client", + cmd => fun(#{client := Pid} = _State) -> + _MRef = erlang:monitor(process, Pid), + ok + end}, + + %% Start the server + #{desc => "order server start", + cmd => fun(#{server := Pid} = _State) -> + ?SEV_ANNOUNCE_START(Pid), + ok + end}, + #{desc => "await server ready (init)", + cmd => fun(#{domain := local, + server := Pid} = State) -> + {ok, Path} = ?SEV_AWAIT_READY(Pid, server, init), + {ok, State#{path => Path}}; + (#{server := Pid} = State) -> + {ok, Port} = ?SEV_AWAIT_READY(Pid, server, init), + {ok, State#{port => Port}} + end}, + + %% Start the client + #{desc => "order client start", + cmd => fun(#{domain := local, + client := Pid, + path := Path} = _State) -> + ?SEV_ANNOUNCE_START(Pid, Path), + ok; + (#{client := Pid, + port := Port} = _State) -> + ?SEV_ANNOUNCE_START(Pid, Port), + ok + end}, + #{desc => "await client ready (init)", + cmd => fun(#{client := Pid} = _State) -> + ok = ?SEV_AWAIT_READY(Pid, client, init) + end}, + + %% *** The actual test *** + + #{desc => "order server to continue (recv_and_validate 1)", + cmd => fun(#{server := Server} = _State) -> + ?SEV_ANNOUNCE_CONTINUE(Server, recv_and_validate), + ok + end}, + #{desc => "order client to continue (send_and_validate 1)", + cmd => fun(#{client := Client} = _State) -> + ?SEV_ANNOUNCE_CONTINUE(Client, send_and_validate), + ok + end}, + #{desc => "await client ready (send_and_validate 1)", + cmd => fun(#{client := Client} = _State) -> + ?SEV_AWAIT_READY(Client, client, send_and_validate) + end}, + #{desc => "await server ready (recv_and_validate 1)", + cmd => fun(#{server := Server} = _State) -> + ?SEV_AWAIT_READY(Server, server, recv_and_validate) + end}, + + ?SEV_SLEEP(?SECS(1)), + + #{desc => "order client to continue (recv_and_validate 1)", + cmd => fun(#{client := Client} = _State) -> + ?SEV_ANNOUNCE_CONTINUE(Client, recv_and_validate), + ok + end}, + #{desc => "order server to continue (send_and_validate 1)", + cmd => fun(#{server := Server} = _State) -> + ?SEV_ANNOUNCE_CONTINUE(Server, send_and_validate), + ok + end}, + #{desc => "await server ready (send_and_validate 1)", + cmd => fun(#{server := Server} = _State) -> + ?SEV_AWAIT_READY(Server, server, send_and_validate) + end}, + #{desc => "await client ready (recv_and_validate 1)", + cmd => fun(#{client := Client} = _State) -> + ?SEV_AWAIT_READY(Client, client, recv_and_validate) + end}, + + ?SEV_SLEEP(?SECS(1)), + + #{desc => "order server to continue (recv_and_validate 2)", + cmd => fun(#{server := Server} = _State) -> + ?SEV_ANNOUNCE_CONTINUE(Server, recv_and_validate), + ok + end}, + #{desc => "order client to continue (send_and_validate 2)", + cmd => fun(#{client := Client} = _State) -> + ?SEV_ANNOUNCE_CONTINUE(Client, send_and_validate), + ok + end}, + #{desc => "await client ready (send_and_validate 2)", + cmd => fun(#{client := Client} = _State) -> + ?SEV_AWAIT_READY(Client, client, send_and_validate) + end}, + #{desc => "await server ready (recv_and_validate 2)", + cmd => fun(#{server := Server} = _State) -> + ?SEV_AWAIT_READY(Server, server, recv_and_validate) + end}, + + ?SEV_SLEEP(?SECS(1)), + + #{desc => "order client to continue (recv_and_validate 2)", + cmd => fun(#{client := Client} = _State) -> + ?SEV_ANNOUNCE_CONTINUE(Client, recv_and_validate), + ok + end}, + #{desc => "order server to continue (send_and_validate 2)", + cmd => fun(#{server := Server} = _State) -> + ?SEV_ANNOUNCE_CONTINUE(Server, send_and_validate), + ok + end}, + #{desc => "await server ready (send_and_validate 2)", + cmd => fun(#{server := Server} = _State) -> + ?SEV_AWAIT_READY(Server, server, send_and_validate) + end}, + #{desc => "await client ready (recv_and_validate 2)", + cmd => fun(#{client := Client} = _State) -> + ?SEV_AWAIT_READY(Client, client, recv_and_validate) + end}, + + %% *** Termination *** + #{desc => "order client to terminate", + cmd => fun(#{client := Client} = _State) -> + ?SEV_ANNOUNCE_TERMINATE(Client), + ok + end}, + #{desc => "await client termination", + cmd => fun(#{client := Client} = State) -> + ?SEV_AWAIT_TERMINATION(Client), + State1 = maps:remove(client, State), + {ok, State1} + end}, + #{desc => "order server to terminate", + cmd => fun(#{server := Server} = _State) -> + ?SEV_ANNOUNCE_TERMINATE(Server), + ok + end}, + #{desc => "await server termination", + cmd => fun(#{server := Server} = State) -> + ?SEV_AWAIT_TERMINATION(Server), + State1 = maps:remove(server, State), + {ok, State1} + end}, + + %% *** We are done *** + ?SEV_FINISH_NORMAL + ], + + i("start server evaluator"), + ServerInitState = InitState#{host => local_host()}, + Server = ?SEV_START("server", ServerSeq, ServerInitState), + + i("start client evaluator(s)"), + ClientInitState = InitState#{host => local_host()}, + Client = ?SEV_START("client", ClientSeq, ClientInitState), + + i("start 'tester' evaluator"), + TesterInitState = #{server => Server#ev.pid, + client => Client#ev.pid}, + Tester = ?SEV_START("tester", TesterSeq, TesterInitState), + + i("await evaluator"), + ok = ?SEV_AWAIT_FINISH([Server, Client, Tester]). + + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case is intended to test that the send and recv functions %% behave as expected when sending and/or reading chunks. %% First send data in one "big" chunk, and read it in "small" chunks. @@ -15180,12 +19590,12 @@ traffic_ping_pong_small_sendto_and_recvfrom_udp6(suite) -> traffic_ping_pong_small_sendto_and_recvfrom_udp6(doc) -> []; traffic_ping_pong_small_sendto_and_recvfrom_udp6(_Config) when is_list(_Config) -> - ?TT(?SECS(45)), Msg = l2b(?TPP_SMALL), Num = ?TPP_SMALL_NUM, tc_try(traffic_ping_pong_small_sendto_and_recvfrom_udp6, fun() -> has_support_ipv6() end, fun() -> + ?TT(?SECS(45)), InitState = #{domain => inet6, proto => udp, msg => Msg, @@ -15209,12 +19619,12 @@ traffic_ping_pong_small_sendto_and_recvfrom_udpL(suite) -> traffic_ping_pong_small_sendto_and_recvfrom_udpL(doc) -> []; traffic_ping_pong_small_sendto_and_recvfrom_udpL(_Config) when is_list(_Config) -> - ?TT(?SECS(45)), Msg = l2b(?TPP_SMALL), Num = ?TPP_SMALL_NUM, tc_try(traffic_ping_pong_small_sendto_and_recvfrom_udpL, fun() -> has_support_unix_domain_socket() end, fun() -> + ?TT(?SECS(45)), InitState = #{domain => local, proto => default, msg => Msg, @@ -15438,7 +19848,7 @@ traffic_ping_pong_medium_sendmsg_and_recvmsg_tcp6(_Config) when is_list(_Config) tc_try(traffic_ping_pong_medium_sendmsg_and_recvmsg_tcp6, fun() -> has_support_ipv6() end, fun() -> - ?TT(?SECS(20)), + ?TT(?SECS(30)), InitState = #{domain => inet6, proto => tcp, msg => Msg, @@ -15466,7 +19876,7 @@ traffic_ping_pong_medium_sendmsg_and_recvmsg_tcpL(_Config) when is_list(_Config) tc_try(traffic_ping_pong_medium_sendmsg_and_recvmsg_tcpL, fun() -> has_support_unix_domain_socket() end, fun() -> - ?TT(?SECS(20)), + ?TT(?SECS(30)), InitState = #{domain => local, proto => default, msg => Msg, @@ -15494,7 +19904,7 @@ traffic_ping_pong_large_sendmsg_and_recvmsg_tcp4(_Config) when is_list(_Config) tc_try(traffic_ping_pong_large_sendmsg_and_recvmsg_tcp4, fun() -> traffic_ping_pong_large_sendmsg_and_recvmsg_cond() end, fun() -> - ?TT(?SECS(30)), + ?TT(?SECS(60)), InitState = #{domain => inet, proto => tcp, msg => Msg, @@ -15535,7 +19945,7 @@ traffic_ping_pong_large_sendmsg_and_recvmsg_tcp6(_Config) when is_list(_Config) traffic_ping_pong_large_sendmsg_and_recvmsg_cond() end, fun() -> - ?TT(?SECS(30)), + ?TT(?SECS(60)), InitState = #{domain => inet6, proto => tcp, msg => Msg, @@ -15564,7 +19974,7 @@ traffic_ping_pong_large_sendmsg_and_recvmsg_tcpL(_Config) when is_list(_Config) tc_try(traffic_ping_pong_large_sendmsg_and_recvmsg_tcpL, fun() -> has_support_unix_domain_socket() end, fun() -> - ?TT(?SECS(30)), + ?TT(?SECS(60)), InitState = #{domain => local, proto => default, msg => Msg, @@ -15620,7 +20030,7 @@ traffic_ping_pong_small_sendmsg_and_recvmsg_udp6(_Config) when is_list(_Config) tc_try(traffic_ping_pong_small_sendmsg_and_recvmsg_udp6, fun() -> has_support_ipv6() end, fun() -> - ?TT(?SECS(30)), + ?TT(?SECS(60)), InitState = #{domain => inet6, proto => udp, msg => Msg, @@ -15648,7 +20058,7 @@ traffic_ping_pong_small_sendmsg_and_recvmsg_udpL(_Config) when is_list(_Config) tc_try(traffic_ping_pong_small_sendmsg_and_recvmsg_udpL, fun() -> has_support_unix_domain_socket() end, fun() -> - ?TT(?SECS(30)), + ?TT(?SECS(60)), InitState = #{domain => local, proto => default, msg => Msg, @@ -15675,7 +20085,7 @@ traffic_ping_pong_medium_sendmsg_and_recvmsg_udp4(_Config) when is_list(_Config) Num = ?TPP_MEDIUM_NUM, tc_try(traffic_ping_pong_medium_sendmsg_and_recvmsg_udp4, fun() -> - ?TT(?SECS(30)), + ?TT(?SECS(60)), InitState = #{domain => inet, proto => udp, msg => Msg, @@ -15703,7 +20113,7 @@ traffic_ping_pong_medium_sendmsg_and_recvmsg_udp6(_Config) when is_list(_Config) tc_try(traffic_ping_pong_medium_sendmsg_and_recvmsg_udp6, fun() -> has_support_ipv6() end, fun() -> - ?TT(?SECS(20)), + ?TT(?SECS(60)), InitState = #{domain => inet6, proto => udp, msg => Msg, @@ -15732,7 +20142,7 @@ traffic_ping_pong_medium_sendmsg_and_recvmsg_udpL(_Config) when is_list(_Config) tc_try(traffic_ping_pong_medium_sendmsg_and_recvmsg_udpL, fun() -> has_support_unix_domain_socket() end, fun() -> - ?TT(?SECS(20)), + ?TT(?SECS(60)), InitState = #{domain => local, proto => default, msg => Msg, @@ -15804,12 +20214,14 @@ traffic_ping_pong_send_and_receive_tcp(#{msg := Msg} = InitState) -> ?SEV_IPRINT("RcvBuf is ~p (needs atleast ~p)", [RcvSz, 16+size(Msg)]), if (RcvSz < size(Msg)) -> - case socket:setopt(Sock, - socket, rcvbuf, 1024+size(Msg)) of + NewRcvSz = 1024+size(Msg), + case socket:setopt(Sock, socket, rcvbuf, NewRcvSz) of ok -> ok; {error, enobufs} -> - skip({failed_change, rcvbuf}); + skip(?F("Change ~w buffer size (to ~w) " + "not allowed", + [rcvbuf, NewRcvSz])); {error, Reason1} -> ?FAIL({rcvbuf, Reason1}) end; @@ -15820,12 +20232,14 @@ traffic_ping_pong_send_and_receive_tcp(#{msg := Msg} = InitState) -> ?SEV_IPRINT("SndBuf is ~p (needs atleast ~p)", [SndSz, 16+size(Msg)]), if (SndSz < size(Msg)) -> - case socket:setopt(Sock, - socket, sndbuf, 1024+size(Msg)) of + NewSndSz = 1024+size(Msg), + case socket:setopt(Sock, socket, sndbuf, NewSndSz) of ok -> ok; {error, enobufs} -> - skip({failed_change, sndbuf}); + skip(?F("Change ~w buffer size (to ~w) " + "not allowed", + [sndbuf, NewSndSz])); {error, Reason2} -> ?FAIL({sndbuf, Reason2}) end; @@ -17413,7 +21827,9 @@ tpp_udp_client_handler_msg_exchange_loop(_Sock, _Dest, _Send, _Recv, _Msg, Start) -> Stop = ?LIB:timestamp(), {Sent, Received, Start, Stop}; -tpp_udp_client_handler_msg_exchange_loop(Sock, Dest, Send, Recv, Data, +tpp_udp_client_handler_msg_exchange_loop(Sock, + #{family := local} = Dest, + Send, Recv, Data, Num, N, Sent, Received, Start) -> case tpp_udp_send_req(Sock, Send, Data, Dest) of {ok, SendSz} -> @@ -17432,6 +21848,28 @@ tpp_udp_client_handler_msg_exchange_loop(Sock, Dest, Send, Recv, Data, {error, SReason} -> ?SEV_EPRINT("send (~w of ~w): ~p", [N, Num, SReason]), exit({send, SReason, N}) + end; +tpp_udp_client_handler_msg_exchange_loop(Sock, + #{addr := Addr, port := Port} = Dest0, + Send, Recv, Data, + Num, N, Sent, Received, Start) -> + case tpp_udp_send_req(Sock, Send, Data, Dest0) of + {ok, SendSz} -> + case tpp_udp_recv_rep(Sock, Recv) of + {ok, NewData, RecvSz, #{addr := Addr, port := Port} = Dest1} -> + tpp_udp_client_handler_msg_exchange_loop(Sock, Dest1, + Send, Recv, + NewData, Num, N+1, + Sent+SendSz, + Received+RecvSz, + Start); + {error, RReason} -> + ?SEV_EPRINT("recv (~w of ~w): ~p", [N, Num, RReason]), + exit({recv, RReason, N}) + end; + {error, SReason} -> + ?SEV_EPRINT("send (~w of ~w): ~p", [N, Num, SReason]), + exit({send, SReason, N}) end. @@ -23455,7 +27893,7 @@ ttest_tcp(TC, fun() -> if (Domain =:= local) -> has_support_unix_domain_socket(); - (Domain =:= inet6) -> has_support_ipv6(); + (Domain =:= inet6) -> has_support_ipv6(); true -> ok end end, @@ -23918,16 +28356,22 @@ ttest_tcp(InitState) -> ?SEV_FINISH_NORMAL ], + Domain = maps:get(domain, InitState), + LHost = local_host(), + LAddr = which_local_addr(Domain), + i("start server evaluator"), - ServerInitState = #{host => local_host(), - domain => maps:get(domain, InitState), + ServerInitState = #{host => LHost, + addr => LAddr, + domain => Domain, mod => maps:get(server_mod, InitState), active => maps:get(server_active, InitState)}, Server = ?SEV_START("server", ServerSeq, ServerInitState), i("start client evaluator"), - ClientInitState = #{host => local_host(), - domain => maps:get(domain, InitState), + ClientInitState = #{host => LHost, + addr => LAddr, + domain => Domain, mod => maps:get(client_mod, InitState), active => maps:get(client_active, InitState), msg_id => maps:get(msg_id, InitState), @@ -23936,9 +28380,14 @@ ttest_tcp(InitState) -> Client = ?SEV_START("client", ClientSeq, ClientInitState), i("start 'tester' evaluator"), - TesterInitState = #{domain => maps:get(domain, InitState), - server => Server#ev.pid, - client => Client#ev.pid}, + TesterInitState = #{domain => Domain, + msg_id => maps:get(msg_id, InitState), + client => Client#ev.pid, + client_mod => maps:get(client_mod, InitState), + client_active => maps:get(client_active, InitState), + server => Server#ev.pid, + server_mod => maps:get(server_mod, InitState), + server_active => maps:get(server_active, InitState)}, Tester = ?SEV_START("tester", TesterSeq, TesterInitState), i("await evaluator(s)"), @@ -23946,8 +28395,9 @@ ttest_tcp(InitState) -> -ttest_tcp_server_start(Node, _Domain, gen, Active) -> - Transport = socket_test_ttest_tcp_gen, +ttest_tcp_server_start(Node, Domain, gen, Active) -> + TransportMod = socket_test_ttest_tcp_gen, + Transport = {TransportMod, #{domain => Domain}}, socket_test_ttest_tcp_server:start_monitor(Node, Transport, Active); ttest_tcp_server_start(Node, Domain, sock, Active) -> TransportMod = socket_test_ttest_tcp_socket, @@ -23961,9 +28411,10 @@ ttest_tcp_server_stop(Pid) -> ttest_tcp_client_start(Node, Notify, - _Domain, gen, + Domain, gen, ServerInfo, Active, MsgID, MaxOutstanding, RunTime) -> - Transport = socket_test_ttest_tcp_gen, + TransportMod = socket_test_ttest_tcp_gen, + Transport = {TransportMod, #{domain => Domain}}, socket_test_ttest_tcp_client:start_monitor(Node, Notify, Transport, @@ -24258,39 +28709,6 @@ sock_sockname(Sock) -> ?FAIL({sockname, C, E, S}) end. - -%% sock_listen(Sock) -> -%% sock_listen2(fun() -> socket:listen(Sock) end). - -%% sock_listen(Sock, BackLog) -> -%% sock_listen2(fun() -> socket:listen(Sock, BackLog) end). - -%% sock_listen2(Listen) -> -%% try Listen() of -%% ok -> -%% ok; -%% {error, Reason} -> -%% ?FAIL({listen, Reason}) -%% catch -%% C:E:S -> -%% ?FAIL({listen, C, E, S}) -%% end. - - -%% sock_accept(LSock) -> -%% try socket:accept(LSock) of -%% {ok, Sock} -> -%% Sock; -%% {error, Reason} -> -%% i("sock_accept -> error: ~p", [Reason]), -%% ?FAIL({accept, Reason}) -%% catch -%% C:E:S -> -%% i("sock_accept -> failed: ~p, ~p, ~p", [C, E, S]), -%% ?FAIL({accept, C, E, S}) -%% end. - - sock_close(Sock) -> try socket:close(Sock) of ok -> @@ -24356,12 +28774,12 @@ which_local_socket_addr(local = Domain) -> #{family => Domain, path => mk_unique_path()}; -%% This gets the local address (not 127.0...) +%% This gets the local socket address (not 127.0...) %% We should really implement this using the (new) net module, %% but until that gets the necessary functionality... which_local_socket_addr(Domain) -> - case which_local_host_info(Domain) of - {ok, {_Name, _Flags, Addr}} -> + case ?LIB:which_local_host_info(Domain) of + {ok, #{addr := Addr}} -> #{family => Domain, addr => Addr}; {error, Reason} -> @@ -24369,55 +28787,15 @@ which_local_socket_addr(Domain) -> end. -%% Returns the interface (name), flags and address (not 127...) -%% of the local host. -which_local_host_info(Domain) -> - case inet:getifaddrs() of - {ok, IFL} -> - which_local_host_info(Domain, IFL); - {error, _} = ERROR -> - ERROR - end. -which_local_host_info(_Domain, []) -> - ?FAIL(no_address); -which_local_host_info(Domain, [{"lo" ++ _, _}|IFL]) -> - which_local_host_info(Domain, IFL); -which_local_host_info(Domain, [{"docker" ++ _, _}|IFL]) -> - which_local_host_info(Domain, IFL); -which_local_host_info(Domain, [{"br-" ++ _, _}|IFL]) -> - which_local_host_info(Domain, IFL); -which_local_host_info(Domain, [{Name, IFO}|IFL]) -> - case which_local_host_info2(Domain, IFO) of - {ok, {Flags, Addr}} -> - {ok, {Name, Flags, Addr}}; - {error, _} -> - which_local_host_info(Domain, IFL) - end; -which_local_host_info(Domain, [_|IFL]) -> - which_local_host_info(Domain, IFL). - -which_local_host_info2(Domain, IFO) -> - case lists:keysearch(flags, 1, IFO) of - {value, {flags, Flags}} -> - which_local_host_info2(Domain, IFO, Flags); - false -> - {error, no_flags} - end. - -which_local_host_info2(_Domain, [], _Flags) -> - {error, no_address}; -which_local_host_info2(inet = _Domain, [{addr, Addr}|_IFO], Flags) - when (size(Addr) =:= 4) andalso (element(1, Addr) =/= 127) -> - {ok, {Flags, Addr}}; -which_local_host_info2(inet6 = _Domain, [{addr, Addr}|_IFO], Flags) - when (size(Addr) =:= 8) andalso - (element(1, Addr) =/= 0) andalso - (element(1, Addr) =/= 16#fe80) -> - {ok, {Flags, Addr}}; -which_local_host_info2(Domain, [_|IFO], Flags) -> - which_local_host_info2(Domain, IFO, Flags). +which_local_addr(local = _Domain) -> + mk_unique_path(); +%% This gets the local address (not 127.0...) +%% We should really implement this using the (new) net module, +%% but until that gets the necessary functionality... +which_local_addr(Domain) -> + ?LIB:which_local_addr(Domain). @@ -24430,12 +28808,12 @@ which_local_host_info2(Domain, [_|IFO], Flags) -> %% We don't do that here, but since we can only do that (find a %% multicast address) for specific platforms, we check that we are %% on of those platforms here. -has_ip_multicast_support() -> +has_support_ip_multicast() -> case os:type() of {unix, OsName} when (OsName =:= linux) orelse (OsName =:= sunos) -> - case which_local_host_info(inet) of - {ok, {_Name, Flags, _Addr}} -> + case ?LIB:which_local_host_info(inet) of + {ok, #{flags := Flags}} -> case lists:member(multicast, Flags) of true -> ok; @@ -24445,26 +28823,64 @@ has_ip_multicast_support() -> {error, Reason} -> not_supported({multicast, Reason}) end; + {unix, OsName} -> + skip(?F("Not Supported: platform ~w", [OsName])); Type -> - not_supported({multicast, Type}) + skip(?F("Not Supported: platform ~p", [Type])) + end. + +has_support_sock_acceptconn() -> + has_support_socket_option_sock(acceptconn). + +has_support_sock_bindtodevice() -> + has_support_socket_option_sock(bindtodevice). + +has_support_sock_broadcast() -> + has_support_socket_option_sock(broadcast), + case ?LIB:which_local_host_info(inet) of + {ok, #{flags := Flags}} -> + case lists:member(broadcast, Flags) of + true -> + ok; + false -> + not_supported({broadcast, Flags}) + end; + {error, Reason} -> + not_supported({broadcast, Reason}) end. -has_ip_add_membership_support() -> - has_socket_option_ip_support(add_membership). +has_support_sock_debug() -> + has_support_socket_option_sock(debug). + +has_support_sock_domain() -> + has_support_socket_option_sock(domain). + +has_support_sock_dontroute() -> + has_support_socket_option_sock(dontroute). + +has_support_sock_keepalive() -> + has_support_socket_option_sock(keepalive). + + +has_support_ip_add_membership() -> + has_support_socket_option_ip(add_membership). + +has_support_ip_drop_membership() -> + has_support_socket_option_ip(drop_membership). -has_ip_drop_membership_support() -> - has_socket_option_ip_support(drop_membership). +has_support_socket_option_ip(Opt) -> + has_support_socket_option(ip, Opt). -has_socket_option_ip_support(Opt) -> - has_socket_option_support(ip, Opt). +has_support_socket_option_sock(Opt) -> + has_support_socket_option(socket, Opt). -has_socket_option_support(Level, Option) -> +has_support_socket_option(Level, Option) -> case socket:supports(options, Level, Option) of true -> ok; false -> - not_supported({options, Level, Option}) + skip(?F("Not Supported: ~w option ~w", [Level, Option])) end. @@ -24496,13 +28912,7 @@ has_support_unix_domain_socket() -> %% support for IPv6. If not, there is no point in running IPv6 tests. %% Currently we just skip. has_support_ipv6() -> - %% case socket:supports(ipv6) of - %% true -> - %% ok; - %% false -> - %% {error, not_supported} - %% end. - not_yet_implemented(). + ?LIB:has_support_ipv6(). diff --git a/erts/emulator/test/socket_test_lib.erl b/erts/emulator/test/socket_test_lib.erl index 4e65c4f3c0..39cbf0c79f 100644 --- a/erts/emulator/test/socket_test_lib.erl +++ b/erts/emulator/test/socket_test_lib.erl @@ -32,6 +32,12 @@ %% String and format f/2, + %% Generic 'has support' test function(s) + has_support_ipv6/0, + + which_local_host_info/1, + which_local_addr/1, + %% Skipping not_yet_implemented/0, skip/1 @@ -40,6 +46,11 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-define(FAIL(R), exit(R)). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + pi(Item) when is_atom(Item) -> pi(self(), Item). @@ -88,6 +99,196 @@ f(F, A) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +has_support_ipv6() -> + case socket:supports(ipv6) of + true -> + ok; + false -> + skip("IPv6 Not Supported") + end, + Domain = inet6, + LocalAddr = + case which_local_addr(Domain) of + {ok, Addr} -> + Addr; + {error, R1} -> + skip(f("Local Address eval failed: ~p", [R1])) + end, + ServerSock = + case socket:open(Domain, dgram, udp) of + {ok, SS} -> + SS; + {error, R2} -> + skip(f("(server) socket open failed: ~p", [R2])) + end, + LocalSA = #{family => Domain, addr => LocalAddr}, + ServerPort = + case socket:bind(ServerSock, LocalSA) of + {ok, P1} -> + P1; + {error, R3} -> + socket:close(ServerSock), + skip(f("(server) socket bind failed: ~p", [R3])) + end, + ServerSA = LocalSA#{port => ServerPort}, + ClientSock = + case socket:open(Domain, dgram, udp) of + {ok, CS} -> + CS; + {error, R4} -> + skip(f("(client) socket open failed: ~p", [R4])) + end, + case socket:bind(ClientSock, LocalSA) of + {ok, _} -> + ok; + {error, R5} -> + socket:close(ServerSock), + socket:close(ClientSock), + skip(f("(client) socket bind failed: ~p", [R5])) + end, + case socket:sendto(ClientSock, <<"hejsan">>, ServerSA) of + ok -> + ok; + {error, R6} -> + socket:close(ServerSock), + socket:close(ClientSock), + skip(f("failed socket sendto test: ~p", [R6])) + end, + case socket:recvfrom(ServerSock) of + {ok, {_, <<"hejsan">>}} -> + socket:close(ServerSock), + socket:close(ClientSock), + ok; + {error, R7} -> + socket:close(ServerSock), + socket:close(ClientSock), + skip(f("failed socket recvfrom test: ~p", [R7])) + end. + + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% This gets the local address (not {127, _} or {0, ...} or {16#fe80, ...}) +%% We should really implement this using the (new) net module, +%% but until that gets the necessary functionality... +which_local_addr(Domain) -> + case which_local_host_info(Domain) of + {ok, #{addr := Addr}} -> + {ok, Addr}; + {error, _Reason} = ERROR -> + ERROR + end. + + +%% Returns the interface (name), flags and address (not 127...) +%% of the local host. +which_local_host_info(Domain) -> + case inet:getifaddrs() of + {ok, IFL} -> + which_local_host_info(Domain, IFL); + {error, _} = ERROR -> + ERROR + end. + +which_local_host_info(_Domain, []) -> + {error, no_address}; +which_local_host_info(Domain, [{"lo" ++ _, _}|IFL]) -> + which_local_host_info(Domain, IFL); +which_local_host_info(Domain, [{"docker" ++ _, _}|IFL]) -> + which_local_host_info(Domain, IFL); +which_local_host_info(Domain, [{"br-" ++ _, _}|IFL]) -> + which_local_host_info(Domain, IFL); +which_local_host_info(Domain, [{Name, IFO}|IFL]) -> + try which_local_host_info2(Domain, IFO) of + Info -> + {ok, Info#{name => Name}} + catch + throw:_:_ -> + which_local_host_info(Domain, IFL) + end; +which_local_host_info(Domain, [_|IFL]) -> + which_local_host_info(Domain, IFL). + +%% which_local_host_info2(Domain, IFO) -> +%% case lists:keysearch(flags, 1, IFO) of +%% {value, {flags, Flags}} -> +%% which_local_host_info2(Domain, IFO, Flags); +%% false -> +%% {error, no_flags} +%% end. + + +%% which_local_host_info2(_Domain, [], _Flags) -> +%% {error, no_address}; +%% which_local_host_info2(inet = _Domain, [{addr, Addr}|_IFO], Flags) +%% when (size(Addr) =:= 4) andalso (element(1, Addr) =/= 127) -> +%% {ok, {Flags, Addr}}; +%% which_local_host_info2(inet6 = _Domain, [{addr, Addr}|_IFO], Flags) +%% when (size(Addr) =:= 8) andalso +%% (element(1, Addr) =/= 0) andalso +%% (element(1, Addr) =/= 16#fe80) -> +%% {ok, {Flags, Addr}}; +%% which_local_host_info2(Domain, [_|IFO], Flags) -> +%% which_local_host_info2(Domain, IFO, Flags). + +%% foo(Info, inet = Domain, IFO) -> +%% foo(Info, Domain, IFO, [flags, addr, netmask, broadaddr, hwaddr]); +%% foo(Info, inet6 = Domain, IFO) -> +%% foo(Info, Domain, IFO, [flags, addr, netmask, hwaddr]). + +which_local_host_info2(inet = _Domain, IFO) -> + Addr = which_local_host_info3(addr, IFO, + fun({A, _, _, _}) when (A =/= 127) -> true; + (_) -> false + end), + NetMask = which_local_host_info3(netmask, IFO, + fun({_, _, _, _}) -> true; + (_) -> false + end), + BroadAddr = which_local_host_info3(broadaddr, IFO, + fun({_, _, _, _}) -> true; + (_) -> false + end), + Flags = which_local_host_info3(flags, IFO, fun(_) -> true end), + #{flags => Flags, + addr => Addr, + broadaddr => BroadAddr, + netmask => NetMask}; +which_local_host_info2(inet6 = _Domain, IFO) -> + Addr = which_local_host_info3(addr, IFO, + fun({A, _, _, _, _, _, _, _}) + when (A =/= 0) andalso + (A =/= 16#fe80) -> true; + (_) -> false + end), + NetMask = which_local_host_info3(netmask, IFO, + fun({_, _, _, _, _, _, _, _}) -> true; + (_) -> false + end), + Flags = which_local_host_info3(flags, IFO, fun(_) -> true end), + #{flags => Flags, + addr => Addr, + netmask => NetMask}. + +which_local_host_info3(_Key, [], _) -> + throw({error, no_address}); +which_local_host_info3(Key, [{Key, Val}|IFO], Check) -> + case Check(Val) of + true -> + Val; + false -> + which_local_host_info3(Key, IFO, Check) + end; +which_local_host_info3(Key, [_|IFO], Check) -> + which_local_host_info3(Key, IFO, Check). + + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + not_yet_implemented() -> skip("not yet implemented"). diff --git a/erts/emulator/test/socket_test_ttest_tcp_client.erl b/erts/emulator/test/socket_test_ttest_tcp_client.erl index b5c5300fd0..f28819ca69 100644 --- a/erts/emulator/test/socket_test_ttest_tcp_client.erl +++ b/erts/emulator/test/socket_test_ttest_tcp_client.erl @@ -266,8 +266,9 @@ init(Quiet, (catch Mod:close(Sock)), exit(normal); {error, Reason} -> - ?E("connect failed: ~p", [Reason]), - exit({connect, Reason}) + ?E("connect failed: ~p" + "~n ~p", [Reason, ServerInfo]), + exit({connect, Reason, ServerInfo}) end. process_transport(Mod) when is_atom(Mod) -> diff --git a/erts/emulator/test/socket_test_ttest_tcp_client_socket.erl b/erts/emulator/test/socket_test_ttest_tcp_client_socket.erl index ca7eff4437..2fb1242028 100644 --- a/erts/emulator/test/socket_test_ttest_tcp_client_socket.erl +++ b/erts/emulator/test/socket_test_ttest_tcp_client_socket.erl @@ -34,24 +34,24 @@ start(Method, Async, Active, ServerInfo) when is_list(ServerInfo) -> Domain = local, socket_test_ttest_tcp_client:start_monitor(?MOD(Domain, Async, Method), - Active, ServerInfo); + ServerInfo, Active); start(Method, Async, Active, ServerInfo = {Addr, _}) when is_tuple(Addr) andalso (size(Addr) =:= 4) -> Domain = inet, socket_test_ttest_tcp_client:start_monitor(?MOD(Domain, Async, Method), - Active, ServerInfo); + ServerInfo, Active); start(Method, Async, Active, ServerInfo = {Addr, _}) when is_tuple(Addr) andalso (size(Addr) =:= 8) -> Domain = inet6, socket_test_ttest_tcp_client:start_monitor(?MOD(Domain, Async, Method), - Active, ServerInfo). + ServerInfo, Active). start(Method, Async, Active, ServerInfo, MsgID) when is_list(ServerInfo) -> %% This is just a simplification Domain = local, socket_test_ttest_tcp_client:start(?MOD(Domain, Async, Method), - Active, ServerInfo, MsgID); + ServerInfo, Active, MsgID); start(Method, Async, Active, ServerInfo = {Addr, _}, MsgID) when is_tuple(Addr) andalso (size(Addr) =:= 4) -> %% This is just a simplification @@ -62,14 +62,14 @@ start(Method, Async, Active, ServerInfo = {Addr, _}, MsgID) when is_tuple(Addr) andalso (size(Addr) =:= 8) -> Domain = inet6, socket_test_ttest_tcp_client:start(?MOD(Domain, Async, Method), - Active, ServerInfo, MsgID). + ServerInfo, Active, MsgID). start(Method, Async, Active, ServerInfo, MsgID, MaxOutstanding, RunTime) when is_list(ServerInfo) -> Domain = local, socket_test_ttest_tcp_client:start(false, ?MOD(Domain, Async, Method), - Active, ServerInfo, + ServerInfo, Active, MsgID, MaxOutstanding, RunTime); start(Method, Async, Active, ServerInfo = {Addr, _}, MsgID, MaxOutstanding, RunTime) @@ -77,7 +77,7 @@ start(Method, Async, Active, ServerInfo = {Addr, _}, Domain = inet, socket_test_ttest_tcp_client:start(false, ?MOD(Domain, Async, Method), - Active, ServerInfo, + ServerInfo, Active, MsgID, MaxOutstanding, RunTime); start(Method, Async, Active, ServerInfo = {Addr, _}, MsgID, MaxOutstanding, RunTime) @@ -85,7 +85,7 @@ start(Method, Async, Active, ServerInfo = {Addr, _}, Domain = inet6, socket_test_ttest_tcp_client:start(false, ?MOD(Domain, Async, Method), - Active, ServerInfo, + ServerInfo, Active, MsgID, MaxOutstanding, RunTime). start(Quiet, Async, Active, Method, ServerInfo, MsgID, MaxOutstanding, RunTime) @@ -93,7 +93,7 @@ start(Quiet, Async, Active, Method, ServerInfo, MsgID, MaxOutstanding, RunTime) Domain = local, socket_test_ttest_tcp_client:start(Quiet, ?MOD(Domain, Async, Method), - Active, ServerInfo, + ServerInfo, Active, MsgID, MaxOutstanding, RunTime); start(Quiet, Async, Active, Method, ServerInfo = {Addr, _}, MsgID, MaxOutstanding, RunTime) @@ -101,7 +101,7 @@ start(Quiet, Async, Active, Method, ServerInfo = {Addr, _}, Domain = inet, socket_test_ttest_tcp_client:start(Quiet, ?MOD(Domain, Async, Method), - Active, ServerInfo, + ServerInfo, Active, MsgID, MaxOutstanding, RunTime); start(Quiet, Async, Active, Method, ServerInfo = {Addr, _}, MsgID, MaxOutstanding, RunTime) @@ -109,7 +109,7 @@ start(Quiet, Async, Active, Method, ServerInfo = {Addr, _}, Domain = inet6, socket_test_ttest_tcp_client:start(Quiet, ?MOD(Domain, Async, Method), - Active, ServerInfo, + ServerInfo, Active, MsgID, MaxOutstanding, RunTime). stop(Pid) -> diff --git a/erts/emulator/test/socket_test_ttest_tcp_gen.erl b/erts/emulator/test/socket_test_ttest_tcp_gen.erl index 05b250e3d9..e59bd881e7 100644 --- a/erts/emulator/test/socket_test_ttest_tcp_gen.erl +++ b/erts/emulator/test/socket_test_ttest_tcp_gen.erl @@ -36,19 +36,7 @@ ]). -%% ========================================================================== - -%% getopt(Sock, Opt) when is_atom(Opt) -> -%% case inet:getopts(Sock, [Opt]) of -%% {ok, [{Opt, Value}]} -> -%% {ok, Value}; -%% {error, _} = ERROR -> -%% ERROR -%% end. - -%% setopt(Sock, Opt, Value) when is_atom(Opt) -> -%% inet:setopts(Sock, [{Opt, Value}]). - +-define(LIB, socket_test_lib). %% ========================================================================== @@ -106,12 +94,12 @@ listen(Port) -> listen(Port, #{domain => inet}). listen(Port, #{domain := Domain}) when is_integer(Port) andalso (Port >= 0) -> - Opts = [Domain, - binary, {ip, {0,0,0,0}}, {packet, raw}, {active, false}, - {buffer, 32*1024}], - case gen_tcp:listen(Port, Opts) of - {ok, Sock} -> - {ok, Sock}; + case ?LIB:which_local_host_info(Domain) of + {ok, {_, _, Addr}} -> + Opts = [Domain, + binary, {ip, Addr}, {packet, raw}, {active, false}, + {buffer, 32*1024}], + gen_tcp:listen(Port, Opts); {error, _} = ERROR -> ERROR end. diff --git a/erts/emulator/test/socket_test_ttest_tcp_server.erl b/erts/emulator/test/socket_test_ttest_tcp_server.erl index 27b561d4b7..2394dc7924 100644 --- a/erts/emulator/test/socket_test_ttest_tcp_server.erl +++ b/erts/emulator/test/socket_test_ttest_tcp_server.erl @@ -134,12 +134,18 @@ server_init(Starter, Parent, Transport, Active) -> if is_integer(PortOrPath) -> %% This is just for convenience - Addr = which_addr(), - ?I("listening on:" - "~n Addr: ~p (~s)" - "~n Port: ~w" - "~n", [Addr, inet:ntoa(Addr), PortOrPath]), - {Addr, PortOrPath}; + case Mod:sockname(LSock) of + {ok, {Addr, _}} -> + ?I("listening on:" + "~n Addr: ~p (~s)" + "~n Port: ~w" + "~n", [Addr, + inet:ntoa(Addr), + PortOrPath]), + {Addr, PortOrPath}; + {error, SNReason} -> + exit({sockname, SNReason}) + end; is_list(PortOrPath) -> ?I("listening on:" "~n Path: ~s" @@ -569,51 +575,51 @@ handler_maybe_activate(_, _, _) -> %% ========================================================================== -which_addr() -> - case inet:getifaddrs() of - {ok, IfAddrs} -> - which_addrs(inet, IfAddrs); - {error, Reason} -> - exit({getifaddrs, Reason}) - end. +%% which_addr() -> +%% case inet:getifaddrs() of +%% {ok, IfAddrs} -> +%% which_addrs(inet, IfAddrs); +%% {error, Reason} -> +%% exit({getifaddrs, Reason}) +%% end. -which_addrs(_Family, []) -> - exit({getifaddrs, not_found}); -which_addrs(Family, [{"lo", _} | IfAddrs]) -> - %% Skip - which_addrs(Family, IfAddrs); -which_addrs(Family, [{"docker" ++ _, _} | IfAddrs]) -> - %% Skip docker - which_addrs(Family, IfAddrs); -which_addrs(Family, [{"br-" ++ _, _} | IfAddrs]) -> - %% Skip docker - which_addrs(Family, IfAddrs); -which_addrs(Family, [{"en" ++ _, IfOpts} | IfAddrs]) -> - %% Maybe take this one - case which_addr(Family, IfOpts) of - {ok, Addr} -> - Addr; - error -> - which_addrs(Family, IfAddrs) - end; -which_addrs(Family, [{_IfName, IfOpts} | IfAddrs]) -> - case which_addr(Family, IfOpts) of - {ok, Addr} -> - Addr; - error -> - which_addrs(Family, IfAddrs) - end. +%% which_addrs(_Family, []) -> +%% exit({getifaddrs, not_found}); +%% which_addrs(Family, [{"lo", _} | IfAddrs]) -> +%% %% Skip +%% which_addrs(Family, IfAddrs); +%% which_addrs(Family, [{"docker" ++ _, _} | IfAddrs]) -> +%% %% Skip docker +%% which_addrs(Family, IfAddrs); +%% which_addrs(Family, [{"br-" ++ _, _} | IfAddrs]) -> +%% %% Skip docker +%% which_addrs(Family, IfAddrs); +%% which_addrs(Family, [{"en" ++ _, IfOpts} | IfAddrs]) -> +%% %% Maybe take this one +%% case which_addr(Family, IfOpts) of +%% {ok, Addr} -> +%% Addr; +%% error -> +%% which_addrs(Family, IfAddrs) +%% end; +%% which_addrs(Family, [{_IfName, IfOpts} | IfAddrs]) -> +%% case which_addr(Family, IfOpts) of +%% {ok, Addr} -> +%% Addr; +%% error -> +%% which_addrs(Family, IfAddrs) +%% end. -which_addr(_, []) -> - error; -which_addr(inet, [{addr, Addr}|_]) - when is_tuple(Addr) andalso (size(Addr) =:= 4) -> - {ok, Addr}; -which_addr(inet6, [{addr, Addr}|_]) - when is_tuple(Addr) andalso (size(Addr) =:= 8) -> - {ok, Addr}; -which_addr(Family, [_|IfOpts]) -> - which_addr(Family, IfOpts). +%% which_addr(_, []) -> +%% error; +%% which_addr(inet, [{addr, Addr}|_]) +%% when is_tuple(Addr) andalso (size(Addr) =:= 4) -> +%% {ok, Addr}; +%% which_addr(inet6, [{addr, Addr}|_]) +%% when is_tuple(Addr) andalso (size(Addr) =:= 8) -> +%% {ok, Addr}; +%% which_addr(Family, [_|IfOpts]) -> +%% which_addr(Family, IfOpts). %% ========================================================================== diff --git a/erts/emulator/test/socket_test_ttest_tcp_socket.erl b/erts/emulator/test/socket_test_ttest_tcp_socket.erl index 3aa3b2c504..9112748b4c 100644 --- a/erts/emulator/test/socket_test_ttest_tcp_socket.erl +++ b/erts/emulator/test/socket_test_ttest_tcp_socket.erl @@ -247,10 +247,16 @@ listen(Path, #{domain := local = Domain} = Opts) listen(Port, #{domain := Domain} = Opts) when is_integer(Port) andalso (Port >= 0) -> %% Bind fills in the rest - SA = #{family => Domain, - port => Port}, - Cleanup = fun() -> ok end, - do_listen(SA, Cleanup, Opts#{proto => tcp}). + case ?LIB:which_local_host_info(Domain) of + {ok, {_, _, Addr}} -> + SA = #{family => Domain, + addr => Addr, + port => Port}, + Cleanup = fun() -> ok end, + do_listen(SA, Cleanup, Opts#{proto => tcp}); + {error, _} = ERROR -> + ERROR + end. do_listen(SA, Cleanup, diff --git a/erts/epmd/epmd.mk b/erts/epmd/epmd.mk index b1fd04dc04..f6889a7ff1 100644 --- a/erts/epmd/epmd.mk +++ b/erts/epmd/epmd.mk @@ -67,5 +67,5 @@ EPMD_NODE_TYPE=110 # Distribution format 5 contains the new md5 based handshake. EPMD_DIST_LOW=5 -EPMD_DIST_HIGH=5 +EPMD_DIST_HIGH=6 diff --git a/erts/epmd/src/epmd.h b/erts/epmd/src/epmd.h index cffcd4ae7a..7332294d3d 100644 --- a/erts/epmd/src/epmd.h +++ b/erts/epmd/src/epmd.h @@ -26,6 +26,7 @@ #define EPMD_ALIVE2_REQ 'x' #define EPMD_PORT2_REQ 'z' #define EPMD_ALIVE2_RESP 'y' +#define EPMD_ALIVE2_X_RESP 'v' #define EPMD_PORT2_RESP 'w' #define EPMD_NAMES_REQ 'n' diff --git a/erts/epmd/src/epmd_int.h b/erts/epmd/src/epmd_int.h index ed9bbdb8cd..a5156a142e 100644 --- a/erts/epmd/src/epmd_int.h +++ b/erts/epmd/src/epmd_int.h @@ -277,6 +277,12 @@ static const struct in6_addr in6addr_loopback = #define put_int16(i, s) {((unsigned char*)(s))[0] = ((i) >> 8) & 0xff; \ ((unsigned char*)(s))[1] = (i) & 0xff;} +#define put_int32(i, s) do {((char*)(s))[0] = (char)((i) >> 24) & 0xff; \ + ((char*)(s))[1] = (char)((i) >> 16) & 0xff; \ + ((char*)(s))[2] = (char)((i) >> 8) & 0xff; \ + ((char*)(s))[3] = (char)(i) & 0xff;} \ + while (0) + #if defined(__GNUC__) # define EPMD_INLINE __inline__ #elif defined(__WIN32__) @@ -307,10 +313,10 @@ struct enode { int fd; /* The socket in use */ unsigned short port; /* Port number of Erlang node */ char symname[MAXSYMLEN+1]; /* Name of the Erlang node */ - short creation; /* Started as a random number 1..3 */ + unsigned int cr_counter; /* Used to generate 'creation' numbers */ char nodetype; /* 77 = normal erlang node 72 = hidden (c-node */ char protocol; /* 0 = tcp/ipv4 */ - unsigned short highvsn; /* 0 = OTP-R3 erts-4.6.x, 1 = OTP-R4 erts-4.7.x*/ + unsigned short highvsn; /* 5: creation=1..3, 6: creation=1..(2^32-1)*/ unsigned short lowvsn; int extralen; char extra[MAXSYMLEN+1]; diff --git a/erts/epmd/src/epmd_srv.c b/erts/epmd/src/epmd_srv.c index 3c6f1fbdf4..633ec71e5f 100644 --- a/erts/epmd/src/epmd_srv.c +++ b/erts/epmd/src/epmd_srv.c @@ -665,6 +665,21 @@ static int do_accept(EpmdVars *g,int listensock) return conn_open(g,msgsock); } +static void bump_creation(Node* node) +{ + if (++node->cr_counter == 0) + node->cr_counter = 1; +} +static unsigned int get_creation(Node* node) +{ + if (node->highvsn >= 6) { + return node->cr_counter; /* 1..(2^32-1)*/ + } + else { + return (node->cr_counter - 1) % 3 + 1; /* 1..3 */ + } +} + /* buf is actually one byte larger than bsize, giving place for null termination */ static void do_request(g, fd, s, buf, bsize) @@ -706,8 +721,10 @@ static void do_request(g, fd, s, buf, bsize) unsigned char protocol; unsigned short highvsn; unsigned short lowvsn; + unsigned int creation; int namelen; int extralen; + int replylen; char *name; char *extra; eport = get_int16(&buf[1]); @@ -737,17 +754,22 @@ static void do_request(g, fd, s, buf, bsize) extra = &buf[11+namelen+2]; extra[extralen]='\000'; - wbuf[0] = EPMD_ALIVE2_RESP; - if ((node = node_reg2(g, namelen, name, fd, eport, nodetype, protocol, - highvsn, lowvsn, extralen, extra)) == NULL) { - wbuf[1] = 1; /* error */ - put_int16(99, wbuf+2); - } else { - wbuf[1] = 0; /* ok */ - put_int16(node->creation, wbuf+2); - } + node = node_reg2(g, namelen, name, fd, eport, nodetype, protocol, + highvsn, lowvsn, extralen, extra); + creation = node ? get_creation(node) : 99; + wbuf[1] = node ? 0 : 1; /* ok | error */ + if (highvsn >= 6) { + wbuf[0] = EPMD_ALIVE2_X_RESP; + put_int32(creation, wbuf+2); + replylen = 6; + } + else { + wbuf[0] = EPMD_ALIVE2_RESP; + put_int16(creation, wbuf+2); + replylen = 4; + } - if (!reply(g, fd, wbuf, 4)) + if (!reply(g, fd, wbuf, replylen)) { node_unreg(g, name); dbg_tty_printf(g,1,"** failed to send ALIVE2_RESP for \"%s\"", @@ -1200,8 +1222,8 @@ static int node_unreg(EpmdVars *g,char *name) for (; node; prev = &node->next, node = node->next) if (is_same_str(node->symname, name)) { - dbg_tty_printf(g,1,"unregistering '%s:%d', port %d", - node->symname, node->creation, node->port); + dbg_tty_printf(g,1,"unregistering '%s:%u', port %d", + node->symname, get_creation(node), node->port); *prev = node->next; /* Link out from "reg" list */ @@ -1235,8 +1257,8 @@ static int node_unreg_sock(EpmdVars *g,int fd) for (; node; prev = &node->next, node = node->next) if (node->fd == fd) { - dbg_tty_printf(g,1,"unregistering '%s:%d', port %d", - node->symname, node->creation, node->port); + dbg_tty_printf(g,1,"unregistering '%s:%u', port %d", + node->symname, get_creation(node), node->port); *prev = node->next; /* Link out from "reg" list */ @@ -1264,19 +1286,8 @@ static int node_unreg_sock(EpmdVars *g,int fd) } /* - * Finding a node slot and a (name,creation) name is a bit tricky. - * We try in order - * - * 1. If the name was used before and we can reuse that slot but use - * a new "creation" digit in the range 1..3. - * - * 2. We try to find a new unused slot. - * - * 3. We try to use an used slot this isn't used any longer. - * FIXME: The criteria for *what* slot to steal should be improved. - * Perhaps use the oldest or something. + * Register a new node */ - static Node *node_reg2(EpmdVars *g, int namelen, char* name, @@ -1346,7 +1357,7 @@ static Node *node_reg2(EpmdVars *g, } /* Try to find the name in the used queue so that we - can change "creation" number 1..3 */ + can change "creation" number */ prev = NULL; @@ -1375,9 +1386,8 @@ static Node *node_reg2(EpmdVars *g, g->nodes.unreg_count--; - /* When reusing we change the "creation" number 1..3 */ - - node->creation = node->creation % 3 + 1; + /* When reusing we change the "creation" number */ + bump_creation(node); break; } @@ -1404,7 +1414,8 @@ static Node *node_reg2(EpmdVars *g, exit(1); } - node->creation = (current_time(g) % 3) + 1; /* "random" 1-3 */ + node->cr_counter = current_time(g); /* "random" */ + bump_creation(node); } } @@ -1423,11 +1434,11 @@ static Node *node_reg2(EpmdVars *g, select_fd_set(g, fd); if (highvsn == 0) { - dbg_tty_printf(g,1,"registering '%s:%d', port %d", - node->symname, node->creation, node->port); + dbg_tty_printf(g,1,"registering '%s:%u', port %d", + node->symname, get_creation(node), node->port); } else { - dbg_tty_printf(g,1,"registering '%s:%d', port %d", - node->symname, node->creation, node->port); + dbg_tty_printf(g,1,"registering '%s:%u', port %d", + node->symname, get_creation(node), node->port); dbg_tty_printf(g,1,"type %d proto %d highvsn %d lowvsn %d", nodetype, protocol, highvsn, lowvsn); } @@ -1561,8 +1572,8 @@ static void print_names(EpmdVars *g) for (node = g->nodes.reg; node; node = node->next) { - fprintf(stderr,"***** active name \"%s#%d\" at port %d, fd = %d\r\n", - node->symname, node->creation, node->port, node->fd); + fprintf(stderr,"***** active name \"%s#%u\" at port %d, fd = %d\r\n", + node->symname, get_creation(node), node->port, node->fd); count ++; } @@ -1572,8 +1583,8 @@ static void print_names(EpmdVars *g) for (node = g->nodes.unreg; node; node = node->next) { - fprintf(stderr,"***** old/unused name \"%s#%d\"\r\n", - node->symname, node->creation); + fprintf(stderr,"***** old/unused name \"%s#%u\"\r\n", + node->symname, get_creation(node)); count ++; } diff --git a/erts/etc/unix/cerl.src b/erts/etc/unix/cerl.src index 710a7a9ef6..59de9bdec8 100644 --- a/erts/etc/unix/cerl.src +++ b/erts/etc/unix/cerl.src @@ -312,8 +312,11 @@ if [ "x$GDB" = "x" ]; then # on multiple cores (especially with async threads). Valgrind only run one pthread # at a time anyway so there is no point letting it utilize more than one core. # Use $sched_arg to force all schedulers online to emulate multicore. - taskset1="taskset 1" ncpu=`cat /proc/cpuinfo | grep -w processor | wc -l` + # Choose a random core in order to not collide with any other valgrind + # run on the same machine. + taskset1=$((1 << (`shuf -i 1-$ncpu -n 1` - 1) )) + taskset1="taskset $taskset1" sched_arg="-S$ncpu:$ncpu" else taskset1= diff --git a/erts/etc/unix/etp-commands.in b/erts/etc/unix/etp-commands.in index 730f0a0c64..20809d61e8 100644 --- a/erts/etc/unix/etp-commands.in +++ b/erts/etc/unix/etp-commands.in @@ -37,7 +37,7 @@ document etp-help % - GDB command toolbox for analyzing core dumps from the % Erlang emulator (BEAM). % -% Should work for 32-bit erts-5.2/R9B, ... +% Should work for 32-bit and 64-bit unix gdb % % The commands are prefixed with: % etp: Acronym for erts-term-print @@ -55,7 +55,8 @@ document etp-help % Special commands for not really terms: % etp-mfa, etp-cp, etp-disasm, % etp-msgq, etpf-msgq, -% etp-stacktrace, etp-stackdump, etpf-stackdump, etp-dictdump +% etp-stacktrace, etp-stacktrace-emu, etp-stackdump, etp-stackdump-emu, +% etpf-stackdump, etp-dictdump % etp-process-info, etp-process-memory-info % etp-port-info, etp-port-state, etp-port-sched-flags % etp-heapdump, etp-offheapdump, etpf-offheapdump, @@ -1452,30 +1453,74 @@ end define etp-stack-preamble set $etp_stack_p = ($arg0)->stop set $etp_stack_end = ($arg0)->hend + if ($arg0)->state.counter & 0x8000 + printf "%%%%%% WARNING: The process is currently running, so c_p->stop will not be correct\r\n" + printf "%%%%%% Consider using %s-emu instead\r\n", $arg1 + end printf "%% Stacktrace (%u)\n", $etp_stack_end-$etp_stack_p if ($arg0)->i != 0 - etp-1 ((Eterm)($arg0)->i) 0 - printf " (I)\n" + printf "I: " + etp ((Eterm)($arg0)->i) + end + if ($arg0)->cp != 0 + printf "cp:" + etp ((Eterm)($arg0)->cp) end +end + +define etp-stack-preamble-emu + set $etp_stack_p = E + set $etp_stack_end = ($arg0)->hend + printf "%% Stacktrace (%u)\n", $etp_stack_end-$etp_stack_p + printf "I: " + etp ((BeamInstr)I) if ($arg0)->cp != 0 - etp-1 ((Eterm)($arg0)->cp) 0 - printf " (cp)\n" + printf "cp: " + etp ((Eterm)($arg0)->cp) + end +end + +define etp-stacktrace-1 + set $etp_stack_stop = (Eterm*)($arg0) + set $etp_stack_send = (Eterm*)($arg1) + set $etp_stack_cnt = 0 + while $etp_stack_stop < $etp_stack_send + if ($etp_stack_stop[0] & 0x3) == 0x0 + # Continuation pointer + printf "%d: ", $etp_stack_cnt + etp $etp_stack_stop[0] + end + set $etp_stack_stop++ + set $etp_stack_cnt++ end end +define etp-stacktrace-emu +# Args: Process* +# +# Non-reentrant +# + etp-stack-preamble-emu ($arg0) + etp-stacktrace-1 $etp_stack_p $etp_stack_end +end + +document etp-stacktrace-emu +%--------------------------------------------------------------------------- +% etp-stacktrace-emu Process* +% +% Take an Process* and print a stactrace for the process. +% This macro assumes that the current frame is the process_main frame +% and that E is not optimized out. +%--------------------------------------------------------------------------- +end + define etp-stacktrace # Args: Process* # # Non-reentrant # - etp-stack-preamble ($arg0) - while $etp_stack_p < $etp_stack_end - if ($etp_stack_p[0] & 0x3) == 0x0 - # Continuation pointer - etp $etp_stack_p[0] - end - set $etp_stack_p++ - end + etp-stack-preamble ($arg0) "etp-stacktrace" + etp-stacktrace-1 $etp_stack_p $etp_stack_end end document etp-stacktrace @@ -1488,16 +1533,48 @@ document etp-stacktrace %--------------------------------------------------------------------------- end +define etp-stackdump-1 + # Args: Eterm *stop, Eterm *hend + # + # Non-reentrant + # + set $etp_stackdump_stop = (Eterm*)($arg0) + set $etp_stackdump_send = (Eterm*)($arg1) + set $etp_stackdump_cnt = 0 + while $etp_stackdump_stop < $etp_stackdump_send + printf "%d: ", $etp_stackdump_cnt + etp $etp_stackdump_stop[0] + set $etp_stackdump_stop++ + set $etp_stackdump_cnt++ + end +end + +define etp-stackdump-emu +# Args: Process* +# +# Non-reentrant +# + etp-stack-preamble-emu ($arg0) + etp-stackdump-1 $etp_stack_p $etp_stack_end +end + +document etp-stacktrace-emu +%--------------------------------------------------------------------------- +% etp-stacktrace-emu Process* +% +% Take an Process* and print a stactdump for the process. +% This macro assumes that the current frame is the process_main frame +% and that E is not optimized out. +%--------------------------------------------------------------------------- +end + define etp-stackdump # Args: Process* # # Non-reentrant # - etp-stack-preamble ($arg0) - while $etp_stack_p < $etp_stack_end - etp $etp_stack_p[0] - set $etp_stack_p++ - end + etp-stack-preamble ($arg0) "etp-stackdump" + etp-stackdump-1 $etp_stack_p $etp_stack_end end document etp-stackdump @@ -2959,12 +3036,21 @@ define etp-fds end end +document etp-fds +%--------------------------------------------------------------------------- +% etp-fds +% +% Print the state of the fds currently in check_io. Only works in running systems. +%--------------------------------------------------------------------------- +end + define etp-disasm-1 - set $code_ptr = ((BeamInstr*)$arg0) - set $addr = *$code_ptr + set $code_ptr = ((BeamInstr*)($arg0)) + set $addr32 = (BeamInstr)(Uint32)*$code_ptr + set $addr64 = (BeamInstr)(Uint64)*$code_ptr set $i = 0 - while $i < (sizeof(opc) / sizeof(OpEntry)) - if $addr == beam_ops[$i] + while $i < num_instructions + if $addr32 == beam_ops[$i] || $addr64 == beam_ops[$i] printf "%s %d", opc[$i].name, opc[$i].sz set $next_i = $code_ptr + opc[$i].sz set $i += 4999 @@ -2974,6 +3060,11 @@ define etp-disasm-1 end define etp-disasm + if $argc == 1 + set $code_end = $arg0 + else + set $code_end = $arg1 + end etp-cp-func-info-1 $arg0 if $etp_cp_p == 0 printf "invalid argument" @@ -2982,7 +3073,7 @@ define etp-disasm printf ": " etp-disasm-1 $arg0 printf "\r\n" - while $next_i < ((BeamInstr*)$arg1) + while $next_i < ((BeamInstr*)$code_end) set $prev_i = $next_i etp-cp-func-info-1 $next_i etp-mfa-1 $etp_cp_p $cp_cp_p_offset @@ -2998,6 +3089,16 @@ define etp-disasm end end +document etp-disasm +%--------------------------------------------------------------------------- +% etp-fds BeamInstr* (BeamInstr*) +% +% Disassemble the instructions inbetween arg0 and arg1, +% if no second argument is given only the current +% instruction is printed. +%--------------------------------------------------------------------------- +end + ############################################################################ # # Timer Wheel @@ -3892,22 +3993,79 @@ end # ETS table debug # +define etp-ets-tab-status-int +# Args: +# +# Non-reentrant + if ($arg0 & 0x1) + printf "priv" + end + if ($arg0 & 0x2) + printf "prot" + end + if ($arg0 & 0x4) + printf "pub" + end + if ($arg0 & 0x8) + printf "|del" + end + if ($arg0 & 0x10) + printf "|set" + end + if ($arg0 & 0x20) + printf "|bag" + end + if ($arg0 & 0x40) + printf "|dbag" + end + if ($arg0 & 0x80) + printf "|oset" + end + if ($arg0 & 0x100) + printf "|caoset" + end + if ($arg0 & 0x200) + printf "|flocked" + end + if ($arg0 & 0x400) + printf "|fread" + end + if ($arg0 & 0x800) + printf "|named" + end + if ($arg0 & 0x1000) + printf "|busy" + end +end + define etp-ets-tables # Args: # # Non-reentrant - printf "%% Dumping < %lu ETS tables\n", (unsigned long)db_max_tabs - while $etp_ets_tables_i < db_max_tabs - if (meta_main_tab[$etp_ets_tables_i].u.next_free & 3) == 0 - printf "%% %d:", $etp_ets_tables_i - etp-1 ((Eterm)(meta_main_tab[$etp_ets_tables_i].u.tb->common.id)) 0 + set $sched_ix = 0 + while $sched_ix < erts_no_schedulers + set $ets_tabs = &erts_aligned_scheduler_data[$sched_ix].esd.ets_tables + set $no_ets_tabs = *(unsigned long *)&($ets_tabs->count) + printf "\n%% %lu ETS tables created on scheduler %lu...\n\n", $no_ets_tabs, (unsigned long)$sched_ix+1 + set $ets_tab = $ets_tabs->clist + set $first_ets_tab = $ets_tab + while $ets_tab + set $refn = &((ErtsMagicBinary *)$ets_tab->common->btid)->refn + printf "%% " + etp-1 $ets_tab->common.the_name 0 + printf " #Ref<0.%u.%u.%u> ", (unsigned)$refn[2], (unsigned)$refn[1], (unsigned)$refn[0] + etp-1 $ets_tab->common.owner 0 printf " " - etp-1 ((Eterm)(meta_main_tab[$etp_ets_tables_i].u.tb->common.owner)) 0 - printf "\n" + etp-ets-tab-status-int $ets_tab->common.status + printf " (DbTable*)%p\n", $ets_tab + if $ets_tab->common.all.next == $first_ets_tab + set $ets_tab = (DbTable *) 0 + else + set $ets_tab = $ets_tab->common.all.next + end end - set $etp_ets_tables_i++ + set $sched_ix++ end - set $etp_ets_tables_i = 0 end document etp-ets-tables diff --git a/erts/lib_src/pthread/ethread.c b/erts/lib_src/pthread/ethread.c index b4b12fcd86..b567ed81b0 100644 --- a/erts/lib_src/pthread/ethread.c +++ b/erts/lib_src/pthread/ethread.c @@ -208,9 +208,9 @@ ethr_x86_cpuid__(int *eax, int *ebx, int *ecx, int *edx) "popl %%eax\n\t" "movl $0x0, %0\n\t" "xorl %%ecx, %%eax\n\t" - "jz no_cpuid\n\t" + "jz 1f\n\t" "movl $0x1, %0\n\t" - "no_cpuid:\n\t" + "1:\n\t" : "=r"(have_cpuid) : : "%eax", "%ecx", "cc"); diff --git a/erts/preloaded/ebin/erl_init.beam b/erts/preloaded/ebin/erl_init.beam Binary files differindex 0c032e8e91..bc7639781c 100644 --- a/erts/preloaded/ebin/erl_init.beam +++ b/erts/preloaded/ebin/erl_init.beam diff --git a/erts/preloaded/ebin/net.beam b/erts/preloaded/ebin/net.beam Binary files differdeleted file mode 100644 index 88d546a3af..0000000000 --- a/erts/preloaded/ebin/net.beam +++ /dev/null diff --git a/erts/preloaded/ebin/prim_file.beam b/erts/preloaded/ebin/prim_file.beam Binary files differindex a2c5f2f336..0152a6091f 100644 --- a/erts/preloaded/ebin/prim_file.beam +++ b/erts/preloaded/ebin/prim_file.beam diff --git a/erts/preloaded/ebin/prim_inet.beam b/erts/preloaded/ebin/prim_inet.beam Binary files differindex f67b660a08..f77e9e863d 100644 --- a/erts/preloaded/ebin/prim_inet.beam +++ b/erts/preloaded/ebin/prim_inet.beam diff --git a/erts/preloaded/ebin/prim_net.beam b/erts/preloaded/ebin/prim_net.beam Binary files differnew file mode 100644 index 0000000000..9d50b3210f --- /dev/null +++ b/erts/preloaded/ebin/prim_net.beam diff --git a/erts/preloaded/ebin/socket.beam b/erts/preloaded/ebin/socket.beam Binary files differindex 134b4eac13..73a0bd4f72 100644 --- a/erts/preloaded/ebin/socket.beam +++ b/erts/preloaded/ebin/socket.beam diff --git a/erts/preloaded/src/Makefile b/erts/preloaded/src/Makefile index 27d450c873..38b85915cc 100644 --- a/erts/preloaded/src/Makefile +++ b/erts/preloaded/src/Makefile @@ -36,10 +36,9 @@ include $(ERL_TOP)/lib/kernel/vsn.mk ifeq ($(USE_ESOCK), yes) PRE_LOADED_ERL_ESOCK_MODULES = \ socket \ - net + prim_net else -PRE_LOADED_ERL_ESOCK_MODULES = \ - net +PRE_LOADED_ERL_ESOCK_MODULES = endif PRE_LOADED_ERL_MODULES = \ @@ -82,9 +81,9 @@ APP_FILE= erts.app APP_SRC= $(APP_FILE).src APP_TARGET= $(STATIC_EBIN)/$(APP_FILE) ifeq ($(USE_ESOCK), yes) -APP_ESOCK_MODS= net, socket +APP_ESOCK_MODS= prim_net, socket else -APP_ESOCK_MODS= net +APP_ESOCK_MODS= endif @@ -96,6 +95,15 @@ ERL_COMPILE_FLAGS += +debug_info -I$(KERNEL_SRC) -I$(KERNEL_INCLUDE) DIA_PLT = erts-preloaded.plt DIA_ANALYSIS = $(basename $(DIA_PLT)).dialyzer_analysis +ifeq ($(DIAW_EH),true) +DIA_WARNINGS += -Werror_handling +endif +ifeq ($(DIAW_US),true) +DIA_WARNINGS += -Wunderspecs +endif +ifeq ($(DIAW_UR),true) +DIA_WARNINGS += -Wunmatched_returns +endif debug opt: $(TARGET_FILES) @@ -145,6 +153,7 @@ dialyzer: $(DIA_PLT) @echo "Running dialyzer on $(basename $(DIA_PLT))" @dialyzer --plt $< \ ../ebin \ + $(DIA_WARNINGS) \ --verbose # diff --git a/erts/preloaded/src/erl_init.erl b/erts/preloaded/src/erl_init.erl index d209c4033b..dadf7dda6f 100644 --- a/erts/preloaded/src/erl_init.erl +++ b/erts/preloaded/src/erl_init.erl @@ -35,7 +35,8 @@ start(Mod, BootArgs) -> erl_tracer:on_load(), prim_buffer:on_load(), prim_file:on_load(), - conditional_load(socket, [socket, net]), % socket:on_load(), net:on_load(), + %% socket:on_load(), prim_net:on_load(), + conditional_load(socket, [socket, prim_net]), %% Proceed to the specified boot module run(Mod, boot, BootArgs). @@ -49,7 +50,9 @@ run(M, F, A) -> end. conditional_load(CondMod, Mods2Load) -> - conditional_load(CondMod, erlang:loaded(), Mods2Load). + Loaded = erlang:loaded(), + %% erlang:display({?MODULE, conditional_load, Loaded}), + conditional_load(CondMod, Loaded, Mods2Load). conditional_load(_CondMod, [], _Mods2LOad) -> ok; diff --git a/erts/preloaded/src/prim_file.erl b/erts/preloaded/src/prim_file.erl index 1aa5d85c64..1982424191 100644 --- a/erts/preloaded/src/prim_file.erl +++ b/erts/preloaded/src/prim_file.erl @@ -34,6 +34,7 @@ -export([read_link/1, read_link_all/1, read_link_info/1, read_link_info/2, read_file_info/1, read_file_info/2, + read_handle_info/1, read_handle_info/2, write_file_info/2, write_file_info/3]). -export([list_dir/1, list_dir_all/1]). @@ -497,6 +498,8 @@ get_handle_nif(_FileRef) -> erlang:nif_error(undef). delayed_close_nif(_FileRef) -> erlang:nif_error(undef). +read_handle_info_nif(_FileRef) -> + erlang:nif_error(undef). %% %% Quality-of-life helpers @@ -598,20 +601,37 @@ read_link_info(Name, Opts) -> read_info_1(Name, FollowLinks, TimeType) -> try case read_info_nif(encode_path(Name), FollowLinks) of - {error, Reason} -> - {error, Reason}; - FileInfo -> - CTime = from_posix_seconds(FileInfo#file_info.ctime, TimeType), - MTime = from_posix_seconds(FileInfo#file_info.mtime, TimeType), - ATime = from_posix_seconds(FileInfo#file_info.atime, TimeType), - {ok, FileInfo#file_info{ ctime = CTime, - mtime = MTime, - atime = ATime }} + {error, Reason} -> {error, Reason}; + FileInfo -> {ok, adjust_times(FileInfo, TimeType)} + end + catch + error:_ -> {error, badarg} + end. + +read_handle_info(Fd) -> + read_handle_info_1(Fd, local). +read_handle_info(Fd, Opts) -> + read_handle_info_1(Fd, proplist_get_value(time, Opts, local)). + +read_handle_info_1(Fd, TimeType) -> + try + #{ handle := FRef } = get_fd_data(Fd), + case read_handle_info_nif(FRef) of + {error, Reason} -> {error, Reason}; + FileInfo -> {ok, adjust_times(FileInfo, TimeType)} end catch error:_ -> {error, badarg} end. +adjust_times(FileInfo, TimeType) -> + CTime = from_posix_seconds(FileInfo#file_info.ctime, TimeType), + MTime = from_posix_seconds(FileInfo#file_info.mtime, TimeType), + ATime = from_posix_seconds(FileInfo#file_info.atime, TimeType), + FileInfo#file_info{ ctime = CTime, + mtime = MTime, + atime = ATime }. + write_file_info(Filename, Info) -> write_file_info_1(Filename, Info, local). write_file_info(Filename, Info, Opts) -> diff --git a/erts/preloaded/src/prim_inet.erl b/erts/preloaded/src/prim_inet.erl index 374facb2a3..4dab3de006 100644 --- a/erts/preloaded/src/prim_inet.erl +++ b/erts/preloaded/src/prim_inet.erl @@ -427,7 +427,7 @@ accept_opts(L, S, FamilyOpts) -> case getopts( L, - [active, nodelay, keepalive, delay_send, priority] + [active, nodelay, keepalive, delay_send, priority, linger] ++ FamilyOpts) of {ok, Opts} -> diff --git a/erts/preloaded/src/net.erl b/erts/preloaded/src/prim_net.erl index 13d2e3a117..107043d1aa 100644 --- a/erts/preloaded/src/net.erl +++ b/erts/preloaded/src/prim_net.erl @@ -18,7 +18,7 @@ %% %CopyrightEnd% %% --module(net). +-module(prim_net). -compile(no_native). @@ -31,22 +31,14 @@ -export([ gethostname/0, - getnameinfo/1, getnameinfo/2, - getaddrinfo/1, getaddrinfo/2, + getnameinfo/2, + getaddrinfo/2, if_name2index/1, if_index2name/1, if_names/0 ]). -%% Deprecated functions from the "old" net module --export([call/4, - cast/4, - broadcast/3, - ping/1, - relay/1, - sleep/1]). - -export_type([ address_info/0, name_info/0, @@ -59,13 +51,6 @@ network_interface_index/0 ]). --deprecated({call, 4, eventually}). --deprecated({cast, 4, eventually}). --deprecated({broadcast, 3, eventually}). --deprecated({ping, 1, eventually}). --deprecated({relay, 1, eventually}). --deprecated({sleep, 1, eventually}). - -type name_info_flags() :: [name_info_flag()|name_info_flag_ext()]. -type name_info_flag() :: namereqd | @@ -88,21 +73,6 @@ %% =========================================================================== %% -%% D E P R E C A T E D F U N C T I O N S -%% -%% =========================================================================== - -call(N,M,F,A) -> rpc:call(N,M,F,A). -cast(N,M,F,A) -> rpc:cast(N,M,F,A). -broadcast(M,F,A) -> rpc:eval_everywhere(M,F,A). -ping(Node) -> net_adm:ping(Node). -sleep(T) -> receive after T -> ok end. -relay(X) -> slave:relay(X). - - - -%% =========================================================================== -%% %% Administrative and utility API %% %% =========================================================================== @@ -117,7 +87,7 @@ on_load() -> Extra :: map(). on_load(Extra) -> - ok = erlang:load_nif(atom_to_list(?MODULE), Extra). + ok = erlang:load_nif(atom_to_list(net), Extra). -spec info() -> list(). @@ -159,14 +129,6 @@ gethostname() -> %% %% --spec getnameinfo(SockAddr) -> {ok, Info} | {error, Reason} when - SockAddr :: socket:sockaddr(), - Info :: name_info(), - Reason :: term(). - -getnameinfo(SockAddr) -> - getnameinfo(SockAddr, undefined). - -spec getnameinfo(SockAddr, Flags) -> {ok, Info} | {error, Reason} when SockAddr :: socket:sockaddr(), Flags :: name_info_flags() | undefined, @@ -178,44 +140,18 @@ getnameinfo(SockAddr, [] = _Flags) -> getnameinfo(#{family := Fam, addr := _Addr} = SockAddr, Flags) when ((Fam =:= inet) orelse (Fam =:= inet6)) andalso (is_list(Flags) orelse (Flags =:= undefined)) -> - nif_getnameinfo((catch ensure_sockaddr(SockAddr)), Flags); + nif_getnameinfo(socket:ensure_sockaddr(SockAddr), Flags); getnameinfo(#{family := Fam, path := _Path} = SockAddr, Flags) when (Fam =:= local) andalso (is_list(Flags) orelse (Flags =:= undefined)) -> nif_getnameinfo(SockAddr, Flags). -%% This function is intended to "handle" the case when the user -%% has built their (OTP) system with "--disable-esock". -%% That means the socket module does not exist. This is not really -%% a problem since the nif_getnameinfo won't work either (since -%% the nif file is not part of the system). The result of calling -%% getnameinfo will be a undef exception (erlang:nif_error(undef)). -%% -%% The only functions in this module that actually work in this case -%% (--disable-esock) is the depricated stuff (call, cast, ...). -%% -ensure_sockaddr(SockAddr) -> - try socket:ensure_sockaddr(SockAddr) - catch - error:undef:_ -> - undefined - end. - %% =========================================================================== %% %% getaddrinfo - Network address and service translation %% %% There is also a "hint" argument that we "at some point" should implement. --spec getaddrinfo(Host) -> {ok, Info} | {error, Reason} when - Host :: string(), - Info :: [address_info()], - Reason :: term(). - -getaddrinfo(Host) when is_list(Host) -> - getaddrinfo(Host, undefined). - - -spec getaddrinfo(Host, undefined) -> {ok, Info} | {error, Reason} when Host :: string(), Info :: [address_info()], diff --git a/erts/preloaded/src/socket.erl b/erts/preloaded/src/socket.erl index ae1ffdb4ac..07e720c44d 100644 --- a/erts/preloaded/src/socket.erl +++ b/erts/preloaded/src/socket.erl @@ -26,9 +26,13 @@ %% Administrative and "global" utility functions -export([ on_load/0, on_load/1, - info/0, - supports/0, supports/1, supports/2, supports/3, - ensure_sockaddr/1 + + ensure_sockaddr/1, + + debug/1, + %% command/1, + info/0, info/1, + supports/0, supports/1, supports/2, supports/3 ]). -export([ @@ -63,6 +67,12 @@ select_ref/0, select_info/0, + socket_counters/0, + socket_counter/0, + socket_info/0, + + %% command/0, + domain/0, type/0, protocol/0, @@ -135,6 +145,27 @@ ]). +%% The command type has the general form: +%% #{ +%% command := atom(), +%% data := term() +%% } +%% But only certain values are actually valid, so the type gets the form: +-type debug_command() :: #{ + command := debug, + data := boolean() + }. +%% -type command() :: debug_command(). + +-type socket_counters() :: [{socket_counter(), non_neg_integer()}]. +-type socket_counter() :: read_byte | read_fails | read_pkg | read_tries | + read_waits | write_byte | write_fails | write_pkg | + write_tries | write_waits. +-type socket_info() :: #{counters := socket_counters(), + num_readers := non_neg_integer(), + num_writers := non_neg_integer(), + num_acceptors := non_neg_integer()}. + -type uint8() :: 0..16#FF. -type uint16() :: 0..16#FFFF. -type uint20() :: 0..16#FFFFF. @@ -282,7 +313,8 @@ path := binary() | string()}. -type sockaddr_in4() :: #{family := inet, port := port_number(), - addr := any | loopback | ip4_address()}. + %% The 'broadcast' here is the "limited broadcast" + addr := any | broadcast | loopback | ip4_address()}. -type sockaddr_in6() :: #{family := inet6, port := port_number(), addr := any | loopback | ip6_address(), @@ -303,7 +335,7 @@ -define(SOCKADDR_IN6_DEFAULTS, ?SOCKADDR_IN6_DEFAULTS(any)). -define(SOCKADDR_IN6_DEFAULT(A), (?SOCKADDR_IN6_DEFAULTS(A))#{family => inet6}). -%% otp - The option is internal to our (OTP) imeplementation. +%% otp - This option is internal to our (OTP) implementation. %% socket - The socket layer (SOL_SOCKET). %% ip - The IP layer (SOL_IP or is it IPPROTO_IP?). %% ipv6 - The IPv6 layer (SOL_IPV6). @@ -311,6 +343,7 @@ %% udp - The UDP (User Datagram Protocol) layer (IPPROTO_UDP). %% sctp - The SCTP (Stream Control Transmission Protocol) layer (IPPROTO_SCTP). %% Int - Raw level, sent down and used "as is". +%% Its up to the caller to make sure this is correct! -type sockopt_level() :: otp | socket | ip | ipv6 | tcp | udp | sctp | @@ -594,11 +627,11 @@ -opaque select_tag() :: atom(). -opaque select_ref() :: reference(). --record(select_info, {tag :: select_tag(), ref :: select_ref()}). +%% -record(select_info, {tag :: select_tag(), ref :: select_ref()}). --type select_info() :: #select_info{}. +-type select_info() :: {select_info, select_tag(), select_ref()}. --define(SELECT_INFO(T, R), #select_info{tag = T, ref = R}). +-define(SELECT_INFO(T, R), {select_info, T, R}). -define(SELECT(T, R), {select, ?SELECT_INFO(T, R)}). @@ -861,12 +894,46 @@ on_load(Extra) -> --spec info() -> list(). +-spec info() -> map(). info() -> nif_info(). +-spec debug(D) -> ok when + D :: boolean(). + +debug(D) when is_boolean(D) -> + command(#{command => debug, + data => D}). + + +-spec command(Command) -> ok when + Command :: debug_command(). + +command(#{command := debug, + data := Dbg} = Command) when is_boolean(Dbg) -> + nif_command(Command). + + + +%% =========================================================================== +%% +%% info - Get miscellaneous information about a socket. +%% +%% Generates a list of various info about the socket, such as counter values. +%% +%% Do *not* call this function often. +%% +%% =========================================================================== + +-spec info(Socket) -> socket_info() when + Socket :: socket(). + +info(#socket{ref = SockRef}) -> + nif_info(SockRef). + + %% =========================================================================== %% @@ -1081,19 +1148,25 @@ open(Domain, Type, Protocol, Extra) when is_map(Extra) -> %% %% bind - bind a name to a socket %% +%% Note that Addr can only have the value of broadcast *if* Domain =:= inet! +%% -spec bind(Socket, Addr) -> ok | {error, Reason} when Socket :: socket(), - Addr :: any | loopback | sockaddr(), + Addr :: any | broadcast | loopback | sockaddr(), Reason :: term(). bind(#socket{ref = SockRef}, Addr) - when ((Addr =:= any) orelse (Addr =:= loopback)) -> + when ((Addr =:= any) orelse + (Addr =:= broadcast) orelse + (Addr =:= loopback)) -> try which_domain(SockRef) of inet -> nif_bind(SockRef, ?SOCKADDR_IN4_DEFAULT(Addr)); - inet6 -> - nif_bind(SockRef, ?SOCKADDR_IN6_DEFAULT(Addr)) + inet6 when (Addr =:= any) orelse (Addr =:= loopback) -> + nif_bind(SockRef, ?SOCKADDR_IN6_DEFAULT(Addr)); + _ -> + einval() catch %% <WIN32-TEMPORARY> error:notsup:S -> @@ -1236,7 +1309,7 @@ connect(#socket{ref = SockRef}, #{family := Fam} = SockAddr, Timeout) ((Timeout =:= nowait) orelse (Timeout =:= infinity) orelse is_integer(Timeout)) -> TS = timestamp(Timeout), - case nif_connect(SockRef, SockAddr) of + case nif_connect(SockRef, ensure_sockaddr(SockAddr)) of ok -> %% Connected! ok; @@ -1494,7 +1567,7 @@ do_send(SockRef, Data, EFlags, Timeout) -> ok | {error, Reason} when Socket :: socket(), Data :: binary(), - Dest :: null | sockaddr(), + Dest :: sockaddr(), Reason :: term(). sendto(Socket, Data, Dest) -> @@ -1503,7 +1576,7 @@ sendto(Socket, Data, Dest) -> -spec sendto(Socket, Data, Dest, Flags) -> ok | {error, Reason} when Socket :: socket(), Data :: binary(), - Dest :: null | sockaddr(), + Dest :: sockaddr(), Flags :: send_flags(), Reason :: term() ; (Socket, Data, Dest, Timeout :: nowait) -> ok | @@ -1511,13 +1584,13 @@ sendto(Socket, Data, Dest) -> {error, Reason} when Socket :: socket(), Data :: iodata(), - Dest :: null | sockaddr(), + Dest :: sockaddr(), SelectInfo :: select_info(), Reason :: term() ; (Socket, Data, Dest, Timeout) -> ok | {error, Reason} when Socket :: socket(), Data :: iodata(), - Dest :: null | sockaddr(), + Dest :: sockaddr(), Timeout :: timeout(), Reason :: term(). @@ -1532,14 +1605,14 @@ sendto(Socket, Data, Dest, Timeout) -> {error, Reason} when Socket :: socket(), Data :: binary(), - Dest :: null | sockaddr(), + Dest :: sockaddr(), Flags :: send_flags(), SelectInfo :: select_info(), Reason :: term() ; (Socket, Data, Dest, Flags, Timeout) -> ok | {error, Reason} when Socket :: socket(), Data :: binary(), - Dest :: null | sockaddr(), + Dest :: sockaddr(), Flags :: send_flags(), Timeout :: timeout(), Reason :: term(). @@ -1547,15 +1620,6 @@ sendto(Socket, Data, Dest, Timeout) -> sendto(Socket, Data, Dest, Flags, Timeout) when is_list(Data) -> Bin = erlang:list_to_binary(Data), sendto(Socket, Bin, Dest, Flags, Timeout); -sendto(#socket{ref = SockRef}, Data, Dest, Flags, Timeout) - when is_binary(Data) andalso - (Dest =:= null) andalso - is_list(Flags) andalso - ((Timeout =:= nowait) orelse - (Timeout =:= infinity) orelse - (is_integer(Timeout) andalso (Timeout > 0))) -> - EFlags = enc_send_flags(Flags), - do_sendto(SockRef, Data, Dest, EFlags, Timeout); sendto(#socket{ref = SockRef}, Data, #{family := Fam} = Dest, Flags, Timeout) when is_binary(Data) andalso ((Fam =:= inet) orelse (Fam =:= inet6) orelse (Fam =:= local)) andalso @@ -1564,7 +1628,7 @@ sendto(#socket{ref = SockRef}, Data, #{family := Fam} = Dest, Flags, Timeout) (Timeout =:= infinity) orelse (is_integer(Timeout) andalso (Timeout > 0))) -> EFlags = enc_send_flags(Flags), - do_sendto(SockRef, Data, Dest, EFlags, Timeout). + do_sendto(SockRef, Data, ensure_sockaddr(Dest), EFlags, Timeout). do_sendto(SockRef, Data, Dest, EFlags, Timeout) -> TS = timestamp(Timeout), @@ -1755,8 +1819,12 @@ do_sendmsg_rest([B|IOVec], Written) -> ensure_msghdr(#{ctrl := []} = M) -> ensure_msghdr(maps:remove(ctrl, M)); -ensure_msghdr(#{iov := IOV} = M) when is_list(IOV) andalso (IOV =/= []) -> - M#{iov := erlang:iolist_to_iovec(IOV)}; +ensure_msghdr(#{iov := IOV, addr := Addr} = M) + when is_list(IOV) andalso (IOV =/= []) -> + M#{iov => erlang:iolist_to_iovec(IOV), addr => ensure_sockaddr(Addr)}; +ensure_msghdr(#{iov := IOV} = M) + when is_list(IOV) andalso (IOV =/= []) -> + M#{iov => erlang:iolist_to_iovec(IOV)}; ensure_msghdr(_) -> einval(). @@ -2617,7 +2685,7 @@ peername(#socket{ref = SockRef}) -> SelectInfo :: select_info(), Reason :: term(). -cancel(#socket{ref = SockRef}, #select_info{tag = Tag, ref = Ref}) -> +cancel(#socket{ref = SockRef}, ?SELECT_INFO(Tag, Ref)) -> cancel(SockRef, Tag, Ref). @@ -2628,17 +2696,17 @@ cancel(#socket{ref = SockRef}, #select_info{tag = Tag, ref = Ref}) -> %% %% =========================================================================== --spec enc_domain(Domain) -> non_neg_integer() when - Domain :: domain(). +%% -spec enc_domain(Domain) -> non_neg_integer() when +%% Domain :: domain(). enc_domain(local) -> ?SOCKET_DOMAIN_LOCAL; enc_domain(inet) -> ?SOCKET_DOMAIN_INET; enc_domain(inet6) -> ?SOCKET_DOMAIN_INET6; enc_domain(Domain) -> invalid_domain(Domain). --spec enc_type(Domain, Type) -> non_neg_integer() when - Domain :: domain(), - Type :: type(). +%% -spec enc_type(Domain, Type) -> non_neg_integer() when +%% Domain :: domain(), +%% Type :: type(). %% What combos are valid? enc_type(_, stream) -> ?SOCKET_TYPE_STREAM; @@ -3308,10 +3376,12 @@ enc_sockopt_key(otp = L, Opt, _, _, _, _) -> %% +++ SOCKET socket options +++ enc_sockopt_key(socket = _L, acceptconn = _Opt, get = _Dir, _D, _T, _P) -> ?SOCKET_OPT_SOCK_ACCEPTCONN; +enc_sockopt_key(socket = L, acceptconn = Opt, Dir, _D, _T, _P) -> + not_supported({L, Opt, Dir}); enc_sockopt_key(socket = L, acceptfilter = Opt, _Dir, _D, _T, _P) -> not_supported({L, Opt}); -%% Before linux 3.8, this socket option could be set. -%% Maximum size of buffer for name: IFNAMSZIZ +%% Before linux 3.8, this socket option could be set but not get. +%% Maximum size of buffer for name: IFNAMSIZ %% So, we let the implementation decide. enc_sockopt_key(socket = _L, bindtodevice = _Opt, _Dir, _D, _T, _P) -> ?SOCKET_OPT_SOCK_BINDTODEVICE; @@ -3845,6 +3915,12 @@ error(Reason) -> nif_info() -> erlang:nif_error(undef). +nif_info(_SRef) -> + erlang:nif_error(undef). + +nif_command(_Command) -> + erlang:nif_error(undef). + nif_supports(_Key) -> erlang:nif_error(undef). diff --git a/erts/test/erl_print_SUITE.erl b/erts/test/erl_print_SUITE.erl index 463d890688..0a5987df88 100644 --- a/erts/test/erl_print_SUITE.erl +++ b/erts/test/erl_print_SUITE.erl @@ -324,6 +324,9 @@ run_case(Config, TestArgs, Fun) -> -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, @@ -351,13 +354,13 @@ mk_pid({NodeName, Creation}, Number, Serial) when is_atom(NodeName) -> mk_pid({atom_to_list(NodeName), Creation}, Number, Serial); mk_pid({NodeName, Creation}, Number, Serial) -> case catch binary_to_term(list_to_binary([?VERSION_MAGIC, - ?PID_EXT, + ?NEW_PID_EXT, ?ATOM_EXT, uint16_be(length(NodeName)), NodeName, uint32_be(Number), uint32_be(Serial), - uint8(Creation)])) of + uint32_be(Creation)])) of Pid when is_pid(Pid) -> Pid; {'EXIT', {badarg, _}} -> @@ -370,12 +373,12 @@ mk_port({NodeName, Creation}, Number) when is_atom(NodeName) -> mk_port({atom_to_list(NodeName), Creation}, Number); mk_port({NodeName, Creation}, Number) -> case catch binary_to_term(list_to_binary([?VERSION_MAGIC, - ?PORT_EXT, + ?NEW_PORT_EXT, ?ATOM_EXT, uint16_be(length(NodeName)), NodeName, uint32_be(Number), - uint8(Creation)])) of + uint32_be(Creation)])) of Port when is_port(Port) -> Port; {'EXIT', {badarg, _}} -> @@ -388,33 +391,16 @@ mk_ref({NodeName, Creation}, Numbers) when is_atom(NodeName), is_integer(Creation), is_list(Numbers) -> mk_ref({atom_to_list(NodeName), Creation}, Numbers); -mk_ref({NodeName, Creation}, [Number]) when is_list(NodeName), - is_integer(Creation), - is_integer(Number) -> - case catch binary_to_term(list_to_binary([?VERSION_MAGIC, - ?REFERENCE_EXT, - ?ATOM_EXT, - uint16_be(length(NodeName)), - NodeName, - uint32_be(Number), - uint8(Creation)])) of - Ref when is_reference(Ref) -> - Ref; - {'EXIT', {badarg, _}} -> - exit({badarg, mk_ref, [{NodeName, Creation}, [Number]]}); - Other -> - exit({unexpected_binary_to_term_result, Other}) - end; mk_ref({NodeName, Creation}, Numbers) when is_list(NodeName), is_integer(Creation), is_list(Numbers) -> case catch binary_to_term(list_to_binary([?VERSION_MAGIC, - ?NEW_REFERENCE_EXT, + ?NEWER_REFERENCE_EXT, uint16_be(length(Numbers)), ?ATOM_EXT, uint16_be(length(NodeName)), NodeName, - uint8(Creation), + uint32_be(Creation), lists:map(fun (N) -> uint32_be(N) end, @@ -429,11 +415,10 @@ mk_ref({NodeName, Creation}, Numbers) when is_list(NodeName), my_cre() -> erlang:system_info(creation). -oth_cre(0) -> 1; -oth_cre(1) -> 2; -oth_cre(2) -> 3; -oth_cre(3) -> 1; -oth_cre(N) -> exit({invalid_creation, N}). +oth_cre(N) when N >= 0, N < (1 bsl 32) -> + (N rem ((1 bsl 32) - 1)) + 1; +oth_cre(N) -> + exit({invalid_creation, N}). str_1_bsl_10000() -> "19950631168807583848837421626835850838234968318861924548520089498529438830221946631919961684036194597899331129423209124271556491349413781117593785932096323957855730046793794526765246551266059895520550086918193311542508608460618104685509074866089624888090489894838009253941633257850621568309473902556912388065225096643874441046759871626985453222868538161694315775629640762836880760732228535091641476183956381458969463899410840960536267821064621427333394036525565649530603142680234969400335934316651459297773279665775606172582031407994198179607378245683762280037302885487251900834464581454650557929601414833921615734588139257095379769119277800826957735674444123062018757836325502728323789270710373802866393031428133241401624195671690574061419654342324638801248856147305207431992259611796250130992860241708340807605932320161268492288496255841312844061536738951487114256315111089745514203313820202931640957596464756010405845841566072044962867016515061920631004186422275908670900574606417856951911456055068251250406007519842261898059237118054444788072906395242548339221982707404473162376760846613033778706039803413197133493654622700563169937455508241780972810983291314403571877524768509857276937926433221599399876886660808368837838027643282775172273657572744784112294389733810861607423253291974813120197604178281965697475898164531258434135959862784130128185406283476649088690521047580882615823961985770122407044330583075869039319604603404973156583208672105913300903752823415539745394397715257455290510212310947321610753474825740775273986348298498340756937955646638621874569499279016572103701364433135817214311791398222983845847334440270964182851005072927748364550578634501100852987812389473928699540834346158807043959118985815145779177143619698728131459483783202081474982171858011389071228250905826817436220577475921417653715687725614904582904992461028630081535583308130101987675856234343538955409175623400844887526162643568648833519463720377293240094456246923254350400678027273837755376406726898636241037491410966718557050759098100246789880178271925953381282421954028302759408448955014676668389697996886241636313376393903373455801407636741877711055384225739499110186468219696581651485130494222369947714763069155468217682876200362777257723781365331611196811280792669481887201298643660768551639860534602297871557517947385246369446923087894265948217008051120322365496288169035739121368338393591756418733850510970271613915439590991598154654417336311656936031122249937969999226781732358023111862644575299135758175008199839236284615249881088960232244362173771618086357015468484058622329792853875623486556440536962622018963571028812361567512543338303270029097668650568557157505516727518899194129711337690149916181315171544007728650573189557450920330185304847113818315407324053319038462084036421763703911550639789000742853672196280903477974533320468368795868580237952218629120080742819551317948157624448298518461509704888027274721574688131594750409732115080498190455803416826949787141316063210686391511681774304792596709376". diff --git a/erts/vsn.mk b/erts/vsn.mk index 40a9685e9d..f06fd08540 100644 --- a/erts/vsn.mk +++ b/erts/vsn.mk @@ -18,7 +18,7 @@ # %CopyrightEnd% # -VSN = 10.4.3 +VSN = 10.4.4 # Port number 4365 in 4.2 # Port number 4366 in 4.3 |