Opened 15 months ago

Last modified 13 months ago

#1425 new defect

Premature error reading from closed socket

Reported by: mstickney Owned by:
Priority: normal Milestone:
Component: other Version: trunk
Keywords: Cc:

Description

If a client connects to a server, writes some data, and closes the socket, and if the server writes some data to the client after the socket was closed, a subsequent read will signal an erroneous error even though there is data available. This issue is also present in SBCL, and seems to be Windows-specific.

(lisp-implementation-version)
;=> "Version 1.11-r16635  (WindowsX8632)"

Test code (run CCL-READ-IT, then run CCL-WRITE-IT in a second process):

(defun ccl-read-it ()
  (let ((srv-sock (make-socket :type :stream :connect :passive :local-host "127.0.0.1" :local-port 9001)))
    (let* ((sock (accept-connection srv-sock)))
      (unwind-protect
          (progn
            ;; Wait for the client to close the socket.
            (sleep 1)
            ;; With this write commented out, everything works normally.
            (write-sequence (make-array 40 :initial-element 3 :element-type '(unsigned-byte 8)) sock)
            (finish-output sock)
            (let ((sequence (make-array 1 :element-type '(unsigned-byte 8))))
              ;; With the right enabled, this signals an error.
              (read-sequence sequence sock :end 1)))
        (close sock)
        (close srv-sock)))))

(defun ccl-write-it ()
  (let ((sock (make-socket :type :stream :connect :active :remote-host "127.0.0.1" :remote-port 9001)))
    (socket-connect sock)
    (unwind-protect
        (progn
          (format sock "Rhubarb")
          (finish-output sock))
      (close sock))))

When the write is enabled, READ-SEQUENCE signals the following error:

> Error: on #<BASIC-TCP-STREAM ISO-8859-1 (SOCKET/1560) #xC8E43CE> :
>        The device does not recognize the command.  (error #22) during read
> While executing: SOCKET-ERROR, in process listener(1).

1 > :b
 (1CC9C1C) : 0 (SOCKET-ERROR #<BASIC-TCP-STREAM ISO-8859-1 (SOCKET/1560) #xC8E43
CE> "read" 22 NIL :CONNECT-ADDRESS NIL) 431
 (1CC9C3C) : 1 (%BIVALENT-IOBLOCK-READ-U8-BYTE #S(CCL::IOBLOCK :STREAM #<BASIC-T
CP-STREAM ISO-8859-1 (SOCKET/1560) #xC8E43CE> :UNTYI-CHAR NIL ...)) 175
 (1CC9C58) : 2 (%IOBLOCK-BINARY-READ-VECTOR #S(CCL::IOBLOCK :STREAM #<BASIC-TCP-
STREAM ISO-8859-1 (SOCKET/1560) #xC8E43CE> :UNTYI-CHAR NIL ...) #(0) 0 1) 439
 (1CC9C84) : 3 (FUNCALL #'#<#<CCL::STANDARD-KERNEL-METHOD STREAM-READ-VECTOR (CC
L::BASIC-BINARY-INPUT-STREAM T T T)>> #<BASIC-TCP-STREAM ISO-8859-1 (SOCKET/1560
) #xC8E43CE> #(0) 0 1) 975
 (1CC9CA8) : 4 (%%STANDARD-COMBINED-METHOD-DCODE (#<CCL::STANDARD-KERNEL-METHOD
STREAM-READ-VECTOR #> #<CCL::STANDARD-KERNEL-METHOD STREAM-READ-VECTOR #>) 75466
77) 623
 (1CC9CE8) : 5 (READ-SEQUENCE #(0) #<BASIC-TCP-STREAM ISO-8859-1 (SOCKET/1560) #
xC8E43CE> :START 0 :END 1) 631
 (1CC9D10) : 6 (CCL-READ-IT) 423
 (1CC9D40) : 7 (CALL-CHECK-REGS CCL-READ-IT) 247
 (1CC9D5C) : 8 (TOPLEVEL-EVAL (CCL-READ-IT) NIL) 711
 (1CC9D98) : 9 (READ-LOOP :INPUT-STREAM #<SYNONYM-STREAM to *TERMINAL-IO* #xC22B
5A6> :OUTPUT-STREAM #<SYNONYM-STREAM to *TERMINAL-IO* #xC22B4CE> :BREAK-LEVEL 0
:PROMPT-FUNCTION #<Compiled-function (:INTERNAL CCL::READ-LOOP) (Non-Global)  #x
44D351E>) 2039
 (1CC9EBC) : 10 (RUN-READ-LOOP :BREAK-LEVEL 0) 183
 (1CC9ED0) : 11 (TOPLEVEL-LOOP) 71
 (1CC9ED8) : 12 (FUNCALL #'#<(:INTERNAL (TOPLEVEL-FUNCTION (CCL::LISP-DEVELOPMEN
T-SYSTEM T)))>) 71
 (1CC9EE8) : 13 (FUNCALL #'#<(:INTERNAL CCL::MAKE-MCL-LISTENER-PROCESS)>) 551
 (1CC9F34) : 14 (RUN-PROCESS-INITIAL-FORM #<TTY-LISTENER listener(1) [Active] #x
C22AC4E> (#<COMPILED-LEXICAL-CLOSURE # #xC22A986>)) 639
 (1CC9F78) : 15 (FUNCALL #'#<(:INTERNAL (CCL::%PROCESS-PRESET-INTERNAL (PROCESS)
))> #<TTY-LISTENER listener(1) [Active] #xC22AC4E> (#<COMPILED-LEXICAL-CLOSURE #
 #xC22A986>)) 519
 (1CC9FCC) : 16 (FUNCALL #'#<(:INTERNAL CCL::THREAD-MAKE-STARTUP-FUNCTION)>) 255

Change History (1)

comment:1 Changed 13 months ago by mstickney

I was able to reproduce this with a non-lisp test program, so this may be a Windows bug; it would be nice to have a workaround, but obviously CCL can't fix an internal windows issue.

I was going to contact Microsoft to either report the bug or ask if this was a known issue, but I was unable to find out how you actually do that. If anyone here knows, I'd appreciate a hint.

Note: See TracTickets for help on using tickets.