]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-111856: Fix os.fstat on windows with FAT32 and exFAT filesystem (GH-112038)
authorAN Long <aisk@users.noreply.github.com>
Mon, 13 Nov 2023 16:10:06 +0000 (00:10 +0800)
committerGitHub <noreply@github.com>
Mon, 13 Nov 2023 16:10:06 +0000 (16:10 +0000)
Misc/NEWS.d/next/Windows/2023-11-13-22-35-27.gh-issue-111856.vEtA5z.rst [new file with mode: 0644]
Python/fileutils.c

diff --git a/Misc/NEWS.d/next/Windows/2023-11-13-22-35-27.gh-issue-111856.vEtA5z.rst b/Misc/NEWS.d/next/Windows/2023-11-13-22-35-27.gh-issue-111856.vEtA5z.rst
new file mode 100644 (file)
index 0000000..b1388df
--- /dev/null
@@ -0,0 +1,2 @@
+Fixes :func:`~os.fstat` on file systems that do not support file ID
+requests. This includes FAT32 and exFAT.
index 17a4ae56ef052813ea3c140dd0e0b8ac8ee766c6..649b188b5167d033fba46999abb6b1ed44813ec1 100644 (file)
@@ -1239,6 +1239,7 @@ _Py_fstat_noraise(int fd, struct _Py_stat_struct *status)
     BY_HANDLE_FILE_INFORMATION info;
     FILE_BASIC_INFO basicInfo;
     FILE_ID_INFO idInfo;
+    FILE_ID_INFO *pIdInfo = &idInfo;
     HANDLE h;
     int type;
 
@@ -1271,15 +1272,19 @@ _Py_fstat_noraise(int fd, struct _Py_stat_struct *status)
     }
 
     if (!GetFileInformationByHandle(h, &info) ||
-        !GetFileInformationByHandleEx(h, FileBasicInfo, &basicInfo, sizeof(basicInfo)) ||
-        !GetFileInformationByHandleEx(h, FileIdInfo, &idInfo, sizeof(idInfo))) {
+        !GetFileInformationByHandleEx(h, FileBasicInfo, &basicInfo, sizeof(basicInfo))) {
         /* The Win32 error is already set, but we also set errno for
            callers who expect it */
         errno = winerror_to_errno(GetLastError());
         return -1;
     }
 
-    _Py_attribute_data_to_stat(&info, 0, &basicInfo, &idInfo, status);
+    if (!GetFileInformationByHandleEx(h, FileIdInfo, &idInfo, sizeof(idInfo))) {
+        /* Failed to get FileIdInfo, so do not pass it along */
+        pIdInfo = NULL;
+    }
+
+    _Py_attribute_data_to_stat(&info, 0, &basicInfo, pIdInfo, status);
     return 0;
 #else
     return fstat(fd, status);