Issue #6397: Support '/dev/poll' polling objects in select module, under Solaris & derivatives.
diff --git a/Doc/library/select.rst b/Doc/library/select.rst
index a4bc6fc..12b05d2 100644
--- a/Doc/library/select.rst
+++ b/Doc/library/select.rst
@@ -6,7 +6,8 @@
 
 
 This module provides access to the :c:func:`select` and :c:func:`poll` functions
-available in most operating systems, :c:func:`epoll` available on Linux 2.5+ and
+available in most operating systems, :c:func:`devpoll` available on
+Solaris and derivatives, :c:func:`epoll` available on Linux 2.5+ and
 :c:func:`kqueue` available on most BSD.
 Note that on Windows, it only works for sockets; on other operating systems,
 it also works for other file types (in particular, on Unix, it works on pipes).
@@ -24,6 +25,19 @@
       Following :pep:`3151`, this class was made an alias of :exc:`OSError`.
 
 
+.. function:: devpoll()
+   (Only supported on Solaris and derivatives.)  Returns a ``/dev/poll``
+   polling object; see section :ref:`devpoll-objects` below for the
+   methods supported by devpoll objects.
+
+   :c:func:`devpoll` objects are linked to the number of file
+   descriptors allowed at the time of instantiation. If your program
+   reduces this value, :c:func:`devpoll` will fail. If your program
+   increases this value, c:func:`devpoll` may return an
+   incomplete list of active file descriptors.
+
+   .. versionadded:: 3.3
+
 .. function:: epoll(sizehint=-1)
 
    (Only supported on Linux 2.5.44 and newer.)  Returns an edge polling object,
@@ -107,6 +121,74 @@
    .. versionadded:: 3.2
 
 
+.. _devpoll-objects:
+
+``/dev/poll`` Polling Objects
+----------------------------------------------
+
+   http://developers.sun.com/solaris/articles/using_devpoll.html
+   http://developers.sun.com/solaris/articles/polling_efficient.html
+
+Solaris and derivatives have ``/dev/poll``. While :c:func:`select` is
+O(highest file descriptor) and :c:func:`poll` is O(number of file
+descriptors), ``/dev/poll`` is O(active file descriptors).
+
+``/dev/poll`` behaviour is very close to the standard :c:func:`poll`
+object.
+
+
+.. method:: devpoll.register(fd[, eventmask])
+
+   Register a file descriptor with the polling object.  Future calls to the
+   :meth:`poll` method will then check whether the file descriptor has any pending
+   I/O events.  *fd* can be either an integer, or an object with a :meth:`fileno`
+   method that returns an integer.  File objects implement :meth:`fileno`, so they
+   can also be used as the argument.
+
+   *eventmask* is an optional bitmask describing the type of events you want to
+   check for. The constants are the same that with :c:func:`poll`
+   object. The default value is a combination of the constants :const:`POLLIN`,
+   :const:`POLLPRI`, and :const:`POLLOUT`.
+
+   .. warning::
+
+      Registering a file descriptor that's already registered is not an
+      error, but the result is undefined. The appropiate action is to
+      unregister or modify it first. This is an important difference
+      compared with :c:func:`poll`.
+
+
+.. method:: devpoll.modify(fd[, eventmask])
+
+   This method does an :meth:`unregister` followed by a
+   :meth:`register`. It is (a bit) more efficient that doing the same
+   explicitly.
+
+
+.. method:: devpoll.unregister(fd)
+
+   Remove a file descriptor being tracked by a polling object.  Just like the
+   :meth:`register` method, *fd* can be an integer or an object with a
+   :meth:`fileno` method that returns an integer.
+
+   Attempting to remove a file descriptor that was never registered is
+   safely ignored.
+
+
+.. method:: devpoll.poll([timeout])
+
+   Polls the set of registered file descriptors, and returns a possibly-empty list
+   containing ``(fd, event)`` 2-tuples for the descriptors that have events or
+   errors to report. *fd* is the file descriptor, and *event* is a bitmask with
+   bits set for the reported events for that descriptor --- :const:`POLLIN` for
+   waiting input, :const:`POLLOUT` to indicate that the descriptor can be written
+   to, and so forth. An empty list indicates that the call timed out and no file
+   descriptors had any events to report. If *timeout* is given, it specifies the
+   length of time in milliseconds which the system will wait for events before
+   returning. If *timeout* is omitted, -1, or :const:`None`, the call will
+   block until there is an event for this poll object.
+
+
 .. _epoll-objects:
 
 Edge and Level Trigger Polling (epoll) Objects
