Howto connect() from Solaris

How do you handle connect() errors? Suppose you are writing a simple TCP client application using standard sockets API, therefore you do (without error checking):

int sock; /* Socket descriptor */
struct sockaddr_in sa; /* Server address */
if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)

die("socket() failed");
bzero(&sa, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = inet_addr("74.125.77.147");
sa.sin_port = htons(80);
if (connect(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)
die("connect() failed");
<...>

This should work quite well, but what if you don’t want your app to die when connect() fails? Can you repeat connect() call, or do you have to close() the socket? Man pages are not very helpful in this case:-( Linux man page doesn’t contain anything relevant, nor does FreeBSD man page. The first hint we can find in X/Open standard:

http://pubs.opengroup.org/onlinepubs/009695399/functions/connect.html

There is again nothing in required sections, but in informative section Application Usage we find:

If connect() fails, the state of the socket is unspecified. Conforming applications should close the file descriptor and create a new socket before attempting to reconnect.

So this seems that if you are writing portable applications (and you are, right?), you should close() the socket in case connect() returns any error. Is this really necessary? Solaris connect(3socket) man page says for ECONNREFUSED error code:

     ECONNREFUSED   The attempt to  connect  was  force-
                             fully  rejected. The calling program
                             should close(2) the socket  descrip-
                             tor,      and      issue     another
                             socket(3SOCKET) call to obtain a new
                             descriptor before attempting another
                             connect() call.

This is only a recommendation, and only for one error code, so again nothing relevant. But finally connect(3xnet) man page says:

USAGE
     If connect() fails, the state of the socket is  unspecified.
     Portable  applications  should close the file descriptor and
     create a new socket before attempting to reconnect.

So in case you are using libxnet library for sockets implementation it’s clear – you have to close() the socket on any error, because you cannot work with socket in unspecified state. But it doesn’t matter which library you are using, does it? Both of them uses the same syscall for connect operation, and therefore the kernel behavior would be the same in both cases, right? So we have a result:

On Solaris you have to close() the socket every time connect() returns any error code.
I am not sure about behavior of other systems, but I would be afraid it’ll be the same in all cases. So close() your sockets rather every time.