Provided by: erlang-manpages_25.2.3+dfsg-1_all bug

NAME

       socket - Socket interface.

DESCRIPTION

       This  module  provides an API for network socket. Functions are provided to create, delete
       and manipulate the sockets as well as sending and receiving data on them.

       The intent is that it shall be as "close as possible" to the OS  level  socket  interface.
       The  only significant addition is that some of the functions, e.g. recv/3, have a time-out
       argument.

   Note:
       Some functions allow for an asynchronous  call. This is achieved by  setting  the  Timeout
       argument  to  nowait.  For  instance,  if  calling the recv/3 function with Timeout set to
       nowait (recv(Sock, 0, nowait)) when there is actually nothing to read, it will return with
       {select,  SelectInfo} (SelectInfo contains the SelectHandle). When data eventually arrives
       a 'select' message will be sent to the caller:

         : {'$socket', socket(), select, SelectHandle}

       The caller can now call the recv function again and probably expect data (it is really  up
       to the OS network protocol implementation).

       Note  that all other users are locked out until the 'current user' has called the function
       (recv in this case) and its return value  shows  that  the  operation  has  completed.  An
       operation can also be cancelled with cancel/2.

       Instead of Timeout = nowait it is equivalent to create a SelectHandle) with make_ref() and
       give as Timeout. This will then be the SelectHandle in the 'select' message, which enables
       a  compiler  optimization  for  receiving a message containing a newly created reference()
       (ignore the part of the message queue that had arrived  before  the  the  reference()  was
       created).

       Another  message  the  user  must  be prepared for (when making asynchronous calls) is the
       abort message:

         : {'$socket', socket(), abort, Info}

       This message indicates that  the  (asynchronous)  operation  has  been  aborted.  If,  for
       instance,  the  socket  has  been closed (by another process), Info will be {SelectHandle,
       closed}.

   Note:
       There is currently no support for Windows.

       Support for IPv6 has been implemented but not tested.

       SCTP has only been partly implemented (and not tested).

