Provided by: erlang-manpages_25.3.2.8+dfsg-1ubuntu4_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.

          Note:
              Note that if multiple calls are made only the last call is "valid":

                       {select, {select_info, _Handle}} = socket:accept(LSock, nowait),
                       {error, timeout} = socket:accept(LSock, 500),
                       .
                          .
                       .

              In the example above, Handle is not valid once the second (accept-) call  has  been
              made  (the first call is automatically "cancelled" and an abort messaage sent, when
              the second call is made). After the (accept-) call resulting  in  the  timeout  has
              been made, there is no longer an active accept call!

       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.

          Note:
              Note that if multiple calls are made only the last call is "valid":

                       {select, {select_info, _Handle1}} = socket:accept(LSock, nowait),
                       {select, {select_info, _Handle2}} = socket:accept(LSock, nowait),
                       receive
                           {'$socket', LSock, select, Handle2} ->
                                {ok, ASock} = socket:accept(LSock, nowait),
                                .
                                   .
                                .
                       end

              In the example above, only Handle2 is valid once the second (accept-) call has been
              made (the first call is automatically "cancelled" and an abort messaage sent,  when
              the second call is made).

       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).