<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY rest "<varname>&amp;rest</varname>">
<!ENTITY key "<varname>&amp;key</varname>">
<!ENTITY optional "<varname>&amp;optional</varname>">
<!ENTITY body "<varname>&amp;body</varname>">
<!ENTITY aux "<varname>&amp;aux</varname>">
<!ENTITY allow-other-keys "<varname>&amp;allow-other-keys</varname>">
<!ENTITY CCL "Clozure CL">
]>

  <chapter id="Programming-with-Sockets">
    <title>Programming with Sockets</title>

    <sect1 id="Sockets-Overview">
      <title>Overview</title>

      <para>&CCL; supports the socket abstraction for
      interprocess communication. A socket represents a connection to
      another process, typically (but not necessarily) a TCP/IP
      network connection to a client or server running on some other
      machine on the network.</para>
      <para>All symbols mentioned in this chapter are exported from
      the CCL package. As of version 0.13, these symbols are
      additionally exported from the OPENMCL-SOCKET package.</para>
      <para>&CCL; supports three types of sockets: TCP sockets, UDP
      sockets, and Unix-domain sockets.  This should be enough for all
      but the most esoteric network situations.  All sockets are
      created by <xref linkend="f_make-socket"/>.  The type of socket
      depends on the arguments to it, as follows:</para>

      <variablelist>
	<varlistentry>
	  <term>tcp-stream</term>

	  <listitem>
	    <para>A buffered bi-directional stream over a TCP/IP connection.
	    tcp-stream is a subclass of stream, and you can read and write to it
	    using all the usual stream functions. Created by (make-socket
	    :address-family :internet :type :stream :connect :active ...) or by
	    (accept-connection ...).</para>
	  </listitem>
	</varlistentry>

	<varlistentry>
	  <term>file-socket-stream</term>

	  <listitem>
	    <para>A buffered bi-directional stream over a &#34;UNIX domain&#34;
	    connection. file-socket-stream is a subclass of stream, and you can
	    read and write to it using all the usual stream functions. Created
	    by (make-socket :address-family :file :type :stream :connect :active
	    ...) or by (accept-connection ...),</para>
	  </listitem>
	</varlistentry>

	<varlistentry>
	  <term>listener-socket</term>

	  <listitem>
	    <para>A passive socket used to listen for incoming TCP/IP
	    connections on a particular port. A listener-socket is not a stream.
	    It doesn&#39;t support I/O. It can only be used to create new
	    tcp-streams by accept-connection. Created by (make-socket :type
	    :stream :connect :passive ...)</para>
	  </listitem>
	</varlistentry>

	<varlistentry>
	  <term>file-listener-socket</term>

	  <listitem>
	    <para>A passive socket used to listen for incoming UNIX domain
	    connections named by a file in the local filesystem. A
	    listener-socket is not a stream. It doesn&#39;t support I/O. It can
	    only be used to create new file-socket-streams by accept-connection.
	    Created by (make-socket :address-family :file :type :stream :connect
	    :passive ...)</para>
	  </listitem>
	</varlistentry>

	<varlistentry>
	  <term>udp-socket</term>

	  <listitem>
	    <para>A socket representing a packet-based UDP/IP connection. A
	    udp-socket supports I/O but it is not a stream. Instead, you must
	    use the special functions send-to and receive-from to read and write
	    to it. Created by (make-socket :type :datagram ...)</para>
	  </listitem>
	</varlistentry>
      </variablelist>
    </sect1>

    <sect1 id="Sockets-Dictionary">
      <title>Sockets Dictionary</title>
      <refentry id="f_make-socket">
	<indexterm zone="f_make-socket">
	  <primary>make-socket</primary>
	</indexterm>
	<refnamediv>
	  <refname>MAKE-SOCKET</refname>
	  <refpurpose></refpurpose>
	  <refclass>Function</refclass>
	</refnamediv>

	<refsynopsisdiv>
	  <synopsis><function>make-socket</function> &key;
	  address-family type connect eol format remote-host
	  remote-port local-host local-port local-filename
	  remote-filename keepalive reuse-address nodelay broadcast
	  linger backlog input-timeout output-timeout connect-timeout
	  auto-close deadline</synopsis>
	</refsynopsisdiv>

	<refsect1>
	  <title>Arguments and Values</title>

	  <variablelist>
	    <varlistentry>
	      <term>address-family</term>

	      <listitem>
		<para>The address/protocol family of this socket. Currently
		only :internet (the default), meaning IP, and :file,
		referring to UNIX domain addresses, are supported.</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>type</term>

	      <listitem>
		<para>One of :stream (the default) to request a
		connection-oriented socket, or :datagram to request a
		connectionless socket. The default is :stream.</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>connect</term>

	      <listitem>
		<para>This argument is only relevant to sockets of type
		:stream. One of :active (the default) to request a :passive
		to request a file or TCP listener socket.</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>eol</term>

	      <listitem>
		<para>This argument is currently ignored (it is accepted for
		compatibility with Franz Allegro).</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>format</term>

	      <listitem>
		<para>One of :text (the default), :binary, or :bivalent.
		This argument is ignored for :stream sockets for now, as
		:stream sockets are currently always bivalent (i.e. they
		support both character and byte I/O). For :datagram sockets,
		this argument is ignored (the format of a datagram socket
		is always :binary).
		</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>remote-host</term>

	      <listitem>
		<para>Required for TCP streams, it specifies the host to
		connect to (in any format acceptable to lookup-hostname).
		Ignored for listener sockets. For UDP sockets, it can be
		used to specify a default host for subsequent calls to
		send-to or receive-from.</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>remote-port</term>

	      <listitem>
		<para>Required for TCP streams, it specifies the port to
		connect to (in any format acceptable to lookup-port).
		Ignored for listener sockets. For UDP sockets, it can be
		used to specify a default port for subsequent calls to for
		subsequent calls to send-to or receive-from.</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>remote-filename</term>

	      <listitem>
		<para>Required for file-socket streams, it specifies the
		name of a file in the local filesystem (e.g., NOT mounted
		via NFS, AFP, SMB, ...) which names and controls access to a
		UNIX-domain socket.</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>local-host</term>

	      <listitem>
		<para>Allows you to specify a local host address for a
		listener or UDP socket, for the rare case where you want to
		restrict connections to those coming to a specific local
		address for security reasons.</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>local-port</term>

	      <listitem>
		<para>Specify a local port for a socket. Most useful for
		listener sockets, where it is the port on which the socket
		will listen for connections.</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>local-filename</term>

	      <listitem>
		<para>Required for file-listener-sockets. Specifies the name
		of a file in the local filesystem which is used to name a
		UNIX-domain socket. The actual filesystem file should not
		previously exist when the file-listener-socket is created;
		its parent directory should exist and be writable by the
		caller. The file used to name the socket will be deleted
		when the file-listener-socket is closed.</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>keepalive</term>

	      <listitem>
		<para>If true, enables the periodic transmission of
		&#34;keepalive&#34; messages.</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>reuse-address</term>

	      <listitem>
		<para>If true, allows the reuse of local ports in listener
		sockets, overriding some TCP/IP protocol specifications. You
		will need this if you are debugging a server..</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>nodelay</term>

	      <listitem>
		<para>If true, disables Nagle&#39;s algorithm, which tries
		to minimize TCP packet fragmentation by introducing
		transmission delays in the absence of replies. Try setting
		this if you are using a protocol which involves sending a
		steady stream of data with no replies and are seeing
		significant degradations in throughput.</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>broadcast</term>

	      <listitem>
		<para>If true, requests permission to broadcast datagrams on
		a UDP socket.</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>linger</term>

	      <listitem>
		<para>If specified and non-nil, should be the number of
		seconds the OS is allowed to wait for data to be pushed
		through when a close is done. Only relevant for TCP sockets.</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>backlog</term>

	      <listitem>
		<para>For a listener socket, specifies the number of
		connections which can be pending but not accepted. The
		default is 5, which is also the maximum on some operating
		systems.</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>input-timeout</term>

	      <listitem>
		<para>The number of seconds before an input operation
		times out.  Must be a real number between zero and one
		million.  If an input operation takes longer than the
		specified number of seconds, an
		<literal>input-timeout</literal> error is signalled.
		(see <xref
		linkend="Stream-Timeouts-And-Deadlines"/>)</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>output-timeout</term>

	      <listitem>
		<para>The number of seconds before an output operation
		times out.  Must be a real number between zero and one
		million.  If an output operation takes longer than the
		specified number of seconds, an
		<literal>output-timeout</literal> error is signalled.
		(see <xref
		linkend="Stream-Timeouts-And-Deadlines"/>)</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>connect-timeout</term>

	      <listitem>
		<para>The number of seconds before a connection
		attempt times out. [TODO: what are acceptable values?]
		If a connection attempt takes longer than the
		specified number of seconds, a
		<literal>socket-error</literal> is signalled.  This
		can be useful if the specified interval is shorter
		than the interval that the OS's socket layer imposes,
		which is sometimes a minute or two.</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>auto-close</term>

	      <listitem>
		<para>When non-nil, any resulting socket stream will
		be closed when the GC can prove that the stream is
		unreferenced.  This is done via CCL's termination
		mechanism [TODO add xref].</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term>deadline</term>

	      <listitem>
		<para>Specifies an absolute time in
		internal-time-units.  If an I/O operation on the
		stream does not complete before the deadline then a
		<literal>COMMUNICATION-DEADLINE-EXPIRED</literal>
		error is signalled.  A deadline takes precedence over
		any input/output timeouts that may be set.  (see <xref
		linkend="Stream-Timeouts-And-Deadlines"/>)</para>
	      </listitem>
	    </varlistentry>

	  </variablelist>
	</refsect1>

	<refsect1>
	  <title>Description</title>

	  <para>Creates and returns a new socket</para>
	</refsect1>
      </refentry>

      <refentry id="f_accept-connection">
	<indexterm zone="f_accept-connection">
	  <primary>accept-connection</primary>
	</indexterm>
	<refnamediv>
	  <refname>ACCEPT-CONNECTION</refname>
	  <refpurpose></refpurpose>
	  <refclass>Function</refclass>
	</refnamediv>

	<refsynopsisdiv>
	  <synopsis><function>accept-connection</function>
	  (socket listener-socket) &key; wait</synopsis>
	</refsynopsisdiv>

	<refsect1>
	  <title>Arguments and Values</title>

	  <variablelist>
	    <varlistentry>
	      <term>socket</term>

	      <listitem>
		<para>The listener-socket to listen on.</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>wait</term>

	      <listitem>
		<para>If true (the default), and there are no connections
		waiting to be accepted, waits until one arrives. If false,
		returns NIL immediately.</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</refsect1>

	<refsect1>
	  <title>Description</title>

	  <para>Extracts the first connection on the queue of pending
	  connections, accepts it (i.e. completes the connection startup
	  protocol) and returns a new tcp-stream or file-socket-stream
	  representing the newly established connection. The tcp stream
	  inherits any properties of the listener socket that are relevant
	  (e.g. :keepalive, :nodelay, etc.) The original listener socket
	  continues to be open listening for more connections, so you can
	  call accept-connection on it again.</para>
	</refsect1>
      </refentry>

      <refentry id="f_dotted-to-ipaddr">
	<indexterm zone="f_dotted-to-ipaddr">
	  <primary>dotted-to-ipaddr</primary>
	</indexterm>
	<refnamediv>
	  <refname>DOTTED-TO-IPADDR</refname>
	  <refpurpose></refpurpose>
	  <refclass>Function</refclass>
	</refnamediv>

	<refsynopsisdiv>
	  <synopsis><function>dotted-to-ipaddr</function>
	  dotted &key; errorp</synopsis>
	</refsynopsisdiv>

	<refsect1>
	  <title>Arguments and Values</title>

	  <variablelist>
	    <varlistentry>
	      <term>dotted</term>

	      <listitem>
		<para>A string representing an IP address in the
		&#34;nn.nn.nn.nn&#34; format</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>errorp</term>

	      <listitem>
		<para>If true (the default) an error is signaled if dotted
		is invalid. If false, NIL is returned.</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</refsect1>

	<refsect1>
	  <title>Description</title>

	  <para>Converts a dotted-string representation of a host address to
	  a 32-bit unsigned IP address.</para>
	</refsect1>
      </refentry>

      <refentry id="f_ipaddr-to-dotted">
	<indexterm zone="f_ipaddr-to-dotted">
	  <primary>ipaddr-to-dotted</primary>
	</indexterm>
	<refnamediv>
	  <refname>IPADDR-TO-DOTTED</refname>
	  <refpurpose></refpurpose>
	  <refclass>Function</refclass>
	</refnamediv>

	<refsynopsisdiv>
	  <synopsis><function>ipaddr-to-dotted</function>
	  ipaddr &key; values</synopsis>
	</refsynopsisdiv>

	<refsect1>
	  <title>Arguments and Values</title>

	  <variablelist>
	    <varlistentry>
	      <term>ipaddr</term>

	      <listitem>
		<para>A 32-bit integer representing an internet host address</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>values</term>

	      <listitem>
		<para>If false (the default), returns a string in the form
		&#34;nn.nn.nn.nn&#34;. If true, returns four values
		representing the four octets of the address as unsigned
		8-bit integers.</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</refsect1>

	<refsect1>
	  <title>Description</title>

	  <para>Converts a 32-bit unsigned IP address into octets.</para>
	</refsect1>
      </refentry>

      <refentry id="f_ipaddr-to-hostname">
	<indexterm zone="f_ipaddr-to-hostname">
	  <primary>ipaddr-to-hostname</primary>
	</indexterm>
	<refnamediv>
	  <refname>IPADDR-TO-HOSTNAME</refname>
	  <refpurpose></refpurpose>
	  <refclass>Function</refclass>
	</refnamediv>

	<refsynopsisdiv>
	  <synopsis><function>ipaddr-to-hostname</function>
	  ipaddr &key; ignore-cache</synopsis>
	</refsynopsisdiv>

	<refsect1>
	  <title>Arguments and Values</title>

	  <variablelist>
	    <varlistentry>
	      <term>ipaddr</term>

	      <listitem>
		<para>a 32-bit integer representing an internet host address</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>ignore-cache</term>

	      <listitem>
		<para>This argument is ignored (it is accepted for
		compatibility with Franz Allegro)</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</refsect1>

	<refsect1>
	  <title>Description</title>

	  <para>Converts a 32-bit unsigned IP address into a host name
	  string</para>
	</refsect1>
      </refentry>

      <refentry id="f_lookup-hostname">
	<indexterm zone="f_lookup-hostname">
	  <primary>lookup-hostname</primary>
	</indexterm>
	<refnamediv>
	  <refname>LOOKUP-HOSTNAME</refname>
	  <refpurpose></refpurpose>
	  <refclass>Function</refclass>
	</refnamediv>

	<refsynopsisdiv>
	  <synopsis><function>lookup-hostname</function>
	  host</synopsis>
	</refsynopsisdiv>

	<refsect1>
	  <title>Arguments and Values</title>

	  <variablelist>
	    <varlistentry>
	      <term>host</term>

	      <listitem>
		<para>Specifies the host. It can be either a host name
		string such as &#34;clozure.com&#34;, or a dotted address
		string such as &#34;192.168.0.1&#34;, or a 32-bit unsigned
		IP address such as 3232235521.</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</refsect1>

	<refsect1>
	  <title>Description</title>

	  <para>Converts a host spec in any of the acceptable formats into a
	  32-bit unsigned IP address</para>
	</refsect1>
      </refentry>

      <refentry id="f_lookup-port">
	<indexterm zone="f_lookup-port">
	  <primary>lookup-port</primary>
	</indexterm>
	<refnamediv>
	  <refname>LOOKUP-PORT</refname>
	  <refpurpose></refpurpose>
	  <refclass>Function</refclass>
	</refnamediv>

	<refsynopsisdiv>
	  <synopsis><function>lookup-port</function>
	  port protocol</synopsis>
	</refsynopsisdiv>

	<refsect1>
	  <title>Arguments and Values</title>

	  <variablelist>
	    <varlistentry>
	      <term>port</term>

	      <listitem>
		<para>Specifies the port. It can be either a string, such as
		&#34;http&#34; or a symbol, such as :http, or an unsigned
		port number. Note that a string is case-sensitive. A symbol
		is lowercased before lookup.</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>protocol</term>

	      <listitem>
		<para>Must be one of &#34;tcp&#34; or &#34;udp&#34;.</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</refsect1>

	<refsect1>
	  <title>Description</title>

	  <para>Finds the port number for the specified port and protocol</para>
	</refsect1>
      </refentry>

      <refentry id="f_receive-from">
	<indexterm zone="f_receive-from">
	  <primary>receive-from</primary>
	</indexterm>
	<refnamediv>
	  <refname>RECEIVE-FROM</refname>
	  <refpurpose></refpurpose>
	  <refclass>Function</refclass>
	</refnamediv>

	<refsynopsisdiv>
	  <synopsis><function>receive-from</function>
	  (socket udp-socket) size &key; buffer
	  extract offset</synopsis>
	</refsynopsisdiv>

	<refsect1>
	  <title>Arguments and Values</title>

	  <variablelist>
	    <varlistentry>
	      <term>socket</term>

	      <listitem>
		<para>The socket to read from</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>size</term>

	      <listitem>
		<para>Maximum number of bytes to read. If the packet is
		larger than this, any extra bytes are discarded.</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>buffer</term>

	      <listitem>
		<para>If specified, must be an octet vector
		which will be used to read in the data. If not specified, a
		new buffer will be created (of type determined by
		socket-format).</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>extract</term>

	      <listitem>
		<para>If true, the subsequence of the buffer corresponding
		only to the data read in is extracted and returned as the
		first value. If false (the default) the original buffer is
		returned even if it is only partially filled.</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>offset</term>

	      <listitem>
		<para>Specifies the start offset into the buffer at which
		data is to be stored. The default is 0.</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</refsect1>

	<refsect1>
	  <title>Description</title>

	  <para>Reads a UDP packet from a socket. If no packets are
	  available, waits for a packet to arrive. Returns four values:</para>

	  <orderedlist continuation="restarts" inheritnum="ignore">
	    <listitem>
	      <para>The buffer with the data</para>
	    </listitem>

	    <listitem>
	      <para>The number of bytes read</para>
	    </listitem>

	    <listitem>
	      <para>The 32-bit unsigned IP address of the sender of the data</para>
	    </listitem>

	    <listitem>
	      <para>The port number of the sender of the data</para>
	    </listitem>
	  </orderedlist>
	</refsect1>
      </refentry>

      <refentry id="f_send-to">
	<indexterm zone="f_send-to">
	  <primary>send-to</primary>
	</indexterm>
	<refnamediv>
	  <refname>SEND-TO</refname>
	  <refpurpose></refpurpose>
	  <refclass>Function</refclass>
	</refnamediv>

	<refsynopsisdiv>
	  <synopsis><function>send-to</function>
	  (socket udp-socket) buffer size &key; remote-host
	  remote-port offset</synopsis>
	</refsynopsisdiv>

	<refsect1>
	  <title>Arguments and Values</title>

	  <variablelist>
	    <varlistentry>
	      <term>socket</term>

	      <listitem>
		<para>The socket to write to</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>buffer</term>

	      <listitem>
		<para>A vector containing the data to send. It must be
		an octet vector.</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>size</term>

	      <listitem>
		<para>Number of octets to send</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>remote-host</term>

	      <listitem>
		<para>The host to send the packet to, in any format
		acceptable to lookup-hostname. The default is the remote
		host specified in the call to make-socket.</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>remote-port</term>

	      <listitem>
		<para>The port to send the packet to, in any format
		acceptable to lookup-port. The default is the remote port
		specified in the call to make-socket.</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>offset</term>

	      <listitem>
		<para>The offset in the buffer where the packet data starts</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</refsect1>

	<refsect1>
	  <title>Description</title>

	  <para>Send a UDP packet over a socket.</para>
	</refsect1>
      </refentry>

      <refentry id="f_shutdown">
	<indexterm zone="f_shutdown">
	  <primary>shutdown</primary>
	</indexterm>
	<refnamediv>
	  <refname>SHUTDOWN</refname>
	  <refpurpose></refpurpose>
	  <refclass>Function</refclass>
	</refnamediv>

	<refsynopsisdiv>
	  <synopsis><function>shutdown</function>
	  socket &key; direction</synopsis>
	</refsynopsisdiv>

	<refsect1>
	  <title>Arguments and Values</title>

	  <variablelist>
	    <varlistentry>
	      <term>socket</term>

	      <listitem>
		<para>The socket to shut down (typically a tcp-stream)</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>direction</term>

	      <listitem>
		<para>One of :input to disallow further input, or :output to
		disallow further output.</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</refsect1>

	<refsect1>
	  <title>Description</title>

	  <para>Shuts down part of a bidirectional connection. This is
	  useful if e.g. you need to read responses after sending an
	  end-of-file signal.</para>
	</refsect1>
      </refentry>

      <refentry id="f_socket-os-fd">
	<indexterm zone="f_socket-os-fd">
	  <primary>socket-os-fd</primary>
	</indexterm>
	<refnamediv>
	  <refname>SOCKET-OS-FD</refname>
	  <refpurpose></refpurpose>
	  <refclass>Function</refclass>
	</refnamediv>

	<refsynopsisdiv>
	  <synopsis><function>socket-os-fd</function>
	  socket</synopsis>
	</refsynopsisdiv>

	<refsect1>
	  <title>Arguments and Values</title>

	  <variablelist>
	    <varlistentry>
	      <term>socket</term>

	      <listitem>
		<para>The socket</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</refsect1>

	<refsect1>
	  <title>Description</title>

	  <para>Returns the native OS&#39;s representation of the socket, or
	  NIL if the socket is closed. On Unix, this is the Unix &#39;file
	  descriptor&#39;, a small non-negative integer. Note that it is
	  rather dangerous to mess around with tcp-stream fd&#39;s, as there
	  is all sorts of buffering and asynchronous I/O going on above the
	  OS level. listener-socket and udp-socket fd&#39;s are safer to
	  mess with directly as there is less magic going on.</para>
	</refsect1>
      </refentry>

      <refentry id="f_remote-host">
	<indexterm zone="f_remote-host">
	  <primary>remote-host</primary>
	</indexterm>
	<refnamediv>
	  <refname>REMOTE-HOST</refname>
	  <refpurpose></refpurpose>
	  <refclass>Function</refclass>
	</refnamediv>

	<refsynopsisdiv>
	  <synopsis><function>remote-host</function>
	  socket</synopsis>
	</refsynopsisdiv>

	<refsect1>
	  <title>Arguments and Values</title>

	  <variablelist>
	    <varlistentry>
	      <term>socket</term>

	      <listitem>
		<para>The socket</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</refsect1>

	<refsect1>
	  <title>Description</title>

	  <para>Returns the 32-bit unsigned IP address of the remote host,
	  or NIL if the socket is not connected.</para>
	</refsect1>
      </refentry>

      <refentry id="f_remote-port">
	<indexterm zone="f_remote-port">
	  <primary>remote-port</primary>
	</indexterm>
	<refnamediv>
	  <refname>REMOTE-PORT</refname>
	  <refpurpose></refpurpose>
	  <refclass>Function</refclass>
	</refnamediv>

	<refsynopsisdiv>
	  <synopsis><function>remote-port</function>
	  socket</synopsis>
	</refsynopsisdiv>

	<refsect1>
	  <title>Arguments and Values</title>

	  <variablelist>
	    <varlistentry>
	      <term>socket</term>

	      <listitem>
		<para>The socket</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</refsect1>

	<refsect1>
	  <title>Description</title>

	  <para>Returns the remote port number, or NIL if the socket is not
	  connected.</para>
	</refsect1>
      </refentry>

      <refentry id="f_local-host">
	<indexterm zone="f_local-host">
	  <primary>local-host</primary>
	</indexterm>
	<refnamediv>
	  <refname>LOCAL-HOST</refname>
	  <refpurpose></refpurpose>
	  <refclass>Function</refclass>
	</refnamediv>

	<refsynopsisdiv>
	  <synopsis><function>local-host</function>
	  socket</synopsis>
	</refsynopsisdiv>

	<refsect1>
	  <title>Arguments and Values</title>

	  <variablelist>
	    <varlistentry>
	      <term>socket</term>

	      <listitem>
		<para>The socket</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</refsect1>

	<refsect1>
	  <title>Description</title>

	  <para>Returns 32-bit unsigned IP address of the local host.</para>
	</refsect1>
      </refentry>

      <refentry id="f_local-port">
	<indexterm zone="f_local-port">
	  <primary>local-port</primary>
	</indexterm>
	<refnamediv>
	  <refname>LOCAL-PORT</refname>
	  <refpurpose></refpurpose>
	  <refclass>Function</refclass>
	</refnamediv>

	<refsynopsisdiv>
	  <synopsis><function>local-port</function>
	  socket</synopsis>
	</refsynopsisdiv>

	<refsect1>
	  <title>Arguments and Values</title>

	  <variablelist>
	    <varlistentry>
	      <term>socket</term>

	      <listitem>
		<para>The socket</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</refsect1>

	<refsect1>
	  <title>Description</title>

	  <para>Returns the local port number</para>
	</refsect1>
      </refentry>

      <refentry id="f_socket-address-family">
	<indexterm zone="f_socket-address-family">
	  <primary>socket-address-family</primary>
	</indexterm>
	<refnamediv>
	  <refname>SOCKET-ADDRESS-FAMILY</refname>
	  <refpurpose></refpurpose>
	  <refclass>Function</refclass>
	</refnamediv>

	<refsynopsisdiv>
	  <synopsis><function>socket-address-family</function>
	  socket</synopsis>
	</refsynopsisdiv>

	<refsect1>
	  <title>Arguments and Values</title>

	  <variablelist>
	    <varlistentry>
	      <term>socket</term>

	      <listitem>
		<para>The socket</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</refsect1>

	<refsect1>
	  <title>Description</title>

	  <para>Returns :internet or :file, as appropriate.</para>
	</refsect1>
      </refentry>

      <refentry id="f_socket-connect">
	<indexterm zone="f_socket-connect">
	  <primary>socket-connect</primary>
	</indexterm>
	<refnamediv>
	  <refname>SOCKET-CONNECT</refname>
	  <refpurpose></refpurpose>
	  <refclass>Function</refclass>
	</refnamediv>

	<refsynopsisdiv>
	  <synopsis><function>socket-connect</function>
	  socket</synopsis>
	</refsynopsisdiv>

	<refsect1>
	  <title>Arguments and Values</title>

	  <variablelist>
	    <varlistentry>
	      <term>socket</term>

	      <listitem>
		<para>The socket</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</refsect1>

	<refsect1>
	  <title>Description</title>

	  <para>Returns :active for tcp-stream, :passive for
	  listener-socket, and NIL for udp-socket</para>
	</refsect1>
      </refentry>

      <refentry id="f_socket-format">
	<indexterm zone="f_socket-format">
	  <primary>socket-format</primary>
	</indexterm>
	<refnamediv>
	  <refname>SOCKET-FORMAT</refname>
	  <refpurpose></refpurpose>
	  <refclass>Function</refclass>
	</refnamediv>

	<refsynopsisdiv>
	  <synopsis><function>socket-format</function>
	  socket</synopsis>
	</refsynopsisdiv>

	<refsect1>
	  <title>Arguments and Values</title>

	  <variablelist>
	    <varlistentry>
	      <term>socket</term>

	      <listitem>
		<para>The socket</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</refsect1>

	<refsect1>
	  <title>Description</title>

	  <para>Returns the socket format as specified by the :format
	  argument to make-socket.</para>
	</refsect1>
      </refentry>

      <refentry id="f_socket-type">
	<indexterm zone="f_socket-type">
	  <primary>socket-type</primary>
	</indexterm>
	<refnamediv>
	  <refname>SOCKET-TYPE</refname>
	  <refpurpose></refpurpose>
	  <refclass>Function</refclass>
	</refnamediv>

	<refsynopsisdiv>
	  <synopsis><function>socket-type</function>
	  socket</synopsis>
	</refsynopsisdiv>

	<refsect1>
	  <title>Arguments and Values</title>

	  <variablelist>
	    <varlistentry>
	      <term>socket</term>

	      <listitem>
		<para>The socket</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</refsect1>

	<refsect1>
	  <title>Description</title>

	  <para>returns :stream for tcp-stream and listener-socket, and
	  :datagram for udp-socket.</para>
	</refsect1>
      </refentry>

      <refentry id="c_socket-error">
	<indexterm zone="c_socket-error">
	  <primary>socket-error</primary>
	</indexterm>
	<refnamediv>
	  <refname>SOCKET-ERROR</refname>
	  <refpurpose></refpurpose>
	  <refclass>Class</refclass>
	</refnamediv>

	<refsect1>
	  <title>Description</title>

	  <para>The class of OS errors signaled by socket functions</para>
	</refsect1>

	<refsect1>
	  <title>Superclasses</title>

	  <para>simple-error</para>
	</refsect1>
      </refentry>

      <refentry id="f_socket-error-code">
	<indexterm zone="f_socket-error-code">
	  <primary>socket-error-code</primary>
	</indexterm>
	<refnamediv>
	  <refname>SOCKET-ERROR-CODE</refname>
	  <refpurpose></refpurpose>
	  <refclass>Function</refclass>
	</refnamediv>

	<refsynopsisdiv>
	  <synopsis><function>socket-error-code</function>
	  socket-error</synopsis>
	</refsynopsisdiv>

	<refsect1>
	  <title>Arguments and Values</title>

	  <variablelist>
	    <varlistentry>
	      <term>socket-error</term>

	      <listitem>
		<para>the condition</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</refsect1>

	<refsect1>
	  <title>Description</title>

	  <para>The OS error code of the error</para>
	</refsect1>
      </refentry>

      <refentry id="f_socket-error-identifier">
	<indexterm zone="f_socket-error-identifier">
	  <primary>socket-error-identifier</primary>
	</indexterm>
	<refnamediv>
	  <refname>SOCKET-ERROR-IDENTIFIER</refname>
	  <refpurpose></refpurpose>
	  <refclass>Function</refclass>
	</refnamediv>

	<refsynopsisdiv>
	  <synopsis><function>socket-error-identifier</function>
	  socket-error</synopsis>
	</refsynopsisdiv>

	<refsect1>
	  <title>Arguments and Values</title>

	  <variablelist>
	    <varlistentry>
	      <term>socket-error</term>

	      <listitem>
		<para>the condition</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</refsect1>

	<refsect1>
	  <title>Description</title>

	  <para>A symbol representing the error code in a more
	  OS-independent way.</para>

	  <para>One of: :address-in-use :connection-aborted :no-buffer-space
	  :connection-timed-out :connection-refused :host-unreachable
	  :host-down :network-down :address-not-available :network-reset
	  :connection-reset :shutdown :access-denied or :unknown.</para>
	</refsect1>
      </refentry>

      <refentry id="f_socket-error-situation">
	<indexterm zone="f_socket-error-situation">
	  <primary>socket-error-situation</primary>
	</indexterm>
	<refnamediv>
	  <refname>SOCKET-ERROR-SITUATION</refname>
	  <refpurpose></refpurpose>
	  <refclass>Function</refclass>
	</refnamediv>

	<refsynopsisdiv>
	  <synopsis><function>socket-error-situation</function>
	  socket-error</synopsis>
	</refsynopsisdiv>

	<refsect1>
	  <title>Arguments and Values</title>

	  <variablelist>
	    <varlistentry>
	      <term>socket-error</term>

	      <listitem>
		<para>the condition</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</refsect1>

	<refsect1>
	  <title>Description</title>

	  <para>A string describing the context where the error happened. On
	  Linux, this is the name of the system call which returned the
	  error.</para>
	</refsect1>
      </refentry>

      <refentry id="o_close">
	<indexterm zone="o_close">
	  <primary>close</primary>
	</indexterm>
	<refnamediv>
	  <refname>CLOSE</refname>
	  <refpurpose></refpurpose>
	  <refclass>Method</refclass>
	</refnamediv>

	<refsynopsisdiv>
	  <synopsis><function>close</function>
	  (socket socket) &key; abort</synopsis>
	</refsynopsisdiv>

	<refsect1>
	  <title>Arguments and Values</title>

	  <variablelist>
	    <varlistentry>
	      <term>socket</term>

	      <listitem>
		<para>The socket to close</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>abort</term>

	      <listitem>
		<para>If false (the default), closes the socket in an
		orderly fashion, finishing up any buffered pending I/O,
		before closing the connection. If true, aborts/ignores
		pending I/O. (For listener and udp sockets, this argument is
		effectively ignored since there is never any buffered I/O to
		clean up).</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</refsect1>

	<refsect1>
	  <title>Description</title>

	  <para>The close generic function can be applied to sockets. It
	  releases the operating system resources associated with the
	  socket.</para>
	</refsect1>
      </refentry>

      <refentry id="m_with-open-socket">
	<indexterm zone="m_with-open-socket">
	  <primary>with-open-socket</primary>
	</indexterm>
	<refnamediv>
	  <refname>WITH-OPEN-SOCKET</refname>
	  <refpurpose></refpurpose>
	  <refclass>Macro</refclass>
	</refnamediv>

	<refsynopsisdiv>
	  <synopsis><function>with-open-socket</function>
	  (var . make-socket-args) &body; body</synopsis>
	</refsynopsisdiv>

	<refsect1>
	  <title>Arguments and Values</title>

	  <variablelist>
	    <varlistentry>
	      <term>var</term>

	      <listitem>
		<para>variable to bind</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>make-socket-args</term>

	      <listitem>
		<para>arguments suitable for passing to make-socket</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>body</term>

	      <listitem>
		<para>body to execute</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</refsect1>

	<refsect1>
	  <title>Description</title>

	  <para>executes body with var bound to the result of applying
	  make-socket to make-socket-args. The socket gets closed on exit.</para>
	</refsect1>
      </refentry>
    </sect1>
  </chapter>
