]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Add workaround for read(2) EINVAL on macOS and FreeBSD [PR102259]
authorJonathan Wakely <jwakely@redhat.com>
Fri, 6 Dec 2024 17:41:01 +0000 (17:41 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Mon, 9 Dec 2024 16:01:21 +0000 (16:01 +0000)
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.

libstdc++-v3/config/io/basic_file_stdio.cc
libstdc++-v3/config/os/bsd/darwin/os_defines.h
libstdc++-v3/config/os/bsd/freebsd/os_defines.h

index 9b529490f08903ae701163dcb90660a2dd41f046..95e6905b3adf43c2533271d712d4849643c5158b 100644 (file)
@@ -338,6 +338,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);
index 6bc7930bdba0964656935ae20f5f45236a20cc97..a9cbdbb557bfbdd567196922a4dfd7c14bf41d9f 100644 (file)
@@ -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
index 125dfdc18885755ad726e9772776e8fea88078ee..bb4a8442dcce5e673dfec7211968134fac8ea27c 100644 (file)
@@ -50,4 +50,7 @@
 #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