 b6cbf7203b
			
		
	
	
		b6cbf7203b
		
	
	
	
	
		
			
			This patch imports the unmodified current version of NetBSD libc. The NetBSD includes are in /nbsd_include, while the libc code itself is split between lib/nbsd_libc and common/lib/libc.
		
			
				
	
	
		
			354 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			Groff
		
	
	
	
	
	
			
		
		
	
	
			354 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			Groff
		
	
	
	
	
	
| .\"	$NetBSD: select.2,v 1.38 2010/04/05 21:25:56 joerg Exp $
 | |
| .\"
 | |
| .\" Copyright (c) 1983, 1991, 1993
 | |
| .\"	The Regents of the University of California.  All rights reserved.
 | |
| .\"
 | |
| .\" Redistribution and use in source and binary forms, with or without
 | |
| .\" modification, are permitted provided that the following conditions
 | |
| .\" are met:
 | |
| .\" 1. Redistributions of source code must retain the above copyright
 | |
| .\"    notice, this list of conditions and the following disclaimer.
 | |
| .\" 2. Redistributions in binary form must reproduce the above copyright
 | |
| .\"    notice, this list of conditions and the following disclaimer in the
 | |
| .\"    documentation and/or other materials provided with the distribution.
 | |
| .\" 3. Neither the name of the University nor the names of its contributors
 | |
| .\"    may be used to endorse or promote products derived from this software
 | |
| .\"    without specific prior written permission.
 | |
| .\"
 | |
| .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 | |
| .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | |
| .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | |
| .\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 | |
| .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | |
| .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | |
| .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | |
| .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 | |
| .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 | |
| .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 | |
| .\" SUCH DAMAGE.
 | |
| .\"
 | |
| .\"     @(#)select.2	8.2 (Berkeley) 3/25/94
 | |
| .\"
 | |
| .Dd October 18, 2008
 | |
| .Dt SELECT 2
 | |
| .Os
 | |
| .Sh NAME
 | |
| .Nm select ,
 | |
| .Nm pselect
 | |
| .Nd synchronous I/O multiplexing
 | |
| .Sh LIBRARY
 | |
| .Lb libc
 | |
| .Sh SYNOPSIS
 | |
| .In sys/select.h
 | |
| .Ft int
 | |
| .Fn select "int nfds" "fd_set * restrict readfds" "fd_set * restrict writefds" "fd_set * restrict exceptfds" "struct timeval * restrict timeout"
 | |
| .Ft int
 | |
| .Fn pselect "int nfds" "fd_set * restrict readfds" "fd_set * restrict writefds" "fd_set * restrict exceptfds" "const struct timespec *restrict timeout" "const sigset_t * restrict sigmask"
 | |
| .Fn FD_SET "int fd" "fd_set *fdset"
 | |
| .Fn FD_CLR "int fd" "fd_set *fdset"
 | |
| .Fn FD_ISSET "int fd" "fd_set *fdset"
 | |
| .Fn FD_ZERO "fd_set *fdset"
 | |
| .Sh DESCRIPTION
 | |
| .Fn select
 | |
| and
 | |
| .Fn pselect
 | |
| examine the I/O descriptor sets whose addresses are passed in
 | |
| .Fa readfds ,
 | |
| .Fa writefds ,
 | |
| and
 | |
| .Fa exceptfds
 | |
| to see if some of their descriptors
 | |
| are ready for reading, are ready for writing, or have an exceptional
 | |
| condition pending, respectively.
 | |
| The first
 | |
| .Fa nfds
 | |
| descriptors are checked in each set;
 | |
| i.e., the descriptors from 0 through
 | |
| .Fa nfds Ns No \-1
 | |
| in the descriptor sets are examined.
 | |
| This means that
 | |
| .Fa nfds
 | |
| must be set to the highest file descriptor of the three sets, plus one.
 | |
| On return,
 | |
| .Fn select
 | |
| and
 | |
| .Fn pselect
 | |
| replace the given descriptor sets
 | |
| with subsets consisting of those descriptors that are ready
 | |
| for the requested operation.
 | |
| .Fn select
 | |
| and
 | |
| .Fn pselect
 | |
| return the total number of ready descriptors in all the sets.
 | |
| .Pp
 | |
| The descriptor sets are stored as bit fields in arrays of integers.
 | |
| The following macros are provided for manipulating such descriptor sets:
 | |
| .Fn FD_ZERO fdset
 | |
| initializes a descriptor set pointed to by
 | |
| .Fa fdset
 | |
| to the null set.
 | |
| .Fn FD_SET fd fdset
 | |
| includes a particular descriptor
 | |
| .Fa fd
 | |
| in
 | |
| .Fa fdset .
 | |
| .Fn FD_CLR fd fdset
 | |
| removes
 | |
| .Fa fd
 | |
| from
 | |
| .Fa fdset .
 | |
| .Fn FD_ISSET fd fdset
 | |
| is non-zero if
 | |
| .Fa fd
 | |
| is a member of
 | |
| .Fa fdset ,
 | |
| zero otherwise.
 | |
| The behavior of these macros is undefined if
 | |
