Skip to content

Commit 86e20b0

Browse files
authored
[libcxx] Use _ftelli64/_fseeki64 on Windows (#123128)
This allows using the full 64 bit range for file offsets. This should fix the issue reported downstream at mstorsjo/llvm-mingw#462.
1 parent d412fe5 commit 86e20b0

File tree

2 files changed

+29
-32
lines changed

2 files changed

+29
-32
lines changed

libcxx/include/fstream

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -216,12 +216,6 @@ typedef basic_fstream<wchar_t> wfstream;
216216
_LIBCPP_PUSH_MACROS
217217
# include <__undef_macros>
218218

219-
# if !defined(_LIBCPP_MSVCRT) && !defined(_NEWLIB_VERSION)
220-
# define _LIBCPP_HAS_OFF_T_FUNCTIONS 1
221-
# else
222-
# define _LIBCPP_HAS_OFF_T_FUNCTIONS 0
223-
# endif
224-
225219
# if _LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION
226220

227221
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -362,6 +356,9 @@ private:
362356
bool __read_mode();
363357
void __write_mode();
364358

359+
_LIBCPP_HIDE_FROM_ABI static int __fseek(FILE* __file, pos_type __offset, int __whence);
360+
_LIBCPP_HIDE_FROM_ABI static pos_type __ftell(FILE* __file);
361+
365362
_LIBCPP_EXPORTED_FROM_ABI friend FILE* __get_ostream_file(ostream&);
366363

367364
// There are multiple (__)open function, they use different C-API open
@@ -936,31 +933,42 @@ basic_filebuf<_CharT, _Traits>::seekoff(off_type __off, ios_base::seekdir __way,
936933
default:
937934
return pos_type(off_type(-1));
938935
}
939-
# if !_LIBCPP_HAS_OFF_T_FUNCTIONS
940-
if (fseek(__file_, __width > 0 ? __width * __off : 0, __whence))
936+
if (__fseek(__file_, __width > 0 ? __width * __off : 0, __whence))
941937
return pos_type(off_type(-1));
942-
pos_type __r = ftell(__file_);
943-
# else
944-
if (::fseeko(__file_, __width > 0 ? __width * __off : 0, __whence))
945-
return pos_type(off_type(-1));
946-
pos_type __r = ftello(__file_);
947-
# endif
938+
pos_type __r = __ftell(__file_);
948939
__r.state(__st_);
949940
return __r;
950941
}
951942

943+
template <class _CharT, class _Traits>
944+
int basic_filebuf<_CharT, _Traits>::__fseek(FILE* __file, pos_type __offset, int __whence) {
945+
# if defined(_LIBCPP_MSVCRT_LIKE)
946+
return _fseeki64(__file, __offset, __whence);
947+
# elif defined(_NEWLIB_VERSION)
948+
return fseek(__file, __offset, __whence);
949+
# else
950+
return ::fseeko(__file, __offset, __whence);
951+
# endif
952+
}
953+
954+
template <class _CharT, class _Traits>
955+
typename basic_filebuf<_CharT, _Traits>::pos_type basic_filebuf<_CharT, _Traits>::__ftell(FILE* __file) {
956+
# if defined(_LIBCPP_MSVCRT_LIKE)
957+
return _ftelli64(__file);
958+
# elif defined(_NEWLIB_VERSION)
959+
return ftell(__file);
960+
# else
961+
return ftello(__file);
962+
# endif
963+
}
964+
952965
template <class _CharT, class _Traits>
953966
typename basic_filebuf<_CharT, _Traits>::pos_type
954967
basic_filebuf<_CharT, _Traits>::seekpos(pos_type __sp, ios_base::openmode) {
955968
if (__file_ == nullptr || sync())
956969
return pos_type(off_type(-1));
957-
# if !_LIBCPP_HAS_OFF_T_FUNCTIONS
958-
if (fseek(__file_, __sp, SEEK_SET))
970+
if (__fseek(__file_, __sp, SEEK_SET))
959971
return pos_type(off_type(-1));
960-
# else
961-
if (::fseeko(__file_, __sp, SEEK_SET))
962-
return pos_type(off_type(-1));
963-
# endif
964972
__st_ = __sp.state();
965973
return __sp;
966974
}
@@ -1007,13 +1015,8 @@ int basic_filebuf<_CharT, _Traits>::sync() {
10071015
}
10081016
}
10091017
}
1010-
# if !_LIBCPP_HAS_OFF_T_FUNCTIONS
1011-
if (fseek(__file_, -__c, SEEK_CUR))
1018+
if (__fseek(__file_, -__c, SEEK_CUR))
10121019
return -1;
1013-
# else
1014-
if (::fseeko(__file_, -__c, SEEK_CUR))
1015-
return -1;
1016-
# endif
10171020
if (__update_st)
10181021
__st_ = __state;
10191022
__extbufnext_ = __extbufend_ = __extbuf_;

libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/offset_range.pass.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,6 @@
1111
// Test that we can seek using offsets larger than 32 bit, and that we can
1212
// retrieve file offsets larger than 32 bit.
1313

14-
// On MSVC targets, we only use the 32 bit fseek/ftell functions. For MinGW
15-
// targets, we use fseeko/ftello, but the user needs to define
16-
// _FILE_OFFSET_BITS=64 to make them 64 bit.
17-
//
18-
// XFAIL: target={{.*}}-windows{{.*}}
19-
2014
// On 32 bit Android platforms, off_t is 32 bit by default. By defining
2115
// _FILE_OFFSET_BITS=64, one gets a 64 bit off_t, but the corresponding
2216
// 64 bit ftello/fseeko functions are only available since Android API 24 (7.0).

0 commit comments

Comments
 (0)