X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=contrib%2Fsb-bsd-sockets%2Fsockets.lisp;h=9f15ad636a932da1e8b86a8271c31eb59a5e6e89;hb=70c980b4c9285f4d518c80d314baac0da511c1bf;hp=3134e7df50466481815a444f8e9e6ae5d63f36ee;hpb=b7eed59f1877263e1af5ad80299e641e8276f77d;p=sbcl.git diff --git a/contrib/sb-bsd-sockets/sockets.lisp b/contrib/sb-bsd-sockets/sockets.lisp index 3134e7d..9f15ad6 100644 --- a/contrib/sb-bsd-sockets/sockets.lisp +++ b/contrib/sb-bsd-sockets/sockets.lisp @@ -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