Date: Wed, 16 Sep 1998 16:37:29 +0300 (IDT) From: Eli Zaretskii To: DJ Delorie cc: djgpp-workers AT delorie DOT com Subject: Re: `select' feature? In-Reply-To: <199809131315.PAA11345@tyr.diku.dk> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Precedence: bulk On Sun, 13 Sep 1998, Morten Welinder wrote: > Solaris 2.6 says > > "On failure, the objects pointed to by the readfs, writefs, > and errorfds arguments are not modified. If the timeout > interval expires without the specified condition being true > for any of the specified file descriptors, the objects > pointed to by the readfs, writefs, and errorfds arguments > have all bits set to 0." Here's the patch that fixes our `select' in the case of expiring timeout. I also took this opportunity to make the docs a bit more explicit. *** src/libc/compat/time/select.c~0 Tue Jul 23 23:41:26 1996 --- src/libc/compat/time/select.c Mon Sep 14 10:11:28 1998 *************** select(int nfds, *** 235,241 **** --- 235,246 ---- gettimeofday (&now, 0); if (now.tv_sec > then.tv_sec || (now.tv_sec == then.tv_sec && now.tv_usec >= then.tv_usec)) + { + FD_ZERO (readfds); + FD_ZERO (writefds); + FD_ZERO (exceptfds); return 0; + } } /* We are busy-waiting, so give other processes a chance to run. */ *** src/libc/compat/time/select.t~0 Sun Jul 23 04:11:10 1995 --- src/libc/compat/time/select.txh Mon Sep 14 18:39:38 1998 *************** *** 14,23 **** @subheading Description ! This function waits for files to be ready for input or output, or for ! a timeout. Each fd_set represents a set of bits representing file ! descriptors. The following macros shall be used to deal with these ! sets: @table @code --- 14,25 ---- @subheading Description ! This function waits for files to be ready for input or output, or to ! have exceptional condition pending, or for a timeout. ! ! Each @code{fd_set} variable is a bitmap representation of a set of file ! descriptors, one bit for every descriptor. The following macros shall ! be used to deal with these sets: @table @code *************** *** 37,49 **** Return the value of member @var{n} in set @var{p}. @end table ! The @var{timeout} value may be a NULL pointer (no timeout), a pointer ! to a zero-value structure (poll mode), or a pointer to an ! interval-filled structure (timeout). @subheading Return Value ! The number of files ready. The input sets are replaced with sets that ! describe which files are ready for which operations. --- 39,167 ---- Return the value of member @var{n} in set @var{p}. + @item FD_SETSIZE + + The maximum number of descriptors supported by the system. + @end table ! The @var{nfds} parameter is the number of bits to be examined in each of ! the @code{fd_set} sets: the function will only check file descriptors ! @code{0} through @code{@var{nfds} - 1}, even if some bits are set for ! descriptors beyond that. ! ! On input, some of the bits of each one of the @code{fd_set} sets for ! which the function should wait, should be set using the @code{FD_SET} ! macro. @code{select} examines only those descriptors whose bits are ! set. ! ! Any of @code{readfds}, @code{writefds}, and @code{exceptfds} can be a ! @code{NULL} pointer, if the caller is not interested in testing the ! corresponding conditions. ! ! On output, if @code{select} returns a non-negative value, each ! non- AT code{NULL} argument of the three sets will be replaced with a ! subset in which a bit is set for every descriptor that was found to be, ! respectively, ready for input, ready for output, and pending an ! exceptional condition. Note that if @code{select} returns -1, meaning a ! failure, the descriptor sets are @emph{unchanged}, so you should always ! test the return value before looking at the bits in the returned sets. ! ! The @var{timeout} value may be a NULL pointer (no timeout, i.e., wait ! forever), a pointer to a zero-value structure (poll mode, i.e., test ! once and exit immediately), or a pointer to a @code{struct timeval} ! variable (timeout: @code{select} will repeatedly test all the ! descriptors until some of them become ready, or the timeout expires). @subheading Return Value ! On successfull return, @code{select} returns the number of files ready, ! or 0, if the timeout expired. The input sets are replaced with subsets ! that describe which files are ready for which operations. If ! @code{select} returns 0 (i.e., the timeout has expired), all the ! non- AT code{NULL} sets have all their bits reset to zero. ! ! On failure, @code{select} returns -1, sets @code{errno} to a suitable ! value, and leaves the descriptor sets unchanged. ! ! @subheading Example ! ! @example ! struct timeval timeout; ! fd_set read_fds, write_fds; ! int i, select_result; ! ! timeout.tv_sec = 5; /* 5-second timeout */ ! timeout.tv_usec = 0; ! ! /* Display status of the 5 files open by default. */ ! for (i = 0; i < 5; i++) ! @{ ! ! FD_ZERO (&read_fds); ! FD_SET (i, &read_fds); ! select_result = select (i + 1, &read_fds, 0, 0, &timeout); ! if (select_result == -1) ! @{ ! fprintf(stderr, "%d: Failure for input", i); ! perror(""); ! @} ! else ! fprintf(stderr, ! "%d: %s ready for input\n", i, select_result ? "" : "NOT"); ! FD_ZERO (&write_fds); ! FD_SET (i, &write_fds); ! select_result = select (i + 1, 0, &write_fds, 0, &timeout); ! if (select_result == -1) ! @{ ! fprintf(stderr, "%d: Failure for output", i); ! perror(""); ! @} ! else ! fprintf(stderr, ! "%d: %s ready for output\n", i, select_result ? "" : "NOT"); ! @} ! @end example ! ! @subheading Implementation Notes ! ! The following notes describe some details pertinent to the DJGPP ! implementation of @code{select}: ! ! @itemize @bullet{} ! @item ! While @code{select} waits for the timeout to expire, it repeatedly calls ! the @code{__dpmi_yield} function (@pxref{__dpmi_yield}), so that any ! other programs that run at the same time (e.g., on Windows) get more CPU ! time. ! ! @item ! A file handle that belongs to a @code{FILE} object created by ! @code{fopen} or @code{fdopen} (@pxref{fopen}) for which @code{feof} or ! @code{ferror} return non-zero, will be reported in the @code{exceptfds} ! set; also, such a handle will be reported not input-ready if there are ! no pending buffered characters in the @code{FILE} object. This might be ! a feature or a bug, depending on your point of view; in particular, Unix ! implementations usually don't check buffered input. Portable programs ! should refrain from mixing @code{select} with buffered I/O. ! ! @item ! DOS doesn't support exceptional conditions, so file handles used for ! unbuffered I/O will @emph{never} be marked in @code{exceptfds}. ! ! @item ! DOS always returns an output-ready indication for a file descriptor ! connected to a disk file. So use of @code{writefds} is only meaningful ! for character devices. ! ! @item ! The usual text-mode input from the keyboard and other character devices ! is line-buffered by DOS. This means that if you type one character, ! @code{select} will indicate that file handle 0 is ready for input, but a ! call to @code{getc} will still block until the @key{Enter} key is ! pressed. If you need to make sure that reading a single character won't ! block, you should read either with BIOS functions such as @code{getkey} ! (@pxref{getkey}, or with raw input DOS functions such as @code{getch} ! (@pxref{getch}), or switch the handle to binary mode with a call to ! @code{setmode} (@pxref{setmode}). ! @end itemize *** src/docs/kb/wc202.t~0 Sun Jul 26 13:34:04 1998 --- src/docs/kb/wc202.txi Wed Sep 16 15:05:52 1998 *************** *** 447,449 **** --- 447,453 ---- interrupted or crashed, and reports the run time with millisecond resolution. @cindex redir + + @code{select} now correctly zeroes out all the bits in the @code{fd_set} + arguments when it returns due to expired timeout. + @findex select