Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!utcs!mnetor!seismo!umcp-cs!chris From: chris@umcp-cs.UUCP Newsgroups: net.unix-wizards Subject: Re: Undocumented behavior of select(2) with sockets in Ultrix 1.2 Message-ID: <2460@umcp-cs.UUCP> Date: Thu, 17-Jul-86 05:35:17 EDT Article-I.D.: umcp-cs.2460 Posted: Thu Jul 17 05:35:17 1986 Date-Received: Fri, 18-Jul-86 00:54:32 EDT References: <154@nbc1.UUCP> Reply-To: chris@maryland.UUCP (Chris Torek) Distribution: net Organization: University of Maryland, Dept. of Computer Sci. Lines: 69 In article <154@nbc1.UUCP> abs@nbc1.UUCP (Andrew Siegel) writes: >I've encountered some undocumented behavior of select(2) that I >find useful. ... calling select so that it blocks indefinitely, thus: > > select(20,&readfds,0,0,0) Actually, you should at least insert a few casts: int cc, nfds; fd_set readfds; ... cc = select(nfds, &readfds, (fd_set *) 0, (fd_set *) 0, (struct timeval *) 0); 4.2BSD defines `fd_set', but leaves it undocumented. (In 4.3, an fd_set contains more than 32 bits: no longer is one limited to 30 descriptors.) Incidentally, the following macros are useful to obtain `forwards compatibility' with 4.3 on a 4.2 system: /* * 4.3 and V8 style file descriptor mask macros. * Should be in but are missing in 4.2. */ #ifndef FD_SET #ifdef notdef /* this already exists in 4.2 */ typedef struct fd_set { int fds_bits[1]; } fd_set; #endif #define FD_ZERO(p) ((p)->fds_bits[0] = 0) #define FD_SET(n, p) ((p)->fds_bits[0] |= (1 << (n))) #define FD_CLR(n, p) ((p)->fds_bits[0] &= ~(1 << (n))) #define FD_ISSET(n, p) ((p)->fds_bits[0] & (1 << (n))) #endif FD_ZERO clears an entire fd_set; FD_SET, FD_CLR, and FD_ISSET set, clear, and test the appropriate bit in an fd_set given a file descriptor and a pointer to the fd_set. >... when one of these clients dies or shuts down its end of the >socket, the select in the server returns with the bit in readfds >set for the descriptor for the server's end of that socket. Doing >an ioctl(fd,FIONREAD,&n), where fd is that file descriptor, yields >zero bytes pending on that socket! So there is a conflict: select >says there are bytes pending, and ioctl says there are none. If >I do a read on that fildes, the read returns 0 (EOF), conforming >to the documented behavior of read(2). The real bug is in the select manual. It should mention that in fact selection for reading or writing holds true if the read or write will not block due to EOF or error. (I guess that errors might someday move to `exceptional condition' status, and I it is conceivable that even EOF might move there, but this select `feature' still works in 4.3. I think at this point it would be too painful to change.) >My hypothesis is that this is the correct (but undocumented) >behavior of select under these circumstances; now I just need >some kind wizard(s) in netland to confirm this for me (I don't >have access to source code). It takes no extra code in the tty-select routines, but it does take an extra test on sockets. That makes it fairly obviously intentional. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1516) UUCP: seismo!umcp-cs!chris CSNet: chris@umcp-cs ARPA: chris@mimsy.umd.edu