From 32fd16ece9931c4de8dd20e3140446e8b2627f22 Mon Sep 17 00:00:00 2001 From: Ronald Oussoren Date: Sun, 23 Apr 2006 12:36:23 +0000 Subject: [PATCH] Patch 1471761 - test for broken poll at runtime This patch checks if poll is broken when the select module is loaded instead of doing so at configure-time. This functionality is only active on Mac OS X. --- Modules/selectmodule.c | 83 +++++++++++++++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 17 deletions(-) diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index c9d403a37d..4a04af179c 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -8,6 +8,13 @@ #include "Python.h" +#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. + */ +#undef HAVE_BROKEN_POLL +#endif + /* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined. 64 is too small (too many people have bumped into that limit). Here we boost it. @@ -618,7 +625,38 @@ select_poll(PyObject *self, PyObject *args) return NULL; return (PyObject *)rv; } -#endif /* HAVE_POLL && !HAVE_BROKEN_POLL */ + +#ifdef __APPLE__ +/* + * On some systems poll() sets errno on invalid file descriptors. We test + * for this at runtime because this bug may be fixed or introduced between + * OS releases. + */ +static int select_have_broken_poll(void) +{ + int poll_test; + int filedes[2]; + + struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 }; + + /* Create a file descriptor to make invalid */ + if (pipe(filedes) < 0) { + return 1; + } + poll_struct.fd = filedes[0]; + close(filedes[0]); + close(filedes[1]); + poll_test = poll(&poll_struct, 1, 0); + if (poll_test < 0) { + return 1; + } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) { + return 1; + } + return 0; +} +#endif /* __APPLE__ */ + +#endif /* HAVE_POLL */ PyDoc_STRVAR(select_doc, "select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\ @@ -645,9 +683,9 @@ On Windows, only sockets are supported; on Unix, all file descriptors."); static PyMethodDef select_methods[] = { {"select", select_select, METH_VARARGS, select_doc}, -#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL) +#if defined(HAVE_POLL) {"poll", select_poll, METH_VARARGS, poll_doc}, -#endif /* HAVE_POLL && !HAVE_BROKEN_POLL */ +#endif /* HAVE_POLL */ {0, 0}, /* sentinel */ }; @@ -668,29 +706,40 @@ initselect(void) SelectError = PyErr_NewException("select.error", NULL, NULL); Py_INCREF(SelectError); PyModule_AddObject(m, "error", SelectError); -#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL) - poll_Type.ob_type = &PyType_Type; - PyModule_AddIntConstant(m, "POLLIN", POLLIN); - PyModule_AddIntConstant(m, "POLLPRI", POLLPRI); - PyModule_AddIntConstant(m, "POLLOUT", POLLOUT); - PyModule_AddIntConstant(m, "POLLERR", POLLERR); - PyModule_AddIntConstant(m, "POLLHUP", POLLHUP); - PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL); +#if defined(HAVE_POLL) + +#ifdef __APPLE__ + if (select_have_broken_poll()) { + if (PyObject_DelAttrString(m, "poll") == -1) { + PyErr_Clear(); + } + } else { +#else + { +#endif + poll_Type.ob_type = &PyType_Type; + PyModule_AddIntConstant(m, "POLLIN", POLLIN); + PyModule_AddIntConstant(m, "POLLPRI", POLLPRI); + PyModule_AddIntConstant(m, "POLLOUT", POLLOUT); + PyModule_AddIntConstant(m, "POLLERR", POLLERR); + PyModule_AddIntConstant(m, "POLLHUP", POLLHUP); + PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL); #ifdef POLLRDNORM - PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM); + PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM); #endif #ifdef POLLRDBAND - PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND); + PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND); #endif #ifdef POLLWRNORM - PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM); + PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM); #endif #ifdef POLLWRBAND - PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND); + PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND); #endif #ifdef POLLMSG - PyModule_AddIntConstant(m, "POLLMSG", POLLMSG); + PyModule_AddIntConstant(m, "POLLMSG", POLLMSG); #endif -#endif /* HAVE_POLL && !HAVE_BROKEN_POLL */ + } +#endif /* HAVE_POLL */ } -- 2.40.0