1 POLL(7D)                            Devices                           POLL(7D)
   2 
   3 
   4 
   5 NAME
   6        poll - driver for fast poll on many file descriptors
   7 
   8 SYNOPSIS
   9        #include <sys/devpoll.h>
  10        int fd = open("/dev/poll", O_RDWR);
  11        ssize_t n = write(int fd, struct pollfd buf[], int bufsize);
  12        int n = ioctl(int fd, DP_POLL, struct dvpoll* arg);
  13        int n = ioctl(int fd, DP_ISPOLLED, struct pollfd* pfd);
  14 
  15 
  16 PARAMETERS
  17        fd
  18                    Open file descriptor that refers to the  /dev/poll driver.
  19 
  20 
  21        path
  22                    /dev/poll
  23 
  24 
  25        buf
  26                    Array of  pollfd structures.
  27 
  28 
  29        bufsize
  30                    Size of  buf in bytes.
  31 
  32 
  33        arg
  34                    Pointer to  pollcall structure.
  35 
  36 
  37        pfd
  38                    Pointer to pollfd structure.
  39 
  40 
  41 DESCRIPTION
  42        The  /dev/poll driver is a special driver that enables you to monitor
  43        multiple sets  of polled file descriptors. By using the  /dev/poll
  44        driver, you can efficiently poll large numbers of file descriptors.
  45        Access to the /dev/poll driver is provided through open(2), write(2),
  46        and  ioctl(2) system calls.
  47 
  48 
  49        Writing an array of  pollfd struct to the  /dev/poll driver has the
  50        effect of  adding these file descriptors to the monitored poll file
  51        descriptor set  represented by the fd. To monitor multiple file
  52        descriptor sets, open the /dev/poll driver multiple times. Each fd
  53        corresponds to one set. For each pollfd struct entry (defined in
  54        sys/poll.h):
  55 
  56           struct pollfd {
  57              int  fd;
  58              short events;
  59              short revents;
  60           }
  61 
  62 
  63 
  64        The  fd field specifies the file descriptor being polled. The events
  65        field indicates the interested poll events on the file descriptor. If a
  66        pollfd array contains multiple pollfd entries with the same fd field,
  67        the "events" field in each pollfd entry is OR'ed. A special POLLREMOVE
  68        event in the events field of the pollfd structure removes the fd from
  69        the monitored set. The revents field is not used. Write returns the
  70        number of bytes written successfully or -1 when write fails.
  71 
  72 
  73        The DP_POLL ioctl is used to retrieve returned poll events occurred on
  74        the  polled file descriptors in the monitored set represented by fd.
  75        arg is a pointer to the devpoll structures which are defined as
  76        follows:
  77 
  78           struct dvpoll {
  79               struct pollfd* dp_fds;
  80               int dp_nfds;
  81               int dp_timeout;
  82           }
  83 
  84 
  85 
  86        The  dp_fds points to a buffer that holds an array of returned pollfd
  87        structures. The dp_nfds field specifies the size of the buffer in terms
  88        of the  number of pollfd entries it contains. The dp_nfds field also
  89        indicates the maximum number of file descriptors from which poll
  90        information can be obtained. If there is no interested  events on any
  91        of the polled file descriptors, the DP_POLL ioctl call will wait
  92        dp_timeout milliseconds before returning. If dp_timeout is 0, the ioctl
  93        call returns immediately. If dp_timeout is -1, the call blocks until an
  94        interested poll events is available or the call is interrupted. Upon
  95        return, if the ioctl call has failed, -1 is returned. The memory
  96        content pointed by dp_fds is not modified. A return value 0 means the
  97        ioctl is timed out. In this case, the memory content pointed by  dp_fds
  98        is not modified. If the call is successful, it returns the number of
  99        valid pollfd entries in  the array pointed by dp_fds; the contents of
 100        the rest of the buffer is undefined. For each valid pollfd entry, the
 101        fd field indicates the file descriptor on which the polled events
 102        happened. The  events field is the user specified poll events. The
 103        revents field contains the  events occurred. -1 is returned if the
 104        call fails.
 105 
 106 
 107        DP_ISPOLLED ioctl allows you to query if a file descriptor is already
 108        in the  monitored set represented by  fd. The fd field of the pollfd
 109        structure indicates the file descriptor of interest. The DP_ISPOLLED
 110        ioctl returns  1 if the file descriptor is in the set.  The events
 111        field contains  0. The revents field contains the currently polled
 112        events. The ioctl returns  0 if the file descriptor is not in the set.
 113        The  pollfd structure pointed by  pfd is not modified. The ioctl
 114        returns a  -1 if the call fails.
 115 
 116 EXAMPLES
 117        The following example shows how  /dev/poll may be used.
 118 
 119          {
 120                  ...
 121                  /*
 122                   * open the driver
 123                   */
 124                  if ((wfd = open("/dev/poll", O_RDWR)) < 0) {
 125                          exit(-1);
 126                  }
 127                  pollfd = (struct pollfd* )malloc(sizeof(struct pollfd) * MAXBUF);
 128                  if (pollfd == NULL) {
 129                          close(wfd);
 130                          exit(-1);
 131                  }
 132                  /*
 133                   * initialize buffer
 134                   */
 135                  for (i = 0; i < MAXBUF; i++) {
 136                          pollfd[i].fd = fds[i];
 137                          pollfd[i].events = POLLIN;
 138                          pollfd[i].revents = 0;
 139                  }
 140                  if (write(wfd, &pollfd[0], sizeof(struct pollfd) * MAXBUF) !=
 141                                  sizeof(struct pollfd) * MAXBUF) {
 142                          perror("failed to write all pollfds");
 143                          close (wfd);
 144                          free(pollfd);
 145                          exit(-1);
 146                  }
 147                  /*
 148                   * read from the devpoll driver
 149                   */
 150                  dopoll.dp_timeout = -1;
 151                  dopoll.dp_nfds = MAXBUF;
 152                  dopoll.dp_fds = pollfd;
 153                  result = ioctl(wfd, DP_POLL, &dopoll);
 154                  if (result < 0) {
 155                          perror("/dev/poll ioctl DP_POLL failed");
 156                          close (wfd);
 157                          free(pollfd);
 158                          exit(-1);
 159                  }
 160                  for (i = 0; i < result; i++) {
 161                          read(dopoll.dp_fds[i].fd, rbuf, STRLEN);
 162                  }
 163           ...
 164          }
 165 
 166 
 167 
 168        The following example is part of a test program which shows how
 169        DP_ISPOLLED() ioctl may be used.
 170 
 171          {
 172               ...
 173 
 174                  loopcnt = 0;
 175                  while (loopcnt < ITERATION) {
 176                          rn = random();
 177                          rn %= RANGE;
 178                          if (write(fds[rn], TESTSTRING, strlen(TESTSTRING)) !=
 179                                          strlen(TESTSTRING)) {
 180                                  perror("write to fifo failed.");
 181                                  close (wfd);
 182                                  free(pollfd);
 183                                  error = 1;
 184                                  goto out1;
 185                          }
 186                          dpfd.fd = fds[rn];
 187                          dpfd.events = 0;
 188                          dpfd.revents = 0;
 189                          result = ioctl(wfd, DP_ISPOLLED, &dpfd);
 190                          if (result < 0) {
 191                                  perror("/dev/poll ioctl DP_ISPOLLED failed");
 192                                  printf("errno = %d\n", errno);
 193                                  close (wfd);
 194                                  free(pollfd);
 195                                  error = 1;
 196                                  goto out1;
 197                          }
 198                          if (result != 1) {
 199                                  printf("DP_ISPOLLED returned incorrect result: %d.\n",
 200                                          result);
 201                                  close (wfd);
 202                                  free(pollfd);
 203                                  error = 1;
 204                                  goto out1;
 205                          }
 206                          if (dpfd.fd != fds[rn]) {
 207                                  printf("DP_ISPOLLED returned wrong fd %d, expect %d\n",
 208                                          dpfd.fd, fds[rn]);
 209                                  close (wfd);
 210                                  free(pollfd);
 211                                  error = 1;
 212                                  goto out1;
 213           }
 214                          if (dpfd.revents != POLLIN) {
 215                                  printf("DP_ISPOLLED returned unexpected revents %d\n",
 216                                          dpfd.revents);
 217                                  close (wfd);
 218                                  free(pollfd);
 219                                  error = 1;
 220                                  goto out1;
 221                          }
 222                          if (read(dpfd.fd, rbuf, strlen(TESTSTRING)) !=
 223                                          strlen(TESTSTRING)) {
 224                                  perror("read from fifo failed");
 225                                  close (wfd);
 226                                  free(pollfd);
 227                                  error = 1;
 228                                  goto out1;
 229                          }
 230                          loopcnt++;
 231                  }
 232 
 233 
 234 
 235 ERRORS
 236        EACCES
 237                   A process does not have permission to access the content
 238                   cached in /dev/poll.
 239 
 240 
 241        EINTR
 242                   A signal was caught during the execution of the ioctl(2)
 243                   function.
 244 
 245 
 246        EFAULT
 247                   The request argument requires a data transfer to or from a
 248                   buffer pointed to by arg, but arg points to an illegal
 249                   address.
 250 
 251 
 252        EINVAL
 253                   The request or arg parameter is not valid for  this device,
 254                   or field of the dvpoll struct pointed by arg is not valid
 255                   (for example, when using write/pwrite dp_nfds is greater
 256                   than {OPEN_MAX}, or when using the DPPOLL ioctl dp_nfds is
 257                   greater than or equal to {OPEN_MAX}}.
 258 
 259 
 260        ENXIO
 261                   The O_NONBLOCK flag is set, the named file is a FIFO, the
 262                   O_WRONLY flag is set, and no process has the file open for
 263                   reading; or the named file is a character special or block
 264                   special file and the device associated with this special
 265                   file does not exist.
 266 
 267 
 268 ATTRIBUTES
 269        See attributes(5) for a description of the following attributes:
 270 
 271 
 272 
 273 
 274        +--------------------------------------+
 275        |ATTRIBUTE TYPE        ATTRIBUTE VALUE |
 276        |Architecture          SPARC, x86      |
 277        |Interface Stability   Obsolete        |
 278        |MT-Level              Safe            |
 279        +--------------------------------------+
 280 
 281 SEE ALSO
 282        open(2), poll(2), write(2), attributes(5)
 283 
 284 NOTES
 285        The /dev/poll API is particularly beneficial to applications that poll
 286        a large number of file descriptors repeatedly.  Applications will
 287        exhibit the best performance gain if the polled file descriptor list
 288        rarely change.
 289 
 290 
 291        When using the /dev/poll driver, you should remove a closed file
 292        descriptor from a monitored poll set. Failure to do so may result in a
 293        POLLNVAL revents being returned for the closed file descriptor.  When a
 294        file descriptor is closed but not removed from the monitored set, and
 295        is reused in subsequent open of a different device, you will be polling
 296        the device associated with the reused file descriptor. In a
 297        multithreaded application, careful coordination among threads doing
 298        close and DP_POLL ioctl is recommended for consistent results.
 299 
 300 
 301        The /dev/poll driver caches a list of polled file descriptors, which
 302        are specific to a process. Therefore, the  /dev/poll file descriptor of
 303        a process will be inherited by its child process, just like any other
 304        file descriptors. But the child process will have very limited access
 305        through this inherited /dev/poll file descriptor. Any attempt to write
 306        or do ioctl by the child process will result in an EACCES error. The
 307        child process should close the inherited  /dev/poll file descriptor and
 308        open its own if desired.
 309 
 310 
 311        The  /dev/poll driver does not yet support polling. Polling on a
 312        /dev/poll file descriptor will result in POLLERR being returned in the
 313        revents field of pollfd structure.
 314 
 315 
 316 
 317                                January 10, 2020                       POLL(7D)