[Python-checkins] cpython: Issue #6397: Support '/dev/poll' polling objects in select module, under

jesus.cea python-checkins at python.org
Mon Nov 14 19:17:53 CET 2011


http://hg.python.org/cpython/rev/8f7ab4bf7ad9
changeset: 73549:8f7ab4bf7ad9
user: Jesus Cea <jcea at jcea.es>
date: Mon Nov 14 19:07:41 2011 +0100
summary:
 Issue #6397: Support '/dev/poll' polling objects in select module, under Solaris & derivatives.
files:
 Doc/library/select.rst | 84 ++++++-
 Lib/test/test_poll.py | 123 ++-------
 Misc/NEWS | 3 +
 Modules/selectmodule.c | 370 +++++++++++++++++++++++++++++
 configure | 7 +-
 configure.in | 7 +-
 pyconfig.h.in | 3 +
 7 files changed, 497 insertions(+), 100 deletions(-)
diff --git a/Doc/library/select.rst b/Doc/library/select.rst
--- 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_poll.py b/Lib/test/test_devpoll.py
copy from Lib/test/test_poll.py
copy to Lib/test/test_devpoll.py
--- a/Lib/test/test_poll.py
+++ b/Lib/test/test_devpoll.py
@@ -1,12 +1,14 @@
-# Test case for the os.poll() function
+# Test case for the select.devpoll() function
 
-import os, select, random, unittest
+# 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.poll
+ select.devpoll
 except AttributeError:
- raise unittest.SkipTest("select.poll not defined -- skipping test_poll")
+ raise unittest.SkipTest("select.devpoll not defined -- skipping test_devpoll")
 
 
 def find_ready_matching(ready, flag):
@@ -16,13 +18,13 @@
 match.append(fd)
 return match
 
-class PollTests(unittest.TestCase):
+class DevPollTests(unittest.TestCase):
 
- def test_poll1(self):
+ def test_devpoll1(self):
 # Basic functional test of poll object
 # Create a bunch of pipe and test that poll works with them.
 
- p = select.poll()
+ p = select.devpoll()
 
 NUM_PIPES = 12
 MSG = b" This is a test."
@@ -48,110 +50,45 @@
 ready = p.poll()
 ready_writers = find_ready_matching(ready, select.POLLOUT)
 if not ready_writers:
- raise RuntimeError("no pipes ready for writing")
+ 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:
- raise RuntimeError("no pipes ready for reading")
- rd = random.choice(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 )
+ 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 poll_unit_tests(self):
- # returns NVAL for invalid file descriptor
- FD = 42
- try:
- os.close(FD)
- except OSError:
- pass
- p = select.poll()
- p.register(FD)
- r = p.poll()
- self.assertEqual(r[0], (FD, select.POLLNVAL))
+ def test_timeout_overflow(self):
+ pollster = select.devpoll()
+ w, r = os.pipe()
+ pollster.register(w)
 
- f = open(TESTFN, 'w')
- fd = f.fileno()
- p = select.poll()
- p.register(f)
- r = p.poll()
- self.assertEqual(r[0][0], fd)
- f.close()
- r = p.poll()
- self.assertEqual(r[0], (fd, select.POLLNVAL))
- os.unlink(TESTFN)
+ pollster.poll(-1)
+ self.assertRaises(OverflowError, pollster.poll, -2)
+ self.assertRaises(OverflowError, pollster.poll, -1 << 31)
+ self.assertRaises(OverflowError, pollster.poll, -1 << 64)
 
- # type error for invalid arguments
- p = select.poll()
- self.assertRaises(TypeError, p.register, p)
- self.assertRaises(TypeError, p.unregister, p)
-
- # can't unregister non-existent object
- p = select.poll()
- self.assertRaises(KeyError, p.unregister, 3)
-
- # Test error cases
- pollster = select.poll()
- class Nope:
- pass
-
- class Almost:
- def fileno(self):
- return 'fileno'
-
- self.assertRaises(TypeError, pollster.register, Nope(), 0)
- self.assertRaises(TypeError, pollster.register, Almost(), 0)
-
- # Another test case for poll(). This is copied from the test case for
- # select(), modified to use poll() instead.
-
- def test_poll2(self):
- cmd = 'for i in 0 1 2 3 4 5 6 7 8 9; do echo testing...; sleep 1; done'
- p = os.popen(cmd, 'r')
- pollster = select.poll()
- pollster.register( p, select.POLLIN )
- for tout in (0, 1000, 2000, 4000, 8000, 16000) + (-1,)*10:
- fdlist = pollster.poll(tout)
- if (fdlist == []):
- continue
- fd, flags = fdlist[0]
- if flags & select.POLLHUP:
- line = p.readline()
- if line != "":
- self.fail('error: pipe seems to be closed, but still returns data')
- continue
-
- elif flags & select.POLLIN:
- line = p.readline()
- if not line:
- break
- continue
- else:
- self.fail('Unexpected return value from select.poll: %s' % fdlist)
- p.close()
-
- def test_poll3(self):
- # test int overflow
- pollster = select.poll()
- pollster.register(1)
-
+ 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)
 
- x = 2 + 3
- if x != 5:
- self.fail('Overflow must have occurred')
-
 def test_main():
- run_unittest(PollTests)
+ run_unittest(DevPollTests)
 
 if __name__ == '__main__':
 test_main()
diff --git a/Misc/NEWS b/Misc/NEWS
--- 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
--- 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
--- 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
--- 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
--- 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
-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /