PEP 3151 / issue #12555: reworking the OS and IO exception hierarchy.
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;