[usocket-cvs] r302 - usocket/trunk/backend

ehuelsmann at common-lisp.net ehuelsmann at common-lisp.net
Sun Feb 10 20:16:43 UTC 2008


Author: ehuelsmann
Date: Sun Feb 10 15:16:42 2008
New Revision: 302

Modified:
   usocket/trunk/backend/sbcl.lisp
Log:
Fix sb-bsd-sockets:unknown-protocol leaking through to the usocket user.

Modified: usocket/trunk/backend/sbcl.lisp
==============================================================================
--- usocket/trunk/backend/sbcl.lisp	(original)
+++ usocket/trunk/backend/sbcl.lisp	Sun Feb 10 15:16:42 2008
@@ -1,322 +1,324 @@
-;;;; $Id$
-;;;; $URL$
-
-;;;; See LICENSE for licensing information.
-
-(in-package :usocket)
-
-;; There's no way to preload the sockets library other than by requiring it
-;;
-;; ECL sockets has been forked off sb-bsd-sockets and implements the
-;; same interface. We use the same file for now.
-#+ecl
-(eval-when (:compile-toplevel :load-toplevel :execute)
-  (require :sockets))
-
-#+sbcl
-(progn
-  #-win32
-  (defun get-host-name ()
-    (sb-unix:unix-gethostname))
-
-  ;; we assume winsock has already been loaded, after all,
-  ;; we already loaded sb-bsd-sockets and sb-alien
-  #+win32
-  (defun get-host-name ()
-    (sb-alien:with-alien ((buf (sb-alien:array sb-alien:char 256)))
-       (let ((result (sb-alien:alien-funcall
-                      (sb-alien:extern-alien "gethostname"
-                                             (sb-alien:function sb-alien:int
-                                                                (* sb-alien:char)
-                                                                sb-alien:int))
-                      (sb-alien:cast buf (* sb-alien:char))
-                      256)))
-         (when (= result 0)
-           (sb-alien:cast buf sb-alien:c-string))))))
-
-
-#+ecl
-(progn
-  #-:wsock
-  (ffi:clines
-   "#include <sys/socket.h>")
-  #+:wsock
-  (ffi:clines
-   "#ifndef FD_SETSIZE"
-   "#define FD_SETSIZE 1024"
-   "#endif"
-   "#include <winsock2.h>")
-
-  (ffi:clines
-   "#include <ecl/ecl-inl.h>")
-
-  #+:prefixed-api
-  (ffi:clines
-   "#define CONS(x, y) ecl_cons((x), (y))"
-   "#define MAKE_INTEGER(x) ecl_make_integer((x))")
-  #-:prefixed-api
-  (ffi:clines
-   "#define CONS(x, y) make_cons((x), (y))"
-   "#define MAKE_INTEGER(x) make_integer((x))")
-
-  (defun fd-setsize ()
-    (ffi:c-inline () () :fixnum
-     "FD_SETSIZE" :one-liner t))
-
-  (defun get-host-name ()
-    (ffi:c-inline
-     () () :object
-     "{ char *buf = GC_malloc(256);
-
-        if (gethostname(buf,256) == 0)
-          @(return) = make_simple_base_string(buf);
-        else
-          @(return) = Cnil;
-      }" :one-liner nil :side-effects nil))
-
-  (defun read-select (read-fds to-secs &optional (to-musecs 0))
-    (ffi:c-inline (read-fds to-secs to-musecs) (t t :unsigned-int) t
-      "{
-          fd_set rfds;
-          cl_object cur_fd = #0;
-          int count;
-          int max_fd = -1;
-          struct timeval tv;
-
-          FD_ZERO(&rfds);
-          while (CONSP(cur_fd)) {
-            int fd = fixint(cur_fd->cons.car);
-            max_fd = (max_fd > fd) ? max_fd : fd;
-            FD_SET(fd, &rfds);
-            cur_fd = cur_fd->cons.cdr;
-          }
-
-          if (#1 != Cnil) {
-            tv.tv_sec = fixnnint(#1);
-            tv.tv_usec = #2;
-          }
-          count = select(max_fd + 1, &rfds, NULL, NULL,
-                         (#1 != Cnil) ? &tv : NULL);
-
-          if (count == 0)
-            @(return) = Cnil;
-          else if (count < 0)
-            /*###FIXME: We should be raising an error here...
-
-              except, ofcourse in case of EINTR or EAGAIN */
-
-            @(return) = Cnil;
-          else
-            {
-              cl_object rv = Cnil;
-              cur_fd = #0;
-
-              /* when we're going to use the same code on Windows,
-                 as well as unix, we can't be sure it'll fit into
-                 a fixnum: these aren't unix filehandle bitmaps sets on
-                 Windows... */
-
-              while (CONSP(cur_fd)) {
-                int fd = fixint(cur_fd->cons.car);
-                if (FD_ISSET(fd, &rfds))
-                  rv = CONS(MAKE_INTEGER(fd), rv);
-
-                cur_fd = cur_fd->cons.cdr;
-              }
-              @(return) = rv;
-            }
-}"))
-
-)
-
-(defun map-socket-error (sock-err)
-  (map-errno-error (sb-bsd-sockets::socket-error-errno sock-err)))
-
-(defparameter +sbcl-condition-map+
-  '((interrupted-error . interrupted-condition)))
-
-(defparameter +sbcl-error-map+
-  `((sb-bsd-sockets:address-in-use-error . address-in-use-error)
-    (sb-bsd-sockets::no-address-error . address-not-available-error)
-    (sb-bsd-sockets:bad-file-descriptor-error . bad-file-descriptor-error)
-    (sb-bsd-sockets:connection-refused-error . connection-refused-error)
-    (sb-bsd-sockets:invalid-argument-error . invalid-argument-error)
-    (sb-bsd-sockets:no-buffers-error . no-buffers-error)
-    (sb-bsd-sockets:operation-not-supported-error
-     . operation-not-supported-error)
-    (sb-bsd-sockets:operation-not-permitted-error
-     . operation-not-permitted-error)
-    (sb-bsd-sockets:protocol-not-supported-error
-     . protocol-not-supported-error)
-    (sb-bsd-sockets:socket-type-not-supported-error
-     . socket-type-not-supported-error)
-    (sb-bsd-sockets:network-unreachable-error . network-unreachable-error)
-    (sb-bsd-sockets:operation-timeout-error . timeout-error)
-    (sb-bsd-sockets:socket-error . ,#'map-socket-error)
-    ;; Nameservice errors: mapped to unknown-error
-;;    (sb-bsd-sockets:no-recovery-error . network-reset-error)
-;;    (sb-bsd-sockets:try-again-condition ...)
-;;    (sb-bsd-sockets:host-not-found ...)
-    ))
-
-(defun handle-condition (condition &optional (socket nil))
-  "Dispatch correct usocket condition."
-  (typecase condition
-    (error (let* ((usock-error (cdr (assoc (type-of condition)
-                                           +sbcl-error-map+)))
-                  (usock-error (if (functionp usock-error)
-                                   (funcall usock-error condition)
-                                 usock-error)))
-             (if usock-error
-                 (error usock-error :socket socket)
-               (error 'unknown-error
-                      :socket socket
-                      :real-error condition))))
-    (condition (let* ((usock-cond (cdr (assoc (type-of condition)
-                                              +sbcl-condition-map+)))
-                      (usock-cond (if (functionp usock-cond)
-                                      (funcall usock-cond condition)
-                                    usock-cond)))
-                 (if usock-cond
-                     (signal usock-cond :socket socket)
-                   (signal 'unknown-condition
-                           :real-condition condition))))))
-
-
-(defun socket-connect (host port &key (element-type 'character))
-  (let* ((socket (make-instance 'sb-bsd-sockets:inet-socket
-                                :type :stream :protocol :tcp))
-         (stream (sb-bsd-sockets:socket-make-stream socket
-                                                    :input t
-                                                    :output t
-                                                    :buffering :full
-                                                    :element-type element-type))
-         ;;###FIXME: The above line probably needs an :external-format
-         (usocket (make-stream-socket :stream stream :socket socket))
-         (ip (host-to-vector-quad host)))
-    (with-mapped-conditions (usocket)
-      (sb-bsd-sockets:socket-connect socket ip port))
-    usocket))
-
-(defun socket-listen (host port
-                           &key reuseaddress
-                           (reuse-address nil reuse-address-supplied-p)
-                           (backlog 5)
-                           (element-type 'character))
-  (let* ((reuseaddress (if reuse-address-supplied-p reuse-address reuseaddress))
-         (ip (host-to-vector-quad host))
-         (sock (make-instance 'sb-bsd-sockets:inet-socket
-                              :type :stream :protocol :tcp)))
-    (with-mapped-conditions ()
-       (setf (sb-bsd-sockets:sockopt-reuse-address sock) reuseaddress)
-       (sb-bsd-sockets:socket-bind sock ip port)
-       (sb-bsd-sockets:socket-listen sock backlog)
-       (make-stream-server-socket sock :element-type element-type))))
-
-(defmethod socket-accept ((socket stream-server-usocket) &key element-type)
-  (with-mapped-conditions (socket)
-     (let ((sock (sb-bsd-sockets:socket-accept (socket socket))))
-       (make-stream-socket
-        :socket sock
-        :stream (sb-bsd-sockets:socket-make-stream
-                 sock
-                 :input t :output t :buffering :full
-                 :element-type (or element-type
-                                   (element-type socket)))))))
-
-;; Sockets and their associated streams are modelled as
-;; different objects. Be sure to close the stream (which
-;; closes the socket too) when closing a stream-socket.
-(defmethod socket-close ((usocket usocket))
-  (with-mapped-conditions (usocket)
-    (sb-bsd-sockets:socket-close (socket usocket))))
-
-(defmethod socket-close ((usocket stream-usocket))
-  (with-mapped-conditions (usocket)
-    (close (socket-stream usocket))))
-
-(defmethod get-local-name ((usocket usocket))
-  (sb-bsd-sockets:socket-name (socket usocket)))
-
-(defmethod get-peer-name ((usocket stream-usocket))
-  (sb-bsd-sockets:socket-peername (socket usocket)))
-
-(defmethod get-local-address ((usocket usocket))
-  (nth-value 0 (get-local-name usocket)))
-
-(defmethod get-peer-address ((usocket stream-usocket))
-  (nth-value 0 (get-peer-name usocket)))
-
-(defmethod get-local-port ((usocket usocket))
-  (nth-value 1 (get-local-name usocket)))
-
-(defmethod get-peer-port ((usocket stream-usocket))
-  (nth-value 1 (get-peer-name usocket)))
-
-
-(defun get-host-by-address (address)
-  (with-mapped-conditions ()
-    (sb-bsd-sockets::host-ent-name
-        (sb-bsd-sockets:get-host-by-address address))))
-
-(defun get-hosts-by-name (name)
-  (with-mapped-conditions ()
-     (sb-bsd-sockets::host-ent-addresses
-         (sb-bsd-sockets:get-host-by-name name))))
-
-#+sbcl
-(progn
-  #-win32
-  (defun wait-for-input-internal (sockets &key timeout)
-    (with-mapped-conditions ()
-      (sb-alien:with-alien ((rfds (sb-alien:struct sb-unix:fd-set)))
-         (sb-unix:fd-zero rfds)
-         (dolist (socket sockets)
-           (sb-unix:fd-set
-            (sb-bsd-sockets:socket-file-descriptor (socket socket))
-            rfds))
-         (multiple-value-bind
-             (secs musecs)
-             (split-timeout (or timeout 1))
-           (multiple-value-bind
-               (count err)
-               (sb-unix:unix-fast-select
-                (1+ (reduce #'max (mapcar #'socket sockets)
-                            :key #'sb-bsd-sockets:socket-file-descriptor))
-                (sb-alien:addr rfds) nil nil
-                (when timeout secs) musecs)
-             (if (<= 0 count)
-                 ;; process the result...
-                 (remove-if
-                  #'(lambda (x)
-                      (not (sb-unix:fd-isset
-                            (sb-bsd-sockets:socket-file-descriptor (socket x))
-                            rfds)))
-                  sockets)
-               (progn
-                 (unless (= err sb-unix:EINTR)
-                   (error (map-errno-error err))))
-               ;;###FIXME generate an error, except for EINTR
-               ))))))
-
-  #+win32
-  (warn "wait-for-input not (yet!) supported...")
-  )
-
-#+ecl
-(progn
-  (defun wait-for-input-internal (sockets &key timeout)
-    (with-mapped-conditions ()
-      (multiple-value-bind
-          (secs usecs)
-          (split-timeout (or timeout 1))
-        (let* ((sock-fds (mapcar #'sb-bsd-sockets:socket-file-descriptor
-                                 (mapcar #'socket sockets)))
-               (result-fds (read-select sock-fds (when timeout secs) usecs)))
-          (remove-if #'(lambda (s)
-                         (not
-                          (member
-                           (sb-bsd-sockets:socket-file-descriptor (socket s))
-                           result-fds)))
-                   sockets)))))
-  )
+;;;; $Id$
+;;;; $URL$
+
+;;;; See LICENSE for licensing information.
+
+(in-package :usocket)
+
+;; There's no way to preload the sockets library other than by requiring it
+;;
+;; ECL sockets has been forked off sb-bsd-sockets and implements the
+;; same interface. We use the same file for now.
+#+ecl
+(eval-when (:compile-toplevel :load-toplevel :execute)
+  (require :sockets))
+
+#+sbcl
+(progn
+  #-win32
+  (defun get-host-name ()
+    (sb-unix:unix-gethostname))
+
+  ;; we assume winsock has already been loaded, after all,
+  ;; we already loaded sb-bsd-sockets and sb-alien
+  #+win32
+  (defun get-host-name ()
+    (sb-alien:with-alien ((buf (sb-alien:array sb-alien:char 256)))
+       (let ((result (sb-alien:alien-funcall
+                      (sb-alien:extern-alien "gethostname"
+                                             (sb-alien:function sb-alien:int
+                                                                (* sb-alien:char)
+                                                                sb-alien:int))
+                      (sb-alien:cast buf (* sb-alien:char))
+                      256)))
+         (when (= result 0)
+           (sb-alien:cast buf sb-alien:c-string))))))
+
+
+#+ecl
+(progn
+  #-:wsock
+  (ffi:clines
+   "#include <sys/socket.h>")
+  #+:wsock
+  (ffi:clines
+   "#ifndef FD_SETSIZE"
+   "#define FD_SETSIZE 1024"
+   "#endif"
+   "#include <winsock2.h>")
+
+  (ffi:clines
+   "#include <ecl/ecl-inl.h>")
+
+  #+:prefixed-api
+  (ffi:clines
+   "#define CONS(x, y) ecl_cons((x), (y))"
+   "#define MAKE_INTEGER(x) ecl_make_integer((x))")
+  #-:prefixed-api
+  (ffi:clines
+   "#define CONS(x, y) make_cons((x), (y))"
+   "#define MAKE_INTEGER(x) make_integer((x))")
+
+  (defun fd-setsize ()
+    (ffi:c-inline () () :fixnum
+     "FD_SETSIZE" :one-liner t))
+
+  (defun get-host-name ()
+    (ffi:c-inline
+     () () :object
+     "{ char *buf = GC_malloc(256);
+
+        if (gethostname(buf,256) == 0)
+          @(return) = make_simple_base_string(buf);
+        else
+          @(return) = Cnil;
+      }" :one-liner nil :side-effects nil))
+
+  (defun read-select (read-fds to-secs &optional (to-musecs 0))
+    (ffi:c-inline (read-fds to-secs to-musecs) (t t :unsigned-int) t
+      "{
+          fd_set rfds;
+          cl_object cur_fd = #0;
+          int count;
+          int max_fd = -1;
+          struct timeval tv;
+
+          FD_ZERO(&rfds);
+          while (CONSP(cur_fd)) {
+            int fd = fixint(cur_fd->cons.car);
+            max_fd = (max_fd > fd) ? max_fd : fd;
+            FD_SET(fd, &rfds);
+            cur_fd = cur_fd->cons.cdr;
+          }
+
+          if (#1 != Cnil) {
+            tv.tv_sec = fixnnint(#1);
+            tv.tv_usec = #2;
+          }
+          count = select(max_fd + 1, &rfds, NULL, NULL,
+                         (#1 != Cnil) ? &tv : NULL);
+
+          if (count == 0)
+            @(return) = Cnil;
+          else if (count < 0)
+            /*###FIXME: We should be raising an error here...
+
+              except, ofcourse in case of EINTR or EAGAIN */
+
+            @(return) = Cnil;
+          else
+            {
+              cl_object rv = Cnil;
+              cur_fd = #0;
+
+              /* when we're going to use the same code on Windows,
+                 as well as unix, we can't be sure it'll fit into
+                 a fixnum: these aren't unix filehandle bitmaps sets on
+                 Windows... */
+
+              while (CONSP(cur_fd)) {
+                int fd = fixint(cur_fd->cons.car);
+                if (FD_ISSET(fd, &rfds))
+                  rv = CONS(MAKE_INTEGER(fd), rv);
+
+                cur_fd = cur_fd->cons.cdr;
+              }
+              @(return) = rv;
+            }
+}"))
+
+)
+
+(defun map-socket-error (sock-err)
+  (map-errno-error (sb-bsd-sockets::socket-error-errno sock-err)))
+
+(defparameter +sbcl-condition-map+
+  '((interrupted-error . interrupted-condition)))
+
+(defparameter +sbcl-error-map+
+  `((sb-bsd-sockets:address-in-use-error . address-in-use-error)
+    (sb-bsd-sockets::no-address-error . address-not-available-error)
+    (sb-bsd-sockets:bad-file-descriptor-error . bad-file-descriptor-error)
+    (sb-bsd-sockets:connection-refused-error . connection-refused-error)
+    (sb-bsd-sockets:invalid-argument-error . invalid-argument-error)
+    (sb-bsd-sockets:no-buffers-error . no-buffers-error)
+    (sb-bsd-sockets:operation-not-supported-error
+     . operation-not-supported-error)
+    (sb-bsd-sockets:operation-not-permitted-error
+     . operation-not-permitted-error)
+    (sb-bsd-sockets:protocol-not-supported-error
+     . protocol-not-supported-error)
+    (sb-bsd-sockets:protocol-unknown
+     . protocol-not-supported-error)
+    (sb-bsd-sockets:socket-type-not-supported-error
+     . socket-type-not-supported-error)
+    (sb-bsd-sockets:network-unreachable-error . network-unreachable-error)
+    (sb-bsd-sockets:operation-timeout-error . timeout-error)
+    (sb-bsd-sockets:socket-error . ,#'map-socket-error)
+    ;; Nameservice errors: mapped to unknown-error
+;;    (sb-bsd-sockets:no-recovery-error . network-reset-error)
+;;    (sb-bsd-sockets:try-again-condition ...)
+;;    (sb-bsd-sockets:host-not-found ...)
+    ))
+
+(defun handle-condition (condition &optional (socket nil))
+  "Dispatch correct usocket condition."
+  (typecase condition
+    (error (let* ((usock-error (cdr (assoc (type-of condition)
+                                           +sbcl-error-map+)))
+                  (usock-error (if (functionp usock-error)
+                                   (funcall usock-error condition)
+                                 usock-error)))
+             (if usock-error
+                 (error usock-error :socket socket)
+               (error 'unknown-error
+                      :socket socket
+                      :real-error condition))))
+    (condition (let* ((usock-cond (cdr (assoc (type-of condition)
+                                              +sbcl-condition-map+)))
+                      (usock-cond (if (functionp usock-cond)
+                                      (funcall usock-cond condition)
+                                    usock-cond)))
+                 (if usock-cond
+                     (signal usock-cond :socket socket)
+                   (signal 'unknown-condition
+                           :real-condition condition))))))
+
+
+(defun socket-connect (host port &key (element-type 'character))
+  (let* ((socket (make-instance 'sb-bsd-sockets:inet-socket
+                                :type :stream :protocol :tcp))
+         (stream (sb-bsd-sockets:socket-make-stream socket
+                                                    :input t
+                                                    :output t
+                                                    :buffering :full
+                                                    :element-type element-type))
+         ;;###FIXME: The above line probably needs an :external-format
+         (usocket (make-stream-socket :stream stream :socket socket))
+         (ip (host-to-vector-quad host)))
+    (with-mapped-conditions (usocket)
+      (sb-bsd-sockets:socket-connect socket ip port))
+    usocket))
+
+(defun socket-listen (host port
+                           &key reuseaddress
+                           (reuse-address nil reuse-address-supplied-p)
+                           (backlog 5)
+                           (element-type 'character))
+  (let* ((reuseaddress (if reuse-address-supplied-p reuse-address reuseaddress))
+         (ip (host-to-vector-quad host))
+         (sock (make-instance 'sb-bsd-sockets:inet-socket
+                              :type :stream :protocol :tcp)))
+    (with-mapped-conditions ()
+       (setf (sb-bsd-sockets:sockopt-reuse-address sock) reuseaddress)
+       (sb-bsd-sockets:socket-bind sock ip port)
+       (sb-bsd-sockets:socket-listen sock backlog)
+       (make-stream-server-socket sock :element-type element-type))))
+
+(defmethod socket-accept ((socket stream-server-usocket) &key element-type)
+  (with-mapped-conditions (socket)
+     (let ((sock (sb-bsd-sockets:socket-accept (socket socket))))
+       (make-stream-socket
+        :socket sock
+        :stream (sb-bsd-sockets:socket-make-stream
+                 sock
+                 :input t :output t :buffering :full
+                 :element-type (or element-type
+                                   (element-type socket)))))))
+
+;; Sockets and their associated streams are modelled as
+;; different objects. Be sure to close the stream (which
+;; closes the socket too) when closing a stream-socket.
+(defmethod socket-close ((usocket usocket))
+  (with-mapped-conditions (usocket)
+    (sb-bsd-sockets:socket-close (socket usocket))))
+
+(defmethod socket-close ((usocket stream-usocket))
+  (with-mapped-conditions (usocket)
+    (close (socket-stream usocket))))
+
+(defmethod get-local-name ((usocket usocket))
+  (sb-bsd-sockets:socket-name (socket usocket)))
+
+(defmethod get-peer-name ((usocket stream-usocket))
+  (sb-bsd-sockets:socket-peername (socket usocket)))
+
+(defmethod get-local-address ((usocket usocket))
+  (nth-value 0 (get-local-name usocket)))
+
+(defmethod get-peer-address ((usocket stream-usocket))
+  (nth-value 0 (get-peer-name usocket)))
+
+(defmethod get-local-port ((usocket usocket))
+  (nth-value 1 (get-local-name usocket)))
+
+(defmethod get-peer-port ((usocket stream-usocket))
+  (nth-value 1 (get-peer-name usocket)))
+
+
+(defun get-host-by-address (address)
+  (with-mapped-conditions ()
+    (sb-bsd-sockets::host-ent-name
+        (sb-bsd-sockets:get-host-by-address address))))
+
+(defun get-hosts-by-name (name)
+  (with-mapped-conditions ()
+     (sb-bsd-sockets::host-ent-addresses
+         (sb-bsd-sockets:get-host-by-name name))))
+
+#+sbcl
+(progn
+  #-win32
+  (defun wait-for-input-internal (sockets &key timeout)
+    (with-mapped-conditions ()
+      (sb-alien:with-alien ((rfds (sb-alien:struct sb-unix:fd-set)))
+         (sb-unix:fd-zero rfds)
+         (dolist (socket sockets)
+           (sb-unix:fd-set
+            (sb-bsd-sockets:socket-file-descriptor (socket socket))
+            rfds))
+         (multiple-value-bind
+             (secs musecs)
+             (split-timeout (or timeout 1))
+           (multiple-value-bind
+               (count err)
+               (sb-unix:unix-fast-select
+                (1+ (reduce #'max (mapcar #'socket sockets)
+                            :key #'sb-bsd-sockets:socket-file-descriptor))
+                (sb-alien:addr rfds) nil nil
+                (when timeout secs) musecs)
+             (if (<= 0 count)
+                 ;; process the result...
+                 (remove-if
+                  #'(lambda (x)
+                      (not (sb-unix:fd-isset
+                            (sb-bsd-sockets:socket-file-descriptor (socket x))
+                            rfds)))
+                  sockets)
+               (progn
+                 (unless (= err sb-unix:EINTR)
+                   (error (map-errno-error err))))
+               ;;###FIXME generate an error, except for EINTR
+               ))))))
+
+  #+win32
+  (warn "wait-for-input not (yet!) supported...")
+  )
+
+#+ecl
+(progn
+  (defun wait-for-input-internal (sockets &key timeout)
+    (with-mapped-conditions ()
+      (multiple-value-bind
+          (secs usecs)
+          (split-timeout (or timeout 1))
+        (let* ((sock-fds (mapcar #'sb-bsd-sockets:socket-file-descriptor
+                                 (mapcar #'socket sockets)))
+               (result-fds (read-select sock-fds (when timeout secs) usecs)))
+          (remove-if #'(lambda (s)
+                         (not
+                          (member
+                           (sb-bsd-sockets:socket-file-descriptor (socket s))
+                           result-fds)))
+                   sockets)))))
+  )



More information about the usocket-cvs mailing list