@@ -105,20 +105,41 @@ const char *levelColor(LogLevel l) {
105105}
106106
107107// Thread-safe, portable errno-to-string conversion.
108- // MSVC deprecates strerror() in favour of strerror_s(); POSIX provides strerror_r().
108+ // strerror_r has two incompatible POSIX signatures depending on libc:
109+ // - GNU: char *strerror_r(int, char *, size_t) (glibc with _GNU_SOURCE)
110+ // - XSI: int strerror_r(int, char *, size_t) (musl, Bionic, uClibc, POSIX)
111+ // _GNU_SOURCE is not a reliable discriminator — it requests GNU extensions but
112+ // only glibc honours it for strerror_r. We let overload resolution pick the
113+ // right handler based on the actual return type the compiler sees, so the
114+ // code is correct under any libc without preprocessor guesswork.
115+ // MSVC uses strerror_s.
116+ #ifndef _WIN32
117+ // Mark both overloads as "may be unused" — only one matches strerror_r's
118+ // signature for any given libc, so the other is intentionally dead code.
119+ #if defined(__GNUC__) || defined(__clang__)
120+ #define ZE_LOGGER_MAYBE_UNUSED __attribute__ ((unused))
121+ #else
122+ #define ZE_LOGGER_MAYBE_UNUSED
123+ #endif
124+ // XSI variant: returns int (0 on success); message is in `buf`.
125+ static ZE_LOGGER_MAYBE_UNUSED std::string strerrorRDispatch (int /* ret*/ , char *buf) {
126+ return std::string (buf);
127+ }
128+ // GNU variant: returns char* that may or may not point at `buf`.
129+ static ZE_LOGGER_MAYBE_UNUSED std::string strerrorRDispatch (char *ret, char *buf) {
130+ return ret ? std::string (ret) : std::string (buf);
131+ }
132+ #undef ZE_LOGGER_MAYBE_UNUSED
133+ #endif
134+
109135static std::string errnoToString (int err) {
110136 char buf[256 ];
137+ buf[0 ] = ' \0 ' ;
111138#ifdef _WIN32
112139 strerror_s (buf, sizeof (buf), err);
113140 return buf;
114- #elif defined(_GNU_SOURCE)
115- // GNU strerror_r returns char* (may or may not use buf)
116- const char *result = strerror_r (err, buf, sizeof (buf));
117- return result ? result : buf;
118141#else
119- // XSI-compliant strerror_r returns int
120- strerror_r (err, buf, sizeof (buf));
121- return buf;
142+ return strerrorRDispatch (strerror_r (err, buf, sizeof (buf)), buf);
122143#endif
123144}
124145
0 commit comments