From: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> Date: Wed, 4 Sep 2019 22:18:05 +0000 (-0700) Subject: bpo-38030: Fix os.stat failures on block devices on Windows (GH-15681) X-Git-Tag: v3.8.0rc1~287 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cad7abf8abe657b696b9c8deb4b727e0cefaf36d;p=python bpo-38030: Fix os.stat failures on block devices on Windows (GH-15681) (cherry picked from commit 772ec0fad57412daa53d16d7019b6b2fe6e94942) Co-authored-by: Steve Dower --- diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 440cd6c1cf..8ff0296fad 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -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 index 0000000000..f1be8a1e1c --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2019-09-04-14-01-08.bpo-38030._USdtk.rst @@ -0,0 +1 @@ +Fixes :func:`os.stat` failing for block devices on Windows diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index b9e8c0d94c..771c561615 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -1793,13 +1793,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; } } @@ -1826,7 +1826,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;