From: Fred Morcos Date: Wed, 9 Mar 2022 09:16:52 +0000 (+0100) Subject: Add a helper to get errno message in a reasonable way X-Git-Tag: rec-4.7.0-beta1~51^2~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=da78b86e42d651e6d765132db0b6853c705248fb;p=thirdparty%2Fpdns.git Add a helper to get errno message in a reasonable way --- diff --git a/pdns/misc.cc b/pdns/misc.cc index cd8062ad8f..2dc3c9f659 100644 --- a/pdns/misc.cc +++ b/pdns/misc.cc @@ -36,7 +36,7 @@ #include "misc.hh" #include #include -#include +#include #include #include #include @@ -198,6 +198,32 @@ size_t writen2WithTimeout(int fd, const void * buffer, size_t len, const struct return len; } +auto pdns::getMessageFromErrno(const int errnum) -> std::string +{ + const size_t errLen = 2048; + std::string errMsgData{}; + errMsgData.resize(errLen); + + const char* errMsg = nullptr; +#ifdef _GNU_SOURCE + errMsg = strerror_r(errnum, errMsgData.data(), errMsgData.length()); +#else + // This can fail, and when it does, it sets errno. We ignore that and + // set our own error message instead. + int res = strerror_r(errnum, errMsgData.data(), errMsgData.length()); + errMsg = errMsgData.c_str(); + if (res != 0) { + errMsg = "Unknown (the exact error could not be retrieved)"; + } +#endif + + // We make a copy here because `strerror_r()` might return a static + // immutable buffer for an error message. The copy shouldn't be + // critical though, we're on the bailout/error-handling path anyways. + std::string message{errMsg}; + return message; +} + string nowTime() { time_t now = time(nullptr); diff --git a/pdns/misc.hh b/pdns/misc.hh index 05aa87d4e7..4d27de7017 100644 --- a/pdns/misc.hh +++ b/pdns/misc.hh @@ -46,6 +46,22 @@ typedef enum { TSIG_MD5, TSIG_SHA1, TSIG_SHA224, TSIG_SHA256, TSIG_SHA384, TSIG_SHA512, TSIG_GSS } TSIGHashEnum; +namespace pdns +{ +/** + * \brief Retrieves the errno-based error message in a reentrant way. + * + * This internally handles the portability issues around using + * `strerror_r` and returns a `std::string` that owns the error + * message's contents. + * + * \param[in] errnum The errno value. + * + * \return The `std::string` error message. + */ +auto getMessageFromErrno(int errnum) -> std::string; +} + string nowTime(); const string unquotify(const string &item); string humanDuration(time_t passed);