This is an automated email from the ASF dual-hosted git repository.

morningman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 4b5ab0433f1 [fix](io) spell errno portably in localfs_error, so an 
ENOENT read is NotFound on macOS too (#67836)
4b5ab0433f1 is described below

commit 4b5ab0433f1eaf2c8fb98e62238a193f15fbc00f
Author: Mingyu Chen (Rayner) <[email protected]>
AuthorDate: Fri Sep 11 17:22:01 2026 +0800

    [fix](io) spell errno portably in localfs_error, so an ENOENT read is 
NotFound on macOS too (#67836)
    
    ### What problem does this PR solve?
    
    Issue Number: N/A
    
    Related PR: #66773
    
    Problem Summary:
    
    `localfs_error(int posix_errno, msg)`, `errno_to_str()` and
    `hdfs_error()` in `be/src/io/fs/err_utils.cpp` format the return value
    of `strerror_r()` straight into the message. That is the text on glibc,
    whose `strerror_r` returns `char*`, but the POSIX flavour on macOS and
    musl returns an `int` and fills the buffer instead, so there the message
    reads `failed to read <path>: 0`.
    
    The ORC reader (and the other readers that copy the pattern) tells
    NotFound apart from any other open failure by looking for `"No such file
    or directory"` in the text, so on macOS an ENOENT surfaces as
    INTERNAL_ERROR and
    `NewOrcReaderTest.InitRestoresNotFoundFromReadFailure` (added by #66773)
    fails.
    
    This spells the errno through `std::generic_category().message()`
    instead, which is what the `std::error_code` overload in the same file
    already does; it reads the same on both libcs and is thread safe.
    `localfs_error(int, ...)` also described the global `errno` rather than
    its `posix_errno` argument - every caller passes `errno` itself, so
    nothing changes, but it now says what it classifies.
---
 be/src/io/fs/err_utils.cpp | 26 +++++++++++++++++++-------
 1 file changed, 19 insertions(+), 7 deletions(-)

diff --git a/be/src/io/fs/err_utils.cpp b/be/src/io/fs/err_utils.cpp
index 74b8b0bc534..a5f446485ba 100644
--- a/be/src/io/fs/err_utils.cpp
+++ b/be/src/io/fs/err_utils.cpp
@@ -20,9 +20,9 @@
 // IWYU pragma: no_include <bthread/errno.h>
 #include <errno.h> // IWYU pragma: keep
 #include <fmt/format.h>
-#include <string.h>
 
 #include <sstream>
+#include <system_error>
 
 #include "common/status.h"
 #include "io/fs/hdfs.h"
@@ -32,9 +32,22 @@ using namespace ErrorCode;
 
 namespace io {
 
+namespace {
+
+// strerror_r has two incompatible flavours: glibc's returns the text (and may 
leave the buffer
+// untouched), the POSIX one on macOS and musl returns an int and fills the 
buffer. Formatting the
+// return value directly prints "0" on the latter, and callers such as the ORC 
reader tell NotFound
+// apart by looking for "No such file or directory" in the text. 
generic_category spells the errno
+// the same way everywhere.
+std::string errno_message(int err) {
+    return std::generic_category().message(err);
+}
+
+} // namespace
+
 std::string errno_to_str() {
-    char buf[1024];
-    return fmt::format("({}), {}", errno, strerror_r(errno, buf, 1024));
+    int err = errno;
+    return fmt::format("({}), {}", err, errno_message(err));
 }
 
 std::string errcode_to_str(const std::error_code& ec) {
@@ -43,8 +56,8 @@ std::string errcode_to_str(const std::error_code& ec) {
 
 std::string hdfs_error() {
     std::stringstream ss;
-    char buf[1024];
-    ss << "(" << errno << "), " << strerror_r(errno, buf, 1024) << ")";
+    int err = errno;
+    ss << "(" << err << "), " << errno_message(err) << ")";
 #ifdef USE_HADOOP_HDFS
     char* root_cause = hdfsGetLastExceptionRootCause();
     if (root_cause != nullptr) {
@@ -96,8 +109,7 @@ Status localfs_error(const std::error_code& ec, 
std::string_view msg) {
 }
 
 Status localfs_error(int posix_errno, std::string_view msg) {
-    char buf[1024];
-    auto message = fmt::format("{}: {}", msg, strerror_r(errno, buf, 1024));
+    auto message = fmt::format("{}: {}", msg, errno_message(posix_errno));
     switch (posix_errno) {
     case EIO:
         return Status::Error<IO_ERROR, false>(message);


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to