0.8.7.49:
[sbcl.git] / contrib / sb-bsd-sockets / sockets.lisp
index 3134e7d..9f15ad6 100644 (file)
@@ -64,7 +64,7 @@ See also bind(2)"))
   (let ((sockaddr (apply #'make-sockaddr-for socket nil address)))
     (if (= (sb-sys:with-pinned-objects (sockaddr)
            (sockint::bind (socket-file-descriptor socket)
-                          (sockint::array-data-address sockaddr)
+                          (sb-grovel::array-data-address sockaddr)
                           (size-of-sockaddr socket)))
            -1)
         (socket-error "bind"))))
@@ -77,9 +77,9 @@ values"))
   
 (defmethod socket-accept ((socket socket))
   (let ((sockaddr (make-sockaddr-for socket)))
-    (sb-ext::with-pointers-preserved (sockaddr)
+    (sb-sys:with-pinned-objects (sockaddr)
       (let ((fd (sockint::accept (socket-file-descriptor socket)
-                                (sockint::array-data-address sickint)
+                                (sb-grovel::array-data-address sockaddr)
                                 (size-of-sockaddr socket))))
        (apply #'values
               (if (= fd -1)
@@ -99,7 +99,7 @@ values"))
   (let* ((sockaddr (apply #'make-sockaddr-for socket nil peer)))
     (if (= (sb-sys:with-pinned-objects (sockaddr)
            (sockint::connect (socket-file-descriptor socket)
-                             (sockint::array-data-address sockaddr)
+                             (sb-grovel::array-data-address sockaddr)
                              (size-of-sockaddr socket)))
           -1)
        (socket-error "connect") )))
@@ -112,7 +112,7 @@ values"))
   (let* ((sockaddr (make-sockaddr-for socket)))
     (when (= (sb-sys:with-pinned-objects (sockaddr)
              (sockint::getpeername (socket-file-descriptor socket)
-                                   (sockint::array-data-address sockaddr)
+                                   (sb-grovel::array-data-address sockaddr)
                                    (size-of-sockaddr socket)))
             -1)
       (socket-error "getpeername"))
@@ -126,7 +126,7 @@ values"))
   (let* ((sockaddr (make-sockaddr-for socket)))
     (when (= (sb-sys:with-pinned-objects (sockaddr)
              (sockint::getsockname (socket-file-descriptor socket)
-                                   (sockint::array-data-address sockaddr)
+                                   (sb-grovel::array-data-address sockaddr)
                                    (size-of-sockaddr socket)))
             -1)
       (socket-error "getsockname"))
@@ -172,10 +172,10 @@ small"))
       (sb-sys:with-pinned-objects (buffer sockaddr) 
        (let ((len
              (sockint::recvfrom (socket-file-descriptor socket)
-                                (sockint::array-data-address buffer)
+                                (sb-grovel::array-data-address buffer)
                                 (or length (length buffer))
                                 flags
-                                (sockint::array-data-address sockaddr)
+                                (sb-grovel::array-data-address sockaddr)
                                 (sb-alien:cast sa-len (* integer)))))
         (when (= len -1) (socket-error "recvfrom"))
         (apply #'values buffer len (multiple-value-list
@@ -207,19 +207,27 @@ stream instead"))
   ;; descriptor).  Presumably this is an oversight and we could also
   ;; get anything that write(2) would have given us.
 
-  ;; What we do: we catch EBADF.  It should only ever happen if
-  ;; (a) someone's closed the socket already (stream closing seems
-  ;; to have this effect) or (b) the caller is messing around with
-  ;; socket internals.  That's not supported, dude
-  
-  (if (slot-boundp socket 'stream)
-      (close (slot-value socket 'stream))  ;; closes socket as well
-    (handler-case
-     (if (= (sockint::close (socket-file-descriptor socket)) -1)
-         (socket-error "close"))
-     (bad-file-descriptor-error (c) (declare (ignore c)) nil)
-     (:no-error (c)  (declare (ignore c)) nil))))
+  ;; note that if you have a socket _and_ a stream on the same fd, 
+  ;; the socket will avoid doing anything to close the fd in case
+  ;; the stream has done it already - if so, it may have been
+  ;; reassigned to some other file, and closing it would be bad
+
+  (let ((fd (socket-file-descriptor socket)))
+    (cond ((eql fd -1) ; already closed
+          nil)
+         ((slot-boundp socket 'stream)
+          (close (slot-value socket 'stream)) ;; closes fd
+          (setf (slot-value socket 'file-descriptor) -1)
+          (slot-makunbound socket 'stream))
+         (t
+          (sb-ext:cancel-finalization socket)
+          (handler-case
+              (if (= (sockint::close fd) -1)
+                  (socket-error "close"))
+            (bad-file-descriptor-error (c) (declare (ignore c)) nil)
+            (:no-error (c)  (declare (ignore c)) nil))))))
 
+    
 (defgeneric socket-make-stream (socket  &rest args)
     (:documentation "Find or create a STREAM that can be used for IO
 on SOCKET (which must be connected).  ARGS are passed onto