* new feature: on platforms where "dladdr" is available foreign
function names now appear in backtraces. (based on Helmut Eller's
work for CMUCL)
+ * documentation: networking interface SB-BSD-SOCKETS' documentation
+ has been integrated into the user manual.
* bug fix: backtraces involving undefined functions or assembly
routines are more informative. (thanks to Brian Downing)
* bug fix: mutually referent alien structures now work correctly.
+++ /dev/null
-o/~ Hey Mr Tambourine Man, play some -*- Text -*- for me o/~
-
-A semi-sane sockets interface for SBCL. Usually also works in CMUCL,
-but is rarely actually tested there so may require some massaging.
-
-It is invoked through the SBCL contrib/ modules system:
- (require :asdf)
- (require :sb-bsd-sockets)
-
-It uses the regression tester from the CMU AI repository, in its
-incarnation as the SBCL contrib SB-RT. The tests themselves are in
-tests.lisp, and can be run using the Makefile target intended for the
-purpose, or by evaluating (sb-rt:do-tests). Note that one of the tests
-is an HTTP client that connects back to ww.telent.net; if this bothers
-your expectations of privacy, don't run it.
-
-There is an automatically generated API reference in
-api-reference.html which you can regenerate if you can figure out how
-doc.lisp works. You might find the examples in tests.lisp useful,
-too.
-
-Feedback, patches, development versions
-
-Instructions on how to access the CVS repository for db-sockets are
-at http://cvs.telent.net/
-
-If you find bugs or want to send patches for enhancements, by email to
-Daniel Barlow <dan@telent.net>, but please check the CVS version first.
-
-$Id$
- write tests for socket-name and socket-peername
-- documentation: see doc.lisp, but beware: it's grotty.
+++ /dev/null
-<html><head><title>db-sockets API Reference</title></head><body>
-
-<!--
- This is intended to be[**] a machine-generated file (from SB-BSD-SOCKETS
- source code, massaged by doc.lisp), so do not edit it directly.
-
- [**] As of sbcl-0.8.0.12, there's clearly been some divergence between
- the text here and the original doc.lisp output, e.g. the way doc.lisp
- says "<title>SBCL BSD-Sockets API Reference</title>" where this file
- says "<title>db-sockets API Reference</title>". FIXME?
- -->
-
-<h1>Package SOCKETS</h1>
-
-<P>
-A thinly-disguised BSD socket API for SBCL. Ideas stolen from the BSD
-socket API for C and Graham Barr's IO::Socket classes for Perl.
-<P>
-We represent sockets as CLOS objects, and rename a lot of methods and
-arguments to fit Lisp style more closely.
-<P>
-
-<P>
-<h2>Contents</h2>
-<P>
-<ol>
-<li> General concepts
-<li> Methods applicable to all <a href="#socket">sockets</a>
-<li> <a href="#sockopt">Socket Options</a>
-<li> Methods applicable to a particular subclass
-<ol>
-<li> <a href="#internet">INET-SOCKET</a> - Internet Protocol (TCP, UDP, raw) sockets
-<li> Methods on <a href="#UNIX-SOCKET">UNIX-SOCKET</a> - Unix-domain sockets
-</ol>
-<li> <a href="#name-service">Name resolution</a> (DNS, /etc/hosts, &c)
-</ol>
-<P>
-<h2>General concepts</h2>
-<P>
-<p>Most of the functions are modelled on the BSD socket API. BSD sockets
-are widely supported, portably <i>(well, fairly portably)</i>
-available on a variety of systems, and documented. There are some
-differences in approach where we have taken advantage of some of the more useful features of Common Lisp - briefly
-<P>
-<ul>
-<li> Where the C API would typically return -1 and set errno, db-sockets
-signals an error. All the errors are subclasses of SOCKET-CONDITION
-and generally correspond one for one with possible <tt>errno</tt> values
-<P>
-<li> We use multiple return values in many places where the C API would use p[ass-by-reference values
-<P>
-<li> We can often avoid supplying an explicit <i>length</i> argument to
-functions because we already know how long the argument is.
-<P>
-<li> IP addresses and ports are represented in slightly friendlier fashion
-than "network-endian integers". See the section on <a href="#internet"
->Internet domain</a> sockets for details.
-</ul>
-<P>
-<P>
-<hr> <h2>SOCKETs</h2>
-<P>
-<p><a name="SOCKET"><i>Class: </i><b>SOCKET</b></a>
-<p><b>Slots:</b><ul><li>FILE-DESCRIPTOR : </li>
-<li>FAMILY : </li>
-<li>PROTOCOL : </li>
-<li>TYPE : </li>
-<li>STREAM : </li>
-</ul><p><a name="SOCKET-BIND"><table width="100%"><tr><td width="80%">(socket-bind <i> (s <a href="#socket">socket</a>) &rest address</i>)</td><td align=right>Generic Function</td></tr></table>
-<p><a name="SOCKET-ACCEPT"><table width="100%"><tr><td width="80%">(socket-accept <i> (socket <a href="#socket">socket</a>)</i>)</td><td align=right>Method</td></tr></table>
-<blockquote>Perform the accept(2) call, returning a newly-created connected socket
-and the peer address as multiple values</blockquote>
-<p><a name="SOCKET-CONNECT"><table width="100%"><tr><td width="80%">(socket-connect <i> (s <a href="#socket">socket</a>) &rest address</i>)</td><td align=right>Generic Function</td></tr></table>
-<p><a name="SOCKET-PEERNAME"><table width="100%"><tr><td width="80%">(socket-peername <i> (socket <a href="#socket">socket</a>)</i>)</td><td align=right>Method</td></tr></table>
-<blockquote>Return the socket's peer; depending on the address family this may return multiple values</blockquote>
-<p><a name="SOCKET-NAME"><table width="100%"><tr><td width="80%">(socket-name <i> (socket <a href="#socket">socket</a>)</i>)</td><td align=right>Method</td></tr></table>
-<blockquote>Return the address (as vector of bytes) and port that the socket is bound to, as multiple values</blockquote>
-<p><a name="SOCKET-RECEIVE"><table width="100%"><tr><td width="80%">(socket-receive <i> (socket <a href="#socket">socket</a>) buffer length &key oob peek waitall (element-type
- 'character)</i>)</td><td align=right>Method</td></tr></table>
-<blockquote>Read LENGTH octets from <a href="#SOCKET">SOCKET</a> into BUFFER (or a freshly-consed buffer if
-NIL), using recvfrom(2). If LENGTH is NIL, the length of BUFFER is
-used, so at least one of these two arguments must be non-NIL. If
-BUFFER is supplied, it had better be of an element type one octet wide.
-Returns the buffer, its length, and the address of the peer
-that sent it, as multiple values. On datagram sockets, sets MSG_TRUNC
-so that the actual packet length is returned even if the buffer was too
-small</blockquote>
-<p><a name="SOCKET-LISTEN"><table width="100%"><tr><td width="80%">(socket-listen <i> (socket <a href="#socket">socket</a>) backlog</i>)</td><td align=right>Method</td></tr></table>
-<blockquote>Mark <a href="#SOCKET">SOCKET</a> as willing to accept incoming connections. BACKLOG
-defines the maximum length that the queue of pending connections may
-grow to before new connection attempts are refused. See also listen(2)</blockquote>
-<p><a name="SOCKET-CLOSE"><table width="100%"><tr><td width="80%">(socket-close <i> (socket <a href="#socket">socket</a>)</i>)</td><td align=right>Method</td></tr></table>
-<blockquote>Close <a href="#SOCKET">SOCKET</a>. May throw any kind of error that write(2) would have
-thrown. If <a href="#SOCKET-MAKE-STREAM">SOCKET-MAKE-STREAM</a> has been called, calls CLOSE on that
-stream instead</blockquote>
-<p><a name="SOCKET-MAKE-STREAM"><table width="100%"><tr><td width="80%">(socket-make-stream <i> (socket <a href="#socket">socket</a>) &rest args</i>)</td><td align=right>Method</td></tr></table>
-<blockquote>Find or create a STREAM that can be used for IO on <a href="#SOCKET">SOCKET</a> (which
-must be connected). ARGS are passed onto SB-SYS:MAKE-FD-STREAM.</blockquote>
-<hr>
-<H2> Socket Options </h2>
-<a name="sockopt"> </a>
-<p> A subset of socket options are supported, using a fairly
-general framework which should make it simple to add more as required
-- see sockopt.lisp for details. The name mapping from C is fairly
-straightforward: <tt>SO_RCVLOWAT</tt> becomes
-<tt>sockopt-receive-low-water</tt> and <tt>(setf
-sockopt-receive-low-water)</tt>.
-|<p><a name="SOCKOPT-REUSE-ADDRESS"><table width="100%"><tr><td width="80%">(sockopt-reuse-address <i> (socket <a href="#socket">socket</a>) argument</i>)</td><td align=right>Accessor</td></tr></table>
-<blockquote>Return the value of the SO-REUSEADDR socket option for <a href="#SOCKET">SOCKET</a>. This can also be updated with SETF.</blockquote>
-<p><a name="SOCKOPT-KEEP-ALIVE"><table width="100%"><tr><td width="80%">(sockopt-keep-alive <i> (socket <a href="#socket">socket</a>) argument</i>)</td><td align=right>Accessor</td></tr></table>
-<blockquote>Return the value of the SO-KEEPALIVE socket option for <a href="#SOCKET">SOCKET</a>. This can also be updated with SETF.</blockquote>
-<p><a name="SOCKOPT-OOB-INLINE"><table width="100%"><tr><td width="80%">(sockopt-oob-inline <i> (socket <a href="#socket">socket</a>) argument</i>)</td><td align=right>Accessor</td></tr></table>
-<blockquote>Return the value of the SO-OOBINLINE socket option for <a href="#SOCKET">SOCKET</a>. This can also be updated with SETF.</blockquote>
-<p><a name="SOCKOPT-BSD-COMPATIBLE"><table width="100%"><tr><td width="80%">(sockopt-bsd-compatible <i> (socket <a href="#socket">socket</a>) argument</i>)</td><td align=right>Accessor</td></tr></table>
-<blockquote>Return the value of the SO-BSDCOMPAT socket option for <a href="#SOCKET">SOCKET</a>. This can also be updated with SETF.</blockquote>
-<p><a name="SOCKOPT-PASS-CREDENTIALS"><table width="100%"><tr><td width="80%">(sockopt-pass-credentials <i> (socket <a href="#socket">socket</a>) argument</i>)</td><td align=right>Accessor</td></tr></table>
-<blockquote>Return the value of the SO-PASSCRED socket option for <a href="#SOCKET">SOCKET</a>. This can also be updated with SETF.</blockquote>
-<p><a name="SOCKOPT-DEBUG"><table width="100%"><tr><td width="80%">(sockopt-debug <i> (socket <a href="#socket">socket</a>) argument</i>)</td><td align=right>Accessor</td></tr></table>
-<blockquote>Return the value of the SO-DEBUG socket option for <a href="#SOCKET">SOCKET</a>. This can also be updated with SETF.</blockquote>
-<p><a name="SOCKOPT-DONT-ROUTE"><table width="100%"><tr><td width="80%">(sockopt-dont-route <i> (socket <a href="#socket">socket</a>) argument</i>)</td><td align=right>Accessor</td></tr></table>
-<blockquote>Return the value of the SO-DONTROUTE socket option for <a href="#SOCKET">SOCKET</a>. This can also be updated with SETF.</blockquote>
-<p><a name="SOCKOPT-BROADCAST"><table width="100%"><tr><td width="80%">(sockopt-broadcast <i> (socket <a href="#socket">socket</a>) argument</i>)</td><td align=right>Accessor</td></tr></table>
-<blockquote>Return the value of the SO-BROADCAST socket option for <a href="#SOCKET">SOCKET</a>. This can also be updated with SETF.</blockquote>
-<p><a name="SOCKOPT-TCP-NODELAY"><table width="100%"><tr><td width="80%">(sockopt-tcp-nodelay <i> (socket <a href="#socket">socket</a>) argument</i>)</td><td align=right>Accessor</td></tr></table>
-<blockquote>Return the value of the TCP-NODELAY socket option for <a href="#SOCKET">SOCKET</a>. This can also be updated with SETF.</blockquote>
-<hr> <h2>INET-domain sockets</h2>
-<P>
-<p>The TCP and UDP sockets that you know and love. Some representation issues:
-<ul>
-<li>These functions do not accept hostnames directly: see <a href="#name-service">name resolution</a>
-<li>Internet <b>addresses</b> are represented by vectors of <tt>(unsigned-byte 8)</tt> - viz. <tt>#(127 0 0 1)</tt>. <b>Ports</b> are just integers: <tt>6010</tt>. No conversion between network- and host-order data is needed from the user of this package.
-<li><b><i>socket addresses</i></b> are represented by the two values for <b>address</b> and <b>port</b>, so for example, <tt>(<a href="#SOCKET-CONNECT">socket-connect</a> s #(192 168 1 1) 80)</tt>
-</ul>
-<P>
-<p><a name="INET-SOCKET"><i>Class: </i><b>INET-SOCKET</b></a>
-<p><b>Slots:</b><ul><li>FAMILY : </li>
-</ul><p><a name="MAKE-INET-ADDRESS"><table width="100%"><tr><td width="80%">(make-inet-address <i> dotted-quads</i>)</td><td align=right>Function</td></tr></table>
-<blockquote>Return a vector of octets given a string DOTTED-QUADS in the format
-"127.0.0.1"</blockquote>
-<p><a name="GET-PROTOCOL-BY-NAME"><table width="100%"><tr><td width="80%">(get-protocol-by-name <i> name</i>)</td><td align=right>Function</td></tr></table>
-<blockquote>Returns the network protocol number associated with the string NAME,
-using getprotobyname(2) which typically looks in NIS or /etc/protocols</blockquote>
-<p><a name="MAKE-INET-SOCKET"><table width="100%"><tr><td width="80%">(make-inet-socket <i> type protocol</i>)</td><td align=right>Function</td></tr></table>
-<blockquote>Make an INET socket. Deprecated in favour of make-instance</blockquote>
-<hr> <h2>File-domain sockets</h2>
-<P>
-File-domain (AF_FILE) sockets are also known as Unix-domain sockets, but were
-renamed by POSIX presumably on the basis that they may be
-available on other systems too.
-<P>
-A file-domain socket address is a string, which is used to create a node
-in the local filesystem. This means of course that they cannot be used across
-a network.
-<P>
-|<p><a name="UNIX-SOCKET"><i>Class: </i><b>UNIX-SOCKET</b></a>
-<p><b>Slots:</b><ul><li>FAMILY : </li>
-</ul><hr> <a name="name-service"><h2>Name Service</h2></a>
-<P>
-<p>Presently name service is implemented by calling whatever
-gethostbyname(2) uses. This may be any or all of /etc/hosts, NIS, DNS,
-or something completely different. Typically it's controlled by
-/etc/nsswitch.conf
-<P>
-<p> Direct links to the asynchronous resolver(3) routines would be nice to have
-eventually, so that we can do DNS lookups in parallel with other things
-<p><a name="HOST-ENT"><i>Class: </i><b>HOST-ENT</b></a>
-<p><b>Slots:</b><ul><li>NAME : </li>
-<li>ALIASES : </li>
-<li>ADDRESS-TYPE : </li>
-<li>ADDRESSES : </li>
-</ul><p><a name="HOST-ENT-ADDRESS"><table width="100%"><tr><td width="80%">(host-ent-address <i> (host-ent <a href="#host-ent">host-ent</a>)</i>)</td><td align=right>Method</td></tr></table>
-<p><a name="GET-HOST-BY-NAME"><table width="100%"><tr><td width="80%">(get-host-by-name <i> host-name</i>)</td><td align=right>Function</td></tr></table>
-<blockquote>Returns a <a href="#HOST-ENT">HOST-ENT</a> instance for HOST-NAME or throws some kind of condition.
-HOST-NAME may also be an IP address in dotted quad notation or some other
-weird stuff - see gethostbyname(3) for grisly details.</blockquote>
-<p><a name="GET-HOST-BY-ADDRESS"><table width="100%"><tr><td width="80%">(get-host-by-address <i> address</i>)</td><td align=right>Function</td></tr></table>
-<blockquote>Returns a <a href="#HOST-ENT">HOST-ENT</a> instance for ADDRESS, which should be a vector of
-(integer 0 255), or throws some kind of error. See gethostbyaddr(3) for
-grisly details.</blockquote>
-<p><a name="NAME-SERVICE-ERROR"><table width="100%"><tr><td width="80%">(name-service-error <i> where</i>)</td><td align=right>Function</td></tr></table>
-<hr><p><a name="NON-BLOCKING-MODE"><table width="100%"><tr><td width="80%">(non-blocking-mode <i> (socket <a href="#socket">socket</a>)</i>)</td><td align=right>Method</td></tr></table>
-<blockquote>Is <a href="#SOCKET">SOCKET</a> in non-blocking mode?</blockquote>
-<hr>
-<P>
-<H1>Tests</h1>
-<P>
-There should be at least one test for pretty much everything you can do
-with the package. In some places I've been more diligent than others; more
-tests gratefully accepted.
-<P>
-Tests are in the file <tt>tests.lisp</tt> and also make good examples.
-<P>
-|
-<h2>Unix-domain sockets</h2>
-<P>
-A fairly rudimentary test that connects to the syslog socket and sends a
-message. Priority 7 is kern.debug; you'll probably want to look at
-/etc/syslog.conf or local equivalent to find out where the message ended up
-|
\ No newline at end of file
+;;;; the old documentation extracted / generator for db-sockets / sb-bsd-sockets
+;;;;
+;;;; Not used anymore as the documentation is now integrated into the user manual,
+;;;; but I didn't have heart yet to delete this. -- NS 20040801
+
(eval-when (:load-toplevel :compile-toplevel :execute)
(defpackage :db-doc (:use :cl :asdf #+sbcl :sb-ext #+cmu :ext )))
(in-package :db-doc)
+++ /dev/null
-<html><head><title>SBCL BSD-Sockets API Reference</title></head><body>
-<h1>Package SB-BSD-SOCKETS</h1>
-
-<P>
-A thinly-disguised BSD socket API for SBCL. Ideas stolen from the BSD
-socket API for C and Graham Barr's IO::Socket classes for Perl.
-<P>
-We represent sockets as CLOS objects, and rename a lot of methods and
-arguments to fit Lisp style more closely.
-<P>
-
-<P>
-<h2>Contents</h2>
-<P>
-<ol>
-<li> General concepts
-<li> Methods applicable to all <a href="#socket">sockets</a>
-<li> <a href="#sockopt">Socket Options</a>
-<li> Methods applicable to a particular subclass
-<ol>
-<li> <a href="#internet">INET-SOCKET</a> - Internet Protocol (TCP, UDP, raw) sockets
-<li> Methods on <a href="#UNIX-SOCKET">UNIX-SOCKET</a> - Unix-domain sockets
-</ol>
-<li> <a href="#name-service">Name resolution</a> (DNS, /etc/hosts, &c)
-</ol>
-<P>
-<h2>General concepts</h2>
-<P>
-<p>Most of the functions are modelled on the BSD socket API. BSD sockets
-are widely supported, portably <i>("portable" by Unix standards, at least)</i>
-available on a variety of systems, and documented. There are some
-differences in approach where we have taken advantage of some of the more useful features of Common Lisp - briefly
-<P>
-<ul>
-<li> Where the C API would typically return -1 and set errno, bsd-sockets
-signals an error. All the errors are subclasses of SOCKET-CONDITION
-and generally correspond one for one with possible <tt>errno</tt> values
-<P>
-<li> We use multiple return values in many places where the C API would use p[ass-by-reference values
-<P>
-<li> We can often avoid supplying an explicit <i>length</i> argument to
-functions because we already know how long the argument is.
-<P>
-<li> IP addresses and ports are represented in slightly friendlier fashion
-than "network-endian integers". See the section on <a href="#internet"
->Internet domain</a> sockets for details.
-</ul>
-<P>
-<P>
-<hr> <h2>SOCKETs</h2>
-<P>
-<p><a name="SOCKET"><i>Class: </i><b>SOCKET</b></a>
-<p><b>Slots:</b><ul><li>FILE-DESCRIPTOR : </li>
-<li>FAMILY : </li>
-<li>PROTOCOL : </li>
-<li>TYPE : </li>
-<li>STREAM : </li>
-</ul><p><a name="SOCKET-BIND"><table width="100%"><tr><td width="80%">(socket-bind <i> socket &rest address</i>)</td><td align=right>Generic Function</td></tr></table>
-<p><a name="SOCKET-ACCEPT"><table width="100%"><tr><td width="80%">(socket-accept <i> (socket <a href="#socket">socket</a>)</i>)</td><td align=right>Method</td></tr></table>
-<blockquote>Perform the accept(2) call, returning a newly-created connected socket
-and the peer address as multiple values</blockquote>
-<p><a name="SOCKET-CONNECT"><table width="100%"><tr><td width="80%">(socket-connect <i> socket &rest address</i>)</td><td align=right>Generic Function</td></tr></table>
-<p><a name="SOCKET-PEERNAME"><table width="100%"><tr><td width="80%">(socket-peername <i> (socket <a href="#socket">socket</a>)</i>)</td><td align=right>Method</td></tr></table>
-<blockquote>Return the socket's peer; depending on the address family this may return multiple values</blockquote>
-<p><a name="SOCKET-NAME"><table width="100%"><tr><td width="80%">(socket-name <i> (socket <a href="#socket">socket</a>)</i>)</td><td align=right>Method</td></tr></table>
-<blockquote>Return the address (as vector of bytes) and port that the socket is bound to, as multiple values</blockquote>
-<p><a name="SOCKET-RECEIVE"><table width="100%"><tr><td width="80%">(socket-receive <i> (socket <a href="#socket">socket</a>) buffer length &key oob peek waitall (element-type
- 'character)</i>)</td><td align=right>Method</td></tr></table>
-<blockquote>Read LENGTH octets from <a href="#SOCKET">SOCKET</a> into BUFFER (or a freshly-consed buffer if
-NIL), using recvfrom(2). If LENGTH is NIL, the length of BUFFER is
-used, so at least one of these two arguments must be non-NIL. If
-BUFFER is supplied, it had better be of an element type one octet wide.
-Returns the buffer, its length, and the address of the peer
-that sent it, as multiple values. On datagram sockets, sets MSG_TRUNC
-so that the actual packet length is returned even if the buffer was too
-small</blockquote>
-<p><a name="SOCKET-LISTEN"><table width="100%"><tr><td width="80%">(socket-listen <i> (socket <a href="#socket">socket</a>) backlog</i>)</td><td align=right>Method</td></tr></table>
-<blockquote>Mark <a href="#SOCKET">SOCKET</a> as willing to accept incoming connections. BACKLOG
-defines the maximum length that the queue of pending connections may
-grow to before new connection attempts are refused. See also listen(2)</blockquote>
-<p><a name="SOCKET-CLOSE"><table width="100%"><tr><td width="80%">(socket-close <i> (socket <a href="#socket">socket</a>)</i>)</td><td align=right>Method</td></tr></table>
-<blockquote>Close <a href="#SOCKET">SOCKET</a>. May throw any kind of error that write(2) would have
-thrown. If <a href="#SOCKET-MAKE-STREAM">SOCKET-MAKE-STREAM</a> has been called, calls CLOSE on that
-stream instead</blockquote>
-<p><a name="SOCKET-MAKE-STREAM"><table width="100%"><tr><td width="80%">(socket-make-stream <i> (socket <a href="#socket">socket</a>) &rest args</i>)</td><td align=right>Method</td></tr></table>
-<blockquote>Find or create a STREAM that can be used for IO on <a href="#SOCKET">SOCKET</a> (which
-must be connected). ARGS are passed onto SB-SYS:MAKE-FD-STREAM.</blockquote>
-<hr>
-<H2> Socket Options </h2>
-<a name="sockopt"> </a>
-<p> A subset of socket options are supported, using a fairly
-general framework which should make it simple to add more as required
-- see sockopt.lisp for details. The name mapping from C is fairly
-straightforward: <tt>SO_RCVLOWAT</tt> becomes
-<tt>sockopt-receive-low-water</tt> and <tt>(setf
-sockopt-receive-low-water)</tt>.
-|<p><a name="SOCKOPT-REUSE-ADDRESS"><table width="100%"><tr><td width="80%">(sockopt-reuse-address <i> (socket <a href="#socket">socket</a>) argument</i>)</td><td align=right>Accessor</td></tr></table>
-<blockquote>Return the value of the SO-REUSEADDR socket option for <a href="#SOCKET">SOCKET</a>. This can also be updated with SETF.</blockquote>
-<p><a name="SOCKOPT-KEEP-ALIVE"><table width="100%"><tr><td width="80%">(sockopt-keep-alive <i> (socket <a href="#socket">socket</a>) argument</i>)</td><td align=right>Accessor</td></tr></table>
-<blockquote>Return the value of the SO-KEEPALIVE socket option for <a href="#SOCKET">SOCKET</a>. This can also be updated with SETF.</blockquote>
-<p><a name="SOCKOPT-OOB-INLINE"><table width="100%"><tr><td width="80%">(sockopt-oob-inline <i> (socket <a href="#socket">socket</a>) argument</i>)</td><td align=right>Accessor</td></tr></table>
-<blockquote>Return the value of the SO-OOBINLINE socket option for <a href="#SOCKET">SOCKET</a>. This can also be updated with SETF.</blockquote>
-<p><a name="SOCKOPT-BSD-COMPATIBLE"><table width="100%"><tr><td width="80%">(sockopt-bsd-compatible <i> (socket <a href="#socket">socket</a>) argument</i>)</td><td align=right>Accessor</td></tr></table>
-<blockquote>Return the value of the SO-BSDCOMPAT socket option for <a href="#SOCKET">SOCKET</a>. This can also be updated with SETF.</blockquote>
-<p><a name="SOCKOPT-PASS-CREDENTIALS"><table width="100%"><tr><td width="80%">(sockopt-pass-credentials <i> (socket <a href="#socket">socket</a>) argument</i>)</td><td align=right>Accessor</td></tr></table>
-<blockquote>Return the value of the SO-PASSCRED socket option for <a href="#SOCKET">SOCKET</a>. This can also be updated with SETF.</blockquote>
-<p><a name="SOCKOPT-DEBUG"><table width="100%"><tr><td width="80%">(sockopt-debug <i> (socket <a href="#socket">socket</a>) argument</i>)</td><td align=right>Accessor</td></tr></table>
-<blockquote>Return the value of the SO-DEBUG socket option for <a href="#SOCKET">SOCKET</a>. This can also be updated with SETF.</blockquote>
-<p><a name="SOCKOPT-DONT-ROUTE"><table width="100%"><tr><td width="80%">(sockopt-dont-route <i> (socket <a href="#socket">socket</a>) argument</i>)</td><td align=right>Accessor</td></tr></table>
-<blockquote>Return the value of the SO-DONTROUTE socket option for <a href="#SOCKET">SOCKET</a>. This can also be updated with SETF.</blockquote>
-<p><a name="SOCKOPT-BROADCAST"><table width="100%"><tr><td width="80%">(sockopt-broadcast <i> (socket <a href="#socket">socket</a>) argument</i>)</td><td align=right>Accessor</td></tr></table>
-<blockquote>Return the value of the SO-BROADCAST socket option for <a href="#SOCKET">SOCKET</a>. This can also be updated with SETF.</blockquote>
-<p><a name="SOCKOPT-TCP-NODELAY"><table width="100%"><tr><td width="80%">(sockopt-tcp-nodelay <i> (socket <a href="#socket">socket</a>) argument</i>)</td><td align=right>Accessor</td></tr></table>
-<blockquote>Return the value of the TCP-NODELAY socket option for <a href="#SOCKET">SOCKET</a>. This can also be updated with SETF.</blockquote>
-<hr> <h2>INET-domain sockets</h2>
-<P>
-<p>The TCP and UDP sockets that you know and love. Some representation issues:
-<ul>
-<li>These functions do not accept hostnames directly: see <a href="#name-service">name resolution</a>
-<li>Internet <b>addresses</b> are represented by vectors of <tt>(unsigned-byte 8)</tt> - viz. <tt>#(127 0 0 1)</tt>. <b>Ports</b> are just integers: <tt>6010</tt>. No conversion between network- and host-order data is needed from the user of this package.
-<li><b><i>socket addresses</i></b> are represented by the two values for <b>address</b> and <b>port</b>, so for example, <tt>(<a href="#SOCKET-CONNECT">socket-connect</a> s #(192.168.1.1) 80)</tt>
-</ul>
-<P>
-<p><a name="INET-SOCKET"><i>Class: </i><b>INET-SOCKET</b></a>
-<p><b>Slots:</b><ul><li>FAMILY : </li>
-</ul><p><a name="MAKE-INET-ADDRESS"><table width="100%"><tr><td width="80%">(make-inet-address <i> dotted-quads</i>)</td><td align=right>Function</td></tr></table>
-<blockquote>Return a vector of octets given a string DOTTED-QUADS in the format
-"127.0.0.1"</blockquote>
-<p><a name="GET-PROTOCOL-BY-NAME"><table width="100%"><tr><td width="80%">(get-protocol-by-name <i> name</i>)</td><td align=right>Function</td></tr></table>
-<blockquote>Returns the network protocol number associated with the string NAME,
-using getprotobyname(2) which typically looks in NIS or /etc/protocols</blockquote>
-<p><a name="MAKE-INET-SOCKET"><table width="100%"><tr><td width="80%">(make-inet-socket <i> type protocol</i>)</td><td align=right>Function</td></tr></table>
-<blockquote>Make an INET socket. Deprecated in favour of make-instance</blockquote>
-<hr> <h2>File-domain sockets</h2>
-<P>
-File-domain (AF_FILE) sockets are also known as Unix-domain sockets, but were
-renamed by POSIX presumably on the basis that they may be
-available on other systems too.
-<P>
-A file-domain socket address is a string, which is used to create a node
-in the local filesystem. This means of course that they cannot be used across
-a network.
-<P>
-|<p><a name="UNIX-SOCKET"><i>Class: </i><b>UNIX-SOCKET</b></a>
-<p><b>Slots:</b><ul><li>FAMILY : </li>
-</ul><hr> <a name="name-service"><h2>Name Service</h2></a>
-<P>
-<p>Presently name service is implemented by calling whatever
-gethostbyname(2) uses. This may be any or all of /etc/hosts, NIS, DNS,
-or something completely different. Typically it's controlled by
-/etc/nsswitch.conf
-<P>
-<p> Direct links to the asynchronous resolver(3) routines would be nice to have
-eventually, so that we can do DNS lookups in parallel with other things
-<p><a name="HOST-ENT"><i>Class: </i><b>HOST-ENT</b></a>
-<p><b>Slots:</b><ul><li>NAME : </li>
-<li>ALIASES : </li>
-<li>ADDRESS-TYPE : </li>
-<li>ADDRESSES : </li>
-</ul><p><a name="HOST-ENT-ADDRESS"><table width="100%"><tr><td width="80%">(host-ent-address <i> (host-ent <a href="#host-ent">host-ent</a>)</i>)</td><td align=right>Method</td></tr></table>
-<p><a name="GET-HOST-BY-NAME"><table width="100%"><tr><td width="80%">(get-host-by-name <i> host-name</i>)</td><td align=right>Function</td></tr></table>
-<blockquote>Returns a <a href="#HOST-ENT">HOST-ENT</a> instance for HOST-NAME or throws some kind of condition.
-HOST-NAME may also be an IP address in dotted quad notation or some other
-weird stuff - see gethostbyname(3) for grisly details.</blockquote>
-<p><a name="GET-HOST-BY-ADDRESS"><table width="100%"><tr><td width="80%">(get-host-by-address <i> address</i>)</td><td align=right>Function</td></tr></table>
-<blockquote>Returns a <a href="#HOST-ENT">HOST-ENT</a> instance for ADDRESS, which should be a vector of
-(integer 0 255), or throws some kind of error. See gethostbyaddr(3) for
-grisly details.</blockquote>
-<p><a name="NAME-SERVICE-ERROR"><table width="100%"><tr><td width="80%">(name-service-error <i> where</i>)</td><td align=right>Function</td></tr></table>
-<hr><p><a name="NON-BLOCKING-MODE"><table width="100%"><tr><td width="80%">(non-blocking-mode <i> (socket <a href="#socket">socket</a>)</i>)</td><td align=right>Method</td></tr></table>
-<blockquote>Is <a href="#SOCKET">SOCKET</a> in non-blocking mode?</blockquote>
-<hr>
-<P>
-<H1>Tests</h1>
-<P>
-There should be at least one test for pretty much everything you can do
-with the package. In some places I've been more diligent than others; more
-tests gratefully accepted.
-<P>
-Tests are in the file <tt>tests.lisp</tt> and also make good examples.
-<P>
-|
-<h2>Unix-domain sockets</h2>
-<P>
-A fairly rudimentary test that connects to the syslog socket and sends a
-message. Priority 7 is kern.debug; you'll probably want to look at
-/etc/syslog.conf or local equivalent to find out where the message ended up
-|
\ No newline at end of file
(in-package :sb-bsd-sockets)
-#|| <h2>INET-domain sockets</h2>
-
-<p>The TCP and UDP sockets that you know and love. Some representation issues:
-<ul>
-<li>These functions do not accept hostnames directly: see <a href="#name-service">name resolution</a>
-<li>Internet <b>addresses</b> are represented by sequences of <tt>(unsigned-byte 8)</tt> - viz. <tt>#(127 0 0 1)</tt>. <b>Ports</b> are just integers: <tt>6010</tt>. No conversion between network- and host-order data is needed from the user of this package.
-<li><b><i>socket addresses</i></b> are represented by the two values for <b>address</b> and <b>port</b>, so for example, <tt>(<a href="#SOCKET-CONNECT">socket-connect</a> s #(192 168 1 1) 80)</tt>
-</ul>
-
-|#
-
;;; Our class and constructor
(eval-when (:compile-toplevel :load-toplevel :execute)
(defclass inet-socket (socket)
- ((family :initform sockint::AF-INET))))
+ ((family :initform sockint::AF-INET))
+ (:documentation "Class representing TCP and UDP sockets.
+
+Examples:
+
+ (make-instance 'inet-socket :type :stream :protocol :tcp)
+
+ (make-instance 'inet-socket :type :datagram :protocol :udp)
+")))
;;; XXX should we *...* this?
(defparameter inet-address-any (vector 0 0 0 0))
(in-package :sb-bsd-sockets)
-#|| <h2>Local (unix) domain sockets</h2>
-
-Local domain (AF_LOCAL) sockets are also known as Unix-domain sockets, but were
-renamed by POSIX presumably on the basis that they may be
-available on other systems too.
-
-A local socket address is a string, which is used to create a node
-in the local filesystem. This means of course that they cannot be used across
-a network.
-
-||#
-
(defclass local-socket (socket)
- ((family :initform sockint::af-local)))
+ ((family :initform sockint::af-local))
+ (:documentation "Class representing local domain (AF_LOCAL) sockets,
+also known as unix-domain sockets."))
-(defmethod make-sockaddr-for ((socket local-socket) &optional sockaddr &rest address &aux (filename (first address)))
+(defmethod make-sockaddr-for ((socket local-socket)
+ &optional sockaddr &rest address &aux (filename (first address)))
(let ((sockaddr (or sockaddr (sockint::allocate-sockaddr-un))))
(setf (sockint::sockaddr-un-family sockaddr) sockint::af-local)
(when filename
(in-package :sb-bsd-sockets)
-#|| <a name="name-service"><h2>Name Service</h2></a>
-
-<p>Presently name service is implemented by calling whatever
-gethostbyname(2) uses. This may be any or all of /etc/hosts, NIS, DNS,
-or something completely different. Typically it's controlled by
-/etc/nsswitch.conf
-
-<p> Direct links to the asynchronous resolver(3) routines would be nice to have
-eventually, so that we can do DNS lookups in parallel with other things
-|#
(defclass host-ent ()
((name :initarg :name :accessor host-ent-name)
(aliases :initarg :aliases :accessor host-ent-aliases)
(address-type :initarg :type :accessor host-ent-address-type)
; presently always AF_INET
- (addresses :initarg :addresses :accessor host-ent-addresses)))
+ (addresses :initarg :addresses :accessor host-ent-addresses))
+ ;; FIXME: Our Texinfo documentation extracter need at least his to spit
+ ;; out the signature. Real documentation would be better...
+ (:documentation ""))
-(defgeneric host-ent-address (host-ent))
+(defgeneric host-ent-address (host-ent)
+ ;; FIXME: Our Texinfo documentation extracter need at least his to spit
+ ;; out the signature. Real documentation would be better...
+ (:documentation ""))
-(defmethod host-ent-address ((host-ent host-ent))
+(defmethod host-ent-address ((host-ent host-ent))
(car (host-ent-addresses host-ent)))
;(define-condition host-not-found-error (socket-error)) ; host unknown
GET-NAME-SERVICE-ERRNO")
(defun name-service-error (where)
+ ;; FIXME: Our Texinfo documentation extracter need at least his to spit
+ ;; out the signature. Real documentation would be better...
+ ""
(get-name-service-errno)
;; Comment next to NETDB_INTERNAL in netdb.h says "See errno.".
;; This special case treatment hasn't actually been tested yet.
;;;; Methods, classes, functions for sockets. Protocol-specific stuff
;;;; is deferred to inet.lisp, unix.lisp, etc
-#|| <h2>SOCKETs</h2>
-
-|#
-
(eval-when (:load-toplevel :compile-toplevel :execute)
(defclass socket ()
((file-descriptor :initarg :descriptor
:reader socket-file-descriptor)
- (family :initform (error "No socket family") :reader socket-family)
- (protocol :initarg :protocol :reader socket-protocol)
- (type :initarg :type :reader socket-type)
- (stream))))
-
+ (family :initform (error "No socket family")
+ :reader socket-family)
+ (protocol :initarg :protocol
+ :reader socket-protocol
+ :documentation "Protocol used by the socket. If a
+keyword, the symbol-name of the keyword will be passed to
+GET-PROTOCOL-BY-NAME downcased, and the returned value used as
+protocol. Other values are used as-is.")
+ (type :initarg :type
+ :reader socket-type
+ :documentation "Type of the socket: :STREAM or :DATAGRAM.")
+ (stream))
+ (:documentation "Common base class of all sockets, not ment to be
+directly instantiated.")))
+
(defmethod print-object ((object socket) stream)
(print-unreadable-object (object stream :type t :identity t)
(princ "descriptor " stream)
(bits-of-sockaddr socket sockaddr)))))))
(sb-alien:free-alien copy-buffer))))))
-
-
(defgeneric socket-listen (socket backlog)
(:documentation "Mark SOCKET as willing to accept incoming connections. BACKLOG
defines the maximum length that the queue of pending connections may
(socket-error-syscall c)
(or (socket-error-symbol c) (socket-error-errno c))
#+cmu (sb-unix:get-unix-error-msg num)
- #+sbcl (sb-int:strerror num))))))
+ #+sbcl (sb-int:strerror num)))))
+ (:documentation "Common base class of socket related conditions."))
;;; watch out for slightly hacky symbol punning: we use both the value
;;; and the symbol-name of sockint::efoo
#+sbcl
(defun socket-error (where)
+ ;; FIXME: Our Texinfo documentation extracter need at least his to spit
+ ;; out the signature. Real documentation would be better...
+ ""
(let* ((errno (sb-unix::get-errno))
(condition (condition-for-errno errno)))
(error condition :errno errno :syscall where)))
(in-package :sb-bsd-sockets)
-#||
-<H2> Socket Options </h2>
-<a name="sockopt"> </a>
-<p> A subset of socket options are supported, using a fairly
-general framework which should make it simple to add more as required
-- see sockopt.lisp for details. The name mapping from C is fairly
-straightforward: <tt>SO_RCVLOWAT</tt> becomes
-<tt>sockopt-receive-low-water</tt> and <tt>(setf
-sockopt-receive-low-water)</tt>.
-||#
-
#|
getsockopt(socket, level, int optname, void *optval, socklen_t *optlen)
setsockopt(socket, level, int optname, void *optval, socklen_t optlen)
fact that most of these take different data types - some are integers,
some are booleans, some are foreign struct instances, etc etc
- (define-socket-option lisp-name level number mangle-arg size mangle-return)
+ (define-socket-option lisp-name doc level number mangle-arg size mangle-return)
macro-expands to two functions that define lisp-name and (setf ,lisp-name)
and calls the functions mangle-arg and mangle-return on outgoing and incoming
Code for options that not every system has should be conditionalised:
(if (boundp 'sockint::IP_RECVIF)
- (define-socket-option so-receive-interface (getprotobyname "ip")
+ (define-socket-option so-receive-interface nil (getprotobyname "ip")
sockint::IP_RECVIF ... ))
-
-
|#
(defmacro define-socket-option
- (lisp-name level number buffer-type mangle-arg mangle-return mangle-setf-buffer)
+ (lisp-name documentation
+ level number buffer-type mangle-arg mangle-return mangle-setf-buffer)
(let ((find-level
(if (numberp (eval level))
level
`(progn
(export ',lisp-name)
(defun ,lisp-name (socket &aux (fd (socket-file-descriptor socket)))
+ ,@(when documentation (list documentation))
(sb-alien:with-alien ((size sb-alien:integer)
(buffer ,buffer-type))
(setf size (sb-alien:alien-size ,buffer-type :bytes))
buffer)
(defmacro define-socket-option-int (name level number)
- `(define-socket-option ,name ,level ,number
+ `(define-socket-option ,name nil ,level ,number
sb-alien:integer nil foreign-int-to-integer sb-alien:addr))
(define-socket-option-int
(defun bool-to-foreign-int (val)
(if val 1 0))
-(defmacro define-socket-option-bool (name level number)
- `(define-socket-option ,name ,level ,number
+(defmacro define-socket-option-bool (name level c-name)
+ `(define-socket-option ,name
+ ,(format nil "Return the value of the ~A socket option for SOCKET. This can also be updated with SETF." (symbol-name c-name))
+ ,level ,c-name
sb-alien:integer bool-to-foreign-int foreign-int-to-bool sb-alien:addr))
(define-socket-option-bool
(declare (ignore args))
x)
-#+linux(define-socket-option sockopt-bind-to-device sockint::sol-socket
+#+linux(define-socket-option sockopt-bind-to-device nil sockint::sol-socket
sockint::so-bindtodevice sb-alien:c-string identity identity-1 identity)
;;; other kinds of socket option
(defpackage "SB-BSD-SOCKETS-TEST"
(:use "CL" "SB-BSD-SOCKETS" "SB-RT"))
-#||
-
-<H1>Tests</h1>
-
-There should be at least one test for pretty much everything you can do
-with the package. In some places I've been more diligent than others; more
-tests gratefully accepted.
-
-Tests are in the file <tt>tests.lisp</tt> and also make good examples.
-
-||#
-
(in-package :sb-bsd-sockets-test)
;;; a real address
DOCSTRINGDIR="docstrings/"
# List of contrib modules that docstring docs will be created for.
# FIXME: should check test-passed and not load them.
-MODULES=':sb-md5 :sb-rotate-byte :sb-grovel :sb-sprof'
+MODULES=':sb-md5 :sb-rotate-byte :sb-grovel :sb-sprof :sb-bsd-sockets'
# List of package names that docstring docs will be created for.
-PACKAGES=":COMMON-LISP :SB-ALIEN :SB-DEBUG :SB-EXT :SB-GRAY :SB-MOP :SB-PROFILE :SB-THREAD :SB-MD5 :SB-ROTATE-BYTE :SB-SPROF"
-
+PACKAGES=":COMMON-LISP :SB-ALIEN :SB-DEBUG :SB-EXT :SB-GRAY :SB-MOP :SB-PROFILE :SB-THREAD :SB-MD5 :SB-ROTATE-BYTE :SB-SPROF :SB-BSD-SOCKETS"
ifeq ($(MAKEINFO),)
MAKEINFO:=makeinfo
(write-line "@end menu" out)
(terpri out)
(dolist (texi-file texi-files)
- (format out "@include ~A~%"
+ (format out "@page~%@include ~A~%"
(namestring (make-pathname
:directory (list* :relative :up :up
(last
:name (pathname-name texi-file)
:type (pathname-type texi-file)))))))
-(sb-ext:quit)
\ No newline at end of file
+(sb-ext:quit)
line))
offset)))
-
(defun collect-maybe-table-section (lines starting-line arglist-symbols)
;; Return index of next line to be processed outside
(let ((this-offset (maybe-table-offset (svref lines starting-line)))
`("" "@table @code" ,@(reverse result) "@end table" ""))
nil)))
-
-
-
(defun string-as-lines (string)
(coerce (with-input-from-string (s string)
(loop for line = (read-line s nil nil)
(defvar *characters-to-drop* '(#\\ #\` #\')
"Characters that should be removed by `alphanumize'.")
-
(defun alphanumize (symbol)
"Construct a string without characters like *`' that will
f-star-ck up filename handling. See `*character-replacements*'
(format nil "~{~A~^ ~}"
(mapcar #'texinfoify-arglist-part (argument-list symbol))))))
+(defun hidden-superclass-name-p (class-name superclass-name)
+ (let ((super-package (symbol-package superclass-name)))
+ (or
+ ;; KLUDGE: We assume that we don't want to advertise internal
+ ;; classes in CP-lists, unless the symbol we're documenting is
+ ;; internal as well.
+ (and (member super-package #.'(mapcar #'find-package '(sb-pcl sb-int sb-kernel)))
+ (not (eq super-package (symbol-package class-name))))
+ ;; KLUDGE: We don't generally want to advertise SIMPLE-ERROR or
+ ;; SIMPLE-CONDITION in the CPLs of conditions that inherit them
+ ;; simply as a matter of convenience. The assumption here is
+ ;; that the inheritance is incidental unless the name of the
+ ;; condition begins with SIMPLE-.
+ (and (member superclass-name '(simple-error simple-condition))
+ (let ((prefix "SIMPLE-"))
+ (mismatch prefix (string class-name) :end2 (length prefix)))
+ t ; don't return number from MISMATCH
+ ))))
+
+(defun hidden-slot-p (symbol slot)
+ ;; FIXME: There is no pricipal reason to avoid the slot docs fo
+ ;; structures and conditions, but their DOCUMENTATION T doesn't
+ ;; currently work with them the way we'd like.
+ (not (and (typep (find-class symbol nil) 'standard-class)
+ (documentation slot t))))
+
+(defun classlike-p (symbol kind)
+ (and (eq 'type kind)
+ (let ((class (find-class symbol nil)))
+ (some (lambda (type)
+ (typep class type))
+ '(structure-class standard-class sb-pcl::condition-class)))))
+
+(defun def-body (symbol kind docstring)
+ (with-output-to-string (s)
+ (when (classlike-p symbol kind)
+ (format s "Class precedence list: @code{~(~{@w{~A}~^, ~}~)}~%~%"
+ (remove-if (lambda (super)
+ (hidden-superclass-name-p symbol super))
+ (mapcar #'class-name
+ (sb-mop:class-precedence-list (find-class symbol)))))
+ (let ((documented-slots (remove-if (lambda (slot)
+ (hidden-slot-p symbol slot))
+ (sb-mop:class-direct-slots (find-class symbol)))))
+ (when documented-slots
+ (format s "Slots:~%@itemize~%")
+ (dolist (slot documented-slots)
+ (format s "@item ~(@code{~A} ~@[--- initargs: @code{~{@w{~S}~^, ~}}~]~)~%~%~A~%"
+ (sb-mop:slot-definition-name slot)
+ (sb-mop:slot-definition-initargs slot)
+ (frob-docstring (documentation slot t) nil)))
+ (format s "@end itemize~%~%"))))
+ (write-string (frob-docstring docstring (ignore-errors (argument-list symbol))) s)))
+
(defun def-end (symbol kind)
(declare (ignore symbol))
(ecase kind
(with-open-file (out filename :direction :output
:if-does-not-exist :create :if-exists :supersede)
(loop for (symbol kind docstring) in docs
- do (format out "~&@anchor{~A}~%~A ~A:~A~@[ ~A~]~%~A~&~A~%~A~%~%"
- (unique-name symbol package kind)
- (def-begin symbol kind)
- (texinfoify (package-name package))
- (texinfoify symbol)
- (def-arglist symbol kind)
- (def-index symbol kind)
- (frob-docstring docstring (argument-list symbol))
- (def-end symbol kind))))
+ do (write-texinfo out package symbol kind docstring)))
filename))
(defun docstrings-to-texinfo (directory &rest packages)
directory)
:direction :output
:if-does-not-exist :create :if-exists :supersede)
- (format out "~&@anchor{~A}~%~A ~A:~A~@[ ~A~]~%~A~&~A~%~A~%~%"
- (unique-name symbol package kind)
- (def-begin symbol kind)
- (texinfoify (package-name package))
- (texinfoify symbol)
- (def-arglist symbol kind)
- (def-index symbol kind)
- (frob-docstring docstring (ignore-errors (argument-list symbol)))
- (def-end symbol kind)))))
+ (write-texinfo out package symbol kind docstring))))
directory))
+
+(defun write-texinfo (stream package symbol kind docstring)
+ (format stream "~&@anchor{~A}~%~A ~A:~A~@[ ~A~]~%~A~&~A~%~A~%~%"
+ (unique-name symbol package kind)
+ (def-begin symbol kind)
+ (texinfoify (package-name package))
+ (texinfoify symbol)
+ (def-arglist symbol kind)
+ (def-index symbol kind)
+ (def-body symbol kind docstring)
+ (def-end symbol kind)))
;;; checkins which aren't released. (And occasionally for internal
;;; versions, especially for internal versions off the main CVS
;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"0.8.13.13"
+"0.8.13.14"