Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
socket(3)		   Erlang Module Definition		     socket(3)

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 re-
       ceiving 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	or to a	(select	or completion)
       handle .

       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 either one of:

	 : {completion,	CompletionInfo}

	 : {select, SelectInfo}

       CompletionInfo contains the CompletionHandle  and  SelectInfo  contains
       the SelectHandle.

       We  have	two different implementations. One on Unix  (select, based di-
       rectly on the synchronous standard socket interface) and	one on Windows
       (completion, based on the asynchronous I/O Completion Ports).

       These two implementations have a	slightly different behaviour and  mes-
       sage interface.

       The  difference will only manifest for the user,	if calls are made with
       the timeout argument set	to 'nowait' (see above).

       When an completion message is received (with the	result of  the	opera-
       tion),  that  means  that  the operation	(connect, send,	recv, ...) has
       been completed (successfully or otherwise). When	a  select  message  is
       received,  that only means that the operation can now be	completed, via
       a call to, for instance,	connect/1.

       The completion message has the format:

	 : {'$socket', socket(), completion, {CompletionHandle,	CompletionSta-
	   tus}}

       The select message has the format:

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

       Note that, on select "system", all other	users are locked out until the
       'current	user' has called the function (recv for	instance) and its  re-
       turn  value  shows  that	the operation has completed. Such an operation
       can also	be cancelled with cancel/2.

       Instead of Timeout = nowait it is equivalent to create  a  SelectHandle
       or CompletionHandle with	make_ref() and give as Timeout.	This will then
       be  the Handle in the 'completion' or 'select' message, which enables a
       compiler	optimization for receiving a message containing	a  newly  cre-
       ated 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:
       The Windows support has currently pre-release status.

       Support for IPv6	has been implemented but not fully tested.

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

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

       eei() =
	   #{info :=
		 econnreset | econnaborted | netname_deleted |
		 too_many_cmds |
		 atom(),
	     raw_info := term()}

	      Extended	Error  Info. A term containing additional (error) info
	      if the socket nif	has been configured to produce it.

       domain()	= inet | inet6 | local | unspec

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

	      The calls	supports(), is_supported(ipv6) and is_supported(local)
	      tells  if	 the IPv6 protocol for the inet6 protocol domain / ad-
	      dress 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  sup-
	      ported,  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() =
	   accept | connect |
	   recv	| recvfrom | recvmsg | send | sendto | sendmsg |
	   sendfile |
	   {recv | recvfrom | recvmsg |	send | sendto |	sendmsg	|
	    sendfile,
	    ContData ::	term()}

	      A	tag that describes the (select)	operation (=  function	name),
	      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.

       completion_tag()	=
	   accept | connect |
	   recv	| recvfrom | recvmsg | send | sendto | sendmsg

	      A	tag that describes the ongoing (completion) operation (= func-
	      tion name), contained in the returned completion_info().

       completion_handle() = reference()

	      A	 reference()  that uniquely identifies the (completion)	opera-
	      tion, contained in the returned completion_info().

       completion_info() =
	   {completion_info,
	    CompletionTag :: completion_tag(),
	    CompletionHandle ::	completion_handle()}

	      Returned by an operation that requires the caller	to wait	for  a
	      completion  message  containing the CompletionHandle and the re-
	      sult of the operation; the CompletionStatus.

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

	      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  han-
	      dled  by not doing any terminating zero processing in either di-
	      rection, 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	 plat-
	      form.  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_sup-
	      ported(msg_flags,	MsgFlag).

       level() = socket	| protocol()

	      The OS protocol levels for, for example, socket options and con-
	      trol 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 num-
		  ber  of  read	attempts to do in a tight loop before assuming
		  no more data is pending.

		rcvctrlbuf:
		   BufSize :: (default | integer()>0)  - Buffer	size  for  re-
		  ceived  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 |
		bsp_state | busy_poll |	debug |	domain | dontroute |
		error |	exclusiveaddruse | keepalive | linger |	mark |
		maxdg |	max_msg_size | 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 in-
	      tended 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  ex-
		  plicitly built with the --enable-esock-rcvsndtimeo configure
		  option for this to be	available.

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

		  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 ex-
		  plicitly built with the --enable-esock-rcvsndtimeo configure
		  option for this to be	available.

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

		  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 li-
		  brary	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 ar-
		  rive 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 | se-
		  lect_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  op-
		  tion.

		{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 op-
	      tion {socket, linger}.

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

	      Corresponds to the C struct timeval. The field  sec  holds  sec-
	      onds, 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	multi-
	      cast 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	 plat-
	      form.

       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 documenta-
	      tion for sendmsg(2).

		addr:
		   Optional peer address, used on unconnected sockets.	Corre-
		  sponds  to  msg_name	and msg_namelen	fields of a struct ms-
		  ghdr.	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  ms-
		  ghdr.	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 documenta-
	      tion for recvmsg(2).

		addr:
		   Optional peer address, used on unconnected sockets.	Corre-
		  sponds  to  msg_name	and msg_namelen	fields of a struct ms-
		  ghdr.	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).	Corre-
		  sponds 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	inter-
	      face.

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

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

	      Types:

		 ListenSocket =	Socket = socket()
		 Reason	=
		     posix() |
		     closed |
		     invalid() |
		     {create_accept_socket, posix()} |
		     {add_socket, posix()} |
		     {update_accept_context, posix()}

	      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 |
		     {create_accept_socket, posix()} |
		     {add_socket, posix()} |
		     {update_accept_context, posix()}

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

	  Note:
	      On unix, 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 (ac-
	      cept-) call has been made	(the first call	is automatically "can-
	      celled" 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} |
		 {completion, CompletionInfo} |
		 {error, Reason}

       accept(ListenSocket,
	      Handle ::	select_handle()	| completion_handle()) ->
		 {ok, Socket} |
		 {select, SelectInfo} |
		 {completion, CompletionInfo} |
		 {error, Reason}

	      Types:

		 ListenSocket =	Socket = socket()
		 SelectInfo = select_info()
		 CompletionInfo	= completion_info()
		 Reason	=
		     posix() |
		     closed |
		     invalid() |
		     {create_accept_socket, posix()} |
		     {add_socket, posix()} |
		     {update_accept_context, posix()}

	      The same as accept/1 but returns promptly.

	      When there is no pending connection to return, the function will
	      return (on Unix )	{select, SelectInfo} or	(on Windows ) {comple-
	      tion, CompletionInfo}, and the caller will later receive	either
	      one  of  these  messages	(depending  on	the platform) when the
	      client connects:

		select message:
		  {'$socket', Socket, select, SelectHandle} (with  the	Selec-
		  tHandle contained in the SelectInfo).

		  A subsequent call to accept/1,2 will then return the socket.

		completion message:
		  {'$socket',  Socket,	completion, {CompletionHandle, Comple-
		  tionStatus}} (with the  CompletionHandle  contained  in  the
		  CompletionInfo).

		  The result of	the accept will	be in the CompletionStatus.

	      If  the  time-out	 argument  is a	Handle,	that term will be con-
	      tained in	a returned SelectInfo or CompletionInfo	and the	corre-
	      sponding select or completion message. The Handle	is presumed to
	      be unique	to this	call.

	      If the time-out argument is nowait:

		On Unix	:
		  And a	SelectInfo is returned,	it will	contain	a  select_han-
		  dle()	generated by the call.

		On Windows :
		  And  a CompletionInfo	is returned, it	will contain a comple-
		  tion_handle()	generated by the call.

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

	  Note:
	      On unix, 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 (ac-
	      cept-) call has been made	(the first call	is automatically "can-
	      celled" 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 (select) 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, Select-
	      Info}}.

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

	      Types:

		 Socket	= socket()
		 CompletionInfo	= completion_info()
		 Reason	= closed | invalid()

	      Cancel an	asynchronous (completion) 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 CompletionInfo	does not match an operation  in	 progress  for
	      the  calling  process,  this  function returns {error, {invalid,
	      CompletionInfo}}.

       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 | not_bound |
		     {add_socket, posix()} |
		     {update_connect_context, posix()}

	      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.

	  Note:
	      On Windows  the socket has to be bound.

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

	      Types:

		 Socket	= socket()
		 SockAddr = sockaddr()
		 Reason	=
		     posix() |
		     closed |
		     invalid() |
		     already | not_bound | timeout |
		     {add_socket, posix()} |
		     {update_connect_context, posix()}

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

	  Note:
	      On Windows  the socket has to be bound.

	      Note that	when this call has returned {error, timeout} the  con-
	      nection  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 connec-
	      tion 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} |
		  {completion, CompletionInfo} |
		  {error, Reason}

       connect(Socket, SockAddr,
	       Handle :: select_handle() | completion_handle())	->
		  ok |
		  {select, SelectInfo} |
		  {completion, CompletionInfo} |
		  {error, Reason}

	      Types:

		 Socket	= socket()
		 SockAddr = sockaddr()
		 SelectInfo = select_info()
		 CompletionInfo	= completion_info()
		 Reason	=
		     posix() |
		     closed |
		     invalid() |
		     already | not_bound |
		     {add_socket, posix()} |
		     {update_connect_context, posix()}

	      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,  Se-
	      lectHandle}  ( 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 con-
	      tained  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  re-
	      turned, it will contain a	select_handle()	generated by the call.

	      If  the  caller  doesn't want to wait for	the connection to com-
	      plete, it	must immediately call cancel/2 to  cancel  the	opera-
	      tion.

	  Note:
	      On Windows  the socket has to be bound.

       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.

	  Note:
	      Not used on Windows .

       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 mon-
		  itor 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 op-
	      tions 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 implementa-
	      tion  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 (do-
	      main(), 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 plat-
	      forms. 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_op-
	      tion()  tuple,  with  a known Level = level() and	an integer Na-
	      tiveOpt, 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  bi-
	      nary().

	      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 (do-
	      main(), 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  in-
	      formation	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 for-
	      mat 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 for-
	      mat 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 for-
	      mat 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	:: gifconf) ->
		{ok, IFConf :: [#{name := string, addr := sockaddr()}]}	|
		{error,	Reason}

       ioctl(Socket, GetRequest	:: nread | nwrite | nspace) ->
		{ok, NumBytes :: integer() >= 0} | {error, Reason}

       ioctl(Socket, GetRequest	:: atmark) ->
		{ok, Available :: boolean()} | {error, Reason}

       ioctl(Socket, GetRequest	:: tcp_info) ->
		{ok, Info :: map()} | {error, Reason}

	      Types:

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

	      Retrieve socket (device) parameters.

	      This  function  retrieves	a specific parameter, according	to Ge-
	      tRequest argument.

		gifconf:
		  Return a list	of interface (transport	layer) addresses.

		  Result, a list of interfaces,	map with name and address.

		nread:
		  Get the number of bytes that are immediately	available  for
		  reading.

		  Result, number of bytes, is a	integer().

		nwrite:
		  The number of	bytes in the send queue.

		  Result, number of bytes, is a	integer().

		nspace:
		  Get the free space in	the send queue.

		  Result, number of bytes, is a	integer().

		atmark:
		  Test if there	is oob (out-of-bound) data waiting to be read.

		  Result is a boolean().

		tcp_info:
		  Return miscellaneous TCP related information for a connected
		  socket.

		  Result is a map().

	  Note:
	      To see if	a ioctl	request	is supported on	the current platform:

		       Request = nread,
		       {ok, true} = socket:is_supported(ioctl_requests,	Request),
		       .
		       .
		       .

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

	      Types:

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

	      Retrieve socket (device) parameters.

	      This  function  retrieves	a specific parameter, according	to Ge-
	      tRequest argument. The third argument is a the  (lookup)	"key",
	      identifying the interface	(usually the name of the interface) or
	      a	command	to set.

		gifname:
		  Get  the name	of the interface with the specified index (in-
		  teger()).

		  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	speci-
		  fied 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:sock-
		  addr().

		gifhwaddr:
		  Get  the  hardware address for the interface with the	speci-
		  fied name.

		  Result, hardware address of the interface, is	a socket:sock-
		  addr(). 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 inte-
		  ger().

		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, Value)	-> ok |	{error,	Reason}

	      Types:

		 Socket	= socket()
		 SetRequest = rcvall
		 Value = off | on | iplevel
		 Reason	= posix() | closed

	      Set socket (device) parameters.

	      This function sets a specific parameter, according to SetRequest
	      argument.	The third argument is the value	to set.

		rcvall:
		  Enables (or disables)	a socket to receive all	IPv4  or  IPv6
		  packages passing through a network interface.

		  The socket has to be either one of:

		  An IPv4 socket:
		    Created  with  the	address	family of inet,	socket type of
		    raw	and protocol set to ip.

		  An IPv6 socket:
		    Created with the address family of inet6, socket  type  of
		    raw	and protocol set to ipv6.

		  The socket must also be bound	to an (explicit) local IPv4 or
		  IPv6 interface (any not allowed).

		  Setting this IOCTL requires admin privileges.

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

	      Types:

		 Socket	= socket()
		 SetRequest = rcvall_igmpmcast | rcvall_mcast
		 Value = off | on
		 Reason	= posix() | closed

	      Set socket (device) parameters.

	      This function sets a specific parameter, according to SetRequest
	      argument.	The third argument is the value	to set.

		rcvall_igmpmcall:
		  Enables  (or disables) a socket to receive IGMP multicast IP
		  traffic, without receiving any other IP traffic.

		  The socket has to be created	with  the  address  family  of
		  inet,	socket type of raw and protocol	set to igmp.

		  The  socket must also	be bound to an (explicit) local	inter-
		  face (any not	allowed).

		  Must have a sufficiently large buffer.

		  Setting this IOCTL requires admin privileges.

		rcvall_mcall:
		  Enables (or disables)	a socket to receive all	 multicast  IP
		  traffic  (as in; all IP packets destined for IP addresses in
		  the range of 224.0.0.0 to 239.255.255.255).

		  The socket has to be created	with  the  address  family  of
		  inet,	socket type of raw and protocol	set to udp.

		  The  socket must also	be bound to an (explicit) local	inter-
		  face (any not	allowed). And bind to port zero

		  Must have a sufficiently large buffer.

		  Setting this IOCTL requires admin privileges.

       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 spec-
		  ified	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  in-
		  terface 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 sup-
	      ports, 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 sup-
	      ports/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.

	  Note:
	      On Windows  the socket has to be bound.

       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 pat-
	      tern:

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

	      In the monitor message MonitorRef	and Type are the same  as  de-
	      scribed 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  cre-
		  ation).

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

       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 al-
	      ready existing file descriptor. The  function  attempts  to  re-
	      trieve  domain,  type and	protocol from the system. This is how-
	      ever 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  pro-
		  tocol	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 plat-
	      form'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 pro-
	      tocol, 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	manda-
		  tory to not select a protocol, that is; to  select  the  de-
		  fault	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, Rea-
	      son}, 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  millisec-
	      onds 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, Handle :: nowait) ->
	       {ok, Data} |
	       {select,	SelectInfo} |
	       {select,	{SelectInfo, Data}} |
	       {completion, CompletionInfo} |
	       {error, Reason} |
	       {error, {Reason,	Data}}

       recv(Socket, Flags,
	    Handle :: select_handle() |	completion_handle()) ->
	       {ok, Data} |
	       {select,	SelectInfo} |
	       {select,	{SelectInfo, Data}} |
	       {completion, CompletionInfo} |
	       {error, Reason} |
	       {error, {Reason,	Data}}

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

       recv(Socket, Length,
	    Handle :: select_handle() |	completion_handle()) ->
	       {ok, Data} |
	       {select,	SelectInfo} |
	       {select,	{SelectInfo, Data}} |
	       {completion, CompletionInfo} |
	       {error, Reason} |
	       {error, {Reason,	Data}}

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

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

	      Types:

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

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

	      The  same	as  infinite time-out recv/1,2,3,4 but if the data can
	      be delivered immediately,	the function returns (on Unix  )  {se-
	      lect, SelectInfo}	or (on Windows ) {completion, CompletionInfo},
	      and the caller will then receive one of these messages:

		select message:
		  {'$socket',  Socket,	select,	SelectHandle} (with the	Selec-
		  tHandle that was contained in	the SelectInfo)	when data  has
		  arrived.

		  A subsequent call to recv/1,2,3,4 will then return the data.

		completion message:
		  {'$socket',  Socket,	completion, {CompletionHandle, Comple-
		  tionStatus}} (with the  CompletionHandle  contained  in  the
		  CompletionInfo).

		  The result of	the receive will be in the CompletionStatus.

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

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

	      Note that	for a socket of	type stream (on	Unix ),	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 mil-
	      liseconds	for it to arrive.

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

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

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

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

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

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

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

	      Types:

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

	      Receives a message from a	socket,	but returns a select continua-
	      tion or a	completion term	if no message could be returned	 imme-
	      diately.

	      The  same	 as  infinite time-out recvfrom/1,2,3,4	but if no mes-
	      sage can be delivered  immediately,  the	function  returns  (on
	      /Unix  ) {select,	SelectInfo} or (on Windows ) {completion, Com-
	      pletionInfo}, and	the caller will	then receive one of these mes-
	      sages:

		select message:
		  {'$socket', Socket, select, SelectHandle} (with  the	Selec-
		  tHandle  that	was contained in the SelectInfo) when data has
		  arrived.

		  A subsequent call to recvfrom/1,2,3,4	will then  return  the
		  message.

		completion message:
		  {'$socket',  Socket,	completion, {CompletionHandle, Comple-
		  tionStatus}} (with the  CompletionHandle  contained  in  the
		  CompletionInfo).

		  The result of	the receive will be in the CompletionStatus.

	      If  the Handle is	a select_handle() or completion_handle(), that
	      term will	be contained in	a returned SelectInfo  or  Completion-
	      Info  and	 the corresponding (select or completion) message. The
	      Handle is	presumed to be unique to this call.

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

	      If the caller doesn't want to wait for the data, it must immedi-
	      ately 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 num-
	      ber  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,recvc-
	      trlbuf}, 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 mil-
	      liseconds	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} |
		  {completion, CompletionInfo} |
		  {error, Reason}

       recvmsg(Socket, Handle :: select_handle() | completion_handle())	->
		  {ok, Msg} |
		  {select, SelectInfo} |
		  {completion, CompletionInfo} |
		  {error, Reason}

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

       recvmsg(Socket, Flags,
	       Handle :: select_handle() | completion_handle())	->
		  {ok, Msg} |
		  {select, SelectInfo} |
		  {completion, CompletionInfo} |
		  {error, Reason}

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

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

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

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

	      Types:

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

	      Receives a message from a	socket,	but returns a select continua-
	      tion or a	completion term	if no message could be returned	 imme-
	      diately.

	      The same as  infinite time-out recvmsg/1,2,3,4 but if no message
	      can  delivered immediately, the function returns (on Unix	) {se-
	      lect, SelectInfo}	or (on Windows ) {completion, CompletionInfo},
	      and the caller will then receive one of these messages:

		select message:
		  {'$socket', Socket, select, SelectHandle} (with  the	Selec-
		  tHandle  that	was contained in the SelectInfo) when data has
		  arrived.

		  A subsequent call to recvmsg/1,2,3,4,5 will then return  the
		  data.

		completion message:
		  {'$socket',  Socket,	completion, {CompletionHandle, Comple-
		  tionStatus}} (with the  CompletionHandle  contained  in  the
		  CompletionInfo).

		  The result of	the receive will be in the CompletionStatus.

	      If  the Handle is	a select_handle() or completion_handle(), that
	      term will	be contained in	a returned SelectInfo  or  Completion-
	      Info  and	 the corresponding (select or completion) message. The
	      Handle is	presumed to be unique to this call.

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

	      If the caller doesn't want to wait for the data, it must immedi-
	      ately 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() |
		     netname_deleted | too_many_cmds |
		     eei()

	      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 re-
	      quired. A	returned RestData is a sub binary of this data binary.

	      The  return  value indicates the result from the platform's net-
	      work layer:

		ok:
		  All data has been accepted.

		{ok, RestData}:
		  Not all data has been	accepted, but no error	has  been  re-
		  ported.  RestData  is	the tail of Data that has not been ac-
		  cepted.

		  This cannot happen for a socket of type stream where a  par-
		  tially  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 argu-
		  ment 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 par-
		  tially 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() |
		     netname_deleted | too_many_cmds |
		     eei()

	      Sends data on a connected	socket,	waiting	at most	 Timeout  mil-
	      liseconds	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 millisec-
	      onds, if no Data or only some of it was accepted	by  the	 plat-
	      form's network layer.

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

       send(Socket, Data,
	    Handle :: select_handle() |	completion_handle()) ->
	       ok |
	       {ok, RestData} |
	       {select,	SelectInfo} |
	       {select,	{SelectInfo, RestData}}	|
	       {completion, CompletionInfo} |
	       {error, Reason}

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

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

	      Types:

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

	      Sends  data  on  a connected socket, but returns completion or 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  (on  Unix ) {select, SelectInfo}	or (on Windows ) {com-
	      pletion, CompletionInfo},	and the	caller will then  receive  one
	      of these messages:

		select message:
		  {'$socket',  Socket, select, SelectHandle} ( with the	Selec-
		  tHandle 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.

		completion message:
		  {'$socket', Socket, completion,  {CompletionHandle,  Comple-
		  tionStatus}}	(with  the  CompletionHandle  contained	in the
		  CompletionInfo).

		  The result of	the send will be in the	CompletionStatus.

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

	      If  Handle  is nowait, and a SelectInfo or CompletionInfo	is re-
	      turned, it will contain a	select_handle()	or completion_handle()
	      generated	by the call.

	      If some of the data was sent, the	function will return  {select,
	      {RestData, SelectInfo},  which can only happen (on Unix )	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  op-
	      eration 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 op-
	      eration  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  net-
	      work 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 con-
	      nected, 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 net-
	      work layer. See send/2,3,4.

	  Note:
	      On Windows, this function	can only be used with datagram and raw
	      sockets.

       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  millisec-
	      onds 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 millisec-
	      onds,  if	 no  data or only some of it was accepted by the plat-
	      form's network layer.

	  Note:
	      On Windows, this function	can only be used with datagram and raw
	      sockets.

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

       sendmsg(Socket, Msg,
	       Handle :: select_handle() | completion_handle())	->
		  ok |
		  {ok, RestData} |
		  {select, SelectInfo} |
		  {select, {SelectInfo,	RestData}} |
		  {completion, CompletionInfo} |
		  {error, Reason} |
		  {error, {Reason, RestData}}

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

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

	      Types:

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

	      Sends a message on a socket, but returns completion or 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	(on Unix ) {select, SelectInfo}	or (on Windows
	      )	{completion, CompletionInfo}, and the caller will then receive
	      one of these messages:

		select message:
		  {'$socket', Socket, select, SelectHandle} ( with the	Selec-
		  tHandle 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.

		completion message:
		  {'$socket', Socket, completion,  {CompletionHandle,  Comple-
		  tionStatus}}	(with  the  CompletionHandle  contained	in the
		  CompletionInfo).

		  The result of	the send will be in the	CompletionStatus.

	      If Handle, is a  select_handle()	or  completion_handle(),  that
	      term  will  be contained in a returned SelectInfo	or Completion-
	      Info and the corresponding select	 or  completion	 message.  The
	      Handle is	presumed to be unique to this call.

	      If  Timeout is nowait, and a SelectInfo or CompletionInfo	is re-
	      turned, it will contain a	select_handle()	or completion_handle()
	      generated	by the call.

	      If some of the data was sent, the	function will return  {select,
	      {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.

	  Note:
	      On Windows, this function	can only be used with datagram and raw
	      sockets.

       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, Timeout :: nowait) ->
		  ok |
		  {ok, RestData} |
		  {select, SelectInfo} |
		  {select, {SelectInfo,	RestData}} |
		  {completion, CompletionInfo} |
		  {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 op-
	      eration  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 respec-
	      tively.

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

	      The  return  value indicates the result from the platform's net-
	      work 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  con-
	      nected 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  net-
	      work 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 millisec-
	      onds, if no Data or only some of it was accepted	by  the	 plat-
	      form's network layer.

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

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

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

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

	      Types:

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

	      Sends  data on a socket, but returns completion or a select con-
	      tinuation	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 (on Unix ) {select, SelectInfo} or (on Windows  )	 {com-
	      pletion,	CompletionInfo},  and the caller will then receive one
	      of these messages:

		select message:
		  {'$socket', Socket, select, SelectHandle} ( with the	Selec-
		  tHandle 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.

		completion message:
		  {'$socket',  Socket,	completion, {CompletionHandle, Comple-
		  tionStatus}} (with the  CompletionHandle  contained  in  the
		  CompletionInfo).

		  The result of	the send will be in the	CompletionStatus.

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

	      If Handle	is nowait, and a SelectInfo or CompletionInfo  is  re-
	      turned, it will contain a	select_handle()	or completion_handle()
	      generated	by the call.

	      If some of the data was sent, the	function will return  {select,
	      {RestData,  SelectInfo},	which can only happen (on Unix ) 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 op-
	      eration 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  net-
	      work 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, wait-
	      ing 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 File-
	      Handle 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 net-
	      work 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 argu-
		  ment is invalid.

		  {error, {Reason, BytesSent}} : An error  has	been  reported
		  but  before that some	data was transferred. See {error, Rea-
		  son} 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  millisec-
	      onds 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  mil-
	      liseconds,  if  not  all	file data was transferred by the plat-
	      form'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,	Selec-
	      tHandle}	(  with	the SelectHandle that was contained in the Se-
	      lectInfo ) 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  con-
	      tained  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 op-
	      eration 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	opera-
	      tion  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 send-
	      file() call.

	      The  return  value indicates the result from the platform's net-
	      work 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,	infin-
	      ity),    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,	Selec-
	      tHandle),	   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  op-
	      tions 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 (do-
	      main(), 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	 plat-
	      forms. 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 bi-
	      nary() its content and size will be used as the option value.

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

	      What options are valid depends on	what kind of socket it is (do-
	      main(), 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 sup-
		  ported 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()  indicat-
		  ing if the socket option is supported	on this	platform.

		  supports(options  =  Key1, Key2) : For a Key2	in level() re-
		  turns	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).

Ericsson AB			  kernel 9.2			     socket(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=socket&sektion=3&manpath=FreeBSD+Ports+15.0.quarterly>

home | help