Chapter Contents

Previous

Next
select

select



Determines the Number of Ready Sockets

Portability: UNIX compatible


SYNOPSIS
DESCRIPTION
RETURN VALUE
CAUTION
PORTABILITY
EXAMPLE
RELATED FUNCTIONS


SYNOPSIS

#include <sys/types.h>
#include <sys/socket.h>

int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, const struct timeval *timeout);


DESCRIPTION

select checks to see if any sockets are ready for reading ( readfds ), writing ( writefds ), or have an exceptional condition pending ( exceptfds ). timeout specifies the maximum time for select to complete. nfds specifies the maximum number of sockets to check. If timeout is a null pointer, select blocks indefinitely. timeout points to a timeval structure. A timeout value of 0 causes select to return immediately. This behavior is useful in applications that periodically poll their sockets. The arrival of out-of-band data is the only possible exceptional condition. fd_set is a type defined in the <sys/types.h> header file. fd_set defines a set of file descriptors on which select operates. Passing NULL for any of the three fd_set arguments specifies that select should not monitor that condition. On return, each of the input sets is modified to indicate the subset of descriptions that are ready. These may be found by using the FD_ISSET macro.

The following macros manipulate sets of socket descriptors:

FD_CLR(fd, &fdset)
removes the socket descriptor fd from the socket descriptor set fdset .

FD_ISSET(fd, &fdset)
returns nonzero if socket descriptor fd is a member of fdset . Otherwise, it returns a 0 .

FD_SET(fd, &fdset)
adds socket descriptor fd to fdset .

FD_SETSIZE
is defined in <sys/types.h> as the number of socket descriptors that a process can have open. The default is 64. This value can be increased before you include <sys/types.h> . If FD_SETSIZE is not increased, the fd_set structure will not be defined to be large enough to accommodate socket numbers larger than 63. The default value for FD_SETSIZE is 256.

FD_ZERO(& fdset)
initializes fdset to 0 , representing the empty set.


RETURN VALUE

If select succeeds, it returns the number of ready socket descriptors. select returns a 0 if the time limit expires before any sockets are selected. If there is an error, select returns a -1 .


CAUTION

The actual timing is not likely to be accurate to the microsecond.

For non-integrated sockets, the SAS/C Library blocks all asynchronous signals during routines that call the TCP/IP communications software. Thus, calls to select may leave asynchronous signals blocked for long periods of time.

For integrated sockets, select may be interrupted by any unblocked signal, either managed by USS or SAS/C, in which case select will return -1 , and errno will be set to EINTR .

If the socket or file descriptor number is greater that FD_SETSIZE, the FD_* macros will produce unpredictable results. For more information, see "getdtablesize" in Chapter 18, "Socket Function Reference" of SAS/C Library Reference, Volume 2.

It is a good programming practice to always check the return code for values greater than zero before testing the descriptor sets.


PORTABILITY

select is portable to other environments, including most UNIX systems, that implement BSD sockets.

Unlike UNIX, the SAS/C implementation of select does not apply to files, unless you are using integrated sockets. Even if you are using integrated sockets, select has no effect on any non-HFS file descriptors specified. In addition, select cannot be used in conjunction with asynchronous I/O, because asynchronous I/O is not supported by the SAS/C Compiler.


EXAMPLE

In this example select waits for data to read from a socket.

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <stdio.h>

/* This function calls select to wait for data to read from */
/* one of the sockets passed as a parameter.                */
/* If more than 3 seconds elapses, it returns.              */
/* Return value flags. These indicate the readiness of      */
/* each socket for read.                                    */
#define S1READY 0x01
#define S2READY 0X02

waittoread(int s1,int s2)
{
   fd_set fds;
   struct timeval timeout;
   int rc, result;

      /* Set time limit. */
   timeout.tv_sec = 3;
   timeout.tv_usec = 0;
      /* Create a descriptor set containing our two sockets.  */
   FD_ZERO(&fds);
   FD_SET(s1, &fds);
   FD_SET(s2, &fds);
   rc = select(sizeof(fds)*8, &fds, NULL, NULL, &timeout);
   if (rc==-1) {
      perror("select failed");
      return -1;
   }

   result = 0;
   if (rc > 0)
   {
      if (FD_ISSET(s1, &fds)) result |= S1READY;
      if (FD_ISSET(s2, &fds)) result |= S2READY;
   }

   return result;
}


RELATED FUNCTIONS

connect , , getdtablesize read , recv , send , write


Chapter Contents

Previous

Next

Top of Page

Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.