select()--Wait for Events on Multiple Sockets
Syntax
#include <sys/types.h>
#include <sys/time.h>
int select(int max_descriptor,
fd_set *read_set,
fd_set *write_set,
fd_set *exception_set,
struct timeval *wait_time)
Service Program Name: QP0LLIB1
Default Public Authority: *USE
Threadsafe: Conditional; see
Usage Notes.
The select() function is used to enable an application to multiplex
I/O. By using select(), an application with multiple interactive I/O
sources avoids blocking on one I/O stream while the other stream is ready.
Thus, for example, an application that receives inputs from two distinct
communication endpoints (using sockets) can use select() to sleep
until input is available from either of the sources. When input is available,
the application wakes up and receives an indication as to which descriptor is
ready for reading.
The application identifies descriptors to be checked for read, write, and
exception status and specifies a timeout value. If any of the specified
descriptors is ready for the specified event (read, write, or exception),
select() returns, indicating which descriptors are ready. Otherwise,
the process waits until one of the specified events occur or the wait times
out.
Parameters
- max_descriptor
- (Input) Descriptors are numbered starting at zero, so the
max_descriptor parameter must specify a value that is one greater than
the largest descriptor number that is to be tested.
- read_set
- (I/O) A pointer to a set of descriptors that should be checked to see if
they are ready for reading. This parameter is a value-result field. Each
descriptor to be tested should be added to the set by issuing a FD_SET() macro.
If no descriptor is to be tested for reading, read_set should be NULL
(or point to an empty set). On return from the call, only those descriptors
that are ready to be read are in the set. FD_ISSET() should be used to test for
membership of a descriptor in the set.
- write_set
- (I/O) A pointer to a set of descriptors that should be checked to see if
they are ready for writing. This parameter is a value-result field. Each
descriptor to be tested should be added to the set by issuing a FD_SET() macro.
If no descriptor is to be tested for writing, write_set should be NULL
(or point to an empty set). On return from the call, only those descriptors
that are ready to be written are in the set. FD_ISSET() should be used to test
for membership of a descriptor in the set.
- exception_set
- (I/O) A pointer to a set of descriptors that should be checked for pending
exception events. This parameter is a value-result field. Each descriptor to be
tested should be added to the set by issuing a FD_SET() macro. If no descriptor
is to be tested for exceptions, exception_set should be NULL (or point
to an empty set). On return from the call, only those descriptors that have an
exception event are in the set. FD_ISSET() should be used to test for
membership of a descriptor in the set.
- wait_time
- (Input) A pointer to a structure which specifies the maximum time to wait
for at least one of the selection criteria to be met. A time to wait of 0 is
allowed; this returns immediately with the current status of the sockets. The
parameter may be specified even if NO descriptors are specified
(select() is being used as a timer). If wait_time is NULL,
select() blocks indefinitely. The structure pointed to by the
wait_time parameter is defined in
<sys/time.h>.
Authorities
No authorization is required.
Return Value
select() returns an integer. Possible values are:
- -1 (unsuccessful)
- 0 (if the time limit expires)
- n (total number of descriptors in all sets that met selection
criteria)
Note: The timeval structure (pointed to by
wait_time) is unchanged.
Error Conditions
When select() fails, errno can be set to one of the
following:
[EBADF] |
Descriptor not valid.
|
[ENOTSAFE] |
Function not allowed.
|
[EFAULT] |
Bad address.
The system detected an address which was not valid while attempting to
access the read_set, write_set, exception_set, or
wait_time parameter.
|
[EINTR] |
Interrupted function call.
|
[EINVAL] |
Parameter not valid.
This error code indicates one of the following:
- The max_descriptor parameter specifies a negative value or a value
greater than [FD_SETSIZE].
- The wait_time parameter specifies a time value which was not
valid.
|
[EIO] |
Input/output error.
|
[ENOTSUP] |
Operation not supported.
The operation, though supported in general, is not supported for the
requested object or the requested arguments.
|
[EUNKNOWN] |
Unknown system state. |
Error Messages
CPE3418 E |
Possible APAR condition or hardware failure. |
CPF3CF2 E |
Error(s) occurred during running of &1
API. |
CPF9872 E |
Program or service program &1 in library
&2 ended. Reason code &3. |
CPFA081 E |
Unable to set return value or error code. |
CPFA0D4 E |
File system error occurred. |
-
The poll() API is more efficient than the select() API and
therefore poll() is always recommended over select().
- An application program must include the header file
<sys/types.h> to use select(). The header file
contains the type and macro definitions needed to use select(). The
maximum number of descriptors that can be selected is defined by FD_SETSIZE.
See DosSetRelMaxFH()
for additional considerations when select()
and DosSetRelMaxFH() are used within the same process.
The following macros can be used to manipulate descriptor sets:
- FD_ZERO(fd_set *p) removes all descriptors from the
set specified by p.
- FD_CLR(int n, fd_set *p) removes descriptor
n from the set specified by p.
- FD_SET(int n, fd_set *p) adds descriptor
n to the set specified by p.
- FD_ISSET(int n, fd_set *p) returns a nonzero
value if descriptor n is returned in the set specified by p;
otherwise, a zero value is returned.
Note: Values of type fd_set should only be manipulated by
the macros supplied in the <sys/types.h> header
file.
- A descriptor can be returned in the set specified by read_set to
indicate one of the following:
- An error event exists on the descriptor.
- A connection request is pending on a socket descriptor. This technique can
be used to wait for connections on multiple socket descriptors. When a
listening socket is returned in the set specified by read_set, an
application can then issue an accept() call to accept the
connection.
- No data can be read from the underlying instance represented by the
descriptor. For example, a socket descriptor for which a shutdown()
call has been done to disable the reception of data.
- A descriptor can be returned in the set specified by write_set to
indicate one of the following:
- Completion of a non-blocking connect() call on a socket
descriptor. This allows an application to set a socket descriptor to
nonblocking (with fcntl() or ioctl()), issue a
connect() and receive [EINPROGRESS], and then use
select() to verify that the connection has completed.
- No data can be written to the underlying instance represented by the
descriptor (for example, a socket descriptor for which a shutdown()
has been done to disable the sending of data).
- When a write() can be successfully issued without blocking (or,
for nonblocking, so it does not return [EWOULDBLOCK]).
- A socket descriptor is returned in the set specified by
exception_set to indicate that out-of-band data has arrived at the
socket. This is only supported for connection-oriented sockets with an address
family of AF_INET
or AF_INET6.
-
Unpredictable results will appear if
this function or any of its associated type and macro definitions are used
in a thread executing one of the scan-related exit programs
(or any of its' created threads). See
Integrated File System Scan on Open Exit Programs and
Integrated File System Scan on Close Exit Programs
for more information.
Related Information
API introduced: V3R1