On macOS and FreeBSD the read(2) system call can return EINVAL for large
sizes, so limit the maximum that we try to read. The calling code in
basic_filebuf::xsgetn will loop until it gets the size it wants, so we don't
need to loop in basic_file::xsgetn, just limit the maximum size.
libstdc++-v3/ChangeLog:
PR libstdc++/102259
* config/io/basic_file_stdio.cc (basic_file::xsgetn): Limit n to
_GLIBCXX_MAX_READ_SIZE if that macro is defined.
* config/os/bsd/darwin/os_defines.h (_GLIBCXX_MAX_READ_SIZE):
Define to INT_MAX-1.
* config/os/bsd/freebsd/os_defines.h (_GLIBCXX_MAX_READ_SIZE):
Likewise.
if (__ret == 0 && ferror(this->file()))
__ret = -1;
#else
+
+#ifdef _GLIBCXX_MAX_READ_SIZE
+ if (__builtin_expect(__n > _GLIBCXX_MAX_READ_SIZE, 0))
+ __n = _GLIBCXX_MAX_READ_SIZE;
+#endif
+
do
__ret = read(this->fd(), __s, __n);
while (__ret == -1L && errno == EINTR);
// No support for referencing weak symbols without a definition.
#define _GLIBCXX_USE_WEAK_REF 0
+// read(2) can return EINVAL for n >= INT_MAX.
+#define _GLIBCXX_MAX_READ_SIZE (__INT_MAX__ - 1)
+
#endif
#define _GLIBCXX_USE_C99_FLOAT_TRANSCENDENTALS_DYNAMIC 0
#endif
+// read(2) can return EINVAL for n >= INT_MAX.
+#define _GLIBCXX_MAX_READ_SIZE (__INT_MAX__ - 1)
+
#endif