Blocking call to connect()

Robert S. Thau rst at ai.mit.edu
Tue Mar 18 11:39:59 PST 1997


Daniel Veillard writes:
 > This is Ok for me, except that connect() is not something we can select()
 > on ... It seems that the standard way to do non-blocking connect() is to
 > set up O_NONBLOCK, then the connect call returns EINPROGRESS or EAGAIN ...

Hmmmm... On many systems, a select() with a bit set in the write mask
for the socket with the connect() in progress will do the right thing;
I'd hope this is specified as standard by POSIX, but I'm not certain.
(Unfortunately, documentation of this fact is often buried in the
"errors" section of the connect(2) man page, as an aside in the
description of the EWOULDBLOCK or EINPROGRESS return code returned by
the original non-blocking connect()).

 > Any opinion on this ? I would also love a patch for non blocking DNS lookup,
 > alas it seems to be nearly impossible to do in a portable way :-(, UNIX and
 > POSIX doesn't seem to offer standardized way to get the name resolution server
 > addresses ...

... which wouldn't always be useful anyway, since the name services
implementing the libc gethostbyfred() interfaces don't necessarily
implement the DNS protocol.  (There are sites, for instance, which use
NIS or NIS+ for the purpose, and don't actually run DNS nameservers
on internal machines).

FWIW, every vendor I've ever seen with DNS-based implementations of
gethostby{name,addr}() uses some variant of the BIND distribution to
interact with the local resolver, and while BIND's interface has not
been ratified by any standards body that I'm aware of, it's fairly
consistent across released versions.  Still, if you want to restrict
yourself to strict POSIX (perhaps to run even on non-DNS systems), and
not count on getting non-blocking variants of the functions from POSIX
threads, the best hack I can think of would be to spawn off a
subprocess to do the lookups (and therefore, block on them); the main
kaffe process could then communicate by non-blocking I/O to it.  (This
would not allow multiple lookups to be in progress simultaneously, but
it would at least keep them from blocking, say, mouse-click handling).

Returning to the notion of dealing with BIND: a while ago, I was
playing with a small threads package of my own, which actually has a
non-blocking interface to DNS, making use of (documented interfaces
to) BIND.  The code isn't bulletproofed, but it should at least give
you an idea of what it takes to implement (nearly) libc-compatible
gethostbyname() and ...byaddr() interfaces.  This code is at

  ftp://ftp.ai.mit.edu/pub/users/rst/rsthreads.tar.gz

if anyone would like to take a look.  (Look specifically at the file
rsthreads_dns.c). 

The main problem I'm aware of, BTW, is that these routines *only*
search DNS --- therefore, lookups for hosts named by, say, your local
/etc/hosts file will fail.  (An easy way to see this on a lot of
systems is to try looking up "localhost").  However, there's probably
something else lurking about.

rst


More information about the kaffe mailing list