poll - driver for fast poll on many file descriptors


     #include <sys/devpoll.h>
     int fd = open("/dev/poll", O_RDWR);
     ssize_t n = write(int fd, struct pollfd buf[], int bufsize);
     int n = ioctl(int fd, DP_POLL, struct dvpoll* arg);
     int n = ioctl(int fd, DP_ISPOLLED, struct pollfd* pfd);


     fd    Open file descriptor that  refers  to  the   /dev/poll

     path  /dev/poll

     buf   Array of  pollfd structures.

           Size of  buf in bytes.

     arg   Pointer to  pollcall structure.

     pfd   Pointer to pollfd structure.


     The  /dev/poll driver is a special driver that  enables  you
     to  monitor  multiple  sets   of polled file descriptors. By
     using the  /dev/poll driver, you can efficiently poll  large
     numbers of file descriptors.  Access to the /dev/poll driver
     is  provided through  open(2), write(2), and  ioctl(2)  sys-
     tem calls.

     Writing an array of  pollfd struct to the  /dev/poll  driver
     has the effect of  adding these file descriptors to the mon-
     itored poll file descriptor set  represented by the  fd.  To
     monitor  multiple  file  descriptor sets, open the /dev/poll
     driver multiple times. Each fd corresponds to one  set.  For
     each pollfd struct entry (defined in sys/poll.h):

      struct pollfd {
         int  fd;
         short events;
         short revents;

     The  fd field specifies the file  descriptor  being  polled.
     The   events  field  indicates the interested poll events on
     the file descriptor. If a  pollfd  array  contains  multiple
     pollfd entries with the same fd field, the "events" field in
     each pollfd entry is OR'ed. A special  POLLREMOVE  event  in
     the  events  field  of  the  pollfd structure removes the fd
     from the monitored set. The revents field is not used. Write
     returns  the number of bytes written successfully or -1 when
     write fails.

     The DP_POLL ioctl is used to retrieve returned  poll  events
     occured on the  polled file descriptors in the monitored set
     represented by  fd. arg is a pointer to the  devpoll  struc-
     tures which are defined as follows:

      struct dvpoll {
          struct pollfd* dp_fds;
          int dp_nfds;
          int dp_timeout;

     The  dp_fds points to  a  buffer  that  holds  an  array  of
     returned  pollfd structures. The dp_nfds field specifies the
     size of the buffer in terms of the number of  pollfd entries
     it  contains.  The  dp_nfds field also indicates the maximum
     number of file descriptors from which poll  information  can
     be obtained. If there is no interested  events on any of the
     polled file descriptors, the  DP_POLL ioctl call  will  wait
     dp_timeout  milliseconds before returning. If  dp_timeout is
     0, the ioctl call returns immediately. If dp_timeout is  -1,
     the call blocks until an interested poll events is available
     or the call is interrupted. Upon return, if the  ioctl  call
     has  failed,  -1  is returned. The memory content pointed by
     dp_fds is not modified. A return value  0 means the ioctl is
     timed  out.  In  this  case,  the  memory content pointed by
     dp_fds is not  modified.  If  the  call  is  successful,  it
     returns  the  number  of valid  pollfd entries in  the array
     pointed by  dp_fds; the contents of the rest of  the  buffer
     is  undefined.  For  each  valid  pollfd entry, the fd field
     indicates the file desciptor on  which  the  polled   events
     happened.  The   events  field  is  the user specified  poll
     events. The revents field contains the  events occurred.  -1
     is returned if the  call fails.

     DP_ISPOLLED ioctl allows you to query if a  file  descriptor
     is  already in the  monitored set represented by  fd. The fd
     field of the  pollfd structure indicates the file descriptor
     of  interest.  The  DP_ISPOLLED ioctl returns  1 if the file
     descriptor is in the set. The   events  field  contains  the
     currently  polled   events.  The  revents field contains  0.
     The ioctl returns  0 if the file descriptor is  not  in  the
     set.  The  pollfd structure pointed by  pfd is not modified.
     The ioctl returns a  -1 if the call fails.


     The following example shows how  /dev/poll may be used.

              * open the driver
             if ((wfd = open("/dev/poll", O_RDWR)) < 0) {
             pollfd = (struct pollfd* )malloc(sizeof(struct pollfd) * MAXBUF);
             if (pollfd == NULL) {
              * initialize buffer
             for (i = 0; i < MAXBUF; i++) {
                     pollfd[i].fd = fds[i];
                     pollfd[i].events = POLLIN;
                     pollfd[i].revents = 0;
             if (write(wfd, &pollfd[0], sizeof(struct pollfd) * MAXBUF) !=
                             sizeof(struct pollfd) * MAXBUF) {
                     perror("failed to write all pollfds");
                     close (wfd);
              * read from the devpoll driver
             dopoll.dp_timeout = -1;
             dopoll.dp_nfds = MAXBUF;
             dopoll.dp_fds = pollfd;
             result = ioctl(wfd, DP_POLL, &dopoll);
             if (result < 0) {
                     perror("/dev/poll ioctl DP_POLL failed");
                     close (wfd);
             for (i = 0; i < result; i++) {
                     read(dopoll.dp_fds[i].fd, rbuf, STRLEN);

     The following example is part of a test program which  shows
     how DP_ISPOLLED() ioctl may be used.


             loopcnt = 0;
             while (loopcnt < ITERATION) {
                     rn = random();
                     rn %= RANGE;
                     if (write(fds[rn], TESTSTRING, strlen(TESTSTRING)) !=
                                     strlen(TESTSTRING)) {
                             perror("write to fifo failed.");
                             close (wfd);
                             error = 1;
                             goto out1;
                     dpfd.fd = fds[rn];
                     dpfd.events = 0;
                     dpfd.revents = 0;
                     result = ioctl(wfd, DP_ISPOLLED, &dpfd);
                     if (result < 0) {
                             perror("/dev/poll ioctl DP_ISPOLLED failed");
                             printf("errno = %d\n", errno);
                             close (wfd);
                             error = 1;
                             goto out1;
                     if (result != 1) {
                             printf("DP_ISPOLLED returned incorrect result: %d.\n",
                             close (wfd);
                             error = 1;
                             goto out1;
                     if (dpfd.fd != fds[rn]) {
                             printf("DP_ISPOLLED returned wrong fd %d, expect %d\n",
                                     dpfd.fd, fds[rn]);
                             close (wfd);
                             error = 1;
                             goto out1;
                     if (dpfd.revents != POLLIN) {
                             printf("DP_ISPOLLED returned unexpected revents %d\n",
                             close (wfd);
                             error = 1;
                             goto out1;
                     if (read(dpfd.fd, rbuf, strlen(TESTSTRING)) !=
                                     strlen(TESTSTRING)) {
                             perror("read from fifo failed");
                             close (wfd);
                             error = 1;
                             goto out1;


           A process does not have permission to access the  con-
           tent cached in /dev/poll.

     EINTR A signal  was  caught  during  the  execution  of  the
           ioctl(2) function.

           The request argument requires a data  transfer  to  or
           from  a buffer pointed to by arg, but arg points to an
           illegal address.

           The request or arg parameter is  not  valid  for  this

     ENXIO The O_NONBLOCK flag is set, the named file is a  FIFO,
           the  O_WRONLY flag is set, and no process has the file
           open for reading; or the named  file  is  a  character
           special  or  block special file and the device associ-
           ated with this special file does not exist.


     See attributes(5) for a description of the following  attri-

  |         ATTRIBUTE TYPE      |         ATTRIBUTE VALUE     |
  |   Architecture              |   SPARC, x86                |
  |   Availability              |   SUNWcarx.u,  SUNWcsxu  (64|
  |                             |   bit Solaris)              |
  |                             |  SUNWcsr,  SUNWcsu   (32-bit|
  |                             |  Solaris on x86)            |
  |                             | SUNWhea (header files)      |
  | Interface Stability         | Evolving                    |
  | MT-Level                    | Safe                        |


     open(2), poll(2), write(2), attributes(5)


     The /dev/poll API is particularly beneficial to applications
     that  poll  a  large  number of file descriptors repeatedly.
     Applications will exhibit the best performance gain  if  the
     polled file descriptor list rarely change.

     When using the  /dev/poll driver, you should remove a closed
     file  descriptor from a monitored poll set. Failure to do so
     may result in a POLLNVAL  revents  being  returned  for  the
     closed file descriptor. When a file descriptor is closed but
     not removed from the monitored set, and is reused in  subse-
     quent  open  of  a different device, you will be polling the
     device associated with the reused file descriptor. In a mul-
     tithreaded  application,  careful coordination among threads
     doing close and DP_POLL ioctl is recommended for  consistent

     The /dev/poll driver caches a list of polled  file  descrip-
     tors,  which  are   specific  to  a  process. Therefore, the
     /dev/poll file descriptor of a process will be inherited  by
     its child process, just like any other file descriptors. But
     the child process will have very limited access through this
     inherited  /dev/poll  file descriptor.  Any attempt to write
     or do ioctl by the child process will result  in  an  EACCES
     error.   The   child  process  should  close  the  inherited
     /dev/poll file descriptor and open its own if desired.

     The  /dev/poll driver does not yet support polling.  Polling
     on a /dev/poll file descriptor will result in  POLLERR being
     returned in the  revents field of pollfd structure.

Man(1) output converted with man2html