PEP 3151 / issue #12555: reworking the OS and IO exception hierarchy.
diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c
index f264756..9061a41 100644
--- a/Modules/_io/_iomodule.c
+++ b/Modules/_io/_iomodule.c
@@ -91,89 +91,6 @@
 
 
 /*
- * BlockingIOError extends IOError
- */
-
-static int
-blockingioerror_init(PyBlockingIOErrorObject *self, PyObject *args,
-                     PyObject *kwds)
-{
-    PyObject *myerrno = NULL, *strerror = NULL;
-    PyObject *baseargs = NULL;
-    Py_ssize_t written = 0;
-
-    assert(PyTuple_Check(args));
-
-    self->written = 0;
-    if (!PyArg_ParseTuple(args, "OO|n:BlockingIOError",
-                          &myerrno, &strerror, &written))
-        return -1;
-
-    baseargs = PyTuple_Pack(2, myerrno, strerror);
-    if (baseargs == NULL)
-        return -1;
-    /* This will take care of initializing of myerrno and strerror members */
-    if (((PyTypeObject *)PyExc_IOError)->tp_init(
-                (PyObject *)self, baseargs, kwds) == -1) {
-        Py_DECREF(baseargs);
-        return -1;
-    }
-    Py_DECREF(baseargs);
-
-    self->written = written;
-    return 0;
-}
-
-static PyMemberDef blockingioerror_members[] = {
-    {"characters_written", T_PYSSIZET, offsetof(PyBlockingIOErrorObject, written), 0},
-    {NULL}  /* Sentinel */
-};
-
-static PyTypeObject _PyExc_BlockingIOError = {
-    PyVarObject_HEAD_INIT(NULL, 0)
-    "BlockingIOError", /*tp_name*/
-    sizeof(PyBlockingIOErrorObject), /*tp_basicsize*/
-    0,                          /*tp_itemsize*/
-    0,                          /*tp_dealloc*/
-    0,                          /*tp_print*/
-    0,                          /*tp_getattr*/
-    0,                          /*tp_setattr*/
-    0,                          /*tp_compare */
-    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 | Py_TPFLAGS_BASETYPE, /*tp_flags*/
-    PyDoc_STR("Exception raised when I/O would block "
-              "on a non-blocking I/O stream"), /* tp_doc */
-    0,                          /* tp_traverse */
-    0,                          /* tp_clear */
-    0,                          /* tp_richcompare */
-    0,                          /* tp_weaklistoffset */
-    0,                          /* tp_iter */
-    0,                          /* tp_iternext */
-    0,                          /* tp_methods */
-    blockingioerror_members,    /* tp_members */
-    0,                          /* tp_getset */
-    0,                          /* tp_base */
-    0,                          /* tp_dict */
-    0,                          /* tp_descr_get */
-    0,                          /* tp_descr_set */
-    0,                          /* tp_dictoffset */
-    (initproc)blockingioerror_init, /* tp_init */
-    0,                          /* tp_alloc */
-    0,                          /* tp_new */
-};
-PyObject *PyExc_BlockingIOError = (PyObject *)&_PyExc_BlockingIOError;
-
-
-/*
  * The main open() function
  */
 PyDoc_STRVAR(open_doc,
@@ -694,9 +611,11 @@
                            state->unsupported_operation) < 0)
         goto fail;
 
-    /* BlockingIOError */
-    _PyExc_BlockingIOError.tp_base = (PyTypeObject *) PyExc_IOError;
-    ADD_TYPE(&_PyExc_BlockingIOError, "BlockingIOError");
+    /* BlockingIOError, for compatibility */
+    Py_INCREF(PyExc_BlockingIOError);
+    if (PyModule_AddObject(m, "BlockingIOError",
+                           (PyObject *) PyExc_BlockingIOError) < 0)
+        goto fail;
 
     /* Concrete base types of the IO ABCs.
        (the ABCs themselves are declared through inheritance in io.py)
diff --git a/Modules/_io/_iomodule.h b/Modules/_io/_iomodule.h
index 4e97dd1..b3a8471 100644
--- a/Modules/_io/_iomodule.h
+++ b/Modules/_io/_iomodule.h
@@ -60,15 +60,6 @@
 
 #define DEFAULT_BUFFER_SIZE (8 * 1024)  /* bytes */
 
