]> granicus.if.org Git - python/commitdiff
bpo-30980: Fix double close in asyncore.file_wrapper (#2789) (#2898)
authorNir Soffer <nirsof@gmail.com>
Wed, 26 Jul 2017 23:27:08 +0000 (02:27 +0300)
committerVictor Stinner <victor.stinner@gmail.com>
Wed, 26 Jul 2017 23:27:08 +0000 (01:27 +0200)
* bpo-30980: Fix close test to fail

test_close_twice was not considering the fact that file_wrapper is
duping the file descriptor. Closing the original descriptor left the
duped one open, hiding the fact that close protection is not effective.

* bpo-30980: Fix double close protection

Invalidated self.fd before closing, handling correctly the case when
os.close raises.

* bpo-30980: Fix fd leak introduced in the fixed test

Lib/asyncore.py
Lib/test/test_asyncore.py

index 705e40681303259f3f976cc72de9b2974d11c695..03d16838b739f9dfa9c6da2e6b33f29aa215267b 100644 (file)
@@ -619,8 +619,9 @@ if os.name == 'posix':
         def close(self):
             if self.fd < 0:
                 return
-            os.close(self.fd)
+            fd = self.fd
             self.fd = -1
+            os.close(fd)
 
         def fileno(self):
             return self.fd
index dc2f716e0bb828202ed97c025059cba8edb635cb..07edf2275bea0ea4e4b260e943d72d315445486b 100644 (file)
@@ -433,7 +433,10 @@ class FileWrapperTest(unittest.TestCase):
         f = asyncore.file_wrapper(fd)
         os.close(fd)
 
-        f.close()
+        os.close(f.fd)  # file_wrapper dupped fd
+        with self.assertRaises(OSError):
+            f.close()
+
         self.assertEqual(f.fd, -1)
         # calling close twice should not fail
         f.close()