]> granicus.if.org Git - python/commitdiff
Merge 3.5 (INVALID_SOCKET)
authorVictor Stinner <victor.stinner@gmail.com>
Fri, 22 Jul 2016 15:47:09 +0000 (17:47 +0200)
committerVictor Stinner <victor.stinner@gmail.com>
Fri, 22 Jul 2016 15:47:09 +0000 (17:47 +0200)
1  2 
Modules/_ssl.c
Modules/socketmodule.c

diff --cc Modules/_ssl.c
Simple merge
index f8d39f67641256a00f26d9fcced7b0f0e956202e,b34981cb6b10f967e7d6f9fb87d98603e3eca3f0..d21d18f7e3dec74394edde189f276ebed6faaebd
@@@ -2576,22 -2563,17 +2576,22 @@@ static PyObject 
  sock_close(PySocketSockObject *s)
  {
      SOCKET_T fd;
 +    int res;
  
 -    /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
 -     * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
 -     * for more details.
 -     */
      fd = s->sock_fd;
-     if (fd != -1) {
-         s->sock_fd = -1;
+     if (fd != INVALID_SOCKET) {
+         s->sock_fd = INVALID_SOCKET;
 +
 +        /* We do not want to retry upon EINTR: see
 +           http://lwn.net/Articles/576478/ and
 +           http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
 +           for more details. */
          Py_BEGIN_ALLOW_THREADS
 -        (void) SOCKETCLOSE(fd);
 +        res = SOCKETCLOSE(fd);
          Py_END_ALLOW_THREADS
 +        if (res < 0) {
 +            return s->errorhandler();
 +        }
      }
      Py_INCREF(Py_None);
      return Py_None;
@@@ -4194,45 -4164,22 +4194,45 @@@ static PyGetSetDef sock_getsetlist[] = 
     First close the file description. */
  
  static void
 -sock_dealloc(PySocketSockObject *s)
 +sock_finalize(PySocketSockObject *s)
  {
-     if (s->sock_fd != -1) {
 +    SOCKET_T fd;
 +    PyObject *error_type, *error_value, *error_traceback;
 +
 +    /* Save the current exception, if any. */
 +    PyErr_Fetch(&error_type, &error_value, &error_traceback);
 +
 -        PyObject *exc, *val, *tb;
 -        Py_ssize_t old_refcount = Py_REFCNT(s);
 -        ++Py_REFCNT(s);
 -        PyErr_Fetch(&exc, &val, &tb);
 -        if (PyErr_WarnFormat(PyExc_ResourceWarning, 1,
 -                             "unclosed %R", s))
+     if (s->sock_fd != INVALID_SOCKET) {
 +        if (PyErr_ResourceWarning((PyObject *)s, 1, "unclosed %R", s)) {
              /* Spurious errors can appear at shutdown */
 -            if (PyErr_ExceptionMatches(PyExc_Warning))
 -                PyErr_WriteUnraisable((PyObject *) s);
 -        PyErr_Restore(exc, val, tb);
 -        (void) SOCKETCLOSE(s->sock_fd);
 -        Py_REFCNT(s) = old_refcount;
 +            if (PyErr_ExceptionMatches(PyExc_Warning)) {
 +                PyErr_WriteUnraisable((PyObject *)s);
 +            }
 +        }
 +
 +        /* Only close the socket *after* logging the ResourceWarning warning
 +           to allow the logger to call socket methods like
 +           socket.getsockname(). If the socket is closed before, socket
 +           methods fails with the EBADF error. */
 +        fd = s->sock_fd;
-         s->sock_fd = -1;
++        s->sock_fd = INVALID_SOCKET;
 +
 +        /* We do not want to retry upon EINTR: see sock_close() */
 +        Py_BEGIN_ALLOW_THREADS
 +        (void) SOCKETCLOSE(fd);
 +        Py_END_ALLOW_THREADS
      }
 +
 +    /* Restore the saved exception. */
 +    PyErr_Restore(error_type, error_value, error_traceback);
 +}
 +
 +static void
 +sock_dealloc(PySocketSockObject *s)
 +{
 +    if (PyObject_CallFinalizerFromDealloc((PyObject *)s) < 0)
 +        return;
 +
      Py_TYPE(s)->tp_free((PyObject *)s);
  }