diff --git a/Lib/test/test_devpoll.py b/Lib/test/test_devpoll.py
new file mode 100644
index 0000000..bef4e18
--- /dev/null
+++ b/Lib/test/test_devpoll.py
@@ -0,0 +1,94 @@
+# Test case for the select.devpoll() function
+
+# Initial tests are copied as is from "test_poll.py"
+
+import os, select, random, unittest, sys
+from test.support import TESTFN, run_unittest
+
+try:
+    select.devpoll
+except AttributeError:
+    raise unittest.SkipTest("select.devpoll not defined -- skipping test_devpoll")
+
+
+def find_ready_matching(ready, flag):
+    match = []
+    for fd, mode in ready:
+        if mode & flag:
+            match.append(fd)
+    return match
+
+class DevPollTests(unittest.TestCase):
+
+    def test_devpoll1(self):
+        # Basic functional test of poll object
+        # Create a bunch of pipe and test that poll works with them.
+
+        p = select.devpoll()
+
+        NUM_PIPES = 12
+        MSG = b" This is a test."
+        MSG_LEN = len(MSG)
+        readers = []
+        writers = []
+        r2w = {}
+        w2r = {}
+
+        for i in range(NUM_PIPES):
+            rd, wr = os.pipe()
+            p.register(rd)
+            p.modify(rd, select.POLLIN)
+            p.register(wr, select.POLLOUT)
+            readers.append(rd)
+            writers.append(wr)
+            r2w[rd] = wr
+            w2r[wr] = rd
+
+        bufs = []
+
+        while writers:
+            ready = p.poll()
+            ready_writers = find_ready_matching(ready, select.POLLOUT)
+            if not ready_writers:
+                self.fail("no pipes ready for writing")
+            wr = random.choice(ready_writers)
+            os.write(wr, MSG)
+
+            ready = p.poll()
+            ready_readers = find_ready_matching(ready, select.POLLIN)
+            if not ready_readers:
+                self.fail("no pipes ready for reading")
+            self.assertEqual([w2r[wr]], ready_readers)
+            rd = ready_readers[0]
+            buf = os.read(rd, MSG_LEN)
+            self.assertEqual(len(buf), MSG_LEN)
+            bufs.append(buf)
+            os.close(r2w[rd]) ; os.close(rd)
+            p.unregister(r2w[rd])
+            p.unregister(rd)
+            writers.remove(r2w[rd])
+
+        self.assertEqual(bufs, [MSG] * NUM_PIPES)
+
+    def test_timeout_overflow(self):
+        pollster = select.devpoll()
+        w, r = os.pipe()
+        pollster.register(w)
+
+        pollster.poll(-1)
+        self.assertRaises(OverflowError, pollster.poll, -2)
+        self.assertRaises(OverflowError, pollster.poll, -1 << 31)
+        self.assertRaises(OverflowError, pollster.poll, -1 << 64)
+
+        pollster.poll(0)
+        pollster.poll(1)
+        pollster.poll(1 << 30)
+        self.assertRaises(OverflowError, pollster.poll, 1 << 31)
+        self.assertRaises(OverflowError, pollster.poll, 1 << 63)
+        self.assertRaises(OverflowError, pollster.poll, 1 << 64)
+
+def test_main():
+    run_unittest(DevPollTests)
+
+if __name__ == '__main__':
+    test_main()
diff --git a/Misc/NEWS b/Misc/NEWS
index c462d6f..423e29d 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -365,6 +365,9 @@
 Library
 -------
 
+- Issue #6397: Support "/dev/poll" polling objects in select module,
+  under Solaris & derivatives.
+
 - Issues #1745761, #755670, #13357, #12629, #1200313: HTMLParser now correctly
   handles non-valid attributes, including adjacent and unquoted attributes.
 
diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c
index 6071144..5d5e772 100644
--- a/Modules/selectmodule.c
+++ b/Modules/selectmodule.c
@@ -7,6 +7,14 @@
 #include "Python.h"
 #include <structmember.h>
 
+#ifdef HAVE_SYS_DEVPOLL_H
+#include <sys/resource.h>
+#include <sys/devpoll.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#endif
+
 #ifdef __APPLE__
     /* Perform runtime testing for a broken poll on OSX to make it easier
      * to use the same binary on multiple releases of the OS.
@@ -648,6 +656,339 @@
     poll_methods,               /*tp_methods*/
 };
 
+#ifdef HAVE_SYS_DEVPOLL_H
+typedef struct {
+    PyObject_HEAD
+    int fd_devpoll;
+    int max_n_fds;
+    int n_fds;
+    struct pollfd *fds;
+} devpollObject;
+
+static PyTypeObject devpoll_Type;
+
+static int devpoll_flush(devpollObject *self)
+{
+    int size, n;
+
+    if (!self->n_fds) return 0;
+
+    size = sizeof(struct pollfd)*self->n_fds;
+    self->n_fds = 0;
+
+    Py_BEGIN_ALLOW_THREADS
+    n = write(self->fd_devpoll, self->fds, size);
+    Py_END_ALLOW_THREADS
+
+    if (n == -1 ) {
+        PyErr_SetFromErrno(PyExc_IOError);
+        return -1;
+    }
+    if (n < size) {
+        /*
+        ** Data writed to /dev/poll is a binary data structure. It is not
+        ** clear what to do if a partial write occurred. For now, raise
+        ** an exception and see if we actually found this problem in
+        ** the wild.
+        ** See http://bugs.python.org/issue6397.
+        */
+        PyErr_Format(PyExc_IOError, "failed to write all pollfds. "
+                "Please, report at http://bugs.python.org/. "
+                "Data to report: Size tried: %d, actual size written: %d.",
+                size, n);
+        return -1;
+    }
+    return 0;
+}
+
+static PyObject *
+internal_devpoll_register(devpollObject *self, PyObject *args, int remove)
+{
+    PyObject *o;
+    int fd, events = POLLIN | POLLPRI | POLLOUT;
+
+    if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
+        return NULL;
+    }
+
+    fd = PyObject_AsFileDescriptor(o);
+    if (fd == -1) return NULL;
+
+    if (remove) {
+        self->fds[self->n_fds].fd = fd;
+        self->fds[self->n_fds].events = POLLREMOVE;
+
+        if (++self->n_fds == self->max_n_fds) {
+            if (devpoll_flush(self))
+                return NULL;
+        }
+    }
+
+    self->fds[self->n_fds].fd = fd;
+    self->fds[self->n_fds].events = events;
+
+    if (++self->n_fds == self->max_n_fds) {
+        if (devpoll_flush(self))
+            return NULL;
+    }
+
+    Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(devpoll_register_doc,
+"register(fd [, eventmask] ) -> None\n\n\
+Register a file descriptor with the polling object.\n\
+fd -- either an integer, or an object with a fileno() method returning an\n\
+      int.\n\
+events -- an optional bitmask describing the type of events to check for");
+
+static PyObject *
+devpoll_register(devpollObject *self, PyObject *args)
+{
+    return internal_devpoll_register(self, args, 0);
+}
+
+PyDoc_STRVAR(devpoll_modify_doc,
+"modify(fd[, eventmask]) -> None\n\n\
+Modify a possible already registered file descriptor.\n\
+fd -- either an integer, or an object with a fileno() method returning an\n\
+      int.\n\
+events -- an optional bitmask describing the type of events to check for");
+
+static PyObject *
+devpoll_modify(devpollObject *self, PyObject *args)
+{
+    return internal_devpoll_register(self, args, 1);
+}
+
+
+PyDoc_STRVAR(devpoll_unregister_doc,
+"unregister(fd) -> None\n\n\
+Remove a file descriptor being tracked by the polling object.");
+
+static PyObject *
+devpoll_unregister(devpollObject *self, PyObject *o)
+{
+    int fd;
+
+    fd = PyObject_AsFileDescriptor( o );
+    if (fd == -1)
+        return NULL;
+
+    self->fds[self->n_fds].fd = fd;
+    self->fds[self->n_fds].events = POLLREMOVE;
+
+    if (++self->n_fds == self->max_n_fds) {
+        if (devpoll_flush(self))
+            return NULL;
+    }
+
+    Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(devpoll_poll_doc,
+"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
+Polls the set of registered file descriptors, returning a list containing \n\
+any descriptors that have events or errors to report.");
+
+static PyObject *
+devpoll_poll(devpollObject *self, PyObject *args)
+{
+    struct dvpoll dvp;
+    PyObject *result_list = NULL, *tout = NULL;
+    int poll_result, i;
+    long timeout;
+    PyObject *value, *num1, *num2;
+
+    if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
+        return NULL;
+    }
+
+    /* Check values for timeout */
+    if (tout == NULL || tout == Py_None)
+        timeout = -1;
+    else if (!PyNumber_Check(tout)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "timeout must be an integer or None");
+        return NULL;
+    }
+    else {
+        tout = PyNumber_Long(tout);
+        if (!tout)
+            return NULL;
+        timeout = PyLong_AsLong(tout);
+        Py_DECREF(tout);
+        if (timeout == -1 && PyErr_Occurred())
+            return NULL;
+    }
+
+    if ((timeout < -1) || (timeout > INT_MAX)) {
+        PyErr_SetString(PyExc_OverflowError,
+                        "timeout is out of range");
+        return NULL;
+    }
+
+    if (devpoll_flush(self))
+        return NULL;
+
+    dvp.dp_fds = self->fds;
+    dvp.dp_nfds = self->max_n_fds;
+    dvp.dp_timeout = timeout;
+
+    /* call devpoll() */
+    Py_BEGIN_ALLOW_THREADS
+    poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp);
+    Py_END_ALLOW_THREADS
+
+    if (poll_result < 0) {
+        PyErr_SetFromErrno(PyExc_IOError);
+        return NULL;
+    }
+
+    /* build the result list */
+
+    result_list = PyList_New(poll_result);
+    if (!result_list)
+        return NULL;
+    else {
+        for (i = 0; i < poll_result; i++) {
+            num1 = PyLong_FromLong(self->fds[i].fd);
+            num2 = PyLong_FromLong(self->fds[i].revents);
+            if ((num1 == NULL) || (num2 == NULL)) {
+                Py_XDECREF(num1);
+                Py_XDECREF(num2);
+                goto error;
+            }
+            value = PyTuple_Pack(2, num1, num2);
+            Py_DECREF(num1);
+            Py_DECREF(num2);
+            if (value == NULL)
+                goto error;
+            if ((PyList_SetItem(result_list, i, value)) == -1) {
+                Py_DECREF(value);
+                goto error;
+            }
+        }
+    }
+
+    return result_list;
+
+  error:
+    Py_DECREF(result_list);
+    return NULL;
+}
+
+static PyMethodDef devpoll_methods[] = {
+    {"register",        (PyCFunction)devpoll_register,
+     METH_VARARGS,  devpoll_register_doc},
+    {"modify",          (PyCFunction)devpoll_modify,
+     METH_VARARGS,  devpoll_modify_doc},
+    {"unregister",      (PyCFunction)devpoll_unregister,
+     METH_O,        devpoll_unregister_doc},
+    {"poll",            (PyCFunction)devpoll_poll,
+     METH_VARARGS,  devpoll_poll_doc},
+    {NULL,              NULL}           /* sentinel */
+};
+
+static devpollObject *
+newDevPollObject(void)
+{
+    devpollObject *self;
+    int fd_devpoll, limit_result;
+    struct pollfd *fds;
+    struct rlimit limit;
+
+    Py_BEGIN_ALLOW_THREADS
+    /*
+    ** If we try to process more that getrlimit()
+    ** fds, the kernel will give an error, so
+    ** we set the limit here. It is a dynamic
+    ** value, because we can change rlimit() anytime.
+    */
+    limit_result = getrlimit(RLIMIT_NOFILE, &limit);
+    if (limit_result != -1)
+        fd_devpoll = open("/dev/poll", O_RDWR);
+    Py_END_ALLOW_THREADS
+
+    if (limit_result == -1) {
+        PyErr_SetFromErrno(PyExc_OSError);
+        return NULL;
+    }
+    if (fd_devpoll == -1) {
+        PyErr_SetFromErrnoWithFilename(PyExc_IOError, "/dev/poll");
+        return NULL;
+    }
+
+    fds = PyMem_NEW(struct pollfd, limit.rlim_cur);
+    if (fds == NULL) {
+        close(fd_devpoll);
+        PyErr_NoMemory();
+        return NULL;
+    }
+
+    self = PyObject_New(devpollObject, &devpoll_Type);
+    if (self == NULL) {
+        close(fd_devpoll);
+        PyMem_DEL(fds);
+        return NULL;
+    }
+    self->fd_devpoll = fd_devpoll;
+    self->max_n_fds = limit.rlim_cur;
+    self->n_fds = 0;
+    self->fds = fds;
+
+    return self;
+}
+
+static void
+devpoll_dealloc(devpollObject *self)
+{
+    Py_BEGIN_ALLOW_THREADS
+    close(self->fd_devpoll);
+    Py_END_ALLOW_THREADS
+
+    PyMem_DEL(self->fds);
+
+    PyObject_Del(self);
+}
+
+static PyTypeObject devpoll_Type = {
+    /* The ob_type field must be initialized in the module init function
+     * to be portable to Windows without using C++. */
+    PyVarObject_HEAD_INIT(NULL, 0)
+    "select.devpoll",           /*tp_name*/
+    sizeof(devpollObject),      /*tp_basicsize*/
+    0,                          /*tp_itemsize*/
+    /* methods */
+    (destructor)devpoll_dealloc, /*tp_dealloc*/
+    0,                          /*tp_print*/
+    0,                          /*tp_getattr*/
+    0,                          /*tp_setattr*/
+    0,                          /*tp_reserved*/
+    0,                          /*tp_repr*/
+    0,                          /*tp_as_number*/
+    0,                          /*tp_as_sequence*/
+    0,                          /*tp_as_mapping*/
+    0,                          /*tp_hash*/
+    0,                          /*tp_call*/
+    0,                          /*tp_str*/
+    0,                          /*tp_getattro*/
+    0,                          /*tp_setattro*/
+    0,                          /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,         /*tp_flags*/
+    0,                          /*tp_doc*/
+    0,                          /*tp_traverse*/
+    0,                          /*tp_clear*/
+    0,                          /*tp_richcompare*/
+    0,                          /*tp_weaklistoffset*/
+    0,                          /*tp_iter*/
+    0,                          /*tp_iternext*/
+    devpoll_methods,            /*tp_methods*/
+};
+#endif  /* HAVE_SYS_DEVPOLL_H */
+
+
+
 PyDoc_STRVAR(poll_doc,
 "Returns a polling object, which supports registering and\n\
 unregistering file descriptors, and then polling them for I/O events.");
