From: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> Date: Mon, 13 Nov 2023 16:25:01 +0000 (+0100) Subject: gh-111856: Fix os.fstat on windows with FAT32 and exFAT filesystem (GH-112038) X-Git-Tag: v3.12.1~132 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=dfdbfc548f45dc254844b71f77f03136c413b76b;p=thirdparty%2FPython%2Fcpython.git gh-111856: Fix os.fstat on windows with FAT32 and exFAT filesystem (GH-112038) (cherry picked from commit 29af7369dbbbba8cefafb196e977bce8189a527d) Co-authored-by: AN Long --- 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 index 000000000000..b1388df8e4c4 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2023-11-13-22-35-27.gh-issue-111856.vEtA5z.rst @@ -0,0 +1,2 @@ +Fixes :func:`~os.fstat` on file systems that do not support file ID +requests. This includes FAT32 and exFAT. diff --git a/Python/fileutils.c b/Python/fileutils.c index 610e729feb35..c7521751cd26 100644 --- a/Python/fileutils.c +++ b/Python/fileutils.c @@ -1236,6 +1236,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; @@ -1268,15 +1269,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);