]> granicus.if.org Git - python/commitdiff
bpo-38030: Fix os.stat failures on block devices on Windows (GH-15681)
authorSteve Dower <steve.dower@python.org>
Wed, 4 Sep 2019 21:42:54 +0000 (14:42 -0700)
committerGitHub <noreply@github.com>
Wed, 4 Sep 2019 21:42:54 +0000 (14:42 -0700)
Lib/test/test_os.py
Misc/NEWS.d/next/Windows/2019-09-04-14-01-08.bpo-38030._USdtk.rst [new file with mode: 0644]
Modules/posixmodule.c

index 440cd6c1cf73c3b0ffb4b3a21b7d96f8ebcedfdd..8ff0296fad0bb4cd519d57614b869ef55569083b 100644 (file)
@@ -591,6 +591,14 @@ class StatAttributeTests(unittest.TestCase):
         result = os.stat(fname)
         self.assertNotEqual(result.st_size, 0)
 
+    @unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
+    def test_stat_block_device(self):
+        # bpo-38030: os.stat fails for block devices
+        # Test a filename like "//./C:"
+        fname = "//./" + os.path.splitdrive(os.getcwd())[0]
+        result = os.stat(fname)
+        self.assertEqual(result.st_mode, stat.S_IFBLK)
+
 
 class UtimeTests(unittest.TestCase):
     def setUp(self):
diff --git a/Misc/NEWS.d/next/Windows/2019-09-04-14-01-08.bpo-38030._USdtk.rst b/Misc/NEWS.d/next/Windows/2019-09-04-14-01-08.bpo-38030._USdtk.rst
new file mode 100644 (file)
index 0000000..f1be8a1
--- /dev/null
@@ -0,0 +1 @@
+Fixes :func:`os.stat` failing for block devices on Windows
index c412d07a0e113c9716cdf3e4b8ce4a01d90b7694..81704eec321cdf19424fd7b71a9b070e5f111d45 100644 (file)
@@ -1794,13 +1794,13 @@ win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
             case ERROR_INVALID_PARAMETER:
             case ERROR_INVALID_FUNCTION:
             case ERROR_NOT_SUPPORTED:
-                retval = -1;
+                /* Volumes and physical disks are block devices, e.g.
+                   \\.\C: and \\.\PhysicalDrive0. */
+                memset(result, 0, sizeof(*result));
+                result->st_mode = 0x6000; /* S_IFBLK */
                 goto cleanup;
             }
-            /* Volumes and physical disks are block devices, e.g.
-               \\.\C: and \\.\PhysicalDrive0. */
-            memset(result, 0, sizeof(*result));
-            result->st_mode = 0x6000; /* S_IFBLK */
+            retval = -1;
             goto cleanup;
         }
     }
@@ -1827,7 +1827,14 @@ win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
 
 cleanup:
     if (hFile != INVALID_HANDLE_VALUE) {
-        CloseHandle(hFile);
+        /* Preserve last error if we are failing */
+        error = retval ? GetLastError() : 0;
+        if (!CloseHandle(hFile)) {
+            retval = -1;
+        } else if (retval) {
+            /* Restore last error */
+            SetLastError(error);
+        }
     }
 
     return retval;