@@ -658,6 +999,19 @@
     return (PyObject *)newPollObject();
 }
 
+#ifdef HAVE_SYS_DEVPOLL_H
+PyDoc_STRVAR(devpoll_doc,
+"Returns a polling object, which supports registering and\n\
+unregistering file descriptors, and then polling them for I/O events.");
+
+static PyObject *
+select_devpoll(PyObject *self, PyObject *unused)
+{
+    return (PyObject *)newDevPollObject();
+}
+#endif
+
+
 #ifdef __APPLE__
 /*
  * On some systems poll() sets errno on invalid file descriptors. We test
@@ -1715,6 +2069,11 @@
 };
 
 #endif /* HAVE_KQUEUE */
+
+
+
+
+
 /* ************************************************************************ */
 
 PyDoc_STRVAR(select_doc,
@@ -1746,6 +2105,9 @@
 #ifdef HAVE_POLL
     {"poll",            select_poll,    METH_NOARGS,    poll_doc},
 #endif /* HAVE_POLL */
+#ifdef HAVE_SYS_DEVPOLL_H
+    {"devpoll",         select_devpoll, METH_NOARGS,    devpoll_doc},
+#endif
     {0,         0},     /* sentinel */
 };
 
@@ -1768,6 +2130,9 @@
     NULL
 };
 
