Skip to content

[libcxx] Use _ftelli64/_fseeki64 on Windows #123128

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jan 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 29 additions & 26 deletions libcxx/include/fstream
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -362,6 +356,9 @@ private:
bool __read_mode();
void __write_mode();

_LIBCPP_HIDE_FROM_ABI static int __fseek(FILE* __file, pos_type __offset, int __whence);
_LIBCPP_HIDE_FROM_ABI static pos_type __ftell(FILE* __file);
Comment on lines +359 to +360
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can just make these free functions. (I'd just define them at the top of the file). It would also be good to remove the !defined(_LIBCPP_MSVCRT) from the definition of _LIBCPP_HAS_OFF_T_FUNCTIONS and probably just inline _LIBCPP_HAS_OFF_T_FUNCTIONS as a whole, since at that point it's just equivalent do defind(_NEWLIB_VERSION).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kept the functions in the class, as they use pos_type, but I updated the PR to remove the unnecessary intermediate define _LIBCPP_HAS_OFF_T_FUNCTIONS.


_LIBCPP_EXPORTED_FROM_ABI friend FILE* __get_ostream_file(ostream&);

// There are multiple (__)open function, they use different C-API open
Expand Down Expand Up @@ -936,31 +933,42 @@ 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 (fseek(__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 = ftell(__file_);
# else
if (::fseeko(__file_, __width > 0 ? __width * __off : 0, __whence))
return pos_type(off_type(-1));
pos_type __r = ftello(__file_);
# endif
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 defined(_NEWLIB_VERSION)
return fseek(__file, __offset, __whence);
# else
return ::fseeko(__file, __offset, __whence);
# endif
}

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 defined(_NEWLIB_VERSION)
return ftell(__file);
# else
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 !_LIBCPP_HAS_OFF_T_FUNCTIONS
if (fseek(__file_, __sp, SEEK_SET))
if (__fseek(__file_, __sp, SEEK_SET))
return pos_type(off_type(-1));
# else
if (::fseeko(__file_, __sp, SEEK_SET))
return pos_type(off_type(-1));
# endif
__st_ = __sp.state();
return __sp;
}
Expand Down Expand Up @@ -1007,13 +1015,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_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down