Skip to content

Commit

Permalink
bpo-38030: Fix os.stat failures on block devices on Windows (GH-15681)
Browse files Browse the repository at this point in the history
(cherry picked from commit 772ec0f)

Co-authored-by: Steve Dower <steve.dower@python.org>
  • Loading branch information
miss-islington and zooba authored Sep 4, 2019
1 parent 5e194f5 commit cad7abf
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 6 deletions.
8 changes: 8 additions & 0 deletions Lib/test/test_os.py
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,14 @@ def test_access_denied(self):
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):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixes :func:`os.stat` failing for block devices on Windows
19 changes: 13 additions & 6 deletions Modules/posixmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand All @@ -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;
Expand Down

0 comments on commit cad7abf

Please sign in to comment.