HPlogo Berkeley Sockets/iX Reference Manual: HP 3000 MPE/iX Computer Systems > Chapter 3 File System Intrinsics

SELECT

» 

Technical documentation

Complete book in PDF
» Feedback

 » Table of Contents

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.

Feedback to webmaster