]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib/utils kr_fail(): don't mangle errno
authorVladimír Čunát <vladimir.cunat@nic.cz>
Wed, 12 May 2021 11:48:00 +0000 (13:48 +0200)
committerTomas Krizek <tomas.krizek@nic.cz>
Tue, 25 May 2021 12:39:44 +0000 (14:39 +0200)
lib/utils.c
lib/utils.h
modules/dnstap/dnstap.c

index b3e9b549e9311c6e4907e4cc9c9a637f6ee8da11..7287fcfe48fc6787c80a14cf5fe2cd74dcac031d 100644 (file)
@@ -43,6 +43,7 @@ int kr_dbg_assumption_fork = DBG_ASSUMPTION_FORK;
 
 void kr_fail(bool is_fatal, const char *expr, const char *func, const char *file, int line)
 {
+       const int errno_orig = errno;
        if (is_fatal)
                kr_log_critical("requirement \"%s\" failed in %s@%s:%d\n", expr, func, file, line);
        else
@@ -51,12 +52,12 @@ void kr_fail(bool is_fatal, const char *expr, const char *func, const char *file
        if (is_fatal || (kr_dbg_assumption_abort && !kr_dbg_assumption_fork))
                abort();
        else if (!kr_dbg_assumption_abort || !kr_dbg_assumption_fork)
-               return;
+               goto recover;
        // We want to fork and abort the child, unless rate-limited.
        static uint64_t limited_until = 0;
        const uint64_t now = kr_now();
        if (now < limited_until)
-               return;
+               goto recover;
        if (kr_dbg_assumption_fork > 0) {
                // Add jitter +- 25%; in other words: 75% + uniform(0,50%).
                // Motivation: if a persistent problem starts happening, desynchronize
@@ -66,6 +67,8 @@ void kr_fail(bool is_fatal, const char *expr, const char *func, const char *file
        }
        if (fork() == 0)
                abort();
+recover:
+       errno = errno_orig;
 }
 
 /*
index 82bcf66e4db14856bce6dc07e5f36a4d41c4e16c..e11e8b144887d82630388029cba3d2ded0bbdede 100644 (file)
@@ -57,6 +57,7 @@ typedef void (*trace_log_f)(const struct kr_request *request, const char *msg);
  * If the check fails, optionally fork()+abort() to generate coredump
  * and continue running in parent process.  Return value must be handled to
  * ensure safe recovery from error.  Use kr_require() for unrecoverable checks.
+ * The errno variable is not mangled, e.g. you can: if (!kr_assume(...)) return errno;
  */
 #define kr_assume(expression) kr_assume_func((expression), #expression,       \
                                             __func__, __FILE__, __LINE__)
index 56e101227e1f11e2b8c457342b8e535757d595ef..73e8df7ddd6b7611f1101612859488f9dc9a87d4 100644 (file)
@@ -387,7 +387,7 @@ static int find_string(const JsonNode *node, char **val, size_t len) {
                return kr_error(EINVAL);
        *val = strndup(node->string_, len);
        if (!kr_assume(*val != NULL))
-               return kr_error(EFAULT);
+               return kr_error(errno);
        return kr_ok();
 }