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