+
+
+
 PyMODINIT_FUNC
 PyInit_select(void)
 {
@@ -1824,6 +2189,11 @@
     }
 #endif /* HAVE_POLL */
 
+#ifdef HAVE_SYS_DEVPOLL_H
+    if (PyType_Ready(&devpoll_Type) < 0)
+        return NULL;
+#endif
+
 #ifdef HAVE_EPOLL
     Py_TYPE(&pyEpoll_Type) = &PyType_Type;
     if (PyType_Ready(&pyEpoll_Type) < 0)
diff --git a/configure b/configure
index 4812732..596336e 100755
--- a/configure
+++ b/configure
@@ -6139,12 +6139,13 @@
 
 for ac_header in asm/types.h conio.h curses.h direct.h dlfcn.h errno.h \
 fcntl.h grp.h \
-ieeefp.h io.h langinfo.h libintl.h ncurses.h poll.h process.h pthread.h \
+ieeefp.h io.h langinfo.h libintl.h ncurses.h process.h pthread.h \
 sched.h shadow.h signal.h stdint.h stropts.h termios.h \
 unistd.h utime.h \
-sys/audioio.h sys/xattr.h sys/bsdtty.h sys/epoll.h sys/event.h sys/file.h sys/loadavg.h \
+poll.h sys/devpoll.h sys/epoll.h sys/poll.h \
+sys/audioio.h sys/xattr.h sys/bsdtty.h sys/event.h sys/file.h sys/loadavg.h \
 sys/lock.h sys/mkdev.h sys/modem.h \