-typedef struct {
-    PyException_HEAD
-    PyObject *myerrno;
-    PyObject *strerror;
-    PyObject *filename; /* Not used, but part of the IOError object */
-    Py_ssize_t written;
-} PyBlockingIOErrorObject;
-PyAPI_DATA(PyObject *) PyExc_BlockingIOError;
-
 /*
  * Offset type for positioning.
  */
diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c
index 6ef2c20..c72bfb9 100644
--- a/Modules/_io/bufferedio.c
+++ b/Modules/_io/bufferedio.c
@@ -622,14 +622,14 @@
 _buffered_check_blocking_error(void)
 {
     PyObject *t, *v, *tb;
-    PyBlockingIOErrorObject *err;
+    PyOSErrorObject *err;
 
     PyErr_Fetch(&t, &v, &tb);
     if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
         PyErr_Restore(t, v, tb);
         return NULL;
     }
-    err = (PyBlockingIOErrorObject *) v;
+    err = (PyOSErrorObject *) v;
     /* TODO: sanity check (err->written >= 0) */
     PyErr_Restore(t, v, tb);
     return &err->written;
diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c
index f4a80c2..35d61ba 100644
--- a/Modules/mmapmodule.c
+++ b/Modules/mmapmodule.c
@@ -78,8 +78,6 @@
 #  define MAP_ANONYMOUS MAP_ANON
 #endif
 
-static PyObject *mmap_module_error;
-
 typedef enum
 {
     ACCESS_DEFAULT,
@@ -459,7 +457,7 @@
     {
         struct stat buf;
         if (-1 == fstat(self->fd, &buf)) {
-            PyErr_SetFromErrno(mmap_module_error);
+            PyErr_SetFromErrno(PyExc_OSError);
             return NULL;
         }
 #ifdef HAVE_LARGEFILE_SUPPORT
@@ -549,7 +547,7 @@
         void *newmap;
 
         if (ftruncate(self->fd, self->offset + new_size) == -1) {
-            PyErr_SetFromErrno(mmap_module_error);
+            PyErr_SetFromErrno(PyExc_OSError);
             return NULL;
         }
 
@@ -564,7 +562,7 @@
 #endif
         if (newmap == (void *)-1)
         {
-            PyErr_SetFromErrno(mmap_module_error);
+            PyErr_SetFromErrno(PyExc_OSError);
             return NULL;
         }
         self->data = newmap;
@@ -605,7 +603,7 @@
     /* XXX semantics of return value? */
     /* XXX flags for msync? */
     if (-1 == msync(self->data + offset, size, MS_SYNC)) {
-        PyErr_SetFromErrno(mmap_module_error);
+        PyErr_SetFromErrno(PyExc_OSError);
         return NULL;
     }
     return PyLong_FromLong(0);
@@ -1205,7 +1203,7 @@
         fd = devzero = open("/dev/zero", O_RDWR);
         if (devzero == -1) {
             Py_DECREF(m_obj);
-            PyErr_SetFromErrno(mmap_module_error);
+            PyErr_SetFromErrno(PyExc_OSError);
             return NULL;
         }
 #endif
@@ -1213,7 +1211,7 @@
         m_obj->fd = dup(fd);
         if (m_obj->fd == -1) {
             Py_DECREF(m_obj);
-            PyErr_SetFromErrno(mmap_module_error);
+            PyErr_SetFromErrno(PyExc_OSError);
             return NULL;
         }
     }
@@ -1229,7 +1227,7 @@
     if (m_obj->data == (char *)-1) {
         m_obj->data = NULL;
         Py_DECREF(m_obj);
-        PyErr_SetFromErrno(mmap_module_error);
+        PyErr_SetFromErrno(PyExc_OSError);
         return NULL;
     }
     m_obj->access = (access_mode)access;
@@ -1310,12 +1308,12 @@
     if (fileno != -1 && fileno != 0) {
         /* Ensure that fileno is within the CRT's valid range */
         if (_PyVerify_fd(fileno) == 0) {
-            PyErr_SetFromErrno(mmap_module_error);
+            PyErr_SetFromErrno(PyExc_OSError);
             return NULL;
         }
         fh = (HANDLE)_get_osfhandle(fileno);
         if (fh==(HANDLE)-1) {
-            PyErr_SetFromErrno(mmap_module_error);
+            PyErr_SetFromErrno(PyExc_OSError);
             return NULL;
         }
         /* Win9x appears to need us seeked to zero */
@@ -1469,11 +1467,7 @@
     dict = PyModule_GetDict(module);
     if (!dict)
         return NULL;
-    mmap_module_error = PyErr_NewException("mmap.error",
-        PyExc_EnvironmentError , NULL);
-    if (mmap_module_error == NULL)
-        return NULL;
-    PyDict_SetItemString(dict, "error", mmap_module_error);
+    PyDict_SetItemString(dict, "error", PyExc_OSError);
     PyDict_SetItemString(dict, "mmap", (PyObject*) &mmap_object_type);
 #ifdef PROT_EXEC
     setint(dict, "PROT_EXEC", PROT_EXEC);
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
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 6d0a44c..2056b61 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -457,7 +457,6 @@
 
 /* Global variable holding the exception type for errors detected
    by this module (but not argument type or memory errors, etc.). */
-static PyObject *socket_error;
 static PyObject *socket_herror;
 static PyObject *socket_gaierror;
 static PyObject *socket_timeout;
@@ -498,7 +497,7 @@
 static PyObject*
 select_error(void)
 {
-    PyErr_SetString(socket_error, "unable to select on socket");
+    PyErr_SetString(PyExc_OSError, "unable to select on socket");
     return NULL;
 }
 
@@ -525,7 +524,7 @@
        recognizes the error codes used by both GetLastError() and
        WSAGetLastError */
     if (err_no)
-        return PyErr_SetExcFromWindowsErr(socket_error, err_no);
+        return PyErr_SetExcFromWindowsErr(PyExc_OSError, err_no);
 #endif
 
 #if defined(PYOS_OS2) && !defined(PYCC_GCC)
@@ -556,7 +555,7 @@
             }
             v = Py_BuildValue("(is)", myerrorcode, outbuf);
             if (v != NULL) {
-                PyErr_SetObject(socket_error, v);
+                PyErr_SetObject(PyExc_OSError, v);
                 Py_DECREF(v);
             }
             return NULL;
@@ -564,7 +563,7 @@
     }
 #endif
 
