[libcxx-commits] [libcxx] [libcxx] Use _ftelli64/_fseeki64 on Windows (PR #123128)
Martin Storsjö via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Jan 28 21:46:12 PST 2025
https://github.com/mstorsjo updated https://github.com/llvm/llvm-project/pull/123128
>From eec1f0c6e22145cedbad4b346bc6892b62e478af Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin at martin.st>
Date: Sat, 11 Jan 2025 17:16:41 +0200
Subject: [PATCH 1/5] [libcxx] Use _ftelli64/_fseeki64 on Windows
This allows using the full 64 bit range for file offsets.
This should fix the issue reported downstream at
https://github.com/mstorsjo/llvm-mingw/issues/462.
---
libcxx/include/fstream | 11 +++++++++--
.../fstreams/ifstream.members/offset_range.pass.cpp | 6 ------
2 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/libcxx/include/fstream b/libcxx/include/fstream
index f0e9425e0a53d9..b6f7f0439c566a 100644
--- a/libcxx/include/fstream
+++ b/libcxx/include/fstream
@@ -936,7 +936,11 @@ basic_filebuf<_CharT, _Traits>::seekoff(off_type __off, ios_base::seekdir __way,
default:
return pos_type(off_type(-1));
}
-# if !_LIBCPP_HAS_OFF_T_FUNCTIONS
+# if defined(_LIBCPP_MSVCRT_LIKE)
+ if (_fseeki64(__file_, __width > 0 ? __width * __off : 0, __whence))
+ return pos_type(off_type(-1));
+ pos_type __r = _ftelli64(__file_);
+# elif !_LIBCPP_HAS_OFF_T_FUNCTIONS
if (fseek(__file_, __width > 0 ? __width * __off : 0, __whence))
return pos_type(off_type(-1));
pos_type __r = ftell(__file_);
@@ -954,7 +958,10 @@ typename basic_filebuf<_CharT, _Traits>::pos_type
basic_filebuf<_CharT, _Traits>::seekpos(pos_type __sp, ios_base::openmode) {
if (__file_ == nullptr || sync())
return pos_type(off_type(-1));
-# if !_LIBCPP_HAS_OFF_T_FUNCTIONS
+# if defined(_LIBCPP_MSVCRT_LIKE)
+ if (_fseeki64(__file_, __sp, SEEK_SET))
+ return pos_type(off_type(-1));
+# elif !_LIBCPP_HAS_OFF_T_FUNCTIONS
if (fseek(__file_, __sp, SEEK_SET))
return pos_type(off_type(-1));
# else
diff --git a/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/offset_range.pass.cpp b/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/offset_range.pass.cpp
index 5afd4465db31e0..ca6c609c7be312 100644
--- a/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/offset_range.pass.cpp
+++ b/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/offset_range.pass.cpp
@@ -11,12 +11,6 @@
// Test that we can seek using offsets larger than 32 bit, and that we can
// retrieve file offsets larger than 32 bit.
-// On MSVC targets, we only use the 32 bit fseek/ftell functions. For MinGW
-// targets, we use fseeko/ftello, but the user needs to define
-// _FILE_OFFSET_BITS=64 to make them 64 bit.
-//
-// XFAIL: target={{.*}}-windows{{.*}}
-
// On 32 bit Android platforms, off_t is 32 bit by default. By defining
// _FILE_OFFSET_BITS=64, one gets a 64 bit off_t, but the corresponding
// 64 bit ftello/fseeko functions are only available since Android API 24 (7.0).
>From fa21664ba0f17e5e0ca91da959d9e2fdfafe4436 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin at martin.st>
Date: Tue, 28 Jan 2025 13:56:39 +0200
Subject: [PATCH 2/5] Factorize repeated fseek/ftell calls
---
libcxx/include/fstream | 56 ++++++++++++++++++++++--------------------
1 file changed, 30 insertions(+), 26 deletions(-)
diff --git a/libcxx/include/fstream b/libcxx/include/fstream
index b6f7f0439c566a..b9f1bccf3ce1cd 100644
--- a/libcxx/include/fstream
+++ b/libcxx/include/fstream
@@ -362,6 +362,9 @@ private:
bool __read_mode();
void __write_mode();
+ static int __fseek(FILE* __file, pos_type __offset, int __whence);
+ static pos_type __ftell(FILE* __file);
+
_LIBCPP_EXPORTED_FROM_ABI friend FILE* __get_ostream_file(ostream&);
// There are multiple (__)open function, they use different C-API open
@@ -936,38 +939,44 @@ basic_filebuf<_CharT, _Traits>::seekoff(off_type __off, ios_base::seekdir __way,
default:
return pos_type(off_type(-1));
}
-# if defined(_LIBCPP_MSVCRT_LIKE)
- if (_fseeki64(__file_, __width > 0 ? __width * __off : 0, __whence))
+ if (__fseek(__file_, __width > 0 ? __width * __off : 0, __whence))
return pos_type(off_type(-1));
- pos_type __r = _ftelli64(__file_);
+ pos_type __r = __ftell(__file_);
+ __r.state(__st_);
+ return __r;
+}
+
+template <class _CharT, class _Traits>
+int
+basic_filebuf<_CharT, _Traits>::__fseek(FILE* __file, pos_type __offset, int __whence) {
+# if defined(_LIBCPP_MSVCRT_LIKE)
+ return _fseeki64(__file, __offset, __whence);
# elif !_LIBCPP_HAS_OFF_T_FUNCTIONS
- if (fseek(__file_, __width > 0 ? __width * __off : 0, __whence))
- return pos_type(off_type(-1));
- pos_type __r = ftell(__file_);
+ return fseek(__file, __offset, __whence);
# else
- if (::fseeko(__file_, __width > 0 ? __width * __off : 0, __whence))
- return pos_type(off_type(-1));
- pos_type __r = ftello(__file_);
+ return ::fseeko(__file, __offset, __whence);
# endif
- __r.state(__st_);
- return __r;
}
template <class _CharT, class _Traits>
typename basic_filebuf<_CharT, _Traits>::pos_type
-basic_filebuf<_CharT, _Traits>::seekpos(pos_type __sp, ios_base::openmode) {
- if (__file_ == nullptr || sync())
- return pos_type(off_type(-1));
+basic_filebuf<_CharT, _Traits>::__ftell(FILE* __file) {
# if defined(_LIBCPP_MSVCRT_LIKE)
- if (_fseeki64(__file_, __sp, SEEK_SET))
- return pos_type(off_type(-1));
+ return _ftelli64(__file);
# elif !_LIBCPP_HAS_OFF_T_FUNCTIONS
- if (fseek(__file_, __sp, SEEK_SET))
- return pos_type(off_type(-1));
+ return ftell(__file);
# else
- if (::fseeko(__file_, __sp, SEEK_SET))
- return pos_type(off_type(-1));
+ return ftello(__file);
# endif
+}
+
+template <class _CharT, class _Traits>
+typename basic_filebuf<_CharT, _Traits>::pos_type
+basic_filebuf<_CharT, _Traits>::seekpos(pos_type __sp, ios_base::openmode) {
+ if (__file_ == nullptr || sync())
+ return pos_type(off_type(-1));
+ if (__fseek(__file_, __sp, SEEK_SET))
+ return pos_type(off_type(-1));
__st_ = __sp.state();
return __sp;
}
@@ -1014,13 +1023,8 @@ int basic_filebuf<_CharT, _Traits>::sync() {
}
}
}
-# if !_LIBCPP_HAS_OFF_T_FUNCTIONS
- if (fseek(__file_, -__c, SEEK_CUR))
+ if (__fseek(__file_, -__c, SEEK_CUR))
return -1;
-# else
- if (::fseeko(__file_, -__c, SEEK_CUR))
- return -1;
-# endif
if (__update_st)
__st_ = __state;
__extbufnext_ = __extbufend_ = __extbuf_;
>From 56b717e341536963d5fb00170cc10e0f1392d996 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin at martin.st>
Date: Tue, 28 Jan 2025 14:03:45 +0200
Subject: [PATCH 3/5] Fix formatting
---
libcxx/include/fstream | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/libcxx/include/fstream b/libcxx/include/fstream
index b9f1bccf3ce1cd..6f00d6d455a05a 100644
--- a/libcxx/include/fstream
+++ b/libcxx/include/fstream
@@ -947,8 +947,7 @@ basic_filebuf<_CharT, _Traits>::seekoff(off_type __off, ios_base::seekdir __way,
}
template <class _CharT, class _Traits>
-int
-basic_filebuf<_CharT, _Traits>::__fseek(FILE* __file, pos_type __offset, int __whence) {
+int basic_filebuf<_CharT, _Traits>::__fseek(FILE* __file, pos_type __offset, int __whence) {
# if defined(_LIBCPP_MSVCRT_LIKE)
return _fseeki64(__file, __offset, __whence);
# elif !_LIBCPP_HAS_OFF_T_FUNCTIONS
@@ -959,8 +958,7 @@ basic_filebuf<_CharT, _Traits>::__fseek(FILE* __file, pos_type __offset, int __w
}
template <class _CharT, class _Traits>
-typename basic_filebuf<_CharT, _Traits>::pos_type
-basic_filebuf<_CharT, _Traits>::__ftell(FILE* __file) {
+typename basic_filebuf<_CharT, _Traits>::pos_type basic_filebuf<_CharT, _Traits>::__ftell(FILE* __file) {
# if defined(_LIBCPP_MSVCRT_LIKE)
return _ftelli64(__file);
# elif !_LIBCPP_HAS_OFF_T_FUNCTIONS
>From ddb31e60ac2c728e1906e7e16e110cc21030991a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin at martin.st>
Date: Tue, 28 Jan 2025 16:11:24 +0200
Subject: [PATCH 4/5] Hide the new symbols from the ABI
---
libcxx/include/fstream | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libcxx/include/fstream b/libcxx/include/fstream
index 6f00d6d455a05a..812bceb595a4aa 100644
--- a/libcxx/include/fstream
+++ b/libcxx/include/fstream
@@ -362,8 +362,8 @@ private:
bool __read_mode();
void __write_mode();
- static int __fseek(FILE* __file, pos_type __offset, int __whence);
- static pos_type __ftell(FILE* __file);
+ _LIBCPP_HIDE_FROM_ABI static int __fseek(FILE* __file, pos_type __offset, int __whence);
+ _LIBCPP_HIDE_FROM_ABI static pos_type __ftell(FILE* __file);
_LIBCPP_EXPORTED_FROM_ABI friend FILE* __get_ostream_file(ostream&);
>From 408297d05023f2c453c8c5e807605c7b8881947e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin at martin.st>
Date: Wed, 29 Jan 2025 07:44:09 +0200
Subject: [PATCH 5/5] Remove the intermediate _LIBCPP_HAS_OFF_T_FUNCTIONS
define
---
libcxx/include/fstream | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/libcxx/include/fstream b/libcxx/include/fstream
index 812bceb595a4aa..de5c07035dba9c 100644
--- a/libcxx/include/fstream
+++ b/libcxx/include/fstream
@@ -216,12 +216,6 @@ typedef basic_fstream<wchar_t> wfstream;
_LIBCPP_PUSH_MACROS
# include <__undef_macros>
-# if !defined(_LIBCPP_MSVCRT) && !defined(_NEWLIB_VERSION)
-# define _LIBCPP_HAS_OFF_T_FUNCTIONS 1
-# else
-# define _LIBCPP_HAS_OFF_T_FUNCTIONS 0
-# endif
-
# if _LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -950,7 +944,7 @@ template <class _CharT, class _Traits>
int basic_filebuf<_CharT, _Traits>::__fseek(FILE* __file, pos_type __offset, int __whence) {
# if defined(_LIBCPP_MSVCRT_LIKE)
return _fseeki64(__file, __offset, __whence);
-# elif !_LIBCPP_HAS_OFF_T_FUNCTIONS
+# elif defined(_NEWLIB_VERSION)
return fseek(__file, __offset, __whence);
# else
return ::fseeko(__file, __offset, __whence);
@@ -961,7 +955,7 @@ template <class _CharT, class _Traits>
typename basic_filebuf<_CharT, _Traits>::pos_type basic_filebuf<_CharT, _Traits>::__ftell(FILE* __file) {
# if defined(_LIBCPP_MSVCRT_LIKE)
return _ftelli64(__file);
-# elif !_LIBCPP_HAS_OFF_T_FUNCTIONS
+# elif defined(_NEWLIB_VERSION)
return ftell(__file);
# else
return ftello(__file);
More information about the libcxx-commits
mailing list