Re: on the semantics of connect(): EINTR, EALREADY, EINPROGRESS

From: David Madore (david.madore@ens.fr)
Date: 04/22/03


From: david.madore@ens.fr (David Madore)
Date: 22 Apr 2003 21:04:07 GMT

joe@invalid.address in litteris <m3fzoal3y0.fsf@invalid.address>
scripsit:
> The standard behavior is defined at
> http://www.opengroup.org/onlinepubs/007904975/functions/connect.html
>
<snip first part>
>
> [...]
>
> "When the connection has been established asynchronously, select()
> and poll() shall indicate that the file descriptor for the socket
> is ready for writing."
>
> I think you just missed the second quote above. Put the descriptor in
> the write mask for select() and then test it when it comes up ready
> for writing. Since it's then essentially a non-blocking connect, see
> also

The quote in question describes what select() and poll() do, but not
what a second call to connect() does, which is what I was asking
about. There are times when one would avoid select() and poll(), and
the whole point of using blocking sockets is precisely to do so: I
don't see why blocking sockets would be available in the first place
if they're just as much a @$!#$%!$ pain in the ass to program with as
non-blocking sockets.

So, basically, I'm asking whether the following code fragment will
work as expected:

/* Start with fd just returned by socket(), blocking... */
while ( connect (fd, &name, namelen) == -1 && errno != EISCONN )
  if ( errno != EINTR )
    {
      perror ("connect");
      exit (EXIT_FAILURE);
    }
/* At this point, fd is connected. */

I expect it to wait and return fd connected (or an error), and not to
fail with an error message such as "Operation already in progress". I
believe under Linux it will work as expected.

I know I *could* do it with poll() or select(), but that means using
way more variables and writing far more complicated code than the six
lines above (which are already far more complicated than I find
reasonable, but that is a matter of taste). I also know I could use
SA_RESTART on all my signal handlers, but this is unreliable in
various ways.

> http://www.muq.org/~cynbe/ref/nonblocking-connects.html
> http://cr.yp.to/docs/connect.html

Thanks, but this essentially shows that non-blocking sockets are far
more complicated to use than blocking sockets (consider the number of
lines in the code fragments under the first URL, as opposed to the six
lines above). Non-blocking is good when one wants to test for events
on a variety of sources: it is definitely overkill when testing
connection on a *single* socket.

>> [...] The connect() function
>> shall fail if: [...] [EALREADY] A connection request is already in
>> progress for the specified socket." There is nothing saying that
>> EALREADY is used only for non-blocking sockets, so the second call
>> should fail with EALREADY if the first one returned EINTR, starting an
>> asynchronous connection attempt: this is behavior 1 in my list above.
>
> As I read it, the situation described turns this into a non-blocking
> connection attempt, even though the socket isn't in non-blocking
> mode ("the connection shall be established asynchronously").

So you read it as behavior 1 in the list I gave?

Can you confirm, then, that Linux, FreeBSD, OpenBSD and Solaris, all
misbehave in this respect by not respecting the standard.

> Of course, the system man pages are probably a better source of what
> any particular implementation actually does.

But they aren't: on FreeBSD, the man page documents EALREADY as a
possible return value of connect() (for non-blocking sockets only),
and does not document EINTR as possible, and the source code seems to
say precisely the contrary.

-- 
     David A. Madore
    (david.madore@ens.fr,
     http://www.eleves.ens.fr:8080/home/madore/ )


Relevant Pages

  • Re: threads & sockets
    ... > initially establishing the connection would be drowned out by the benefits. ... initial request. ... > the number of active sockets, then poll is O. ...
    (comp.unix.programmer)
  • Re: threads & sockets
    ... initially establishing the connection would be drowned out by the benefits. ... I'm at most messing with 100 sockets. ... > One active connection!= high load, ... then poll is O. ...
    (comp.unix.programmer)
  • Re: Why my call to close() or shutdown() stalls all network I/O (and other related questions) ?
    ... > then make it non-blocking with ioctl. ... > Then I loop on acceptfor the next connection. ... descriptor referring to the connection. ... > of non-blocking sockets, so I expected than a manual polling with fd was ...
    (comp.unix.programmer)
  • Re: NIO
    ... non-blocking, which means that it will return from your .writeright away, ... Once this is done you can close the connection ... be sure you actually need non-blocking sockets to begin with. ... > I have a little test server and client application. ...
    (comp.lang.java.programmer)
  • Re: Close a blocked socket
    ... ..NET, that non-blocking model is easier and should scale better, you decided ... by dedicating a thread or two to the socket i/o and using blocking ... using blocking sockets, then good for you. ... connection to the Internet on the server side. ...
    (microsoft.public.dotnet.languages.csharp)