-    return PyErr_SetFromErrno(socket_error);
+    return PyErr_SetFromErrno(PyExc_OSError);
 }
 
 
@@ -883,13 +882,13 @@
 #endif
         default:
             freeaddrinfo(res);
-            PyErr_SetString(socket_error,
+            PyErr_SetString(PyExc_OSError,
                 "unsupported address family");
             return -1;
         }
         if (res->ai_next) {
             freeaddrinfo(res);
-            PyErr_SetString(socket_error,
+            PyErr_SetString(PyExc_OSError,
                 "wildcard resolved to multiple address");
             return -1;
         }
@@ -902,7 +901,7 @@
     if (name[0] == '<' && strcmp(name, "<broadcast>") == 0) {
         struct sockaddr_in *sin;
         if (af != AF_INET && af != AF_UNSPEC) {
-            PyErr_SetString(socket_error,
+            PyErr_SetString(PyExc_OSError,
                 "address family mismatched");
             return -1;
         }
@@ -960,7 +959,7 @@
         return 16;
 #endif
     default:
-        PyErr_SetString(socket_error, "unknown address family");
+        PyErr_SetString(PyExc_OSError, "unknown address family");
         return -1;
     }
 }
@@ -1009,7 +1008,7 @@
         bdaddr->b[5] = b5;
         return 6;
     } else {
-        PyErr_SetString(socket_error, "bad bluetooth address");
+        PyErr_SetString(PyExc_OSError, "bad bluetooth address");
         return -1;
     }
 }
