SELECT [ Berkeley Sockets/iX Reference Manual ] MPE/iX 5.0 Documentation
Berkeley Sockets/iX Reference Manual
SELECT
C Interface
#include <time.h>
int select(nfds, readfds, writefds, exceptfds,timeout)
int nfds, *readfds, *writefds, *exceptfds;
struc timeval *timeout;
Description
The select intrinsic examines the file descriptors specified by the bit
masks readfds, writefds, and exceptfds. The bits from 0 through nfds-1
are examined. File descriptor f is represented by the bit 1 <f in the
masks. More formally, a file descriptor is represented by the following:
fds[(f / BITS_PER_INT)] & (1 << (f % BITS_PER_INT))
When select completes successfully, it returns the three bit masks
modified as follows: For each file descriptor less than nfds, the
corresponding bit in each mask is set if the bit was set upon entry and
the file descriptor is ready for reading or writing, or has an
exceptional condition pending.
If timeout is a non-zero pointer, it specifies a maximum interval to wait
for the selection to complete. If timeout is a zero pointer, the select
waits until an event causes one of the masks to be returned with a valid
(non-zero) value. To poll, the timeout argument should be non-zero,
pointing to a zero valued timeval structure. Specific implementations
may place limitations on the maximum timeout interval supported.
Any or all of readfds, writefds, and exceptfds may be given as 0 if no
descriptors are of interest. If all of the masks are given as 0 and
timeout is not a zero pointer, select blocks for the time specified, or
until interrupted by a signal. If all of the masks are given as 0 and
timeout is a zero pointer, select blocks until interrupted by a signal.
Ordinary files always select true whenever selecting on reads, writes,
and/or exceptions.
Examples
Example 1.
The following call to select checks if any of four sockets are ready for
reading. The select intrinsic times out after 5 seconds if no sockets
are ready for reading:
NOTE The code for opening the sockets or reading from the sockets is not
shown in this example and this example must be modified if the
calling process has more than 32 file descriptors open.
#define MASK(f) (1 << (f))
#define NSDS 4int sd[NSDS];
int sdmask[NSDS];
int readmask = 0;
int readfds;
int nfound, i;
struct timeval timeout;
/* First open each socket for reading and put the */
/* file descriptors into array sd[NSDS]. The code */
/* for opening the sockets is not shown here. */
for (i=0; i < NSDS; i++) {
sdmask[i] = MASK(sd[i]);
readmask |= sdmask[i];
}
timeout.tv_sec = 5;
timeout.tv_usec = 0;
readfds = readmask;
/* select on NSDS+3 file descriptors if stdin, stdout */
/* and stderr are also open */
if ((nfound = select (NSDS+3, &readfds, 0, 0, &timeout)) == -1)
perror ("select failed");
else
if (nfound == 0)
printf ("select timed out \n");
else
for (i=0; i < NSDS; i++)
if (sdmask[i] & readfds)
/* Read from sd[i]. The code for reading */
/* is not shown here. */
else
printf ("sd[%d] is not ready for reading \n",i);
Example 2.
The following programming example shows how select can be used to wait on
multiple sockets.
/* This program is an example of how select can be
used on multiple sockets */
/* on MPE/iX. */
/* Compile with SOCKET_SOURCE and POSIX_SOURCE defined. */
/* Link with socketrl and libcinit. */
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/in.h>
#include <sys/errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#define TRUE 0
#define FALSE 1
main ()
{
int maxfds;
int sock, sock2, peer1;
int struc_len;
int fret;
int done = FALSE;
char data[256];
char data_to_send = 'D';
char *datptr;
int dlen;
int readfds;
int writefds;
struc timeval timeout;
struc sockaddr_in sockaddr;
sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP;
peer1 = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
sockaddr.sin_family = AF_INET;
sockaddr.sin_addr.s_addr = INADDR_THISHOST;
sockaddr.sin_port = 4444;
struc_len = 8;
if (bind (sock, (struc sockaddr *) &sockaddr,
sizeof sockaddr) << 0 ) {
printf ("Bind failed\n");};
listen (sock, 10);
sfcntl (peer1, F_SETFL, O_NONBLOCK);
/* connect() returns with EINPROGRESS. */
fret = connect (peer1, (struct sockaddr *) &sockaddr,
struc_len);
sock2 = accept (sock,
(struc sockaddr *) &sockaddr,
&struc_len);
/* Call recv to complete the connection */
recv (peer1, 0, 0, 0);
/* sock2 and peer1 are now connected */
daptr = data;
done = FALSE;
while (done == FALSE) {
/* This code example shows how to use select() to wait on multiple
*/
/* sockets. Note that first you have to find the maximum descriptor
*/
/* number being used. The appropriate bit(s) must be set for the */
/* select masks and then they must be checked after the call. In */
/* this example, sock2 is waiting to receive data from peer1. */
if (peer1 << sock2) {
maxfds = sock2;
}
else
maxfds = peer1;
/* set a 5 second timer for the call to select(). */
timeout.tv_sec = 5;
timeout.tv_usec = 0;
writefds = (1 << peer1);
readfds = (1 << peer1) + (1 << sock2);
fret = select (maxfds + 1, &readfds, &writefds, 0, &timeout);
if (fret << = 0) {
printf ("error1\n");
done = TRUE;
}
else
{
if ((readfds && (1 << sock2)) ! = 0) {
dlen = 100;
fret = recv (sock2, datptr, dlen, 0);
printf ("received %d bytes.\n", fret);
if (data[0]! = data_to_send) {
printf ("error2\n");
};
done = TRUE;
}
else
{
if ((writefds && (1 << peer1))! = 0) {
dlen = 1;
data[0] = data_to_send;
fret = send (peer1, datptr, dlen, 0);
printf ("sent %d bytes.\n", fret);
}
else
{
printf ("error3\n");
}
}
};/* end else */
};/* end while */
}
Return Value
The select intrinsic returns the number of descriptors contained in the
bit masks. If an error occurs, -1 is returned and an error code is
stored in errno. If the time limit expires, then select returns 0, and
all of the masks are cleared.
Errors
The select intrinsic returns the following errors:
[EBADF] One or more of the bit masks specified an invalid
descriptor.
[EFAULT] One or more of the pointers was invalid.
[EINVAL] An invalid timeval was passed for timeout.
[EINVAL] The value of nfds is less than zero.
NOTE The file descriptor masks are always modified on return, even if
the call returns as the result of a timeout.
Author
The select intrinsic was developed by Hewlett-Packard and the University
of California, Berkeley.
MPE/iX 5.0 Documentation