summaryrefslogtreecommitdiffstats
path: root/misc.hh
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 21:14:51 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 21:14:51 +0000
commitbc282425088455198a7a99511c75914477d4ed32 (patch)
tree1b1fb887a634136a093deea7e4dd95d054201e7a /misc.hh
parentReleasing progress-linux version 1.8.3-3~progress7.99u1. (diff)
downloaddnsdist-bc282425088455198a7a99511c75914477d4ed32.tar.xz
dnsdist-bc282425088455198a7a99511c75914477d4ed32.zip
Merging upstream version 1.9.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'misc.hh')
-rw-r--r--misc.hh69
1 files changed, 50 insertions, 19 deletions
diff --git a/misc.hh b/misc.hh
index 8800cd7..76887ee 100644
--- a/misc.hh
+++ b/misc.hh
@@ -49,7 +49,6 @@ class DNSName;
typedef enum { TSIG_MD5, TSIG_SHA1, TSIG_SHA224, TSIG_SHA256, TSIG_SHA384, TSIG_SHA512, TSIG_GSS } TSIGHashEnum;
namespace pdns
{
-#if defined(HAVE_LIBCRYPTO)
/**
* \brief Retrieves the errno-based error message in a reentrant way.
*
@@ -63,6 +62,7 @@ namespace pdns
*/
auto getMessageFromErrno(int errnum) -> std::string;
+#if defined(HAVE_LIBCRYPTO)
namespace OpenSSL
{
/**
@@ -131,9 +131,8 @@ stringtok (Container &container, string const &in,
template<typename T> bool rfc1982LessThan(T a, T b)
{
- static_assert(std::is_unsigned<T>::value, "rfc1982LessThan only works for unsigned types");
- typedef typename std::make_signed<T>::type signed_t;
- return static_cast<signed_t>(a - b) < 0;
+ static_assert(std::is_unsigned_v<T>, "rfc1982LessThan only works for unsigned types");
+ return std::make_signed_t<T>(a - b) < 0;
}
// fills container with ranges, so {posbegin,posend}
@@ -414,17 +413,21 @@ struct CIStringCompare
struct CIStringComparePOSIX
{
- bool operator() (const std::string& lhs, const std::string& rhs)
+ bool operator() (const std::string& lhs, const std::string& rhs) const
{
- std::string::const_iterator a,b;
const std::locale &loc = std::locale("POSIX");
- a=lhs.begin();b=rhs.begin();
- while(a!=lhs.end()) {
- if (b==rhs.end() || std::tolower(*b,loc)<std::tolower(*a,loc)) return false;
- else if (std::tolower(*a,loc)<std::tolower(*b,loc)) return true;
- ++a;++b;
+ auto lhsIter = lhs.begin();
+ auto rhsIter = rhs.begin();
+ while (lhsIter != lhs.end()) {
+ if (rhsIter == rhs.end() || std::tolower(*rhsIter,loc) < std::tolower(*lhsIter,loc)) {
+ return false;
+ }
+ if (std::tolower(*lhsIter,loc) < std::tolower(*rhsIter,loc)) {
+ return true;
+ }
+ ++lhsIter;++rhsIter;
}
- return (b!=rhs.end());
+ return rhsIter != rhs.end();
}
};
@@ -616,7 +619,7 @@ T valueOrEmpty(const P val) {
// I'm not very OCD, but I appreciate loglines like "processing 1 delta", "processing 2 deltas" :-)
template <typename Integer,
-typename std::enable_if_t<std::is_integral<Integer>::value, bool> = true>
+typename std::enable_if_t<std::is_integral_v<Integer>, bool> = true>
const char* addS(Integer siz, const char* singular = "", const char *plural = "s")
{
if (siz == 1) {
@@ -626,7 +629,7 @@ const char* addS(Integer siz, const char* singular = "", const char *plural = "s
}
template <typename C,
-typename std::enable_if_t<std::is_class<C>::value, bool> = true>
+typename std::enable_if_t<std::is_class_v<C>, bool> = true>
const char* addS(const C& c, const char* singular = "", const char *plural = "s")
{
return addS(c.size(), singular, plural);
@@ -790,10 +793,7 @@ struct FDWrapper
~FDWrapper()
{
- if (d_fd != -1) {
- close(d_fd);
- d_fd = -1;
- }
+ reset();
}
FDWrapper(FDWrapper&& rhs) noexcept : d_fd(rhs.d_fd)
@@ -803,7 +803,7 @@ struct FDWrapper
FDWrapper& operator=(FDWrapper&& rhs) noexcept
{
- if (d_fd != -1) {
+ if (d_fd >= 0) {
close(d_fd);
}
d_fd = rhs.d_fd;
@@ -821,6 +821,37 @@ struct FDWrapper
return d_fd;
}
+ void reset()
+ {
+ if (d_fd >= 0) {
+ close(d_fd);
+ }
+ d_fd = -1;
+ }
+
private:
int d_fd{-1};
};
+
+namespace pdns
+{
+[[nodiscard]] std::optional<std::string> visit_directory(const std::string& directory, const std::function<bool(ino_t inodeNumber, const std::string_view& name)>& visitor);
+
+struct FilePtrDeleter
+{
+ /* using a deleter instead of decltype(&fclose) has two big advantages:
+ - the deleter is included in the type and does not have to be passed
+ when creating a new object (easier to use, less memory usage, in theory
+ better inlining)
+ - we avoid the annoying "ignoring attributes on template argument ‘int (*)(FILE*)’"
+ warning from the compiler, which is there because fclose is tagged as __nonnull((1))
+ */
+ void operator()(FILE* filePtr) const noexcept {
+ fclose(filePtr);
+ }
+};
+
+using UniqueFilePtr = std::unique_ptr<FILE, FilePtrDeleter>;
+
+UniqueFilePtr openFileForWriting(const std::string& filePath, mode_t permissions, bool mustNotExist = true, bool appendIfExists = false);
+}