From owner-freebsd-hackers Wed Nov 13 12:29:51 1996 Return-Path: owner-hackers Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id MAA13534 for hackers-outgoing; Wed, 13 Nov 1996 12:29:51 -0800 (PST) Received: from lehman.Lehman.COM (lehman.Lehman.COM [192.147.66.1]) by freefall.freebsd.org (8.7.5/8.7.3) with SMTP id MAA13511 for ; Wed, 13 Nov 1996 12:29:42 -0800 (PST) From: carson@lehman.com Received: (from smap@localhost) by lehman.Lehman.COM (8.6.12/8.6.12) id PAA18646; Wed, 13 Nov 1996 15:28:53 -0500 Received: from relay.mail.lehman.com(192.9.140.112) by lehman via smap (V1.3) id tmp018639; Wed Nov 13 15:28:50 1996 Received: from kublai.lehman.com by relay.lehman.com (4.1/LB-0.6) id AA16191; Wed, 13 Nov 96 15:28:48 EST Received: from dragon.lehman.com by kublai.lehman.com (4.1/Lehman Bros. V1.6) id AA28386; Wed, 13 Nov 96 15:28:39 EST Received: by dragon.lehman.com (SMI-8.6/Lehman Bros. V1.5) id PAA18081; Wed, 13 Nov 1996 15:28:39 -0500 Date: Wed, 13 Nov 1996 15:28:39 -0500 Message-Id: <199611132028.PAA18081@dragon.lehman.com> To: Terry Lambert Cc: stesin@gu.net (Andrew Stesin), hackers@freebsd.org, squid-users@nlanr.net, basch@lehman.com Subject: Re: Programming technique for non-forking servers? In-Reply-To: <199611131938.MAA22676@phaeton.artisoft.com> References: <199611131938.MAA22676@phaeton.artisoft.com> Reply-To: carson@lehman.com Sender: owner-hackers@freebsd.org X-Loop: FreeBSD.org Precedence: bulk Unfortunately, your code fragment doesn't handle async connect properly. Error handling for async connect is non-trivial to write portably. Here are the possible statuses and select() returns: Connect Status Select Return -------------- ------------- inprogress nothing success write _and_, possibly, read (if data was written from the far side before select returned) failure read (and usually write as well, but some OS's seem to be broken) So, the question is, how do you tell if connect actually failed, and what the errno was? Good question... Here are your options: 1) getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&err, &len) Nice, but some systems (HP?) don't support SO_ERROR 2) read(fd, buf, 0) Will either succeed or fail and set errno to the connect failure cause. Unless the system doesn't support 0-byte reads... or it doesn't return connect's error in errno... 3) getpeername() Works everywhere, but looses the connect error... Oh, and don't forget that sometimes connect() will return immediately, even if the socket is non-blocking, so you have to check for all possible states (success, non-blocking, or error). And be carefull, connect() can return different values for non-blocking on different OS's (EINPROGRESS, EWOULDBLOCK, etc.) -- Carson Gaspar -- carson@cs.columbia.edu carson@lehman.com http://www.cs.columbia.edu/~carson/home.html