Function

Team-FLY

4.5 The poll Function

The poll function is similar to select , but it organizes the information by file descriptor rather than by type of condition. That is, the possible events for one file descriptor are stored in a struct pollfd . In contrast, select organizes information by the type of event and has separate descriptor masks for read, write and error conditions. The poll function is part of the POSIX:XSI Extension and has its origins in UNIX System V.

The poll function takes three parameters: fds , nfds and timeout . The fds is an array of struct pollfd , representing the monitoring information for the file descriptors. The nfds parameter gives the number of descriptors to be monitored . The timeout value is the time in milliseconds that the poll should wait without receiving an event before returning. If the timeout value is “1, poll never times out. If integers are 32 bits, the maximum timeout period is about 30 minutes.

  SYNOPSIS  #include <poll.h>   int poll(struct pollfd fds[], nfds_t nfds, int timeout);  POSIX:XSI  

The poll function returns 0 if it times out. If successful, poll returns the number of descriptors that have events. If unsuccessful , poll returns “1 and sets errno . The following table lists the mandatory errors for poll .

errno

cause

EAGAIN

allocation of internal data structures failed, but a subsequent request may succeed

EINTR

a signal was caught during poll

EINVAL

nfds is greater than OPEN_MAX

The struct pollfd structure includes the following members .

 int fd;         /* file descriptor */ short events;   /* requested events */ short revents;  /* returned events */ 

The fd is the file descriptor number, and the events and revents are constructed by taking the logical OR of flags representing the various events listed in Table 4.2. Set events to contain the events to monitor; poll fills in the revents with the events that have occurred. The poll function sets the POLLHUP , POLLERR and POLLNVAL flags in revents to reflect the existence of the associated conditions. You do not need to set the corresponding bits in events for these. If fd is less than zero, the events field is ignored and revents is set to zero. The standard does not specify how end-of-file is to be handled. End-of-file can either be communicated by an revents flag of POLLHUP or a normal read of 0 bytes. It is possible for POLLHUP to be set even if POLLIN or POLLRDNORM indicates that there is still data to read. Therefore, normal reading should be handled before error checking.

Table 4.2. Values of the event flags for the poll function.

event flag

meaning

POLLIN

read other than high priority data without blocking

POLLRDNORM

read normal data without blocking

POLLRDBAND

read priority data without blocking

POLLPRI

read high-priority data without blocking

POLLOUT

write normal data without blocking

POLLWRNORM

same as POLLOUT

POLLERR

error occurred on the descriptor

POLLHUP

device has been disconnected

POLLNVAL

file descriptor invalid

Program 4.17 implements a function to process commands from multiple file descriptors by using the poll function. Compare the implementation with that of Program 4.14. The select call modifies the file descriptor sets that are passed to it, and the program must reset these descriptor sets each time it calls select . The poll function uses separate variables for input and return values, so it is not necessary to reset the list of monitored descriptors after each call to poll . The poll function has a number of advantages. The masks do not need to be reset after each call. Unlike select , the poll function treats errors as events that cause poll to return. The timeout parameter is easier to use, although its range is limited. Finally, poll does not need a max_fd argument.

Program 4.17 monitorpoll.c

A function to monitor an array of file descriptors by using poll .

 #include <errno.h> #include <poll.h> #include <stdlib.h> #include <stropts.h> #include <unistd.h> #include "restart.h" #define BUFSIZE 1024 void docommand(char *, int); void monitorpoll(int fd[], int numfds)  {    char buf[BUFSIZE];    int bytesread;    int i;    int numnow = 0;    int numready;    struct pollfd *pollfd;    for (i=0; i< numfds; i++)             /* initialize the polling structure */       if (fd[i] >= 0)           numnow++;    if ((pollfd = (void *)calloc(numfds, sizeof(struct pollfd))) == NULL)       return;    for (i = 0; i < numfds; i++) {       (pollfd + i)->fd = *(fd + i);       (pollfd + i)->events = POLLRDNORM;    }    while (numnow > 0) {        /* Continue monitoring until descriptors done */       numready = poll(pollfd, numfds, -1);       if ((numready == -1) && (errno == EINTR))          continue;                /* poll interrupted by a signal, try again */       else if (numready == -1)            /* real poll error, can't continue */          break;       for (i = 0; i < numfds && numready > 0; i++)  {          if ((pollfd + i)->revents) {             if ((pollfd + i)->revents & (POLLRDNORM  POLLIN) ) {                bytesread = r_read(fd[i], buf, BUFSIZE);                numready--;                if (bytesread > 0)                   docommand(buf, bytesread);                else                   bytesread = -1;                             /* end of file */             } else if ((pollfd + i)->revents & (POLLERR  POLLHUP))                bytesread = -1;             else                    /* descriptor not involved in this round */                bytesread = 0;             if (bytesread == -1) {      /* error occurred, remove descriptor */                r_close(fd[i]);                (pollfd + i)->fd = -1;                numnow--;             }          }       }    }    for (i = 0; i < numfds; i++)        r_close(fd[i]);    free(pollfd); } 
Team-FLY


Unix Systems Programming
UNIX Systems Programming: Communication, Concurrency and Threads
ISBN: 0130424110
EAN: 2147483647
Year: 2003
Pages: 274

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net