SOCKET-PEERNAME.
** SOCKET-MAKE-STREAM once more supports the :AUTO-CLOSE option.
(lp#540413)
+ ** SOCKET-CLOSE now accepts :ABORT argument, which is passed on to
+ CL:CLOSE when appropriate, and no longer disassociates the stream
+ from the socket if close failed. (lp#543951)
* improvements to the instrumenting profiler
** new feature: report per-function GC overhead. (thanks to John Fremlin)
** optimization: counters no longer use locks for the overflow mode.
(open-stream-p (slot-value socket 'stream))
(/= -1 (socket-file-descriptor socket))))
-(defgeneric socket-close (socket)
- (:documentation "Close SOCKET. May throw any kind of error that
-write(2) would have thrown. If SOCKET-MAKE-STREAM has been called,
-calls CLOSE on that stream instead"))
+(defgeneric socket-close (socket &key abort)
+ (:documentation
+ "Close SOCKET, unless it was already closed.
+
+If SOCKET-MAKE-STREAM has been called, calls CLOSE using ABORT on that stream.
+Otherwise closes the socket file descriptor using close(2)."))
-(defmethod socket-close ((socket socket))
+(defmethod socket-close ((socket socket) &key abort)
;; the close(2) manual page has all kinds of warning about not
;; checking the return value of close, on the grounds that an
;; earlier write(2) might have returned successfully w/o actually
;; 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)
- (unwind-protect (close (slot-value socket 'stream)) ;; closes fd
+ (flet ((drop-it (&optional streamp)
(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))
- (setf (slot-value socket 'file-descriptor) -1)
- nil))))))
-
+ (if streamp
+ (slot-makunbound socket 'stream)
+ (sb-ext:cancel-finalization socket))
+ t))
+ (cond ((eql fd -1)
+ ;; already closed
+ nil)
+ ((slot-boundp socket 'stream)
+ (close (slot-value socket 'stream) :abort abort)
+ ;; Don't do this if there was an error from CLOSE -- the stream is
+ ;; still live.
+ (drop-it t))
+ (t
+ (handler-case
+ (when (minusp (sockint::close fd))
+ (socket-error "close"))
+ (bad-file-descriptor-error ()
+ (drop-it))
+ (:no-error (r)
+ (declare (ignore r))
+ (drop-it))))))))
(defgeneric socket-make-stream (socket &key input output
element-type external-format