[comp.protocols.tcp-ip] HELP: select

ron@TOPAZ.RUTGERS.EDU (Ron Natalie) (09/06/87)

The definition of the first argument to the socket is the maximum file
descriptor that can be specified in any of the other fields.  You set
it to one (presumably because you are assuming the value was supposed to
be the number of things selecting on).  Setting this value to one means
that you can only select on file descriptor 0.  Set the value to something
larger like the maximum number of file descriptors (NFILE).

-ROn

geof@apolling.UUCP (Geof Cooper) (09/08/87)

 > The definition of the first argument to the socket is the maximum file
 > descriptor that can be specified in any of the other fields.  You set
 > it to one (presumably because you are assuming the value was supposed to
 > be the number of things selecting on).  Setting this value to one means
 > that you can only select on file descriptor 0.  Set the value to something
 > larger like the maximum number of file descriptors (NFILE).

Umm, I just looked into /usr/include/stdio.h on our apollo system:

    Changelog entry:
        10/01/82 jrw  increased _NFILE from 20 to 128.....

So using NFILE is probably NOT the way to go, unless you declare
readfds, et al as arrays (this leads one to wonder, of course, why
the existing apollo software works at all -- since I know of no code
that actually uses arrays with select.  Probably because no one actually
opens more than 32 file descriptors and only THEN creates a socket...).

In a separate note to Mr. Widdowson, I suggested:

        min( 8 * (sizeof readfds), NFILE )

so that the argument really does reflect the size of the data
being passed to it.  Actually,

        8 * (sizeof readfds)

is probably sufficient, since you will never actually turn on
a bit that is beyond NFILE (hmmm... maybe little-endian vs
big-endian affects things... comments?).

Unfortunately, this is non-portable, since the size of a char is
not necessarily 8 bits.  But I suspect that all network software
would break if char != octet.

- Geof

zben@umd5.umd.edu (Ben Cranston) (09/08/87)

In article <8709061618.AA14584@topaz.rutgers.edu> ron@TOPAZ.RUTGERS.EDU (Ron Natalie) writes:
> The definition of the first argument to the socket is the maximum file
> descriptor that can be specified in any of the other fields.  You set
> it to one ... Set the value to something
> larger like the maximum number of file descriptors (NFILE).

(Hiya Ron!) People have been talking about setting NFILE bigger than 32,
so I think it is worth mentioning that the first argument to select is used
to tell it the width of the bitmaps in the succeeding arguments.  So if they
are INTs you probably want to set it to 32.  Of course, if your system DOES
have NFILE set bigger than 32 and you happen to get a FD with a higher number,
that (1<<nfd) suddenly turns into a zero and the code no longer does what
one thought it would...  So waddya want to do?

	if (nfd>31)
		diehorribly("fix this mess")
	else {
		num = select( 32 , (1<<nfd) , ...)
	}

or what?  Idunno...
-- 
Copyright 1987 Ben Cranston (you may redistribute ONLY if your recipients can).
       umd5.UUCP    <=      {seismo!mimsy,ihnp4!rlgvax}!cvl!umd5!zben
zben @ umd2.UMD.EDU         Kingdom of Merryland UniSys 1100/92
       umd2.BITNET          "via HASP with RSCS"

mts@EMPTYS.CC.UMICH.EDU (Michael T. Stolarchuk) (09/09/87)

	Umm, I just looked into /usr/include/stdio.h on our apollo system:
	 
	    Changelog entry:
		10/01/82 jrw  increased _NFILE from 20 to 128.....
	 
	So using NFILE is probably NOT the way to go, unless you declare
	readfds, et al as arrays (this leads one to wonder, of course, why
	the existing apollo software works at all -- since I know of no code
	that actually uses arrays with select.  Probably because no one actually
	opens more than 32 file descriptors and only THEN creates a socket...).
 
 How about 4.3? Where select is:
 
	nfound = select(nfds, readfds, writefds, exceptfds, timeout)
	        int nfound, nfds;
	   	fd_set *readfds, *writefds, *exceptfds;
		struct timeval *timeout;
	
 And you have:
	FD_SET(fd, &fdset)
	FD_CLR(fd, &fdset)
	FD_ISSET(fd, &fdset)
	FD_ZERO(&fdset)

 And fd_set is:
	typedef struct fd_set {
		fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
		} fd_set;

 And FD_SETSIZE is 256.


mts. the snail.  imagine him at 100 mhp.

chris@GYRE.UMD.EDU (Chris Torek) (09/09/87)

Please read the select(2) manual entry on your 4.3BSD machine to
see how 4.3BSD defines select() (it is backwards compatible with
4.2BSD's definition through an implementation trick only).

(You might mentally substitute `properly cast NULL' for `zero pointer'
while you are reading...)

Chris

ron@topaz.rutgers.EDU (Ron Natalie) (09/09/87)

The other arguments to select are pointers to bit fields so assumably

char	buf[10];

	select(80, buf, (char *) 0, (char *) 0, (char *) 0, (time_t) 0)

meissner@xyzzy.UUCP (Michael Meissner) (09/21/87)

In article <8709091653.AA15944@topaz.rutgers.edu> ron@topaz.rutgers.EDU (Ron Natalie) writes:
> The other arguments to select are pointers to bit fields so assumably
> 
> char	buf[10];
> 
> 	select(80, buf, (char *) 0, (char *) 0, (char *) 0, (time_t) 0)
> 

In 4.2 systems the three pointer arguments are pointers to INT's, not char's.
In 4.3 this was changed to be the type fd_set (declared in sys/types.h), which
is a structure big enough to hold 256 file descriptors, with a way to expand
it further.  In no case is a character array used.  This may be seen as picking
nits, but it becomes important on machines that have different representations
for pointers to char's and other pointers.
-- 
Michael Meissner, Data General.		Uucp: ...!mcnc!rti!xyzzy!meissner
					Arpa/Csnet:  meissner@dg-rtp.DG.COM