Update ASDF to 2.21.
[sbcl.git] / contrib / sb-bsd-sockets / sockets.lisp
index dcccc79..9118a6a 100644 (file)
@@ -5,6 +5,13 @@
 
 (eval-when (:load-toplevel :compile-toplevel :execute)
 
+
+;;; Winsock is different w.r.t errno
+(defun socket-errno ()
+  "Get socket error code, usually from errno, but see #+win32."
+  #+win32 (sockint::wsa-get-last-error)
+  #-win32 (sb-unix::get-errno))
+
 (defclass socket ()
   ((file-descriptor :initarg :descriptor
                     :reader socket-file-descriptor)
@@ -59,7 +66,8 @@ directly instantiated.")))
       (setf (slot-value socket 'file-descriptor) fd
             (slot-value socket 'protocol) proto-num
             (slot-value socket 'type) type)
-      (sb-ext:finalize socket (lambda () (sockint::close fd)))))
+      (sb-ext:finalize socket (lambda () (sockint::close fd))
+                       :dont-save t)))
 
 \f
 
@@ -108,7 +116,7 @@ values"))
                                (size-of-sockaddr socket))))
       (cond
         ((and (= fd -1)
-              (member (sb-unix::get-errno)
+              (member (socket-errno)
                       (list sockint::EAGAIN sockint::EINTR)))
          nil)
         ((= fd -1) (socket-error "accept"))
@@ -117,7 +125,8 @@ values"))
                               :type (socket-type socket)
                               :protocol (socket-protocol socket)
                               :descriptor fd)))
-                    (sb-ext:finalize s (lambda () (sockint::close fd))))
+                    (sb-ext:finalize s (lambda () (sockint::close fd))
+                                     :dont-save t))
                   (multiple-value-list (bits-of-sockaddr socket sockaddr))))))))
 
 (defgeneric socket-connect (socket &rest address)
@@ -216,7 +225,7 @@ buffer was too small."))
                                         (sb-alien:addr sa-len))))
                 (cond
                   ((and (= len -1)
-                        (member (sb-unix::get-errno)
+                        (member (socket-errno)
                                 (list sockint::EAGAIN sockint::EINTR)))
                    nil)
                   ((= len -1) (socket-error "recvfrom"))
@@ -293,7 +302,7 @@ send(2) will be called instead. Returns the number of octets written."))
                                    flags)))))
     (cond
       ((and (= len -1)
-            (member (sb-unix::get-errno)
+            (member (socket-errno)
                     (list sockint::EAGAIN sockint::EINTR)))
        nil)
       ((= len -1)
@@ -381,17 +390,33 @@ for the stream."))
                                (buffering :full)
                                (external-format :default)
                                timeout
-                               auto-close)
-  "Default method for SOCKET objects. An ELEMENT-TYPE of :DEFAULT will
-construct a bivalent stream. Acceptable values for BUFFERING are :FULL, :LINE
-and :NONE. Streams will have no TIMEOUT by default. If AUTO-CLOSE is true, the
-underlying OS socket is automatically closed after the stream and the socket
-have been garbage collected.
-
-The stream for SOCKET will be cached, and a second invocation of this method
-will return the same stream. This may lead to oddities if this function is
-invoked with inconsistent arguments \(e.g., one might request an input stream
-and get an output stream in response\)."
+                               auto-close
+                               serve-events)
+  "Default method for SOCKET objects.
+
+ELEMENT-TYPE defaults to CHARACTER, to construct a bivalent stream,
+capable of both binary and character IO use :DEFAULT.
+
+Acceptable values for BUFFERING are :FULL, :LINE and :NONE, default
+is :FULL, ie. output is buffered till it is explicitly flushed using
+CLOSE or FINISH-OUTPUT. (FORCE-OUTPUT forces some output to be
+flushed: to ensure all buffered output is flused use FINISH-OUTPUT.)
+
+Streams have no TIMEOUT by default. If one is provided, it is the
+number of seconds the system will at most wait for input to appear on
+the socket stream when trying to read from it.
+
+If AUTO-CLOSE is true, the underlying OS socket is automatically
+closed after the stream and the socket have been garbage collected.
+Default is false.
+
+If SERVE-EVENTS is true, blocking IO on the socket will dispatch to
+the recursive event loop. Default is false.
+
+The stream for SOCKET will be cached, and a second invocation of this
+method will return the same stream. This may lead to oddities if this
+function is invoked with inconsistent arguments \(e.g., one might
+request an input stream and get an output stream in response\)."
   (let ((stream
          (and (slot-boundp socket 'stream) (slot-value socket 'stream))))
     (unless stream
@@ -407,8 +432,9 @@ and get an output stream in response\)."
                     :buffering buffering
                     :external-format external-format
                     :timeout timeout
-                    :auto-close auto-close)))
-      (setf (slot-value socket 'stream) stream)
+                    :auto-close auto-close
+                    :serve-events serve-events))
+      (setf (slot-value socket 'stream) stream))
     (sb-ext:cancel-finalization socket)
     stream))
 
@@ -480,7 +506,7 @@ and get an output stream in response\)."
   ;; 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))
+  (let* ((errno (socket-errno))
          (condition (condition-for-errno errno)))
     (error condition :errno errno  :syscall where)))