@@ -1278,7 +1277,7 @@
         if (len > 0 && path[0] == 0) {
             /* Linux abstract namespace extension */
             if (len > sizeof addr->sun_path) {
-                PyErr_SetString(socket_error,
+                PyErr_SetString(PyExc_OSError,
                                 "AF_UNIX path too long");
                 return 0;
             }
@@ -1288,7 +1287,7 @@
         {
             /* regular NULL-terminated string */
             if (len >= sizeof addr->sun_path) {
-                PyErr_SetString(socket_error,
+                PyErr_SetString(PyExc_OSError,
                                 "AF_UNIX path too long");
                 return 0;
             }
@@ -1418,7 +1417,7 @@
             _BT_L2_MEMB(addr, family) = AF_BLUETOOTH;
             if (!PyArg_ParseTuple(args, "si", &straddr,
                                   &_BT_L2_MEMB(addr, psm))) {
-                PyErr_SetString(socket_error, "getsockaddrarg: "
+                PyErr_SetString(PyExc_OSError, "getsockaddrarg: "
                                 "wrong format");
                 return 0;
             }
@@ -1437,7 +1436,7 @@
             _BT_RC_MEMB(addr, family) = AF_BLUETOOTH;
             if (!PyArg_ParseTuple(args, "si", &straddr,
                                   &_BT_RC_MEMB(addr, channel))) {
-                PyErr_SetString(socket_error, "getsockaddrarg: "
+                PyErr_SetString(PyExc_OSError, "getsockaddrarg: "
                                 "wrong format");
                 return 0;
             }
@@ -1455,7 +1454,7 @@
 
                         _BT_HCI_MEMB(addr, family) = AF_BLUETOOTH;
             if (straddr == NULL) {
-                PyErr_SetString(socket_error, "getsockaddrarg: "
+                PyErr_SetString(PyExc_OSError, "getsockaddrarg: "
                     "wrong format");
                 return 0;
             }
@@ -1464,7 +1463,7 @@
 #else
             _BT_HCI_MEMB(addr, family) = AF_BLUETOOTH;
             if (!PyArg_ParseTuple(args, "i", &_BT_HCI_MEMB(addr, dev))) {
-                PyErr_SetString(socket_error, "getsockaddrarg: "
+                PyErr_SetString(PyExc_OSError, "getsockaddrarg: "
                                 "wrong format");
                 return 0;
             }
@@ -1481,7 +1480,7 @@
             addr = (struct sockaddr_sco *)addr_ret;
             _BT_SCO_MEMB(addr, family) = AF_BLUETOOTH;
             if (!PyBytes_Check(args)) {
-                PyErr_SetString(socket_error, "getsockaddrarg: "
+                PyErr_SetString(PyExc_OSError, "getsockaddrarg: "
                                 "wrong format");
                 return 0;
             }
@@ -1494,7 +1493,7 @@
         }
 #endif
         default:
-            PyErr_SetString(socket_error, "getsockaddrarg: unknown Bluetooth protocol");
+            PyErr_SetString(PyExc_OSError, "getsockaddrarg: unknown Bluetooth protocol");
             return 0;
         }
     }
@@ -1633,7 +1632,7 @@
                     return 0;
                 }
             } else {
-                PyErr_SetString(socket_error,
+                PyErr_SetString(PyExc_OSError,
                                 "AF_CAN interface name too long");
                 Py_DECREF(interfaceName);
                 return 0;
@@ -1647,7 +1646,7 @@
             return 1;
         }
         default:
-            PyErr_SetString(socket_error,
+            PyErr_SetString(PyExc_OSError,
                             "getsockaddrarg: unsupported CAN protocol");
             return 0;
         }
@@ -1656,7 +1655,7 @@
     /* More cases here... */
 
     default:
-        PyErr_SetString(socket_error, "getsockaddrarg: bad family");
+        PyErr_SetString(PyExc_OSError, "getsockaddrarg: bad family");
         return 0;
 
     }
@@ -1722,7 +1721,7 @@
             return 1;
 #endif
         default:
-            PyErr_SetString(socket_error, "getsockaddrlen: "
+            PyErr_SetString(PyExc_OSError, "getsockaddrlen: "
                             "unknown BT protocol");
             return 0;
 
@@ -1757,7 +1756,7 @@
     /* More cases here... */
 
     default:
-        PyErr_SetString(socket_error, "getsockaddrlen: bad family");
+        PyErr_SetString(PyExc_OSError, "getsockaddrlen: bad family");
         return 0;
 
     }
@@ -2098,7 +2097,7 @@
 #else
     if (buflen <= 0 || buflen > 1024) {
 #endif
-        PyErr_SetString(socket_error,
+        PyErr_SetString(PyExc_OSError,
                         "getsockopt buflen out of range");
         return NULL;
     }
@@ -2926,7 +2925,7 @@
         if (cmsg_status < 0)
             break;
         if (cmsgdatalen > PY_SSIZE_T_MAX) {
-            PyErr_SetString(socket_error, "control message too long");
+            PyErr_SetString(PyExc_OSError, "control message too long");
             goto err_closefds;
         }
 
@@ -3087,7 +3086,7 @@
         return NULL;
     nitems = PySequence_Fast_GET_SIZE(fast);
     if (nitems > INT_MAX) {
-        PyErr_SetString(socket_error, "recvmsg_into() argument 1 is too long");
+        PyErr_SetString(PyExc_OSError, "recvmsg_into() argument 1 is too long");
         goto finally;
     }
 
@@ -3394,7 +3393,7 @@
         goto finally;
     ndataparts = PySequence_Fast_GET_SIZE(data_fast);
     if (ndataparts > INT_MAX) {
-        PyErr_SetString(socket_error, "sendmsg() argument 1 is too long");
+        PyErr_SetString(PyExc_OSError, "sendmsg() argument 1 is too long");
         goto finally;
     }
     msg.msg_iovlen = ndataparts;
@@ -3426,7 +3425,7 @@
 
 #ifndef CMSG_SPACE
     if (ncmsgs > 1) {
-        PyErr_SetString(socket_error,
+        PyErr_SetString(PyExc_OSError,
                         "sending multiple control messages is not supported "
                         "on this system");
         goto finally;
@@ -3455,12 +3454,12 @@
 #else
         if (!get_CMSG_LEN(bufsize, &space)) {
 #endif
-            PyErr_SetString(socket_error, "ancillary data item too large");
+            PyErr_SetString(PyExc_OSError, "ancillary data item too large");
             goto finally;
         }
         controllen += space;
         if (controllen > SOCKLEN_T_LIMIT || controllen < controllen_last) {
-            PyErr_SetString(socket_error, "too much ancillary data");
+            PyErr_SetString(PyExc_OSError, "too much ancillary data");
             goto finally;
         }
         controllen_last = controllen;
@@ -4000,7 +3999,7 @@
 
     if (h->h_addrtype != af) {
         /* Let's get real error message to return */
-        PyErr_SetString(socket_error,
+        PyErr_SetString(PyExc_OSError,
                         (char *)strerror(EAFNOSUPPORT));
 
         return NULL;
@@ -4085,7 +4084,7 @@
 #endif
 
         default:                /* can't happen */
-            PyErr_SetString(socket_error,
+            PyErr_SetString(PyExc_OSError,
                             "unsupported address family");
             return NULL;
         }
@@ -4239,7 +4238,7 @@
         break;
 #endif
     default:
-        PyErr_SetString(socket_error, "unsupported address family");
+        PyErr_SetString(PyExc_OSError, "unsupported address family");
         goto finally;
     }
     Py_BEGIN_ALLOW_THREADS
@@ -4295,7 +4294,7 @@
     sp = getservbyname(name, proto);
     Py_END_ALLOW_THREADS
     if (sp == NULL) {
-        PyErr_SetString(socket_error, "service/proto not found");
+        PyErr_SetString(PyExc_OSError, "service/proto not found");
         return NULL;
     }
     return PyLong_FromLong((long) ntohs(sp->s_port));
@@ -4332,7 +4331,7 @@
     sp = getservbyport(htons((short)port), proto);
     Py_END_ALLOW_THREADS
     if (sp == NULL) {
-        PyErr_SetString(socket_error, "port/proto not found");
+        PyErr_SetString(PyExc_OSError, "port/proto not found");
         return NULL;
     }
     return PyUnicode_FromString(sp->s_name);
@@ -4361,7 +4360,7 @@
     sp = getprotobyname(name);
     Py_END_ALLOW_THREADS
     if (sp == NULL) {
-        PyErr_SetString(socket_error, "protocol not found");
+        PyErr_SetString(PyExc_OSError, "protocol not found");
         return NULL;
     }
     return PyLong_FromLong((long) sp->p_proto);
@@ -4616,7 +4615,7 @@
         return PyBytes_FromStringAndSize((char *)(&buf),
                                           sizeof(buf));
 
-    PyErr_SetString(socket_error,
+    PyErr_SetString(PyExc_OSError,
                     "illegal IP address string passed to inet_aton");
     return NULL;
 
@@ -4637,7 +4636,7 @@
         packed_addr = inet_addr(ip_addr);
 
         if (packed_addr == INADDR_NONE) {               /* invalid address */
-            PyErr_SetString(socket_error,
+            PyErr_SetString(PyExc_OSError,
                 "illegal IP address string passed to inet_aton");
             return NULL;
         }
@@ -4669,7 +4668,7 @@
     }
 
     if (addr_len != sizeof(packed_addr)) {
-        PyErr_SetString(socket_error,
+        PyErr_SetString(PyExc_OSError,
             "packed IP wrong length for inet_ntoa");
         return NULL;
     }
@@ -4704,7 +4703,7 @@
 
 #if !defined(ENABLE_IPV6) && defined(AF_INET6)
     if(af == AF_INET6) {
-        PyErr_SetString(socket_error,
+        PyErr_SetString(PyExc_OSError,
                         "can't use AF_INET6, IPv6 is disabled");
         return NULL;
     }
@@ -4712,10 +4711,10 @@
 
     retval = inet_pton(af, ip, packed);
     if (retval < 0) {
-        PyErr_SetFromErrno(socket_error);
+        PyErr_SetFromErrno(PyExc_OSError);
         return NULL;
     } else if (retval == 0) {
-        PyErr_SetString(socket_error,
+        PyErr_SetString(PyExc_OSError,
             "illegal IP address string passed to inet_pton");
         return NULL;
     } else if (af == AF_INET) {
@@ -4727,7 +4726,7 @@
                                           sizeof(struct in6_addr));
 #endif
     } else {
-        PyErr_SetString(socket_error, "unknown address family");
+        PyErr_SetString(PyExc_OSError, "unknown address family");
         return NULL;
     }
 }
@@ -4779,7 +4778,7 @@
 
     retval = inet_ntop(af, packed, ip, sizeof(ip));
     if (!retval) {
-        PyErr_SetFromErrno(socket_error);
+        PyErr_SetFromErrno(PyExc_OSError);
         return NULL;
     } else {
         return PyUnicode_FromString(retval);
@@ -4850,7 +4849,7 @@
     } else if (pobj == Py_None) {
         pptr = (char *)NULL;
     } else {
-        PyErr_SetString(socket_error, "Int or String expected");
+        PyErr_SetString(PyExc_OSError, "Int or String expected");
         goto err;
     }
     memset(&hints, 0, sizeof(hints));
@@ -4947,7 +4946,7 @@
         goto fail;
     }
     if (res->ai_next) {
-        PyErr_SetString(socket_error,
+        PyErr_SetString(PyExc_OSError,
             "sockaddr resolved to multiple addresses");
         goto fail;
     }
@@ -4955,7 +4954,7 @@
     case AF_INET:
         {
         if (PyTuple_GET_SIZE(sa) != 2) {
-            PyErr_SetString(socket_error,
+            PyErr_SetString(PyExc_OSError,
                 "IPv4 sockaddr must be 2 tuple");
             goto fail;
         }
@@ -5054,7 +5053,7 @@
 
     ni = if_nameindex();
     if (ni == NULL) {
-        PyErr_SetFromErrno(socket_error);
+        PyErr_SetFromErrno(PyExc_OSError);
         return NULL;
     }
 
@@ -5100,7 +5099,7 @@
     Py_DECREF(oname);
     if (index == 0) {
         /* if_nametoindex() doesn't set errno */
-        PyErr_SetString(socket_error, "no interface with this name");
+        PyErr_SetString(PyExc_OSError, "no interface with this name");
         return NULL;
     }
 
@@ -5123,7 +5122,7 @@
         return NULL;
 
     if (if_indextoname(index, name) == NULL) {
-        PyErr_SetFromErrno(socket_error);
+        PyErr_SetFromErrno(PyExc_OSError);
         return NULL;
     }
 
@@ -5403,27 +5402,24 @@
     if (m == NULL)
         return NULL;
 
-    socket_error = PyErr_NewException("socket.error",
-                                      PyExc_IOError, NULL);
-    if (socket_error == NULL)
-        return NULL;
-    PySocketModuleAPI.error = socket_error;
-    Py_INCREF(socket_error);
-    PyModule_AddObject(m, "error", socket_error);
+    Py_INCREF(PyExc_OSError);
+    PySocketModuleAPI.error = PyExc_OSError;
+    Py_INCREF(PyExc_OSError);
+    PyModule_AddObject(m, "error", PyExc_OSError);
     socket_herror = PyErr_NewException("socket.herror",
-                                       socket_error, NULL);
+                                       PyExc_OSError, NULL);
     if (socket_herror == NULL)
         return NULL;
     Py_INCREF(socket_herror);
     PyModule_AddObject(m, "herror", socket_herror);
-    socket_gaierror = PyErr_NewException("socket.gaierror", socket_error,
+    socket_gaierror = PyErr_NewException("socket.gaierror", PyExc_OSError,
         NULL);
     if (socket_gaierror == NULL)
         return NULL;
     Py_INCREF(socket_gaierror);
     PyModule_AddObject(m, "gaierror", socket_gaierror);
     socket_timeout = PyErr_NewException("socket.timeout",
-                                        socket_error, NULL);
+                                        PyExc_OSError, NULL);
     if (socket_timeout == NULL)
         return NULL;
     PySocketModuleAPI.timeout_error = socket_timeout;