DATA TYPES

       invalid() = {invalid, What :: term()}

       domain() = inet | inet6 | local | unspec

              A lowercase atom() representing a protocol domain on the platform  named  AF_*  (or
              PF_*).

              The  calls supports(), is_supported(ipv6) and is_supported(local) tells if the IPv6
              protocol for the inet6 protocol domain / address family, and if the local  protocol
              domain / address family is supported by the platform's header files.

       type() = stream | dgram | raw | rdm | seqpacket

              A lowercase atom() representing a protocol type on the platform named SOCK_*.

       protocol() = atom()

              An  atom()  means any protocol as enumerated by the C library call getprotoent() on
              the platform, or at least the supported ones of ip | ipv6 | tcp | udp | sctp.

              See open/2,3,4

              The  call  supports(protocols)  returns  which   protocols   are   supported,   and
              is_supported(protocols, Protocol) tells if Protocol is among the enumerated.

       socket() = {'$socket', socket_handle()}

              As returned by open/1,2,3,4 and accept/1,2.

       socket_handle()

              An opaque socket handle unique for the socket.

       select_tag()

              A   tag   that   describes  the  (select)  operation,  contained  in  the  returned
              select_info().

       select_handle() = reference()

              A reference() that uniquely identifies the (select)  operation,  contained  in  the
              returned select_info().

       select_info() =
           {select_info,
            SelectTag :: select_tag(),
            SelectHandle :: select_handle()}

              Returned  by  an  operation  that  requires the caller to wait for a select message
              containing the SelectHandle.

       info() =
           #{counters := #{atom() := integer() >= 0},
             iov_max := integer() >= 0,
             use_registry := boolean()}

              The smallest allowed iov_max value  according  to  POSIX  is  16,  but  check  your
              platform documentation to be sure.

       socket_counters() =
           #{read_byte := integer() >= 0,
             read_fails := integer() >= 0,
             read_pkg := integer() >= 0,
             read_pkg_max := integer() >= 0,
             read_tries := integer() >= 0,
             read_waits := integer() >= 0,
             write_byte := integer() >= 0,
             write_fails := integer() >= 0,
             write_pkg := integer() >= 0,
             write_pkg_max := integer() >= 0,
             write_tries := integer() >= 0,
             write_waits := integer() >= 0,
             sendfile => integer() >= 0,
             sendfile_byte => integer() >= 0,
             sendfile_fails => integer() >= 0,
             sendfile_max => integer() >= 0,
             sendfile_pkg => integer() >= 0,
             sendfile_pkg_max => integer() >= 0,
             sendfile_tries => integer() >= 0,
             sendfile_waits => integer() >= 0,
             acc_success := integer() >= 0,
             acc_fails := integer() >= 0,
             acc_tries := integer() >= 0,
             acc_waits := integer() >= 0}

       info_keys() =
           [domain | type | protocol | fd | owner | local_address |
            remote_address | recv | sent | state]

              Defines  the  information  elements of the table(s) printed by the i/0, i/1 and i/2
              functions.

       socket_info() =
           #{domain := domain() | integer(),
             type := type() | integer(),
             protocol := protocol() | integer(),
             owner := pid(),
             ctype := normal | fromfd | {fromfd, integer()},
             counters := socket_counters(),
             num_readers := integer() >= 0,
             num_writers := integer() >= 0,
             num_acceptors := integer() >= 0,
             writable := boolean(),
             readable := boolean(),
             rstates := [atom()],
             wstates := [atom()]}

       in_addr() = {0..255, 0..255, 0..255, 0..255}

       in6_addr() =
           {0..65535,
            0..65535,
            0..65535,
            0..65535,
            0..65535,
            0..65535,
            0..65535,
            0..65535}

       sockaddr() =
           sockaddr_in() |
           sockaddr_in6() |
           sockaddr_un() |
           sockaddr_ll() |
           sockaddr_dl() |
           sockaddr_unspec() |
           sockaddr_native()

       sockaddr_recv() = sockaddr() | binary()

       sockaddr_in() =
           #{family := inet,
             port := port_number(),
             addr := any | broadcast | loopback | in_addr()}

       sockaddr_in6() =
           #{family := inet6,
             port := port_number(),
             addr := any | loopback | in6_addr(),
             flowinfo := in6_flow_info(),
             scope_id := in6_scope_id()}

       sockaddr_un() = #{family := local, path := binary() | string()}

              The path element will always be a binary  when  returned  from  this  module.  When
              supplied  to  an  API  function  in this module it may be a string(), which will be
              encoded into a binary according to the  native file name encoding  on the platform.

              A terminating zero character will be appended before the address path is  given  to
              the OS, and the terminating zero will be stripped before giving the address path to
              the caller.

              Linux's non-portable abstract socket address extension is handled by not doing  any
              terminating  zero  processing in either direction, if the first byte of the address
              is zero.

       sockaddr_ll() =
           #{family := packet,
             protocol := integer() >= 0,
             ifindex := integer(),
             pkttype := packet_type(),
             hatype := hatype(),
             addr := binary()}

       sockaddr_dl() =
           #{family := link,
             index := integer() >= 0,
             type := integer() >= 0,
             nlen := integer() >= 0,
             alen := integer() >= 0,
             slen := integer() >= 0,
             data := binary()}

       sockaddr_unspec() = #{family := unspec, addr := binary()}

       sockaddr_native() = #{family := integer(), addr := binary()}

       packet_type() =
           host | broadcast | multicast | otherhost | outgoing |
           loopback | user | kernel | fastroute |
           integer() >= 0

       hatype() =
           netrom | eether | ether | ax25 | pronet | chaos | ieee802 |
           arcnet | appletlk | dlci | atm | metricom | ieee1394 | eui64 |
           infiniband | tunnel | tunnel6 | loopback | localtlk | none |
           void |
           integer() >= 0

       port_number() = 0..65535

       in6_flow_info() = 0..1048575

       in6_scope_id() = 0..4294967295

       msg_flag() =
           cmsg_cloexec | confirm | ctrunc | dontroute | eor | errqueue |
           more | oob | peek | trunc

              Flags corresponding to the message flag constants on the platform.  The  flags  are
              lowercase and the constants are uppercase with the prefix MSG_.

              Some  flags  are  only  used for sending, some only for receiving, some in received
              control messages, and some for several of these. Not all flags are supported on all
              platforms.    See    the   platform's   documentation,   supports(msg_flags),   and
              is_supported(msg_flags, MsgFlag).

       level() = socket | protocol()

              The OS protocol levels for, for example, socket options and control messages,  with
              the following names in the OS header files:

                socket:
                  SOL_SOCKET with options named SO_*.

                ip:
                  IPPROTO_IP a.k.a SOL_IP with options named IP_*.

                ipv6:
                  IPPROTO_IPV6 a.k.a SOL_IPV6 with options named IPV6_*.

                tcp:
                  IPPROTO_TCP with options named TCP_*.

                udp:
                  IPPROTO_UDP with options named UDP_*.

                sctp:
                  IPPROTO_SCTP with options named SCTP_*.

              There  are  many  other  possible protocols, but the ones above are those for which
              this socket library implements socket options and/or control messages.

              All protocols known to the OS are enumerated when the Erlang VM is started. See the
              OS  man page for protocols(5). The protocol level 'socket' is always implemented as
              SOL_SOCKET and all the others mentioned in the list above are valid,  if  supported
              by the platform, enumerated or not.

              The  calls supports() and is_supported(protocols, Protocol) can be used to find out
              if protocols ipv6 and/or sctp are supported  according  to  the  platform's  header
              files.

       otp_socket_option() =
           debug | iow | controlling_process | rcvbuf | rcvctrlbuf |
           sndctrlbuf | meta | use_registry | fd | domain

              These  are  socket options for the otp protocol level, that is {otp, Name} options,
              above all OS protocol levels. They affect Erlang/OTP's socket implementation.

                debug:
                  boolean() - Activate debug printout.

                iow:
                  boolean() - Inform On Wrap of statistics counters.

                controlling_process:
                  pid() - The socket "owner". Only the current controlling process can  set  this
                  option.

                rcvbuf:
                   BufSize  :: (default | integer()>0) | {N :: integer()>0, BufSize :: (default |
                  integer()>0)}  - Receive buffer size. The value default is only valid to set. N
                  specifies  the number of read attempts to do in a tight loop before assuming no
                  more data is pending.

                rcvctrlbuf:
                   BufSize :: (default | integer()>0)   -  Buffer  size  for  received  ancillary
                  messages. The value default is only valid to set.

                sndctrlbuf:
                   BufSize :: (default | integer()>0)  - Buffer size for sent ancillary messages.
                  The value default is only valid to set.

                fd:
                  integer() - Only valid to get.  The  OS  protocol  levels'  socket  descriptor.
                  Functions open/1,2 can be used to create a socket according to this module from
                  an existing OS socket descriptor.

                use_registry:
                  boolean() - Only valid to get. The value is set when the socket is created with
                  open/2 or open/4.

              Options  not  described  here  are  intentionally  undocumented  and for Erlang/OTP
              internal use only.

       socket_option() =
           {Level :: socket,
            Opt ::
                acceptconn | acceptfilter | bindtodevice | broadcast |
                busy_poll | debug | domain | dontroute | error |
                keepalive | linger | mark | oobinline | passcred |
                peek_off | peercred | priority | protocol | rcvbuf |
                rcvbufforce | rcvlowat | rcvtimeo | reuseaddr |
                reuseport | rxq_ovfl | setfib | sndbuf | sndbufforce |
                sndlowat | sndtimeo | timestamp | type} |
           {Level :: ip,
            Opt ::
                add_membership | add_source_membership | block_source |
                dontfrag | drop_membership | drop_source_membership |
                freebind | hdrincl | minttl | msfilter | mtu |
                mtu_discover | multicast_all | multicast_if |
                multicast_loop | multicast_ttl | nodefrag | options |
                pktinfo | recvdstaddr | recverr | recvif | recvopts |
                recvorigdstaddr | recvtos | recvttl | retopts |
                router_alert | sndsrcaddr | tos | transparent | ttl |
                unblock_source} |
           {Level :: ipv6,
            Opt ::
                addrform | add_membership | authhdr | auth_level |
                checksum | drop_membership | dstopts | esp_trans_level |
                esp_network_level | faith | flowinfo | hopopts |
                ipcomp_level | join_group | leave_group | mtu |
                mtu_discover | multicast_hops | multicast_if |
                multicast_loop | portrange | pktoptions | recverr |
                recvhoplimit | hoplimit | recvpktinfo | pktinfo |
                recvtclass | router_alert | rthdr | tclass |
                unicast_hops | use_min_mtu | v6only} |
           {Level :: tcp,
            Opt ::
                congestion | cork | info | keepcnt | keepidle |
                keepintvl | maxseg | md5sig | nodelay | noopt | nopush |
                syncnt | user_timeout} |
           {Level :: udp, Opt :: cork} |
           {Level :: sctp,
            Opt ::
                adaption_layer | associnfo | auth_active_key |
                auth_asconf | auth_chunk | auth_key | auth_delete_key |
                autoclose | context | default_send_params |
                delayed_ack_time | disable_fragments | hmac_ident |
                events | explicit_eor | fragment_interleave |
                get_peer_addr_info | initmsg | i_want_mapped_v4_addr |
                local_auth_chunks | maxseg | maxburst | nodelay |
                partial_delivery_point | peer_addr_params |
                peer_auth_chunks | primary_addr | reset_streams |
                rtoinfo | set_peer_primary_addr | status |
                use_ext_recvinfo}

              Socket option on the form {Level, Opt} where the OS protocol Level  =  level()  and
              Opt is a socket option on that protocol level.

              The  OS  name  for  an  options  is, except where otherwise noted, the Opt atom, in
              capitals, with prefix according to level().

          Note:
              The IPv6 option pktoptions is a special (barf) case. It is  intended  for  backward
              compatibility usage only.

              Do not use this option.

          Note:
              See the OS documentation for every socket option.

              An option below that has the value type boolean() will translate the value false to
              a C int with value 0, and the value true to !!0 (not (not false)).

              An option with value type integer() will be translated to a C int that may  have  a
              restricted range, for example byte: 0..255. See the OS documentation.

              The  calls  supports(options),  supports(options,  Level) and is_supported(options,
              {Level, Opt}) can be used to find out which socket options that  are  supported  by
              the platform.

              Options for protocol level socket:

                {socket, acceptconn}:
                  Value = boolean()

                {socket, bindtodevice}:
                  Value = string()

                {socket, broadcast}:
                  Value = boolean()

                {socket, debug}:
                  Value = integer()

                {socket, domain}:
                  Value = domain()

                  Only valid to get.

                  The socket's protocol domain. Does not work on for instance FreeBSD.

                {socket, dontroute}:
                  Value = boolean()

                {socket, keepalive}:
                  Value = boolean()

                {socket, linger}:
                  Value = abort | linger()

                  The  value abort is shorthand for #{onoff => true, linger => 0}, and only valid
                  to set.

                {socket, oobinline}:
                  Value = boolean()

                {socket, passcred}:
                  Value = boolean()

                {socket, peek_off}:
                  Value = integer()

                  Currently disabled due to a possible infinite loop when calling  recv/1-4  with
                  peek in Flags.

                {socket, priority}:
                  Value = integer()

                {socket, protocol}:
                  Value = protocol()

                  Only valid to get.

                  The socket's protocol. Does not work on for instance Darwin.

                {socket, rcvbuf}:
                  Value = integer()

                {socket, rcvlowat}:
                  Value = integer()

                {socket, rcvtimeo}:
                  Value = timeval()

                  This option is unsupported per default; OTP has to be explicitly built with the
                  --enable-esock-rcvsndtimeo configure option for this to be available.

                  Since our implementation uses nonblocking sockets, it is  unknown  if  and  how
                  this  option  works,  or even if it may cause malfunction. Therefore, we do not
                  recommend setting this option.

                  Instead, use the Timeout argument to, for instance, the recv/3 function.

                {socket, reuseaddr}:
                  Value = boolean()

                {socket, reuseport}:
                  Value = boolean()

                {socket, sndbuf}:
                  Value = integer()

                {socket, sndlowat}:
                  Value = integer()

                {socket, sndtimeo}:
                  Value = timeval()

                  This option is unsupported per default; OTP has to be explicitly built with the
                  --enable-esock-rcvsndtimeo configure option for this to be available.

                  Since  our  implementation  uses  nonblocking sockets, it is unknown if and how
                  this option works, or even if it may cause malfunction. Therefore,  we  do  not
                  recommend setting this option.

                  Instead, use the Timeout argument to, for instance, the send/3 function.

                {socket, timestamp}:
                  Value = boolean()

                {socket, type}:
                  Value = type()

                  Only valid to get.

                  The socket's type.

              Options for protocol level ip:

                {ip, add_membership}:
                  Value = ip_mreq()

                  Only valid to set.

                {ip, add_source_membership}:
                  Value = ip_mreq_source()

                  Only valid to set.

                {ip, block_source}:
                  Value = ip_mreq_source()

                  Only valid to set.

                {ip, drop_membership}:
                  Value = ip_mreq()

                  Only valid to set.

                {ip, drop_source_membership}:
                  Value = ip_mreq_source()

                  Only valid to set.

                {ip, freebind}:
                  Value = boolean()

                {ip, hdrincl}:
                  Value = boolean()

                {ip, minttl}:
                  Value = integer()

                {ip, msfilter}:
                  Value = null | ip_msfilter()

                  Only valid to set.

                  The value null passes a NULL pointer and size 0 to the C library call.

                {ip, mtu}:
                  Value = integer()

                  Only valid to get.

                {ip, mtu_discover}:
                  Value = ip_pmtudisc() | integer()

                  An integer() value is according to the platform's header files.

                {ip, multicast_all}:
                  Value = boolean()

                {ip, multicast_if}:
                  Value = any | in_addr()

                {ip, multicast_loop}:
                  Value = boolean()

                {ip, multicast_ttl}:
                  Value = integer()

                {ip, nodefrag}:
                  Value = boolean()

                {ip, pktinfo}:
                  Value = boolean()

                {ip, recvdstaddr}:
                  Value = boolean()

                {ip, recverr}:
                  Value = boolean()

                  Warning! When this option is enabled, error messages may arrive on the socket's
                  error queue, which should be read using the message flag  errqueue,  and  using
                  recvmsg/1,2,3,4,5 to get all error information in the message's ctrl field as a
                  control message #{level := ip, type := recverr}.

                  A working strategy should be to first poll the error queue using  recvmsg/2,3,4
                  with  Timeout  =:=  0  and  Flags  containing errqueue (ignore the return value
                  {error, timeout}) before reading the actual data to ensure that the error queue
                  gets  cleared. And read the data using one of the nowait | select_handle() recv
                  functions:  recv/3,4,  recvfrom/3,4  or  recvmsg/3,4,5.  Otherwise  you   might
                  accidentally cause a busy loop in and out of 'select' for the socket.

                {ip, recvif}:
                  Value = boolean()

                {ip, recvopts}:
                  Value = boolean()

                {ip, recvorigdstaddr}:
                  Value = boolean()

                {ip, recvtos}:
                  Value = boolean()

                {ip, recvttl}:
                  Value = boolean()

                {ip, retopts}:
                  Value = boolean()

                {ip, router_alert}:
                  Value = integer()

                {ip, sendsrcaddr}:
                  Value = boolean()

                {ip, tos}:
                  Value = ip_tos()  | integer()

                  An integer() value is according to the platform's header files.

                {ip, transparent}:
                  Value = boolean()

                {ip, ttl}:
                  Value = integer()

                {ip, unblock_source}:
                  Value = ip_mreq_source()

                  Only valid to set.

              Options for protocol level ipv6:

                {ipv6, addrform}:
                  Value = domain()

                  As  far  as  we know the only valid value is inet and it is only allowed for an
                  IPv6 socket that is connected and bound to an IPv4-mapped IPv6 address.

                {ipv6, add_membership}:
                  Value = ipv6_mreq()

                  Only valid to set.

                {ipv6, authhdr}:
                  Value = boolean()

                {ipv6, drop_membership}:
                  Value = ipv6_mreq()

                  Only valid to set.

                {ipv6, dstopts}:
                  Value = boolean()

                {ipv6, flowinfo}:
                  Value = boolean()

                {ipv6, hoplimit}:
                  Value = boolean()

                {ipv6, hopopts}:
                  Value = boolean()

                {ipv6, mtu}:
                  Value = integer()

                {ipv6, mtu_discover}:
                  Value = ipv6_pmtudisc() | integer()

                  An integer() value is according to the platform's header files.

                {ipv6, multicast_hops}:
                  Value = ipv6_hops()

                {ipv6, multicast_if}:
                  Value = integer()

                {ipv6, multicast_loop}:
                  Value = boolean()

                {ipv6, recverr}:
                  Value = boolean()

                  Warning! See the socket option  {ip,  recverr}  regarding  the  socket's  error
                  queue. The same warning applies for this option.

                {ipv6, recvhoplimit}:
                  Value = boolean()

                {ipv6, recvpktinfo}:
                  Value = boolean()

                {ipv6, recvtclass}:
                  Value = boolean()

                {ipv6, router_alert}:
                  Value = integer()

                {ipv6, rthdr}:
                  Value = boolean()

                {ipv6, tclass}:
                  Value = boolean()

                {ipv6, unicast_hops}:
                  Value = ipv6_hops()

                {ipv6, v6only}:
                  Value = boolean()

              Options for protocol level sctp. See also RFC 6458.

                {sctp, associnfo}:
                  Value = sctp_assocparams()

                {sctp, autoclose}:
                  Value = integer()

                {sctp, disable_fragments}:
                  Value = boolean()

                {sctp, events}:
                  Value = sctp_event_subscribe()

                  Only valid to set.

                {sctp, initmsg}:
                  Value = sctp_initmsg()

                {sctp, maxseg}:
                  Value = integer()

                {sctp, nodelay}:
                  Value = boolean()

                {sctp, rtoinfo}:
                  Value = sctp_rtoinfo()

              Options for protocol level tcp:

                {tcp, congestion}:
                  Value = string()

                {tcp, cork}:
                  Value = boolean()

                {tcp, maxseg}:
                  Value = integer()

                {tcp, nodelay}:
                  Value = boolean()

              Options for protocol level udp:

                {udp, cork}:
                  Value = boolean()

       linger() = #{onoff := boolean(), linger := integer() >= 0}

              Corresponds to the C struct linger for managing the socket option {socket, linger}.

       timeval() = #{sec := integer(), usec := integer()}

              Corresponds  to  the  C  struct  timeval.  The  field  sec  holds seconds, and usec
              microseconds.

       ip_mreq() = #{multiaddr := in_addr(), interface := in_addr()}

              Corresponds to the C struct ip_mreq for managing multicast groups.

       ip_mreq_source() =
           #{multiaddr := in_addr(),
             interface := in_addr(),
             sourceaddr := in_addr()}

              Corresponds to the C struct ip_mreq_source for managing multicast groups.

       ip_msfilter() =
           #{multiaddr := in_addr(),
             interface := in_addr(),
             mode := include | exclude,
             slist := [in_addr()]}

              Corresponds to the C struct ip_msfilter for  managing  multicast  source  filtering
              (RFC 3376).

       ip_pmtudisc() = want | dont | do | probe

              Lowercase  atom()  values  corresponding  to the C library constants IP_PMTUDISC_*.
              Some constant(s) may be unsupported by the platform.

       ip_tos() = lowdelay | throughput | reliability | mincost

              Lowercase atom() values corresponding to the  C  library  constants  IPTOS_*.  Some
              constant(s) may be unsupported by the platform.

       ip_pktinfo() =
           #{ifindex := integer() >= 0,
             spec_dst := in_addr(),
             addr := in_addr()}

       ipv6_mreq() =
           #{multiaddr := in6_addr(), interface := integer() >= 0}

              Corresponds  to  the C struct ipv6_mreq for managing multicast groups. See also RFC
              2553.

       ipv6_hops() = default | 0..255

              The value default is only valid to set and is translated to the C value -1, meaning
              the route default.

       ipv6_pmtudisc() = want | dont | do | probe

              Lowercase  atom()  values corresponding to the C library constants IPV6_PMTUDISC_*.
              Some constant(s) may be unsupported by the platform.

       ipv6_pktinfo() = #{addr := in6_addr(), ifindex := integer()}

       sctp_assocparams() =
           #{assoc_id := integer(),
             asocmaxrxt := 0..65535,
             numbe_peer_destinations := 0..65535,
             peer_rwnd := 0..4294967295,
             local_rwnd := 0..4294967295,
             cookie_life := 0..4294967295}

              Corresponds to the C struct sctp_assocparams.

       sctp_event_subscribe() =
           #{data_io := boolean(),
             association := boolean(),
             address := boolean(),
             send_failure := boolean(),
             peer_error := boolean(),
             shutdown := boolean(),
             partial_delivery := boolean(),
             adaptation_layer => boolean(),
             sender_dry => boolean()}

              Corresponds to the C struct sctp_event_subscribe.

              Not all fields are implemented on all platforms; unimplemented fields are  ignored,
              but  implemented  fields  are  mandatory. Note that the '_event' suffixes have been
              stripped from the C struct field names, for convenience.

       sctp_initmsg() =
           #{num_ostreams := 0..65535,
             max_instreams := 0..65535,
             max_attempts := 0..65535,
             max_init_timeo := 0..65535}

              Corresponds to the C struct sctp_initmsg.

       sctp_rtoinfo() =
           #{assoc_id := integer(),
             initial := 0..4294967295,
             max := 0..4294967295,
             min := 0..4294967295}

              Corresponds to the C struct sctp_rtoinfo.

       msg() = msg_send() | msg_recv()

       msg_send() =
           #{addr => sockaddr(),
             iov := erlang:iovec(),
             ctrl =>
                 [cmsg_send() |
                  #{level := level() | integer(),
                    type := integer(),
                    data := binary()}]}

              Message sent by sendmsg/2,3,4.

              Corresponds to a C struct msghdr, see your platform documentation for sendmsg(2).

                addr:
                   Optional peer address, used on unconnected sockets.  Corresponds  to  msg_name
                  and msg_namelen fields of a struct msghdr. If not used they are set to NULL, 0.

                iov:
                   Mandatory  data  as a list of binaries. The msg_iov and msg_iovlen fields of a
                  struct msghdr.

                ctrl:
                   Optional list of control messages (CMSG). Corresponds to the  msg_control  and
                  msg_controllen fields of a struct msghdr. If not used they are set to NULL, 0.

              The msg_flags field of the struct msghdr is set to 0.

       msg_recv() =
           #{addr => sockaddr_recv(),
             iov := erlang:iovec(),
             ctrl :=
                 [cmsg_recv() |
                  #{level := level() | integer(),
                    type := integer(),
                    data := binary()}],
             flags := [msg_flag() | integer()]}

              Message returned by recvmsg/1,2,3,5.

              Corresponds to a C struct msghdr, see your platform documentation for recvmsg(2).

                addr:
                   Optional  peer  address,  used on unconnected sockets. Corresponds to msg_name
                  and msg_namelen fields of a struct msghdr. If NULL the map key is not present.

                iov:
                   Data as a list of binaries. The msg_iov and  msg_iovlen  fields  of  a  struct
                  msghdr.

                ctrl:
                   A  possibly  empty  list  of  control  messages  (CMSG).  Corresponds  to  the
                  msg_control and msg_controllen fields of a struct msghdr.

                flags:
                   Message flags. Corresponds to the msg_flags field of a struct msghdr.  Unknown
                  flags, if any, are returned in one integer(), last in the containing list.

       native_value() = integer() | boolean() | binary()

       cmsg_send() =
           #{level := socket,
             type := timestamp,
             data => native_value(),
             value => timeval()} |
           #{level := socket, type := rights, data := native_value()} |
           #{level := socket,
             type := credentials,
             data := native_value()} |
           #{level := ip,
             type := tos,
             data => native_value(),
             value => ip_tos() | integer()} |
           #{level := ip,
             type := ttl,
             data => native_value(),
             value => integer()} |
           #{level := ip,
             type := hoplimit,
             data => native_value(),
             value => integer()} |
           #{level := ipv6,
             type := tclass,
             data => native_value(),
             value => integer()}

              Control messages (ancillary messages) accepted by sendmsg/2,3,4.

              A  control  message  may  for some message types have a value field with a symbolic
              value, or a data field with a native value, that has to be binary  compatible  what
              is defined in the platform's header files.

       cmsg_recv() =
           #{level := socket,
             type := timestamp,
             data := binary(),
             value => timeval()} |
           #{level := socket, type := rights, data := binary()} |
           #{level := socket, type := credentials, data := binary()} |
           #{level := ip,
             type := tos,
             data := binary(),
             value => ip_tos() | integer()} |
           #{level := ip,
             type := recvtos,
             data := binary(),
             value := ip_tos() | integer()} |
           #{level := ip,
             type := ttl,
             data := binary(),
             value => integer()} |
           #{level := ip,
             type := recvttl,
             data := binary(),
             value := integer()} |
           #{level := ip,
             type := pktinfo,
             data := binary(),
             value => ip_pktinfo()} |
           #{level := ip,
             type := origdstaddr,
             data := binary(),
             value => sockaddr_recv()} |
           #{level := ip,
             type := recverr,
             data := binary(),
             value => extended_err()} |
           #{level := ipv6,
             type := hoplimit,
             data := binary(),
             value => integer()} |
           #{level := ipv6,
             type := pktinfo,
             data := binary(),
             value => ipv6_pktinfo()} |
           #{level := ipv6,
             type := recverr,
             data := binary(),
             value => extended_err()} |
           #{level := ipv6,
             type := tclass,
             data := binary(),
             value => integer()}

              Control messages (ancillary messages) returned by recvmsg/1,2,3,5.

              A control message has got a data field with a native (binary) value for the message
              data, and may also have a decoded value field if this socket  library  successfully
              decoded the data.

       icmp_dest_unreach() =
           net_unreach | host_unreach | port_unreach | frag_needed |
           net_unknown | host_unknown

       icmpv6_dest_unreach() =
           noroute | adm_prohibited | not_neighbour | addr_unreach |
           port_unreach | policy_fail | reject_route

       ee_origin() = none | local | icmp | icmp6

       extended_err() =
           #{error := posix(),
             origin := icmp,
             type := dest_unreach,
             code := icmp_dest_unreach() | 0..255,
             info := 0..4294967295,
             data := 0..4294967295,
             offender := sockaddr_recv()} |
           #{error := posix(),
             origin := icmp,
             type := time_exceeded | 0..255,
             code := 0..255,
             info := 0..4294967295,
             data := 0..4294967295,
             offender := sockaddr_recv()} |
           #{error := posix(),
             origin := icmp6,
             type := dest_unreach,
             code := icmpv6_dest_unreach() | 0..255,
             info := 0..4294967295,
             data := 0..4294967295,
             offender := sockaddr_recv()} |
           #{error := posix(),
             origin := icmp6,
             type := pkt_toobig | time_exceeded | 0..255,
             code := 0..255,
             info := 0..4294967295,
             data := 0..4294967295,
             offender := sockaddr_recv()} |
           #{error := posix(),
             origin := ee_origin() | 0..255,
             type := 0..255,
             code := 0..255,
             info := 0..4294967295,
             data := 0..4294967295,
             offender := sockaddr_recv()}

       posix() = inet:posix()

              The POSIX error codes originates from the OS level socket interface.

