]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Add a helper to get errno message in a reasonable way
authorFred Morcos <fred.morcos@open-xchange.com>
Wed, 9 Mar 2022 09:16:52 +0000 (10:16 +0100)
committerFred Morcos <fred.morcos@open-xchange.com>
Thu, 17 Mar 2022 10:33:39 +0000 (11:33 +0100)
pdns/misc.cc
pdns/misc.hh

index cd8062ad8fd9504f20908fc75cc054d44a4875e7..2dc3c9f659f4179afd344bce2260cec30d6e2e48 100644 (file)
@@ -36,7 +36,7 @@
 #include "misc.hh"
 #include <vector>
 #include <sstream>
-#include <errno.h>
+#include <cerrno>
 #include <cstring>
 #include <iostream>
 #include <sys/types.h>
@@ -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);
index 05aa87d4e72b37e972f9402a3300392a70c2926e..4d27de70179662c112fa0eed9b19101d0b43c964 100644 (file)
 
 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);