https://gcc.gnu.org/g:f4afecdce5275555973a032bbcf540caf037cbc2

commit r13-10321-gf4afecdce5275555973a032bbcf540caf037cbc2
Author: Jonathan Wakely <[email protected]>
Date:   Fri Dec 6 17:41:01 2024 +0000

    libstdc++: Add workaround for read(2) EINVAL on macOS and FreeBSD [PR102259]
    
    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.
    
    (cherry picked from commit 4065bf7c2c61dd6eb19fdccbcda99000d8e44b7a)

Diff:
---
 libstdc++-v3/config/io/basic_file_stdio.cc      | 6 ++++++
 libstdc++-v3/config/os/bsd/darwin/os_defines.h  | 3 +++
 libstdc++-v3/config/os/bsd/freebsd/os_defines.h | 3 +++
 3 files changed, 12 insertions(+)

diff --git a/libstdc++-v3/config/io/basic_file_stdio.cc 
b/libstdc++-v3/config/io/basic_file_stdio.cc
index 27c2ad2afe3a..a51b3afb1d13 100644
--- a/libstdc++-v3/config/io/basic_file_stdio.cc
+++ b/libstdc++-v3/config/io/basic_file_stdio.cc
@@ -336,6 +336,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     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);
diff --git a/libstdc++-v3/config/os/bsd/darwin/os_defines.h 
b/libstdc++-v3/config/os/bsd/darwin/os_defines.h
index 9f0d43a083f3..22f1f6d424d2 100644
--- a/libstdc++-v3/config/os/bsd/darwin/os_defines.h
+++ b/libstdc++-v3/config/os/bsd/darwin/os_defines.h
@@ -54,4 +54,7 @@
 // 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
diff --git a/libstdc++-v3/config/os/bsd/freebsd/os_defines.h 
b/libstdc++-v3/config/os/bsd/freebsd/os_defines.h
index cddec56281d3..6f2ddd0f7911 100644
--- a/libstdc++-v3/config/os/bsd/freebsd/os_defines.h
+++ b/libstdc++-v3/config/os/bsd/freebsd/os_defines.h
@@ -40,4 +40,7 @@
 #define _GLIBCXX_USE_C99_FLOAT_TRANSCENDENTALS_CHECK 1
 #define _GLIBCXX_USE_C99_FLOAT_TRANSCENDENTALS_DYNAMIC defined _XOPEN_SOURCE
 
+// read(2) can return EINVAL for n >= INT_MAX.
+#define _GLIBCXX_MAX_READ_SIZE (__INT_MAX__ - 1)
+
 #endif

Reply via email to