Using select(2) to wait for connect(2)

der Mouse mouse at mcgill-vision.UUCP
Thu Dec 4 17:21:28 AEST 1986


In article <46 at otc.OZ>, adjg at otc.OZ (Andrew Gollan) writes:
> I need to have a server that forms a junction between two client
> processes.  Further if one of the clients is not present the other
> must still be serviced.  I read the manual on accept(2) and found
> that one could use select(2) to wait for incoming connections.

Or at least that one is supposed to be able to do so.  In this case,
luckily, the documentation isn't lying.

> I wrote two programs of which the following are the pertinent
> ex[c]erpts.
[much edited]
> /*	SERVER	*/
[...]
> main()
> {
[...]
>     for (;;)
>     {
> 	int 		mask	= (1 << s0) | (1 << s1);
> 	register int 	i;
> 	if (select(2, &mask, (int *)0, (int *)0, 0) < 0)

[ The last zero in the call should be (struct timeval *)0.  Your care
  in casting the other zeros to (int *) is commendable, but carry it
  the rest of the way! ]

> 	    exit(1);
[...]
> ------------------------------------------------------------------------
> The problem:
> 	The select in the server never returns.  The connects in the
> 	client return immediately.  [...] I was told that there were
> 	lots of bugs in the AF_UNIX domain, so I rewrote the code for
> 	the AF_INET domain.  Same problem.

> The questions:
> 	Am I doing something horribly wrong or is it that select(2)
> 	does not perform as documented? Have I missed something in the
> 	documentation?

You don't state what sort of system it is, but since it has select() I
assume 4.2 or 4.3 BSD.  Since you are using ints rather than fd_sets
for the select() arguments, I assume 4.2 BSD.

You missed (or misunderstood) something in the documentation for
select().  Here are the relevant excerpts from the 4.3 man page; the
meaning applies to 4.2 as well, though the wording may be different:

SELECT(2)           UNIX Programmer's Manual            SELECT(2)

     nfound = select(nfds, readfds, writefds, exceptfds, timeout)

DESCRIPTION
     [...] The first nfds descriptors are checked in each set; i.e. the
     descriptors from 0 through nfds-1 in the descriptor sets are
     examined.

That is, your specification of 2 means that file descriptors 0 and 1
are the only ones select() is paying any attention to.  Unless s0 and
s1 are zero and one, this means that at least one of them is being
ignored.  You should be passing at least one more than the larger of s0
and s1:

	int mask = (1 << s0) | (1 << s1);
	int maxs = (s0 < s1) ? s1 : s0;

	if (select(maxs+1,&mask,(int *)0,(int *)0,(struct timeval *)0) < 0)

					der Mouse

USA: {ihnp4,decvax,akgua,utzoo,etc}!utcsri!mcgill-vision!mouse
     think!mosart!mcgill-vision!mouse
Europe: mcvax!decvax!utcsri!mcgill-vision!mouse
ARPAnet: think!mosart!mcgill-vision!mouse at harvard.harvard.edu

[USA NSA food: terrorist, cryptography, DES, drugs, CIA, secret, decode]



More information about the Comp.unix.wizards mailing list