EXPORTS

       accept(ListenSocket) -> {ok, Socket} | {error, Reason}

       accept(ListenSocket, Timeout :: infinity) ->
                 {ok, Socket} | {error, Reason}

              Types:

                 ListenSocket = Socket = socket()
                 Reason = posix() | closed | invalid()

              Accept a connection on a socket.

              This  call  is used with connection oriented socket types (stream or seqpacket). It
              returns the first pending incoming connection for a listen socket, or waits for one
              to arrive, and returns the (newly) connected socket.

       accept(ListenSocket, Timeout :: integer() >= 0) ->
                 {ok, Socket} | {error, Reason}

              Types:

                 ListenSocket = Socket = socket()
                 Reason = posix() | closed | invalid() | timeout

              The  same  as  accept/1  but  returns  {error,  timeout}  if no connection has been
              accepted after Timeout milliseconds.

       accept(ListenSocket, Timeout :: nowait) ->
                 {ok, Socket} | {select, SelectInfo} | {error, Reason}

       accept(ListenSocket, SelectHandle :: select_handle()) ->
                 {ok, Socket} | {select, SelectInfo} | {error, Reason}

              Types:

                 ListenSocket = Socket = socket()
                 SelectInfo = select_info()
                 Reason = posix() | closed | invalid()

              The same as accept/1 but returns promptly.

              When there is no pending connection to return, the function  will  return  {select,
              SelectInfo},  and  the  caller  will  later  receive  a select message, {'$socket',
              Socket, select, SelectHandle} ( with the SelectHandle contained in the SelectInfo )
              when  a  client  connects.  A  subsequent  call  to accept/1,2 will then return the
              socket.

              If the time-out argument is SelectHandle, that term will be contained in a returned
              SelectInfo and the corresponding select message. The SelectHandle is presumed to be
              unique to this call.

              If the time-out argument is nowait, and a SelectInfo is returned, it will contain a
              select_handle() generated by the call.

              If  the  caller  doesn't  want  to  wait for a connection, it must immediately call
              cancel/2 to cancel the operation.

       bind(Socket, Addr) -> ok | {error, Reason}

              Types:

                 Socket = socket()
                 Addr = sockaddr() | any | broadcast | loopback
                 Reason = posix() | closed | invalid()

              Bind a name to a socket.

              When a socket is created (with open), it  has  no  address  assigned  to  it.  bind
              assigns the address specified by the Addr argument.

              The rules used for name binding vary between domains.

              If  you  bind  a  socket to an address in for example the 'inet' or 'inet6' address
              families, with an ephemeral port number (0), and want to know which port  that  was
              chosen,   you  can  find  out  using  something  like:  {ok,  #{port  :=  Port}}  =
              socket:sockname(Socket)

       cancel(Socket, SelectInfo) -> ok | {error, Reason}

              Types:

                 Socket = socket()
                 SelectInfo = select_info()
                 Reason = closed | invalid()

              Cancel an asynchronous request.

              Call this function in order to cancel a previous asynchronous call to, e.g. recv/3.

              An ongoing asynchronous operation blocks the socket until the  operation  has  been
              finished in good order, or until it has been cancelled by this function.

              Any  other  process that tries an operation of the same basic type (accept / send /
              recv) will  be  enqueued  and  notified  with  the  regular  select  mechanism  for
              asynchronous  operations  when the current operation and all enqueued before it has
              been completed.

              If SelectInfo does not match an operation in progress for the calling process, this
              function returns {error, {invalid, SelectInfo}}.

       close(Socket) -> ok | {error, Reason}

              Types:

                 Socket = socket()
                 Reason = posix() | closed | timeout

              Closes the socket.

          Note:
              Note  that  for  e.g.  protocol  = tcp, most implementations doing a close does not
              guarantee that any data sent is delivered to the  recipient  before  the  close  is
              detected at the remote side.

              One  way  to  handle  this is to use the shutdown function (socket:shutdown(Socket,
              write)) to signal that no more data is to be sent and then wait for the  read  side
              of the socket to be closed.

       connect(Socket, SockAddr) -> ok | {error, Reason}

       connect(Socket, SockAddr, Timeout :: infinity) ->
                  ok | {error, Reason}

              Types:

                 Socket = socket()
                 SockAddr = sockaddr()
                 Reason = posix() | closed | invalid() | already

              This  function  connects  the  socket  to  the  address  specified  by the SockAddr
              argument, and returns when the connection has been established or failed.

              If a connection attempt is  already  in  progress  (by  another  process),  {error,
              already} is returned.

       connect(Socket, SockAddr, Timeout :: integer() >= 0) ->
                  ok | {error, Reason}

              Types:

                 Socket = socket()
                 SockAddr = sockaddr()
                 Reason = posix() | closed | invalid() | already | timeout

              The  same  as  connect/2  but  returns  {error,  timeout} if no connection has been
              established after Timeout milliseconds.

          Note:
              Note that when this call has returned {error, timeout} the connection state of  the
              socket  is uncertain since the platform's network stack may complete the connection
              at any time, up to some platform specific time-out.

              Repeating a connection attempt towards the same address would be ok, but towards  a
              different address could end up with a connection to either address.

              The safe play would be to close the socket and start over.

              Also  note  that all this applies to cancelling a connect call with a no-wait time-
              out described below.

       connect(Socket, SockAddr, Timeout :: nowait) ->
                  ok | {select, SelectInfo} | {error, Reason}

       connect(Socket, SockAddr, SelectHandle :: select_handle()) ->
                  ok | {select, SelectInfo} | {error, Reason}

              Types:

                 Socket = socket()
                 SockAddr = sockaddr()
                 SelectInfo = select_info()
                 Reason = posix() | closed | invalid() | already

              The same as connect/2 but returns promptly.

              If it is not possible to immediately establish  a  connection,  the  function  will
              return  {select,  SelectInfo},  and the caller will later receive a select message,
              {'$socket', Socket, select, SelectHandle} ( with the SelectHandle contained in  the
              SelectInfo ) when the connection has been completed or failed. A subsequent call to
              connect/1 will then finalize the connection and return the result.

              If the time-out argument is SelectHandle, that term will be contained in a returned
              SelectInfo and the corresponding select message. The SelectHandle is presumed to be
              unique to this call.

              If the time-out argument is nowait, and a SelectInfo is returned, it will contain a
              select_handle() generated by the call.

              If  the  caller  doesn't  want  to  wait  for  the  connection to complete, it must
              immediately call cancel/2 to cancel the operation.

       connect(Socket) -> ok | {error, Reason}

              Types:

                 Socket = socket()
                 Reason = posix() | closed | invalid()

              This function finalizes a connection setup on a socket, after calling connect(_, _,
              nowait  |  select_handle())  that  returned {select, SelectInfo}, and receiving the
              select message {'$socket', Socket, select, SelectHandle}, and returns  whether  the
              connection setup was successful or not.

              Instead  of  calling  this  function, for backwards compatibility, it is allowed to
              call connect/2,3, but that incurs more overhead since the connect address and time-
              out are processed in vain.

       cancel_monitor(MRef) -> boolean()

              Types:

                 MRef = reference()

              If MRef is a reference that the calling process obtained by calling monitor/1, this
              monitor is turned off. If the monitoring is already turned off, nothing happens.

              The returned value is one of the following:

                true:
                  The  monitor  was  found  and  removed.  In  this  case,  no   'DOWN'   message
                  corresponding to this monitor has been delivered and will not be delivered.

                false:
                  The  monitor  was  not  found and could not be removed. This probably because a
                  'DOWN' message corresponding to this monitor has already  been  placed  in  the
                  caller message queue.

              Failure: It is an error if MRef refers to a monitor started by another process.

       getopt(X1 :: socket(),
              SocketOption :: {Level :: otp, Opt :: otp_socket_option()}) ->
                 {ok, Value :: term()} | {error, invalid() | closed}

              Gets  a  socket  option from the protocol level otp, which is this implementation's
              level above the OS protocol layers.

              See the type  otp_socket_option()  for a description of the options on this level.

       getopt(X1 :: socket(), SocketOption :: socket_option()) ->
                 {ok, Value :: term()} |
                 {error, posix() | invalid() | closed}

              Gets a  socket  option  from  one  of  the  OS's  protocol  levels.  See  the  type
              socket_option()  for  which  options that this implementation knows about, how they
              are related to option names in the OS, and if there are  known  peculiarities  with
              any of them.

              What  options  are valid depends on what kind of socket it is (domain(), type() and
              protocol()).

              See the  socket options  chapter of the users guide for more info.

          Note:
              Not all options are valid, nor possible to get, on all platforms. That is, even  if
              "we" support an option; it does not mean that the underlying OS does.

       getopt(Socket, Level, Opt) -> ok | {error, Reason}

              Types:

                  Socket = socket()
                  Reason = inet:posix() | invalid() | closed

              Backwards compatibility function.

              The same as getopt(Socket, {Level, Opt})

       getopt_native(X1 :: socket(),
                     SocketOption ::
                         socket_option() |
                         {Level :: level() | (NativeLevel :: integer()),
                          NativeOpt :: integer()},
                     ValueType :: integer) ->
                        {ok, Value :: integer()} |
                        {error, posix() | invalid() | closed}

       getopt_native(X1 :: socket(),
                     SocketOption ::
                         socket_option() |
                         {Level :: level() | (NativeLevel :: integer()),
                          NativeOpt :: integer()},
                     ValueType :: boolean) ->
                        {ok, Value :: boolean()} |
                        {error, posix() | invalid() | closed}

       getopt_native(X1 :: socket(),
                     SocketOption ::
                         socket_option() |
                         {Level :: level() | (NativeLevel :: integer()),
                          NativeOpt :: integer()},
                     ValueSize :: integer() >= 0) ->
                        {ok, Value :: binary()} |
                        {error, posix() | invalid() | closed}

       getopt_native(X1 :: socket(),
                     SocketOption ::
                         socket_option() |
                         {Level :: level() | (NativeLevel :: integer()),
                          NativeOpt :: integer()},
                     ValueSpec :: binary()) ->
                        {ok, Value :: binary()} |
                        {error, posix() | invalid() | closed}

              Gets  a socket option that may be unknown to our implementation, or that has a type
              not compatible with our implementation, that is; in "native mode".

              The socket option may be specified with an ordinary socket_option() tuple,  with  a
              known Level = level() and an integer NativeOpt, or with both an integer NativeLevel
              and NativeOpt.

              How to decode the option value has  to  be  specified  either  with  ValueType,  by
              specifying the ValueSize for a binary() that will contain the fetched option value,
              or by specifying a binary() ValueSpec that will be  copied  to  a  buffer  for  the
              getsockopt() call to write the value in which will be returned as a new binary().

              If  ValueType  is integer a C type (int) will be fetched, if it is boolean a C type
              (int)  will  be  fetched  and  converted  into  a  boolean()  according  to  the  C
              implementation.

              What  options  are valid depends on what kind of socket it is (domain(), type() and
              protocol()).

              The integer values for NativeLevel and NativeOpt as well as the Value encoding  has
              to be deduced from the header files for the running system.

       i() -> ok

              Print all sockets in table format in the erlang shell.

       i(InfoKeys) -> ok

              Types:

                 InfoKeys = info_keys()

              Print all sockets in table format in the erlang shell. What information is included
              is defined by InfoKeys.

       i(Domain) -> ok

              Types:

                 Domain = inet | inet6 | local

              Print a selection, based on domain, of the sockets in table format  in  the  erlang
              shell.

       i(Proto) -> ok

              Types:

                 Proto = sctp | tcp | udp

              Print  a selection, based on protocol, of the sockets in table format in the erlang
              shell.

       i(Type) -> ok

              Types:

                 Type = dgram | seqpacket | stream

              Print a selection, based on type, of the sockets in  table  format  in  the  erlang
              shell.

       i(Domain, InfoKeys) -> ok

              Types:

                 Domain = inet | inet6 | local
                 InfoKeys = info_keys()

              Print  a  selection,  based on domain, of the sockets in table format in the erlang
              shell. What information is included is defined by InfoKeys.

       i(Proto, InfoKeys) -> ok

              Types:

                 Proto = sctp | tcp | udp
                 InfoKeys = info_keys()

              Print a selection, based on domain, of the sockets in table format  in  the  erlang
              shell. What information is included is defined by InfoKeys.

       i(Type, InfoKeys) -> ok

              Types:

                 Type = dgram | seqpacket | stream
                 InfoKeys = info_keys()

              Print  a  selection,  based  on  type, of the sockets in table format in the erlang
              shell. What information is included is defined by InfoKeys.

       info() -> info()

              Get miscellaneous info about the socket library.

              The function returns a map with each info item as a key-value binding.

          Note:
              In order to ensure data integrity, mutex'es are taken when needed. So, do not  call
              this function often.

       info(Socket) -> socket_info()

              Types:

                 Socket = socket()

              Get miscellaneous info about the socket.

              The  function returns a map with each info item as a key-value binding. It reflects
              the "current" state of the socket.

          Note:
              In order to ensure data integrity, mutex'es are taken when needed. So, do not  call
              this function often.

       ioctl(Socket, GetRequest) -> {ok, IFConf} | {error, Reason}

              Types:

                 Socket = socket()
                 GetRequest = gifconf
                 IFConf = [#{name := string, addr := sockaddr()}]
                 Reason = posix() | closed

              Retrieve socket (device) parameters.

       ioctl(Socket, GetRequest, NameOrIndex) ->
                {ok, Result} | {error, Reason}

              Types:

                 Socket = socket()
                 GetRequest =
                     gifname | gifindex | gifaddr | gifdstaddr | gifbrdaddr |
                     gifnetmask | gifhwaddr | gifmtu | giftxqlen | gifflags
                 NameOrIndex = string() | integer()
                 Result = term()
                 Reason = posix() | closed

              Retrieve  socket (device) parameters. This function retrieves a specific parameter,
              according to GetRequest  argument.  The  third  argument  is  the  (lookup)  "key",
              identifying the interface (usually the name of the interface).

                gifname:
                  Get the name of the interface with the specified index (integer()).

                  Result, name of the interface, is a string().

                gifindex:
                  Get the index of the interface with the specified name.

                  Result, interface index, is a integer().

                gifaddr:
                  Get  the  address  of the interface with the specified name. Result, address of
                  the interface, is a socket:sockaddr().

                gifdstaddr:
                  Get the destination address of the point-to-point interface with the  specified
                  name.

                  Result, destination address of the interface, is a socket:sockaddr().

                gifbrdaddr:
                  Get the droadcast address for the interface with the specified name.

                  Result, broadcast address of the interface, is a socket:sockaddr().

                gifnetmask:
                  Get the network mask for the interface with the specified name.

                  Result, network mask of the interface, is a socket:sockaddr().

                gifhwaddr:
                  Get the hardware address for the interface with the specified name.

                  Result,  hardware  address of the interface, is a socket:sockaddr(). The family
                  field contains the 'ARPHRD' device type (or an integer).

                gifmtu:
                  Get the MTU (Maximum Transfer Unit) for the interface with the specified name.

                  Result, MTU of the interface, is an integer().

                giftxqlen:
                  Get the transmit queue length of the interface with the specified name.

                  Result, transmit queue length of the interface, is an integer().

                gifflags:
                  Get the active flag word of the interface with the specified name.

                  Result,  the  active  flag   word   of   the   interface,   is   an   list   of
                  socket:ioctl_device_flag() | integer().

       ioctl(Socket, SetRequest, Name, Value) -> ok | {error, Reason}

              Types:

                 Socket = socket()
                 SetRequest =
                     sifflags | sifaddr | sifdstaddr | sifbrdaddr | sifnetmask |
                     sifhwaddr | gifmtu | siftxqlen
                 Name = string()
                 Value = term()
                 Reason = posix() | closed

              Set  socket (device) parameters. This function sets a specific parameter, according
              to SetRequest argument. The third argument is the "key", identifying the  interface
              (usually the name of the interface), and the fourth is the "new" value.

              These are privileged operation's.

                sifflags:
                  Set  the  the active flag word, #{Flag => boolean()}, of the interface with the
                  specified name.

                  Each flag to be changed, should be added to  the  value  map,  with  the  value
                  'true'  if  the  flag  (Flag)  should  be set and 'false' if the flag should be
                  reset.

                sifaddr:
                  Set the address, sockaddr(), of the interface with the specified name.

                sifdstaddr:
                  Set the destination address, sockaddr(), of a point-to-point interface with the
                  specified name.

                sifbrdaddr:
                  Set  the  broadcast  address,  sockaddr(),  of the interface with the specified
                  name.

                sifnetmask:
                  Set the network mask, sockaddr(), of the interface with the specified name.

                sifmtu:
                  Set the MTU (Maximum Transfer Unit), integer(),  for  the  interface  with  the
                  specified name.

                siftxqlen:
                  Set  the  transmit queue length, integer(), of the interface with the specified
                  name.

       is_supported(Key1 :: term()) -> boolean()

       is_supported(Key1 :: term(), Key2 :: term()) -> boolean()

              This function retrieves information about what the platform supports,  such  as  if
              SCTP is supported, or if a socket options are supported.

              For  keys  other than the known false is returned. Note that in a future version or
              on a different platform there might be more supported items.

              This functions returns a boolean corresponding to what supports/0-2 reports for the
              same Key1 (and Key2).

       listen(Socket) -> ok | {error, Reason}

       listen(Socket, Backlog) -> ok | {error, Reason}

              Types:

                 Socket = socket()
                 Backlog = integer()
                 Reason = posix() | closed

              Listen for connections on a socket.

       monitor(Socket) -> reference()

              Types:

                 Socket = socket()

              Start monitor the socket Socket.

              If  the  monitored socket does not exist or when the monitor is triggered, a 'DOWN'
              message is sent that has the following pattern:

                       {'DOWN', MonitorRef, socket, Object, Info}

              In the monitor message MonitorRef and Type are the same as described earlier, and:

                Object:
                  The monitored entity, socket, which triggered the event.

                Info:
                  Either the termination reason of the socket or nosock (socket  Socket  did  not
                  exist at the time of monitor creation).

              Making  several  calls  to socket:monitor/1 for the same Socket is not an error; it
              results in as many independent monitoring instances.

       number_of() -> integer() >= 0

              Returns the number of active sockets.

       open(FD) -> {ok, Socket} | {error, Reason}

       open(FD, Opts) -> {ok, Socket} | {error, Reason}

              Types:

                 FD = integer()
                 Opts =
                     #{domain => domain() | integer(),
                       type => type() | integer(),
                       protocol => default | protocol() | integer(),
                       dup => boolean(),
                       debug => boolean(),
                       use_registry => boolean()}
                 Socket = socket()
                 Reason = posix() | domain | type | protocol

              Creates an endpoint (socket) for communication based on an  already  existing  file
              descriptor.  The  function  attempts to retrieve domain, type and protocol from the
              system. This is however not possible on all platforms,  and  they  should  then  be
              specified in Opts.

              The Opts argument is intended for providing extra information for the open call:

                domain:
                  Which protocol domain is the descriptor of. See also open/2,3,4.

                type:
                  Which protocol type type is the descriptor of.

                  See also open/2,3,4.

                protocol:
                  Which  protocol  is  the  descriptor  of. The atom default is equivalent to the
                  integer protocol number 0 which means the default protocol for a  given  domain
                  and type.

                  If  the  protocol  can  not  be retrieved from the platform for the socket, and
                  protocol is not specified, the default protocol is used, which may or  may  not
                  be correct.

                  See also open/2,3,4.

                dup:
                  Shall the provided descriptor be duplicated (dup) or not.
                  Defaults to true.

                debug:
                  Enable or disable debug during the open call.
                  Defaults to false.

                use_registry>:
                  Enable  or  disable  use of the socket registry for this socket. This overrides
                  the global value.
                  Defaults to the global value, see use_registry/1.

          Note:
              This function should be used with care!

              On some platforms it is necessary to provide domain, type and protocol  since  they
              cannot be retrieved from the platform.

       open(Domain, Type) -> {ok, Socket} | {error, Reason}

       open(Domain, Type, Opts) -> {ok, Socket} | {error, Reason}

              Types:

                 Domain = domain() | integer()
                 Type = type() | integer()
                 Opts = map()
                 Socket = socket()
                 Reason = posix() | protocol

              Creates an endpoint (socket) for communication.

              The  same  as  open(Domain,  Type,  default)  and open(Domain, Type, default, Opts)
              respectively.

       open(Domain, Type, Protocol) -> {ok, Socket} | {error, Reason}

       open(Domain, Type, Protocol, Opts) ->
               {ok, Socket} | {error, Reason}

              Types:

                 Domain = domain() | integer()
                 Type = type() | integer()
                 Protocol = default | protocol() | integer()
                 Opts =
                     #{netns => string(),
                       debug => boolean(),
                       use_registry => boolean()}
                 Socket = socket()
                 Reason = posix() | protocol

              Creates an endpoint (socket) for communication.

              Domain and Type may be integer()s, as defined in the platform's header  files.  The
              same  goes for Protocol as defined in the platform's services(5) database. See also
              the OS man page for the library call socket(2).

          Note:
              For some combinations of Domain and Type the platform has got  a  default  protocol
              that can be selected with Protocol = default, and the platform may allow or require
              selecting the default protocol, a specific protocol, or either.

              Examples:

                socket:open(inet, stream, tcp):
                  It is common that for protocol domain and type inet,stream  it  is  allowed  to
                  select the tcp protocol although that mostly is the default.

                socket:open(local, dgram):
                  It is common that for the protocol domain local it is mandatory to not select a
                  protocol, that is; to select the default protocol.

              The Opts argument is intended for "other"  options.  The  supported  option(s)  are
              described below:

                netns: string():
                  Used  to  set the network namespace during the open call. Only supported on the
                  Linux platform.

                debug: boolean():
                  Enable or disable debug during the open call.
                  Defaults to false.

                use_registry: boolean():
                  Enable or disable use of the socket registry for this  socket.  This  overrides
                  the global value.
                  Defaults to the global value, see use_registry/1.

       peername(Socket) -> {ok, SockAddr} | {error, Reason}

              Types:

                 Socket = socket()
                 SockAddr = sockaddr_recv()
                 Reason = posix() | closed

              Returns the address of the peer connected to the socket.

       recv(Socket) ->
               {ok, Data} | {error, Reason} | {error, {Reason, Data}}

       recv(Socket, Flags) ->
               {ok, Data} | {error, Reason} | {error, {Reason, Data}}

       recv(Socket, Length) ->
               {ok, Data} | {error, Reason} | {error, {Reason, Data}}

       recv(Socket, Flags, Timeout :: infinity) ->
               {ok, Data} | {error, Reason} | {error, {Reason, Data}}

       recv(Socket, Length, Flags) ->
               {ok, Data} | {error, Reason} | {error, {Reason, Data}}

       recv(Socket, Length, Timeout :: infinity) ->
               {ok, Data} | {error, Reason} | {error, {Reason, Data}}

       recv(Socket, Length, Flags, Timeout :: infinity) ->
               {ok, Data} | {error, Reason} | {error, {Reason, Data}}

              Types:

                 Socket = socket()
                 Length = integer() >= 0
                 Flags = [msg_flag() | integer()]
                 Data = binary()
                 Reason = posix() | closed | invalid()

              Receives data from a socket, waiting for it to arrive.

              The  argument  Length  specifies how many bytes to receive, with the special case 0
              meaning "all available".

              For a socket of type stream this call will not return until all requested data  can
              be  delivered,  or  if "all available" data was requested when the first data chunk
              arrives.

              The message Flags  may  be  symbolic  msg_flag()s  and/or  integer()s,  as  in  the
              platform's  appropriate header files. The values of all symbolic flags and integers
              are or:ed together.

              When there is a socket error this function returns {error, Reason}, or if some data
              arrived before the error; {error, {Reason, Data}}.

       recv(Socket, Flags, Timeout :: integer() >= 0) ->
               {ok, Data} | {error, Reason} | {error, {Reason, Data}}

       recv(Socket, Length, Timeout :: integer() >= 0) ->
               {ok, Data} | {error, Reason} | {error, {Reason, Data}}

       recv(Socket, Length, Flags, Timeout :: integer() >= 0) ->
               {ok, Data} | {error, Reason} | {error, {Reason, Data}}

              Types:

                 Socket = socket()
                 Length = integer() >= 0
                 Flags = [msg_flag() | integer()]
                 Data = binary()
                 Reason = posix() | closed | invalid() | timeout

              Receives data from a socket, waiting at most Timeout milliseconds for it to arrive.

              The same as  infinite time-out recv/1,2,3,4 but returns {error, timeout} or {error,
              {timeout, Data}} after Timeout milliseconds, if the requested  data  has  not  been
              delivered.

       recv(Socket, Flags, SelectHandle :: nowait) ->
               {ok, Data} |
               {select, SelectInfo} |
               {select, {SelectInfo, Data}} |
               {error, Reason} |
               {error, {Reason, Data}}

       recv(Socket, Flags, SelectHandle :: select_handle()) ->
               {ok, Data} |
               {select, SelectInfo} |
               {select, {SelectInfo, Data}} |
               {error, Reason} |
               {error, {Reason, Data}}

       recv(Socket, Length, SelectHandle :: nowait) ->
               {ok, Data} |
               {select, SelectInfo} |
               {select, {SelectInfo, Data}} |
               {error, Reason} |
               {error, {Reason, Data}}

       recv(Socket, Length, SelectHandle :: select_handle()) ->
               {ok, Data} |
               {select, SelectInfo} |
               {select, {SelectInfo, Data}} |
               {error, Reason} |
               {error, {Reason, Data}}

       recv(Socket, Length, Flags, SelectHandle :: nowait) ->
               {ok, Data} |
               {select, SelectInfo} |
               {select, {SelectInfo, Data}} |
               {error, Reason} |
               {error, {Reason, Data}}

       recv(Socket, Length, Flags, SelectHandle :: select_handle()) ->
               {ok, Data} |
               {select, SelectInfo} |
               {select, {SelectInfo, Data}} |
               {error, Reason} |
               {error, {Reason, Data}}

              Types:

                 Socket = socket()
                 Length = integer() >= 0
                 Flags = [msg_flag() | integer()]
                 Data = binary()
                 SelectInfo = select_info()
                 Reason = posix() | closed | invalid()

              Receives  data  from  a socket, but returns a select continuation if the data could
              not be returned immediately.

              The same as  infinite time-out recv/1,2,3,4 but if the  data  cannot  be  delivered
              immediately,  the  function  returns {select, SelectInfo}, and the caller will then
              receive a select message, {'$socket', Socket,  select,  SelectHandle}  (  with  the
              SelectHandle contained in the SelectInfo ) when data has arrived. A subsequent call
              to recv/1,2,3,4 will then return the data.

              If the time-out argument is SelectHandle, that term will be contained in a returned
              SelectInfo and the corresponding select message. The SelectHandle is presumed to be
              unique to this call.

              If the time-out argument is nowait, and a SelectInfo is returned, it will contain a
              select_handle() generated by the call.

              Note  that  for a socket of type stream, if Length > 0 and only part of that amount
              of data is available, the function will return {ok, {Data, SelectInfo with  partial
              data.  If  the  caller doesn't want to wait for more data, it must immediately call
              cancel/2 to cancel the operation.

       recvfrom(Socket) -> {ok, {Source, Data}} | {error, Reason}

       recvfrom(Socket, Flags) -> {ok, {Source, Data}} | {error, Reason}

       recvfrom(Socket, BufSz) -> {ok, {Source, Data}} | {error, Reason}

       recvfrom(Socket, Flags, Timeout :: infinity) ->
                   {ok, {Source, Data}} | {error, Reason}

       recvfrom(Socket, BufSz, Flags) ->
                   {ok, {Source, Data}} | {error, Reason}

       recvfrom(Socket, BufSz, Timeout :: infinity) ->
                   {ok, {Source, Data}} | {error, Reason}

       recvfrom(Socket, BufSz, Flags, Timeout :: infinity) ->
                   {ok, {Source, Data}} | {error, Reason}

              Types:

                 Socket = socket()
                 BufSz = integer() >= 0
                 Flags = [msg_flag() | integer()]
                 Source = sockaddr_recv()
                 Data = binary()
                 Reason = posix() | closed | invalid()

              Receive a message from a socket, waiting for it to arrive.

              The function returns when a message is received, or when there is a  socket  error.
              Argument  BufSz specifies the number of bytes for the receive buffer. If the buffer
              size is too small, the message will be truncated.

              If BufSz is not specified or 0, a default buffer size is used, which can be set  by
              socket:setopt(Socket, {otp,recvbuf}, BufSz).

              If  it is impossible to know the appropriate buffer size, it may be possible to use
              the receive message flag  peek.  When  this  flag  is  used,  the  message  is  not
              "consumed" from the underlying buffers, so another recvfrom/1,2,3,4 call is needed,
              possibly with an adjusted buffer size.

              The message Flags  may  be  symbolic  msg_flag()s  and/or  integer()s,  as  in  the
              platform's  appropriate header files. The values of all symbolic flags and integers
              are or:ed together.

       recvfrom(Socket, Flags, Timeout :: integer() >= 0) ->
                   {ok, {Source, Data}} | {error, Reason}

       recvfrom(Socket, BufSz, Timeout :: integer() >= 0) ->
                   {ok, {Source, Data}} | {error, Reason}

       recvfrom(Socket, BufSz, Flags, Timeout :: integer() >= 0) ->
                   {ok, {Source, Data}} | {error, Reason}

              Types:

                 Socket = socket()
                 BufSz = integer() >= 0
                 Flags = [msg_flag() | integer()]
                 Source = sockaddr_recv()
                 Data = binary()
                 Reason = posix() | closed | invalid() | timeout

              Receives a message from a socket, waiting at most Timeout milliseconds  for  it  to
              arrive.

              The  same as  infinite time-out recvfrom/1,2,3,4 but returns {error, timeout} after
              Timeout milliseconds, if no message has been delivered.

       recvfrom(Socket, Flags, SelectHandle :: nowait) ->
                   {ok, {Source, Data}} |
                   {select, SelectInfo} |
                   {error, Reason}

       recvfrom(Socket, Flags, SelectHandle :: select_handle()) ->
                   {ok, {Source, Data}} |
                   {select, SelectInfo} |
                   {error, Reason}

       recvfrom(Socket, BufSz, SelectHandle :: nowait) ->
                   {ok, {Source, Data}} |
                   {select, SelectInfo} |
                   {error, Reason}

       recvfrom(Socket, BufSz, SelectHandle :: select_handle()) ->
                   {ok, {Source, Data}} |
                   {select, SelectInfo} |
                   {error, Reason}

       recvfrom(Socket, BufSz, Flags, SelectHandle :: nowait) ->
                   {ok, {Source, Data}} |
                   {select, SelectInfo} |
                   {error, Reason}

       recvfrom(Socket, BufSz, Flags, SelectHandle :: select_handle()) ->
                   {ok, {Source, Data}} |
                   {select, SelectInfo} |
                   {error, Reason}

              Types:

                 Socket = socket()
                 BufSz = integer() >= 0
                 Flags = [msg_flag() | integer()]
                 Source = sockaddr_recv()
                 Data = binary()
                 SelectInfo = select_info()
                 Reason = posix() | closed | invalid()

              Receives a message from a socket, but returns a select continuation if  no  message
              could be returned immediately.

              The  same as  infinite time-out recvfrom/1,2,3,4 but if no message cannot delivered
              immediately, the function returns {select, SelectInfo}, and the  caller  will  then
              receive  a  select  message,  {'$socket',  Socket, select, SelectHandle} ( with the
              SelectHandle contained in the SelectInfo ) when data has arrived. A subsequent call
              to recvfrom/1,2,3,4 will then return the message.

              If the time-out argument is SelectHandle, that term will be contained in a returned
              SelectInfo and the corresponding select message. The SelectHandle is presumed to be
              unique to this call.

              If the time-out argument is nowait, and a SelectInfo is returned, it will contain a
              select_handle() generated by the call.

              If the caller doesn't want to wait for the data, it must immediately call  cancel/2
              to cancel the operation.

       recvmsg(Socket) -> {ok, Msg} | {error, Reason}

       recvmsg(Socket, Flags) -> {ok, Msg} | {error, Reason}

       recvmsg(Socket, Timeout :: infinity) ->
                  {ok, Msg} | {error, Reason}

       recvmsg(Socket, Flags, Timeout :: infinity) ->
                  {ok, Msg} | {error, Reason}

       recvmsg(Socket, BufSz, CtrlSz) -> {ok, Msg} | {error, Reason}

       recvmsg(Socket, BufSz, CtrlSz, Timeout :: infinity) ->
                  {ok, Msg} | {error, Reason}

       recvmsg(Socket, BufSz, CtrlSz, Flags, Timeout :: infinity) ->
                  {ok, Msg} | {error, Reason}

              Types:

                 Socket = socket()
                 BufSz = CtrlSz = integer() >= 0
                 Flags = [msg_flag() | integer()]
                 Msg = msg_recv()
                 Reason = posix() | closed | invalid()

              Receive a message from a socket, waiting for it to arrive.

              The  function  returns when a message is received, or when there is a socket error.
              Arguments BufSz and CtrlSz specifies the number of bytes for the receive buffer and
              the  control  message  buffer. If the buffer size(s) is(are) too small, the message
              and/or control message list will be truncated.

              If BufSz is not specified or 0, a default buffer size is used, which can be set  by
              socket:setopt(Socket,  {otp,recvbuf},  BufSz).   The  same  applies  to  CtrlSz and
              socket:setopt(Socket, {otp,recvctrlbuf}, CtrlSz).

              If it is impossible to know the appropriate buffer size, it may be possible to  use
              the  receive  message  flag  peek.  When  this  flag  is  used,  the message is not
              "consumed" from the underlying  buffers,  so  another  recvfrom/1,2,3,4,5  call  is
              needed, possibly with an adjusted buffer size.

              The  message  Flags  may  be  symbolic  msg_flag()s  and/or  integer()s,  as in the
              platform's appropriate header files. The values of all symbolic flags and  integers
              are or:ed together.

       recvmsg(Socket, Timeout :: integer() >= 0) ->
                  {ok, Msg} | {error, Reason}

       recvmsg(Socket, Flags, Timeout :: integer() >= 0) ->
                  {ok, Msg} | {error, Reason}

       recvmsg(Socket, BufSz, CtrlSz, Timeout :: integer() >= 0) ->
                  {ok, Msg} | {error, Reason}

       recvmsg(Socket, BufSz, CtrlSz, Flags,
               Timeout :: integer() >= 0) ->
                  {ok, Msg} | {error, Reason}

              Types:

                 Socket = socket()
                 BufSz = CtrlSz = integer() >= 0
                 Flags = [msg_flag() | integer()]
                 Msg = msg_recv()
                 Reason = posix() | closed | invalid() | timeout

              Receives  a  message  from a socket, waiting at most Timeout milliseconds for it to
              arrive.

              The  same  as  recvmsg/1,2,3,4,5  but  returns  {error,  timeout}   after   Timeout
              milliseconds, if no message has been delivered.

       recvmsg(Socket, Timeout :: nowait) ->
                  {ok, Msg} | {select, SelectInfo} | {error, Reason}

       recvmsg(Socket, SelectHandle :: select_handle()) ->
                  {ok, Msg} | {select, SelectInfo} | {error, Reason}

       recvmsg(Socket, Flags, Timeout :: nowait) ->
                  {ok, Msg} | {select, SelectInfo} | {error, Reason}

       recvmsg(Socket, Flags, SelectHandle :: select_handle()) ->
                  {ok, Msg} | {select, SelectInfo} | {error, Reason}

       recvmsg(Socket, BufSz, CtrlSz, SelectHandle :: nowait) ->
                  {ok, Msg} | {select, SelectInfo} | {error, Reason}

       recvmsg(Socket, BufSz, CtrlSz, SelectHandle :: select_handle()) ->
                  {ok, Msg} | {select, SelectInfo} | {error, Reason}

       recvmsg(Socket, BufSz, CtrlSz, Flags, SelectHandle :: nowait) ->
                  {ok, Msg} | {select, SelectInfo} | {error, Reason}

       recvmsg(Socket, BufSz, CtrlSz, Flags,
               SelectHandle :: select_handle()) ->
                  {ok, Msg} | {select, SelectInfo} | {error, Reason}

              Types:

                 Socket = socket()
                 BufSz = CtrlSz = integer() >= 0
                 Flags = [msg_flag() | integer()]
                 Msg = msg_recv()
                 SelectInfo = select_info()
                 Reason = posix() | closed | invalid()

              Receives  a  message from a socket, but returns a select continuation if no message
              could be returned immediately.

              The same as  infinite time-out recvfrom/1,2,3,4 but if no message cannot  delivered
              immediately,  the  function  returns {select, SelectInfo}, and the caller will then
              receive a select message, {'$socket', Socket,  select,  SelectHandle}  (  with  the
              SelectHandle contained in the SelectInfo ) when data has arrived. A subsequent call
              to recvmsg/1,2,3,4,5 will then return the data.

              If the time-out argument is SelectHandle, that term will be contained in a returned
              SelectInfo and the corresponding select message. The SelectHandle is presumed to be
              unique to this call.

              If the time-out argument is nowait, and a SelectInfo is returned, it will contain a
              select_handle() generated by the call.

              If  the caller doesn't want to wait for the data, it must immediately call cancel/2
              to cancel the operation.

       send(Socket, Data) ->
               ok |
               {ok, RestData} |
               {error, Reason} |
               {error, {Reason, RestData}}

       send(Socket, Data, Flags) ->
               ok |
               {ok, RestData} |
               {error, Reason} |
               {error, {Reason, RestData}}

       send(Socket, Data, Timeout :: infinity) ->
               ok |
               {ok, RestData} |
               {error, Reason} |
               {error, {Reason, RestData}}

       send(Socket, Data, Flags, Timeout :: infinity) ->
               ok |
               {ok, RestData} |
               {error, Reason} |
               {error, {Reason, RestData}}

              Types:

                 Socket = socket()
                 Data = iodata()
                 Flags = [msg_flag() | integer()]
                 RestData = binary()
                 Reason = posix() | closed | invalid()

              Sends data on a connected socket, waiting for it to be sent.

              This call will not return until the  Data  has  been  accepted  by  the  platform's
              network layer, or it reports an error.

              The  message  Flags  may  be  symbolic  msg_flag()s and/or integer()s, matching the
              platform's appropriate header files. The values of all symbolic flags and  integers
              are or:ed together.

              The  Data,  if it is not a binary(), is copied into one before calling the platform
              network API, because a single buffer is required. A  returned  RestData  is  a  sub
              binary of this data binary.

              The return value indicates the result from the platform's network layer:

                ok:
                  All data has been accepted.

                {ok, RestData}:
                  Not all data has been accepted, but no error has been reported. RestData is the
                  tail of Data that has not been accepted.

                  This cannot happen for a socket of type stream  where  a  partially  successful
                  send is retried until the data is either accepted or there is an error.

                  For a socket of type dgram this should probably also not happen since a message
                  that cannot be passed atomically should render an error.

                  It is nevertheless possible for the platform's network layer to return this.

                {error, Reason}:
                  An error has been reported and no data has been accepted. The  posix()  Reasons
                  are  from  the  platform's network layer. closed means that this socket library
                  knows that the socket is closed, and invalid() means that  something  about  an
                  argument is invalid.

                 {error, {Reason, RestData}} :
                  An  error has been reported but before that some data was accepted. RestData is
                  the tail of Data that has not been accepted. See {error, Reason} above.

                  This can only happen for a socket of type stream when  a  partially  successful
                  send is retried until there is an error.

       send(Socket, Data, Timeout :: integer() >= 0) ->
               ok |
               {ok, RestData} |
               {error, Reason | timeout} |
               {error, {Reason | timeout, RestData}}

       send(Socket, Data, Flags, Timeout :: integer() >= 0) ->
               ok |
               {ok, RestData} |
               {error, Reason | timeout} |
               {error, {Reason | timeout, RestData}}

              Types:

                 Socket = socket()
                 Data = iodata()
                 Flags = [msg_flag() | integer()]
                 RestData = binary()
                 Reason = posix() | closed | invalid()

              Sends data on a connected socket, waiting at most Timeout milliseconds for it to be
              sent.

              The same as  infinite time-out send/2,3,4 but returns {error, timeout}  or  {error,
              {timeout,  RestData}} after Timeout milliseconds, if no Data or only some of it was
              accepted by the platform's network layer.

       send(Socket, Data, SelectHandle :: nowait) ->
               ok |
               {ok, RestData} |
               {select, SelectInfo} |
               {select, {SelectInfo, RestData}} |
               {error, Reason}

       send(Socket, Data, SelectHandle :: select_handle()) ->
               ok |
               {ok, RestData} |
               {select, SelectInfo} |
               {select, {SelectInfo, RestData}} |
               {error, Reason}

       send(Socket, Data, Flags, SelectHandle :: nowait) ->
               ok |
               {ok, RestData} |
               {select, SelectInfo} |
               {select, {SelectInfo, RestData}} |
               {error, Reason}

       send(Socket, Data, Flags, SelectHandle :: select_handle()) ->
               ok |
               {ok, RestData} |
               {select, SelectInfo} |
               {select, {SelectInfo, RestData}} |
               {error, Reason}

              Types:

                 Socket = socket()
                 Data = iodata()
                 Flags = [msg_flag() | integer()]
                 RestData = binary()
                 SelectInfo = select_info()
                 Reason = posix() | closed | invalid()

              Sends data on a connected socket, but returns a select  continuation  if  the  data
              could not be sent immediately.

              The same as  infinite time-out send/2,3 but if the data is not immediately accepted
              by the platform network layer, the function returns {select, SelectInfo},  and  the
              caller   will   then   receive   a  select  message,  {'$socket',  Socket,  select,
              SelectHandle} ( with the SelectHandle that was contained in the SelectInfo  )  when
              there is room for more data. A subsequent call to send/2-4 will then send the data.

              If  SelectHandle  is  a  select_handle(), that term will be contained in a returned
              SelectInfo and the corresponding select message. The SelectHandle is presumed to be
              unique to this call.

              If  SelectHandle  is  nowait,  and  a  SelectInfo  is  returned,  it will contain a
              select_handle() generated by the call.

              If  some  of  the  data  was  sent,  the  function  will  return   {ok,  {RestData,
              SelectInfo},  which can only happen for a socket of type stream. If the caller does
              not want to wait to send the rest of the data, it  should  immediately  cancel  the
              operation with cancel/2.

       send(Socket, Data, Cont) ->
               ok |
               {ok, RestData} |
               {error, Reason} |
               {error, {Reason, RestData}}

       send(Socket, Data, Cont, Timeout :: infinity) ->
               ok |
               {ok, RestData} |
               {error, Reason} |
               {error, {Reason, RestData}}

       send(Socket, Data, Cont, Timeout :: integer() >= 0) ->
               ok |
               {ok, RestData} |
               {error, Reason | timeout} |
               {error, {Reason | timeout, RestData}}

       send(Socket, Data, Cont, SelectHandle :: nowait) ->
               ok |
               {ok, RestData} |
               {select, SelectInfo} |
               {select, {SelectInfo, RestData}} |
               {error, Reason}

       send(Socket, Data, Cont, SelectHandle :: select_handle()) ->
               ok |
               {ok, RestData} |
               {select, SelectInfo} |
               {select, {SelectInfo, RestData}} |
               {error, Reason}

              Types:

                 Socket = socket()
                 Data = iodata()
                 Cont = select_info()
                 RestData = binary()
                 SelectInfo = select_info()
                 Reason = posix() | closed | invalid()

              Continues  sending  data  on  a  connected  socket,  where  the  send operation was
              initiated by send/3,4 that  returned  a  SelectInfo  continuation.  Otherwise  like
              infinite  time-out  send/2,3,4  ,   limited  time-out  send/3,4 or  nowait send/3,4
              respectively.

              Cont is the SelectInfo that was returned from the previous send() call.

              If Data is not a binary(), it will be copied into one, again.

              The return value indicates the  result  from  the  platform's  network  layer.  See
              send/2,3,4 and nowait send/3,4.

       sendmsg(Socket, Msg) ->
                  ok |
                  {ok, RestData} |
                  {error, Reason} |
                  {error, {Reason, RestData}}

       sendmsg(Socket, Msg, Flags) ->
                  ok |
                  {ok, RestData} |
                  {error, Reason} |
                  {error, {Reason, RestData}}

       sendmsg(Socket, Msg, Timeout :: infinity) ->
                  ok |
                  {ok, RestData} |
                  {error, Reason} |
                  {error, {Reason, RestData}}

       sendmsg(Socket, Msg, Flags, Timeout :: infinity) ->
                  ok |
                  {ok, RestData} |
                  {error, Reason} |
                  {error, {Reason, RestData}}

              Types:

                 Socket = socket()
                 Msg = msg_send()
                 Flags = [msg_flag() | integer()]
                 RestData = erlang:iovec()
                 Reason = posix() | closed | invalid()

              Sends a message on a socket, waiting for it to be sent.

              The destination, if needed, that is: if the socket is not connected, is provided in
              Msg, which also contains the data to send as a  list  of  binaries.  Msg  may  also
              contain  an  list  of optional control messages (depending on what the protocol and
              platform supports).

              For a connected socket no address field should be present in Msg, the platform  may
              return an error or ignore one.

              The  message data is given to to the platform's network layer in the form of an I/O
              vector without copying the content. If the number of elements in the I/O vector  is
              larger than allowed on the platform (reported in the iov_max field from info/0), on
              a socket of type stream the send is iterated  over  all  elements,  but  for  other
              socket types the call fails.

              This  call  will  not  return until the data has been handed over to the platform's
              network layer, or when it reports an error.

              The message Flags may be  symbolic  msg_flag()s  and/or  integer()s,  matching  the
              platform's  appropriate header files. The values of all symbolic flags and integers
              are or:ed together.

              The return value indicates the  result  from  the  platform's  network  layer.  See
              send/2,3,4.

       sendmsg(Socket, Msg, Timeout :: integer() >= 0) ->
                  ok |
                  {ok, RestData} |
                  {error, Reason | timeout} |
                  {error, {Reason | timeout, RestData}}

       sendmsg(Socket, Msg, Flags, Timeout :: integer() >= 0) ->
                  ok |
                  {ok, RestData} |
                  {error, Reason | timeout} |
                  {error, {Reason | timeout, RestData}}

              Types:

                 Socket = socket()
                 Msg = msg_send()
                 Flags = [msg_flag() | integer()]
                 RestData = erlang:iovec()
                 Reason = posix() | closed | invalid()

              Sends  a  message  on  a  socket, waiting at most Timeout milliseconds for it to be
              sent.

              The same as  infinite  time-out  sendmsg/2,3,4  but  returns  {error,  timeout}  or
              {error, {timeout, RestData}} after Timeout milliseconds, if no data or only some of
              it was accepted by the platform's network layer.

       sendmsg(Socket, Msg, Timeout :: nowait) ->
                  ok |
                  {ok, RestData} |
                  {select, SelectInfo} |
                  {select, {SelectInfo, RestData}} |
                  {error, Reason} |
                  {error, {Reason, RestData}}

       sendmsg(Socket, Msg, SelectHandle :: select_handle()) ->
                  ok |
                  {ok, RestData} |
                  {select, SelectInfo} |
                  {select, {SelectInfo, RestData}} |
                  {error, Reason} |
                  {error, {Reason, RestData}}

       sendmsg(Socket, Msg, Flags, SelectHandle :: nowait) ->
                  ok |
                  {ok, RestData} |
                  {select, SelectInfo} |
                  {select, {SelectInfo, RestData}} |
                  {error, Reason} |
                  {error, {Reason, RestData}}

       sendmsg(Socket, Msg, Flags, SelectHandle :: select_handle()) ->
                  ok |
                  {ok, RestData} |
                  {select, SelectInfo} |
                  {select, {SelectInfo, RestData}} |
                  {error, Reason} |
                  {error, {Reason, RestData}}

              Types:

                 Socket = socket()
                 Msg = msg_send()
                 Flags = [msg_flag() | integer()]
                 RestData = erlang:iovec()
                 SelectInfo = select_info()
                 Reason = posix() | closed | invalid()

              Sends a message on a socket, but returns a select continuation if  the  data  could
              not be sent immediately.

              The  same  as   infinity  time-out  sendmsg/2,3  but if the data is not immediately
              accepted by the platform network layer, the function returns {select,  SelectInfo},
              and  the  caller  will  then  receive a select message, {'$socket', Socket, select,
              SelectHandle} ( with the SelectHandle that was contained in the SelectInfo  )  when
              there  is  room  for more data. A subsequent call to sendmsg/2-4 will then send the
              data.

              If SelectHandle, is a select_handle(), that term will be contained  in  a  returned
              SelectInfo and the corresponding select message. The SelectHandle is presumed to be
              unique to this call.

              If SelectHandle is nowait,  and  a  SelectInfo  is  returned,  it  will  contain  a
              select_handle() generated by the call.

              If  some  of  the  data  was  sent,  the  function  will  return   {ok,  {RestData,
              SelectInfo},  which can only happen for a socket of type stream. If the caller does
              not  want  to  wait  to send the rest of the data, it should immediately cancel the
              operation with cancel/2.

       sendmsg(Socket, Data, Cont) ->
                  ok |
                  {ok, RestData} |
                  {error, Reason} |
                  {error, {Reason, RestData}}

       sendmsg(Socket, Data, Cont, Timeout :: infinity) ->
                  ok |
                  {ok, RestData} |
                  {error, Reason} |
                  {error, {Reason, RestData}}

       sendmsg(Socket, Data, Cont, Timeout :: integer() >= 0) ->
                  ok |
                  {ok, RestData} |
                  {error, Reason | timeout} |
                  {error, {Reason | timeout, RestData}}

       sendmsg(Socket, Data, Cont, SelectHandle :: nowait) ->
                  ok |
                  {ok, RestData} |
                  {select, SelectInfo} |
                  {select, {SelectInfo, RestData}} |
                  {error, Reason} |
                  {error, {Reason, RestData}}

       sendmsg(Socket, Data, Cont, SelectHandle :: select_handle()) ->
                  ok |
                  {ok, RestData} |
                  {select, SelectInfo} |
                  {select, {SelectInfo, RestData}} |
                  {error, Reason} |
                  {error, {Reason, RestData}}

              Types:

                 Socket = socket()
                 Data = msg_send() | erlang:iovec()
                 Cont = select_info()
                 RestData = erlang:iovec()
                 SelectInfo = select_info()
                 Reason = posix() | closed | invalid()

              Continues sending a message  data  on  a  socket,  where  the  send  operation  was
              initiated  by  sendmsg/3,4  that returned a SelectInfo continuation. Otherwise like
              infinite  time-out  sendmsg/2,3,4  ,   limited  time-out  sendmsg/3,4  or    nowait
              sendmsg/3,4 respectively.

              Cont is the SelectInfo that was returned from the previous sendmsg() call.

              The  return  value  indicates  the  result  from  the platform's network layer. See
              send/2,3,4 and nowait sendmsg/3,4.

       sendto(Socket, Data, Dest) ->
                 ok |
                 {ok, RestData} |
                 {error, Reason} |
                 {error, {Reason, RestData}}

       sendto(Socket, Data, Dest, Flags) ->
                 ok |
                 {ok, RestData} |
                 {error, Reason} |
                 {error, {Reason, RestData}}

       sendto(Socket, Data, Dest, Timeout :: infinity) ->
                 ok |
                 {ok, RestData} |
                 {error, Reason} |
                 {error, {Reason, RestData}}

       sendto(Socket, Data, Dest, Flags, Timeout :: infinity) ->
                 ok |
                 {ok, RestData} |
                 {error, Reason} |
                 {error, {Reason, RestData}}

              Types:

                 Socket = socket()
                 Data = iodata()
                 Dest = sockaddr()
                 Flags = [msg_flag() | integer()]
                 RestData = binary()
                 Reason = posix() | closed | invalid()

              Sends data on a socket, to the specified destination, waiting for it to be sent.

              This call will not return until the  data  has  been  accepted  by  the  platform's
              network layer, or it reports an error.

              If  this  call  is  used  on a connection mode socket or on a connected socket, the
              platforms's network layer may return an error or ignore the destination address.

              The message Flags may be  symbolic  msg_flag()s  and/or  integer()s,  matching  the
              platform's  appropriate header files. The values of all symbolic flags and integers
              are or:ed together.

              The return value indicates the  result  from  the  platform's  network  layer.  See
              send/2,3,4.

       sendto(Socket, Data, Dest, Timeout :: integer() >= 0) ->
                 ok |
                 {ok, RestData} |
                 {error, Reason | timeout} |
                 {error, {Reason | timeout, RestData}}

       sendto(Socket, Data, Dest, Flags, Timeout :: integer() >= 0) ->
                 ok |
                 {ok, RestData} |
                 {error, Reason | timeout} |
                 {error, {Reason | timeout, RestData}}

              Types:

                 Socket = socket()
                 Data = iodata()
                 Dest = sockaddr()
                 Flags = [msg_flag() | integer()]
                 RestData = binary()
                 Reason = posix() | closed | invalid()

              Sends data on a socket, waiting at most Timeout milliseconds for it to be sent.

              The same as  infinite time-out sendto/3,4,5 but returns {error, timeout} or {error,
              {timeout, RestData}} after Timeout milliseconds, if no Data or only some of it  was
              accepted by the platform's network layer.

       sendto(Socket, Data, Dest, SelectHandle :: nowait) ->
                 ok |
                 {ok, RestData} |
                 {select, SelectInfo} |
                 {select, {SelectInfo, RestData}} |
                 {error, Reason}

       sendto(Socket, Data, Dest, SelectHandle :: select_handle()) ->
                 ok |
                 {ok, RestData} |
                 {select, SelectInfo} |
                 {select, {SelectInfo, RestData}} |
                 {error, Reason}

       sendto(Socket, Data, Dest, Flags, SelectHandle :: nowait) ->
                 ok |
                 {ok, RestData} |
                 {select, SelectInfo} |
                 {select, {SelectInfo, RestData}} |
                 {error, Reason}

       sendto(Socket, Data, Dest, Flags, SelectHandle :: select_handle()) ->
                 ok |
                 {ok, RestData} |
                 {select, SelectInfo} |
                 {select, {SelectInfo, RestData}} |
                 {error, Reason}

              Types:

                 Socket = socket()
                 Data = iodata()
                 Dest = sockaddr()
                 Flags = [msg_flag() | integer()]
                 RestData = binary()
                 SelectInfo = select_info()
                 Reason = posix() | closed | invalid()

              Sends  data on a socket, but returns a select continuation if the data could not be
              sent immediately.

              The same as  infinity time-out sendto/3,4  but  if  the  data  is  not  immediately
              accepted  by the platform network layer, the function returns {select, SelectInfo},
              and the caller will then receive a  select  message,  {'$socket',  Socket,  select,
              SelectHandle}  (  with the SelectHandle that was contained in the SelectInfo ) when
              there is room for more data. A subsequent call to sendto/3-5  will  then  send  the
              data.

              If  SelectHandle  is  a  select_handle(), that term will be contained in a returned
              SelectInfo and the corresponding select message. The SelectHandle is presumed to be
              unique to this call.

              If  SelectHandle  is  nowait,  and  a  SelectInfo  is  returned,  it will contain a
              select_handle() generated by the call.

              If  some  of  the  data  was  sent,  the  function  will  return   {ok,  {RestData,
              SelectInfo},  which can only happen for a socket of type stream. If the caller does
              not want to wait to send the rest of the data, it  should  immediately  cancel  the
              operation with cancel/2.

       sendto(Socket, Data, Cont) ->
                 ok |
                 {ok, RestData} |
                 {error, Reason} |
                 {error, {Reason, RestData}}

       sendto(Socket, Data, Cont, Timeout :: infinity) ->
                 ok |
                 {ok, RestData} |
                 {error, Reason} |
                 {error, {Reason, RestData}}

       sendto(Socket, Data, Cont, Timeout :: integer() >= 0) ->
                 ok |
                 {ok, RestData} |
                 {error, Reason | timeout} |
                 {error, {Reason | timeout, RestData}}

       sendto(Socket, Data, Cont, SelectHandle :: nowait) ->
                 ok |
                 {ok, RestData} |
                 {select, SelectInfo} |
                 {select, {SelectInfo, RestData}} |
                 {error, Reason}

       sendto(Socket, Data, Cont, SelectHandle :: select_handle()) ->
                 ok |
                 {ok, RestData} |
                 {select, SelectInfo} |
                 {select, {SelectInfo, RestData}} |
                 {error, Reason}

              Types:

                 Socket = socket()
                 Data = iodata()
                 Cont = select_info()
                 RestData = binary()
                 SelectInfo = select_info()
                 Reason = posix() | closed | invalid()

              Continues  sending  data  on  a  socket,  where the send operation was initiated by
              sendto/4,5 that returned a SelectInfo continuation. Otherwise like  infinite  time-
              out sendto/3,4,5 ,  limited time-out sendto/4,5 or  nowait sendto/4,5 respectively.

              Cont is the SelectInfo that was returned from the previous sendto() call.

              If Data is not a binary(), it will be copied into one, again.

              The  return  value  indicates  the  result  from  the platform's network layer. See
              send/2,3,4 and nowait sendto/4,5.

       sendfile(Socket, FileHandle, Offset, Count, Timeout :: infinity) ->
                   {ok, BytesSent} |
                   {error, Reason} |
                   {error, {Reason, BytesSent}}

              Types:

                 Socket = socket()
                 FileHandle = file:fd()
                 Offset = integer()
                 Count = BytesSent = integer() >= 0
                 Reason = posix() | closed | invalid()

              Sends file data on a socket, to the specified destination, waiting  for  it  to  be
              sent ("infinite" time-out).

              The FileHandle must refer to an open raw file as described in file:open/2.

              This  call  will  not  return  until  the  data has been accepted by the platform's
              network layer, or it reports an error.

              The Offset argument is the file offset to start reading from. The default value  is
              0.

              The Count argument is the number of bytes to transfer from FileHandle to Socket. If
              Count =:= 0 (the default) the transfer stops at the end of file.

              The return value indicates the result from the platform's network layer:

                {ok, BytesSent}:
                  The transfer completed successfully after BytesSent bytes of data.

                {error, Reason}:
                  An error has been reported and  no  data  has  been  transferred.  The  posix()
                  Reasons  are  from  the platform's network layer. closed means that this socket
                  library knows that the socket is closed, and  invalid()  means  that  something
                  about an argument is invalid.

                 {error, {Reason, BytesSent}} :
                  An  error  has  been  reported  but  before that some data was transferred. See
                  {error, Reason} and {ok, BytesSent} above.

       sendfile(Socket, FileHandle, Offset, Count,
                Timeout :: integer() >= 0) ->
                   {ok, BytesSent} |
                   {error, Reason | timeout} |
                   {error, {Reason | timeout, BytesSent}}

              Types:

                 Socket = socket()
                 FileHandle = file:fd()
                 Offset = integer()
                 Count = BytesSent = integer() >= 0
                 Reason = posix() | closed | invalid()

              Sends file data on a socket, waiting at most Timeout milliseconds for it to be sent
              (limited time-out).

              The same as  "infinite" time-out sendfile/5 but returns {error, timeout} or {error,
              {timeout, BytesSent}}  after  Timeout  milliseconds,  if  not  all  file  data  was
              transferred by the platform's network layer.

       sendfile(Socket, FileHandle, Offset, Count,
                SelectHandle :: nowait) ->
                   {ok, BytesSent} |
                   {select, SelectInfo} |
                   {select, {SelectInfo, BytesSent}} |
                   {error, Reason}

       sendfile(Socket, FileHandle, Offset, Count,
                SelectHandle :: select_handle()) ->
                   {ok, BytesSent} |
                   {select, SelectInfo} |
                   {select, {SelectInfo, BytesSent}} |
                   {error, Reason}

              Types:

                 Socket = socket()
                 FileHandle = file:fd()
                 Offset = integer()
                 Count = BytesSent = integer() >= 0
                 SelectInfo = select_info()
                 Reason = posix() | closed | invalid()

              Sends  file  data  on a socket, but returns a select continuation if the data could
              not be sent immediately (nowait).

              The same as  "infinite" time-out sendfile/5 but if  the  data  is  not  immediately
              accepted  by the platform network layer, the function returns {select, SelectInfo},
              and the caller will then receive a  select  message,  {'$socket',  Socket,  select,
              SelectHandle}  (  with the SelectHandle that was contained in the SelectInfo ) when
              there is room for more data. Then a call  to  sendfile/3  with  SelectInfo  as  the
              second argument will continue the data transfer.

              If  SelectHandle  is  a  select_handle(), that term will be contained in a returned
              SelectInfo and the corresponding select message. The SelectHandle is presumed to be
              unique to this call.

              If  SelectHandle  is  nowait,  and  a  SelectInfo  is  returned,  it will contain a
              select_handle() generated by the call.

              If some file data was sent, the function will return  {ok, {BytesSent, SelectInfo}.
                If  the  caller  does  not  want  to wait to send the rest of the data, it should
              immediately cancel the operation with cancel/2.

       sendfile(Socket, Cont, Offset, Count, Timeout :: infinity) ->
                   {ok, BytesSent} |
                   {error, Reason} |
                   {error, {Reason, BytesSent}}

       sendfile(Socket, Cont, Offset, Count,
                Timeout :: integer() >= 0) ->
                   {ok, BytesSent} |
                   {error, Reason | timeout} |
                   {error, {Reason | timeout, BytesSent}}

       sendfile(Socket, Cont, Offset, Count, SelectHandle :: nowait) ->
                   {ok, BytesSent} |
                   {select, SelectInfo} |
                   {select, {SelectInfo, BytesSent}} |
                   {error, Reason}

       sendfile(Socket, Cont, Offset, Count,
                SelectHandle :: select_handle()) ->
                   {ok, BytesSent} |
                   {select, SelectInfo} |
                   {select, {SelectInfo, BytesSent}} |
                   {error, Reason}

              Types:

                 Socket = socket()
                 Cont = select_info()
                 Offset = integer()
                 Count = BytesSent = integer() >= 0
                 SelectInfo = select_info()
                 Reason = posix() | closed | invalid()

              Continues sending file data on a socket, where the send operation was initiated  by
              sendfile/3,5  that  returned  a SelectInfo continuation. Otherwise like  "infinite"
              time-out  sendfile/5  ,   limited  time-out  sendfile/5   or    nowait   sendfile/5
              respectively.

              Cont is the SelectInfo that was returned from the previous sendfile() call.

              The  return  value  indicates  the  result  from  the platform's network layer. See
              "infinite" time-out sendfile/5.

       sendfile(Socket, FileHandle, Offset, Count) -> Result

              Types:

                 Socket = socket()
                 FileHandle = file:fd()
                 Offset = integer()
                 Count = integer() >= 0

              The same as  sendfile(Socket, FileHandle, Offset, Count, infinity),  that is:  send
              the  file  data at Offset and Count to the socket, without time-out other than from
              the platform's network stack.

       sendfile(Socket, FileHandle, Timeout) -> Result

              Types:

                 Socket = socket()
                 FileHandle = file:fd()
                  Timeout = timeout() | 'nowait' | select_handle()

              Depending on the Timeout argument; the same as  sendfile(Socket, FileHandle, 0,  0,
              infinity),     sendfile(Socket,  FileHandle,  0, 0, Timeout),  or  sendfile(Socket,
              FileHandle, 0, 0, SelectHandle),  that is: send all data in the file to the socket,
              with the given Timeout.

       sendfile(Socket, FileHandle) -> Result

              Types:

                 Socket = socket()
                 FileHandle = file:fd()

              The  same as  sendfile(Socket, FileHandle, 0, 0, infinity),  that is: send all data
              in the file to the socket, without time-out other than from the platform's  network
              stack.

       setopt(Socket :: socket(),
              SocketOption :: {Level :: otp, Opt :: otp_socket_option()},
              Value :: term()) ->
                 ok | {error, invalid() | closed}

              Sets  a  socket  option  in  the protocol level otp, which is this implementation's
              level above the OS protocol layers.

              See the type  otp_socket_option()  for a description of the options on this level.

       setopt(Socket :: socket(),
              SocketOption :: socket_option(),
              Value :: term()) ->
                 ok | {error, posix() | invalid() | closed}

              Set  a  socket  option  in  one  of  the  OS's  protocol  levels.  See   the   type
              socket_option()  for  which  options that this implementation knows about, how they
              are related to option names in the OS, and if there are  known  peculiarities  with
              any of them.

              What  options  are valid depends on what kind of socket it is (domain(), type() and
              protocol()).

              See the  socket options  chapter of the users guide for more info.

          Note:
              Not all options are valid, nor possible to set, on all platforms. That is, even  if
              "we" support an option; it does not mean that the underlying OS does.

       setopt(Socket, Level, Opt, Value) -> ok | {error, Reason}

              Types:

                  Socket = socket()
                  Value = term()
                  Reason = inet:posix() | invalid() | closed

              Backwards compatibility function.

              The same as setopt(Socket, {Level, Opt}, Value)

       setopt_native(Socket :: socket(),
                     SocketOption ::
                         socket_option() |
                         {Level :: level() | (NativeLevel :: integer()),
                          NativeOpt :: integer()},
                     Value :: native_value()) ->
                        ok | {error, posix() | invalid() | closed}

              Sets  a socket option that may be unknown to our implementation, or that has a type
              not compatible with our implementation, that is; in "native mode".

              If Value is an integer() it will be used as a C type (int), if it is a boolean() it
              will be used as a C type (int) with the C implementations values for false or true,
              and if it is a binary() its content and size will be used as the option value.

              The socket option may be specified with an ordinary socket_option() tuple,  with  a
              known Level = level() and an integer NativeOpt, or with both an integer NativeLevel
              and NativeOpt.

              What options are valid depends on what kind of socket it is (domain(),  type()  and
              protocol()).

              The  integer  values for NativeLevel and NativeOpt as well as the encoding of Value
              has to be deduced from the header files for the running system.

       shutdown(Socket, How) -> ok | {error, Reason}

              Types:

                 Socket = socket()
                 How = read | write | read_write
                 Reason = posix() | closed

              Shut down all or part of a full-duplex connection.

       sockname(Socket) -> {ok, SockAddr} | {error, Reason}

              Types:

                 Socket = socket()
                 SockAddr = sockaddr_recv()
                 Reason = posix() | closed

              Returns the current address to which the socket is bound.

       supports() ->
                   [{Key1 :: term(),
                     boolean() |
                     [{Key2 :: term(),
                       boolean() | [{Key3 :: term(), boolean()}]}]}]

       supports(Key1 :: term()) ->
                   [{Key2 :: term(),
                     boolean() | [{Key3 :: term(), boolean()}]}]

       supports(Key1 :: term(), Key2 :: term()) ->
                   [{Key3 :: term(), boolean()}]

              These functions function retrieves information about what  the  platform  supports,
              such which platform features or which socket options, are supported.

              For  keys  other  than  the known the empty list is returned, Note that in a future
              version or on a different platform there might be more supported items.

                supports():
                  Returns a list of {Key1, supports(Key1)} tuples for  every  Key1  described  in
                  supports/1 and {Key1, boolean()} tuples for each of the following keys:

                  sctp:
                    SCTP support

                  ipv6:
                    IPv6 support

                  local:
                     Unix Domain sockets support (AF_UNIX | AF_LOCAL)

                  netns:
                     Network Namespaces support (Linux, setns(2))

                  sendfile:
                     Sendfile support (sendfile(2))

                supports(msg_flags = Key1):
                  Returns  a  list  of {Flag, boolean()} tuples for every Flag in msg_flag() with
                  the boolean() indicating if the flag is supported on this platform.

                supports(protocols = Key1):
                  Returns a list of  {Name  ::  atom(),  boolean()}  tuples  for  every  Name  in
                  protocol()  with  the boolean() indicating if the protocol is supported on this
                  platform.

                supports(options = Key1):
                  Returns a list of {SocketOption, boolean()} tuples for  every  SocketOption  in
                  socket_option() with the boolean() indicating if the socket option is supported
                  on this platform.

                 supports(options = Key1, Key2) :
                  For a Key2 in level() returns a list of {Opt, boolean()} tuples for  all  known
                  socket options Opt on that Level =:= Key2,  and the boolean() indicating if the
                  socket option is supported on this platform. See setopt/3 and getopt/2.

       use_registry(D :: boolean()) -> ok

              Globally change if the socket registry is to be used or not. Note  that  its  still
              possible  to  override  this  explicitly  when  creating an individual sockets, see
              open/2 or open/4 for more info (use the Extra argument).

       which_sockets() -> [socket()]

       which_sockets(FilterRule) -> [socket()]

              Types:

                 FilterRule =
                     inet | inet6 | local | stream | dgram | seqpacket | sctp |
                     tcp | udp |
                     pid() |
                     fun((socket_info()) -> boolean())

              Returns a list of all sockets, according to the filter rule.

              There are several pre-made filter rule(s) and one general:

                inet | inet6:
                  Selection based on the domain of the socket.
                  Only a subset is valid.

                stream | dgram | seqpacket:
                  Selection based on the type of the socket.
                  Only a subset is valid.

                sctp | tcp | udp:
                  Selection based on the protocol of the socket.
                  Only a subset is valid.

                pid():
                  Selection base on which sockets has this pid as Controlling Process.

                fun((socket_info()) -> boolean()):
                  The general filter rule.
                  A fun that takes the socket info and returns a boolean() (true  if  the  socket
                  could be included and false if should not).

EXAMPLES

       client(SAddr, SPort) ->
          {ok, Sock} = socket:open(inet, stream, tcp),
          ok = socket:connect(Sock, #{family => inet,
                                      addr   => SAddr,
                                      port   => SPort}),
          Msg = <<"hello">>,
          ok = socket:send(Sock, Msg),
          ok = socket:shutdown(Sock, write),
          {ok, Msg} = socket:recv(Sock),
          ok = socket:close(Sock).

       server(Addr, Port) ->
          {ok, LSock} = socket:open(inet, stream, tcp),
          ok = socket:bind(LSock, #{family => inet,
                                    port   => Port,
                                    addr   => Addr}),
          ok = socket:listen(LSock),
          {ok, Sock} = socket:accept(LSock),
          {ok, Msg} = socket:recv(Sock),
          ok = socket:send(Sock, Msg),
          ok = socket:close(Sock),
          ok = socket:close(LSock).