| a descriptor value is less than zero or greater than or equal to
 | |
| .Dv FD_SETSIZE ,
 | |
| which is normally at least equal
 | |
| to the maximum number of descriptors supported by the system.
 | |
| .Pp
 | |
| If
 | |
| .Fa timeout
 | |
| is a non-null pointer, it specifies a maximum interval to wait for the
 | |
| selection to complete.
 | |
| If
 | |
| .Fa timeout
 | |
| is a null pointer, the select blocks indefinitely.
 | |
| To poll without blocking, the
 | |
| .Fa timeout
 | |
| argument should be non-null, pointing to a zero-valued timeval or timespec
 | |
| structure, as appropriate.
 | |
| .Fa timeout
 | |
| is not changed by
 | |
| .Fn select ,
 | |
| and may be reused on subsequent calls; however, it is good style to
 | |
| re-initialize it before each invocation of
 | |
| .Fn select .
 | |
| .Pp
 | |
| If
 | |
| .Fa sigmask
 | |
| is a non-null pointer, then the
 | |
| .Fn pselect
 | |
| function shall replace the signal mask of the caller by the set of
 | |
| signals pointed to by
 | |
| .Fa sigmask
 | |
| before examining the descriptors, and shall restore the signal mask
 | |
| of the calling thread before returning.
 | |
| .Pp
 | |
| Any of
 | |
| .Fa readfds ,
 | |
| .Fa writefds ,
 | |
| and
 | |
| .Fa exceptfds
 | |
| may be given as null pointers if no descriptors are of interest.
 | |
| .Sh NOTES
 | |
| It is recommended to use the
 | |
| .Xr poll 2
 | |
| interface instead, which tends to be more portable and efficient.
 | |
| .Sh RETURN VALUES
 | |
| .Fn select
 | |
| returns the number of ready descriptors that are contained in
 | |
| the descriptor sets,
 | |
| or \-1 if an error occurred.
 | |
| If the time limit expires,
 | |
| .Fn select
 | |
| returns 0.
 | |
| If
 | |
| .Fn select
 | |
| returns with an error,
 | |
| including one due to an interrupted call,
 | |
| the descriptor sets will be unmodified.
 | |
| .Sh EXAMPLES
 | |
| .Bd -literal
 | |
| #include \*[Lt]stdio.h\*[Gt]
 | |
| #include \*[Lt]stdlib.h\*[Gt]
 | |
| #include \*[Lt]unistd.h\*[Gt]
 | |
| #include \*[Lt]string.h\*[Gt]
 | |
| #include \*[Lt]err.h\*[Gt]
 | |
| #include \*[Lt]errno.h\*[Gt]
 | |
| #include \*[Lt]sys/types.h\*[Gt]
 | |
| #include \*[Lt]sys/time.h\*[Gt]
 | |
| 
 | |
| int
 | |
| main(int argc, char **argv)
 | |