-sys/param.h sys/poll.h sys/select.h sys/sendfile.h sys/socket.h sys/statvfs.h \
+sys/param.h sys/select.h sys/sendfile.h sys/socket.h sys/statvfs.h \
 sys/stat.h sys/termio.h sys/time.h \
 sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h \
 libutil.h sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \
diff --git a/configure.in b/configure.in
index 7b0a88b..532ec92 100644
--- a/configure.in
+++ b/configure.in
@@ -1329,12 +1329,13 @@
 AC_HEADER_STDC
 AC_CHECK_HEADERS(asm/types.h conio.h curses.h direct.h dlfcn.h errno.h \
 fcntl.h grp.h \
-ieeefp.h io.h langinfo.h libintl.h ncurses.h poll.h process.h pthread.h \
+ieeefp.h io.h langinfo.h libintl.h ncurses.h process.h pthread.h \
 sched.h shadow.h signal.h stdint.h stropts.h termios.h \
 unistd.h utime.h \
-sys/audioio.h sys/xattr.h sys/bsdtty.h sys/epoll.h sys/event.h sys/file.h sys/loadavg.h \
+poll.h sys/devpoll.h sys/epoll.h sys/poll.h \
+sys/audioio.h sys/xattr.h sys/bsdtty.h sys/event.h sys/file.h sys/loadavg.h \
 sys/lock.h sys/mkdev.h sys/modem.h \
-sys/param.h sys/poll.h sys/select.h sys/sendfile.h sys/socket.h sys/statvfs.h \
+sys/param.h sys/select.h sys/sendfile.h sys/socket.h sys/statvfs.h \
 sys/stat.h sys/termio.h sys/time.h \
 sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h \
 libutil.h sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \
diff --git a/pyconfig.h.in b/pyconfig.h.in
index 33ba6c7..2d1fd48 100644
--- a/pyconfig.h.in
+++ b/pyconfig.h.in
@@ -883,6 +883,9 @@
 /* Define to 1 if you have the <sys/bsdtty.h> header file. */
 #undef HAVE_SYS_BSDTTY_H
 
+/* Define to 1 if you have the <sys/devpoll.h> header file. */
+#undef HAVE_SYS_DEVPOLL_H
+
 /* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
    */
 #undef HAVE_SYS_DIR_H