Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 5 Apr 1995 02:05:38 +1000
From:      Bruce Evans <bde@zeta.org.au>
To:        pritc003@maroon.tc.umn.edu, wpaul@freefall.cdrom.com
Cc:        CVS-commiters@freefall.cdrom.com, cvs-lib@freefall.cdrom.com
Subject:   Re: cvs commit: src/lib/libc/rpc rpc_dtablesize.c
Message-ID:  <199504041605.CAA26586@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
>>   A temporary fix for this is to clamp the value returned by _rpc_dtablesize()
>>   at FD_SETSIZE (as defined in <sys/types.h> (256)). I suppose the Right
>>   Thing would be to provide some mechanism for select() to dynamically
>>   adjust itself to handle FD_SETSIZE values larger than 256, but it's a
>>   bit late in the game for that. Hopefully 256 file descriptors will be enough
>>   to keep RPC happy for now.

>I've done some work directly related to this in the past.  You run
>into problems anytime the user is able to raise the open file limit
>higher than FD_SETSIZE.  Just so everyone knows, the problem is
>that whenever the open file limit is higher than FD_SETSIZE, and
>select() is called and given an "nfds" parmeter > FD_SETSIZE, select
>winds up reading past the fdset array and finds bogus bits set and
>usually blows the system call off with EBADF.  Programs really shouldn't
>be calling select with a "nfds" parameter of "getdtablesize()",
>they should use FD_SETSIZE instead.

FreeBSD avoids the EBADF problem by rejecting the select() if `nfds'
is too hard.  It has to, because it copies the user fd_set structs
to local variables, and it can't afford to write past the end of
the copies.  The code is:

	if (uap->nd > FD_SETSIZE)
		return (EINVAL);
	if (uap->nd > p->p_fd->fd_nfiles)
		uap->nd = p->p_fd->fd_nfiles;	/* forgiving; slightly wrong */

How about this instead:

	if (uap->nd > p->p_fd->fd_nfiles)
		uap->nd = p->p_fd->fd_nfiles;	/* forgiving; slightly wrong */
	if (uap->nd > FD_SETSIZE)
		return (EINVAL);

>POSIX doesn't say anything about select/poll, either.  But POSIX does
>take a stand on several issues on the maximum number of open files.
>One of them being the fact that the maximum number of open files per process 
>can't change over the life of the process, which FreeBSD currently violates.  
>The fix for this is to allow a "new" limit to be set that is inherited by 
>any new child processes that are created, but the limit for the process that 
>set the limit is not changed.  

Someone broke this some more by introducing the sysctl variable
`kern.maxfilesperproc'.  What systems implement "new" limits?

>POSIX also has some things to say about the OPEN_MAX symbol (if it is
>defined then certain things must be a certain way, and that if
>it is not defined then certain things can work another way, I forget
>the exact details), and something about a minimum number of open files 
>(OPEN_MIN?).  I don't have a POSIX manual handy, so I can't be anymore 
>specific right now.  The ANSI C spec also has something to say about
>OPEN_MAX.

There's no OPEN_MIN.  FreeBSD violates POSIX by defining OPEN_MAX when
the max is variable.  Many programs expect OPEN_MAX and NOFILE to be
constant so it's pragmatic to define it as a constant.

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199504041605.CAA26586>