Subject: Re: sys_select() EBADF bug
To: Ben Harris <bjh21@netbsd.org>
From: David Laight <david@l8s.co.uk>
List: tech-kern
Date: 11/15/2002 13:37:44
> >	EINVAL
> >           The nfds argument is less than 0, or greater  than  or
> >           equal to FD_SETSIZE.
> 
> This agrees with POSIX which states that select() "shall fail" with EINVAL
> if nfds > FD_SETSIZE.  This means that succeeding under such circumstances
> is forbidden.  Of course, this need only apply when the application doesn't
> override FD_SETSIZE, since doing so puts them out of POSIX-defined
> behaviour.

This is all horrid....  POSIX doesn't seem to allow for arbitrarily
large fd_set.  FD_SETSIZE doesn't seem to be a sysconf() value either...

I'm not sure what solaris does, but if, when select.h is included,
FD_SETSIZE is defined to a value > 1024 it does:

#ifdef __PRAGMA_REDEFINE_EXTNAME
#pragma redefine_extname        select  select_large_fdset
#else   /* __PRAGMA_REDEFINE_EXTNAME */
#define select  select_large_fdset
#endif  /* __PRAGMA_REDEFINE_EXTNAME */

I therefore guess that the EINVAL response is actually generated
from within libc.
I presume gcc has a similar feature?

The other solution is to do something like?

#if defined(FD_SETSIZE) && FD_SETSIZE != 256
static inline int
select(int nfd, void *r, void *w, void *e, void *t)
{
	return _select(nfd, r, w, e, t, FD_SETSIZE);
}

	David

-- 
David Laight: david@l8s.co.uk