| {
 | |
| 	fd_set read_set;
 | |
| 	struct timeval timeout;
 | |
| 	int ret, fd, i;
 | |
| 
 | |
| 	/* file descriptor 1 is stdout */
 | |
| 	fd = 1;
 | |
| 
 | |
| 	/* Wait for ten seconds. */
 | |
| 	timeout.tv_sec = 10;
 | |
| 	timeout.tv_usec = 0;
 | |
| 
 | |
| 	/* Initialize the read set to null */
 | |
| 	FD_ZERO(\*[Am]read_set);
 | |
| 
 | |
| 	/* Add file descriptor 1 to read_set */
 | |
| 	FD_SET(fd, \*[Am]read_set);
 | |
| 
 | |
| 	/*
 | |
| 	 * Check if data is ready to be readen on
 | |
| 	 * file descriptor 1, give up after 10 seconds.
 | |
| 	 */
 | |
| 	ret = select(fd + 1, \*[Am]read_set, NULL, NULL, \*[Am]timeout);
 | |
| 
 | |
| 	/*
 | |
| 	 * Returned value is the number of file
 | |
| 	 * descriptors ready for I/O, or -1 on error.
 | |
| 	 */
 | |
| 	switch (ret) {
 | |
| 	case \-1:
 | |
| 		err(EXIT_FAILURE, "select() failed");
 | |
| 		break;
 | |
| 
 | |
| 	case 0:
 | |
| 		printf("Timeout, no data received.\en");
 | |
| 		break;
 | |
| 
 | |
| 	default:
 | |
| 		printf("Data received on %d file desciptor(s)\en", ret);
 | |
| 
 | |
| 		/*
 | |
| 		 * select(2) hands back a file descriptor set where
 | |
| 		 * only descriptors ready for I/O are set. These can
 | |
| 		 * be tested using FD_ISSET
 | |
| 		 */
 | |
| 		for (i = 0; i \*[Lt]= fd; i++) {
 | |
| 			if (FD_ISSET(i, \*[Am]read_set)) {
 | |
| 				printf("Data on file descriptor %d\en", i);
 | |
| 				/* Remove the file descriptor from the set */
 | |
| 				FD_CLR(fd, \*[Am]read_set);
 | |
| 			}
 | |
| 		}
 | |
| 		break;
 | |
| 	}
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| .Ed
 | |
| .Sh ERRORS
 | |
| An error return from
 | |
| .Fn select
 | |
| indicates:
 | |
| .Bl -tag -width Er
 | |
| .It Bq Er EBADF
 | |
| One of the descriptor sets specified an invalid descriptor.
 | |
| .It Bq Er EFAULT
 | |
| One or more of
 | |
| .Fa readfds ,
 | |
| .Fa writefds ,
 | |
| or
 | |
| .Fa exceptfds
 | |
| points outside the process's allocated address space.
 | |
| .It Bq Er EINTR
 | |
| A signal was delivered before the time limit expired and
 | |
| before any of the selected events occurred.
 | |
| .It Bq Er EINVAL
 | |
| The specified time limit is invalid.
 | |
| One of its components is negative or too large.
 | |
| .El
 | |
| .Sh SEE ALSO
 | |
| .Xr accept 2 ,
 | |
| .Xr connect 2 ,
 | |
| .Xr gettimeofday 2 ,
 | |
| .Xr poll 2 ,
 | |
| .Xr read 2 ,
 | |
| .Xr recv 2 ,
 | |
| .Xr send 2 ,
 | |
| .Xr write 2 ,
 | |
| .Xr getdtablesize 3
 | |
| .Sh HISTORY
 | |
| The
 | |
| .Fn select
 | |
| function call appeared in
 | |
| .Bx 4.2 .
 | |
| .Sh BUGS
 | |
| Although the provision of
 | |
| .Xr getdtablesize 3
 | |
| was intended to allow user programs to be written independent
 | |
| of the kernel limit on the number of open files, the dimension
 | |
| of a sufficiently large bit field for select remains a problem.
 | |
| The default bit size of
 | |
| .Ft fd_set
 | |
| is based on the symbol
 | |
| .Dv FD_SETSIZE
 | |
| (currently 256),
 | |
| but that is somewhat smaller than the current kernel limit
 | |
| to the number of open files.
 | |
| However, in order to accommodate programs which might potentially
 | |
| use a larger number of open files with select, it is possible
 | |
| to increase this size within a program by providing
 | |
| a larger definition of
 | |
| .Dv FD_SETSIZE
 | |
| before the inclusion of
 | |
| .In sys/types.h .
 | |
| The kernel will cope, and the userland libraries provided with the
 | |
| system are also ready for large numbers of file descriptors.
 | |
| .Pp
 | |
| Note:
 | |
| .Xr rpc 3
 | |
| library uses
 | |
| .Ft fd_set
 | |
| with the default
 | |
| .Dv FD_SETSIZE
 | |
| as part of its ABI.
 | |
| Therefore, programs that use
 | |
| .Xr rpc 3
 | |
| routines cannot change
 | |
| .Dv FD_SETSIZE .
 | |
| .Pp
 | |
| Alternatively, to be really safe, it is possible to allocate
 | |
| .Ft fd_set
 | |
| bit-arrays dynamically.
 | |
| The idea is to permit a program to work properly even if it is
 | |
| .Xr execve 2 Ns 'd
 | |
| with 4000 file descriptors pre-allocated.
 | |
| The following illustrates the technique which is used by
 | |
| userland libraries:
 | |
| .Pp
 | |
| .Bd -literal -offset indent -compact
 | |
| 	fd_set *fdsr;
 | |
| 	int max = fd;
 | |
| 
 | |
| 	fdsr = (fd_set *)calloc(howmany(max+1, NFDBITS),
 | |
| 	    sizeof(fd_mask));
 | |
| 	if (fdsr == NULL) {
 | |
| 		...
 | |
| 		return (-1);
 | |
| 	}
 | |
| 	FD_SET(fd, fdsr);
 | |
| 	n = select(max+1, fdsr, NULL, NULL, \*[Am]tv);
 | |
| 	...
 | |
| 	free(fdsr);
 | |
| .Ed
 | |
| .Pp
 | |
| .Fn select
 | |
| should probably have been designed to return the time remaining from the
 | |
| original timeout, if any, by modifying the time value in place.
 | |
| Even though some systems stupidly act in this different way, it is
 | |
| unlikely this semantic will ever be commonly implemented, as the
 | |
| change causes massive source code compatibility problems.
 | |
| Furthermore, recent new standards have dictated the current behaviour.
 | |
| In general, due to the existence of those
 | |
| non-conforming systems, it is unwise to assume that the timeout
 | |
| value will be unmodified by the
 | |
| .Fn select
 | |
| call, and the caller should reinitialize it on each invocation.
 | |
| Calculating the delta is easily done by calling
 | |
| .Xr gettimeofday 2
 | |
| before and after the call to
 | |
| .Fn select ,
 | |
| and using
 | |
| .Fn timersub
 | |
| (as described in
 | |
| .Xr getitimer 2 ) .
 | |
| .Pp
 | |
| Internally to the kernel,
 | |
| .Fn select
 | |
| works poorly if multiple processes wait on the same file descriptor.
 |