(type :initarg :type
:reader socket-type
:documentation "Type of the socket: :STREAM or :DATAGRAM.")
+ #+win32
+ (non-blocking-p :type (member t nil) :initform nil)
(stream))
(:documentation "Common base class of all sockets, not meant to be
directly instantiated.")))
(list sockint::EAGAIN sockint::EINTR)))
nil)
((= len -1) (socket-error "recvfrom"))
- (t (loop for i from 0 below len
+ (t (loop for i from 0 below (min len length)
do (setf (elt buffer i)
(cond
((or (eql element-type 'character) (eql element-type 'base-char))
(declare (ignore r))
(drop-it))))))))
+(defgeneric socket-shutdown (socket &key direction)
+ (:documentation
+ "Indicate that no communication in DIRECTION will be performed on SOCKET.
+
+DIRECTION has to be one of :INPUT, :OUTPUT or :IO.
+
+After a shutdown, no input and/or output of the indicated DIRECTION
+can be performed on SOCKET."))
+
+(defmethod socket-shutdown ((socket socket) &key direction)
+ (let* ((fd (socket-file-descriptor socket))
+ (how (ecase direction
+ (:input sockint::SHUT_RD)
+ (:output sockint::SHUT_WR)
+ (:io sockint::SHUT_RDWR))))
+ (when (minusp (sockint::shutdown fd how))
+ (socket-error "shutdown"))))
+
(defgeneric socket-make-stream (socket &key input output
element-type external-format
buffering
:external-format external-format
:timeout timeout
:auto-close auto-close
- :serve-events serve-events))
+ :serve-events (and serve-events #+win32 nil)))
(setf (slot-value socket 'stream) stream))
(sb-ext:cancel-finalization socket)
stream))
(socket-error-syscall c)
(or (socket-error-symbol c) (socket-error-errno c))
#+cmu (sb-unix:get-unix-error-msg num)
- #+sbcl (sb-int:strerror num)))))
+ #+sbcl
+ #+win32 (sb-win32::get-last-error-message num)
+ #-win32 (sb-int:strerror num)))))
(:documentation "Common base class of socket related conditions."))
;;; watch out for slightly hacky symbol punning: we use both the value