PEP 3151 / issue #12555: reworking the OS and IO exception hierarchy.
diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c
index e594b51..6071144 100644
--- a/Modules/selectmodule.c
+++ b/Modules/selectmodule.c
@@ -54,8 +54,6 @@
 #  endif
 #endif
 
-static PyObject *SelectError;
-
 /* list of Python objects and their file descriptor */
 typedef struct {
     PyObject *obj;                           /* owned reference */
@@ -274,11 +272,11 @@
 
 #ifdef MS_WINDOWS
     if (n == SOCKET_ERROR) {
-        PyErr_SetExcFromWindowsErr(SelectError, WSAGetLastError());
+        PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
     }
 #else
     if (n < 0) {
-        PyErr_SetFromErrno(SelectError);
+        PyErr_SetFromErrno(PyExc_OSError);
     }
 #endif
     else {
@@ -425,7 +423,7 @@
         return NULL;
     if (PyDict_GetItem(self->dict, key) == NULL) {
         errno = ENOENT;
-        PyErr_SetFromErrno(PyExc_IOError);
+        PyErr_SetFromErrno(PyExc_OSError);
         return NULL;
     }
     value = PyLong_FromLong(events);
@@ -524,7 +522,7 @@
     Py_END_ALLOW_THREADS
 
     if (poll_result < 0) {
-        PyErr_SetFromErrno(SelectError);
+        PyErr_SetFromErrno(PyExc_OSError);
         return NULL;
     }
 
@@ -764,7 +762,7 @@
     }
     if (self->epfd < 0) {
         Py_DECREF(self);
-        PyErr_SetFromErrno(PyExc_IOError);
+        PyErr_SetFromErrno(PyExc_OSError);
         return NULL;
     }
     return (PyObject *)self;
@@ -797,7 +795,7 @@
 {
     errno = pyepoll_internal_close(self);
     if (errno < 0) {
-        PyErr_SetFromErrno(PyExc_IOError);
+        PyErr_SetFromErrno(PyExc_OSError);
         return NULL;
     }
     Py_RETURN_NONE;
@@ -890,7 +888,7 @@
     }
 
     if (result < 0) {
-        PyErr_SetFromErrno(PyExc_IOError);
+        PyErr_SetFromErrno(PyExc_OSError);
         return NULL;
     }
     Py_RETURN_NONE;
@@ -914,7 +912,7 @@
 PyDoc_STRVAR(pyepoll_register_doc,
 "register(fd[, eventmask]) -> None\n\
 \n\
-Registers a new fd or raises an IOError if the fd is already registered.\n\
+Registers a new fd or raises an OSError if the fd is already registered.\n\
 fd is the target file descriptor of the operation.\n\
 events is a bit set composed of the various EPOLL constants; the default\n\
 is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
@@ -1013,7 +1011,7 @@
     nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
     Py_END_ALLOW_THREADS
     if (nfds < 0) {
-        PyErr_SetFromErrno(PyExc_IOError);
+        PyErr_SetFromErrno(PyExc_OSError);
         goto error;
     }
 
@@ -1404,7 +1402,7 @@
     }
     if (self->kqfd < 0) {
         Py_DECREF(self);
-        PyErr_SetFromErrno(PyExc_IOError);
+        PyErr_SetFromErrno(PyExc_OSError);
         return NULL;
     }
     return (PyObject *)self;
@@ -1436,7 +1434,7 @@
 {
     errno = kqueue_queue_internal_close(self);
     if (errno < 0) {
-        PyErr_SetFromErrno(PyExc_IOError);
+        PyErr_SetFromErrno(PyExc_OSError);
         return NULL;
     }
     Py_RETURN_NONE;
@@ -1778,9 +1776,8 @@
     if (m == NULL)
         return NULL;
 
-    SelectError = PyErr_NewException("select.error", NULL, NULL);
-    Py_INCREF(SelectError);
-    PyModule_AddObject(m, "error", SelectError);
+    Py_INCREF(PyExc_OSError);
+    PyModule_AddObject(m, "error", PyExc_OSError);
 
 #ifdef PIPE_BUF
 #ifdef HAVE_BROKEN_PIPE_BUF