From owner-freebsd-current Tue Oct 17 00:55:26 1995 Return-Path: owner-current Received: (from root@localhost) by freefall.freebsd.org (8.6.12/8.6.6) id AAA12826 for current-outgoing; Tue, 17 Oct 1995 00:55:26 -0700 Received: from netcom17.netcom.com (root@netcom17.netcom.com [192.100.81.130]) by freefall.freebsd.org (8.6.12/8.6.6) with ESMTP id AAA12821 ; Tue, 17 Oct 1995 00:55:19 -0700 Received: from localhost by netcom17.netcom.com (8.6.12/Netcom) id AAA00821; Tue, 17 Oct 1995 00:26:43 -0700 Message-Id: <199510170726.AAA00821@netcom17.netcom.com> To: Terry Lambert cc: hackers@freefall.freebsd.org, current@freefall.freebsd.org Subject: Re: getdtablesize() broken? In-reply-to: Your message of "Mon, 16 Oct 95 11:31:02 PDT." <199510161831.LAA25019@phaeton.artisoft.com> Date: Tue, 17 Oct 95 00:26:42 -0700 From: Bakul Shah Sender: owner-current@FreeBSD.org Precedence: bulk > Using FD_SETSIZE or using RLIMIT_NOFILE, or getting the current open > descriptor limit from the kernel (when the application has an explicit > bitvector element limitation set at compile time, not because of a > check for FD_SETSIZE by because declaration of a bit vector uses the > FD_SETSIZE to declare the vector length) is equally stupid and equally > succeptible to screwups. > The "correct" way is to get rid of the interfaces which are succeptible > to bad programming style. The user *SHOULD* be using the highest open > FD in the set of FD's being selected upon, *NOT* some arbitrary constant. My mistake. I didn't explicitly state that I was bitching about an *in-kernel* limitation. Granted that an application should use what you suggest but the problem is that a {Free|Net}BSD _kernel_ restricts nfds that can be passed to select() to FD_SETSIZE. I can open, say, 1000 sockets, there is no way I can select on an fd >= FD_SETSIZE. Unshar the attached little program and try this test. % cc x.c % limit openefiles 500 # you may need to do `limit descriptors 500' % a.out 500 255 except select(). This happens because of this line in /sys/kern/sys_generic.c:select() if (uap->nd > FD_SETSIZE) It should be replaced with if (uap->nd > p->fd->fd_nfiles) It is this hardwired use of FD_SETSIZE *in* the kernel I am bitching about. There *are* scalability problems with select() and we can use a more scalable interface but regardless, select() needs to work with any valid file descriptor. --bakul #!/bin/sh # This is a shell archive (produced by shar 3.49) # To extract the files from this archive, save it to a file, remove # everything above the "!/bin/sh" line above, and type "sh file_name". # # made 10/17/1995 07:18 UTC by bakul@netcom17 # Source directory /u7/bakul # # existing files will NOT be overwritten unless -c is specified # # This shar contains: # length mode name # ------ ---------- ------------------------------------------ # 502 -rw-r--r-- x.c # # ============= x.c ============== if test -f 'x.c' -a X"$1" != X"-c"; then echo 'x - skipping x.c (File already exists)' else echo 'x - extracting x.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'x.c' && #include #include #include X int main(int argc, char**argv) { X int n = argc > 1 ? atoi(argv[1]) : 257; X int * bits = calloc((n+31)/32, sizeof(int)); X int i; X X for (i = 3; i < n; i++) { X int fd = dup(0); X if (fd < 0) { X fprintf(stderr, "Can only get %d descriptors\n", i); X exit(1); X } X bits[fd/32] |= 1<<(fd%32); X if (select(fd+1, bits, 0, 0, 0) < 0) { X fprintf(stderr, "select error %s when fd = %d\n", X strerror(errno), fd); X exit(1); X } X } X exit(0); } SHAR_EOF chmod 0644 x.c || echo 'restore of x.c failed' Wc_c="`wc -c < 'x.c'`" test 502 -eq "$Wc_c" || echo 'x.c: original size 502, current size' "$Wc_c" fi exit 0