Hello,

While writing a socket server in Chicken for kicks I think I run into a
bug in the sockets egg where socket-accept would not handle the error
generated by select() if the listener socket had been closed - the error
is already handled in the egg when selecting for writing.

I am not sure how the procedure for reporting bugs for eggs or
submitting patches works and am still very new to Chicken, but the
chicken-install utility has been very nice so far and has made it very
easy to test modifications (with -R and just chicken-install to
reinstall a local version). Thanks for that, for the useful
implementation, and for the egg!

I have attached a patch that I believe fixes the bug.

Regards,
-- 
  Jonathan Chan
  j...@fastmail.fm
--- socket.scm	2013-11-27 00:21:47.016722696 -0800
+++ socket.new.scm	2013-11-27 00:21:40.046604461 -0800
@@ -737,17 +737,21 @@
   (let ((s (socket-fileno so))
         (to (socket-accept-timeout)))
     (let restart ()
-      (if (eq? 1 (select-for-read s))
-          (let ((s (_accept s #f #f)))
-            (when (eq? -1 s)
-              (network-error/errno 'socket-accept "could not accept from listener" so))
-            (let ((so (make-socket s (socket-family so) (socket-type so) (socket-protocol so))))
-              (unless (_make_socket_nonblocking s)
-                (network-error/errno 'socket-accept "unable to set socket to non-blocking" so))
-              so))
-          (begin
+      (let ((f (select-for-read s)))
+        (cond 
+          ((eq? f -1)
+           (network-error/errno 'socket-connect "select failed" so))
+          ((eq? f 1)
+           (let ((s (_accept s #f #f)))
+             (when (eq? -1 s)
+               (network-error/errno 'socket-accept "could not accept from listener" so))
+             (let ((so (make-socket s (socket-family so) (socket-type so) (socket-protocol so))))
+               (unless (_make_socket_nonblocking s)
+                 (network-error/errno 'socket-accept "unable to set socket to non-blocking" so))
+               so)))
+          (else 
             (block-for-timeout! 'socket-accept to s #:input)
-            (restart))))))
+            (restart)))))))
 
 ;; Returns number of bytes received.  If 0, and socket is sock/stream, peer has shut down his side.
 (define (socket-receive! so buf #!optional (start 0) (end #f) (flags 0))
_______________________________________________
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users

Reply via email to