From: Mike Yuan Date: Wed, 24 Jul 2024 14:28:48 +0000 (+0200) Subject: basic/log: do not treat all negative errnos as synthetic X-Git-Tag: v257-rc1~824 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=268f58076f7e0258dce75f521d08199092279853;p=thirdparty%2Fsystemd.git basic/log: do not treat all negative errnos as synthetic Currently, IS_SYNTHETIC_ERRNO() evaluates to true for all negative errnos, because of the two's-complement negative value representation. Subsequently, ERRNO= is not logged for most of our own code. Let's fix this, by formatting all synthetic errnos as positive. Then, treat all negative values as non-synthetic. While at it, mark the evaluation order explicitly, and remove unneeded comment. Fixes #33800 --- diff --git a/src/basic/log.h b/src/basic/log.h index 0597bd1e84b..2da6d5767d6 100644 --- a/src/basic/log.h +++ b/src/basic/log.h @@ -35,9 +35,8 @@ typedef enum LogTarget{ * used as a regular log level. */ #define LOG_NULL (LOG_EMERG - 1) -/* Note to readers: << and >> have lower precedence (are evaluated earlier) than & and | */ -#define SYNTHETIC_ERRNO(num) (1 << 30 | (num)) -#define IS_SYNTHETIC_ERRNO(val) ((val) >> 30 & 1) +#define SYNTHETIC_ERRNO(num) (abs(num) | (1 << 30)) +#define IS_SYNTHETIC_ERRNO(val) (((val) >> 30) == 1) #define ERRNO_VALUE(val) (abs(val) & ~(1 << 30)) /* The callback function to be invoked when syntax warnings are seen diff --git a/src/test/test-log.c b/src/test/test-log.c index 97eb5e01990..57cab632690 100644 --- a/src/test/test-log.c +++ b/src/test/test-log.c @@ -13,11 +13,6 @@ #include "strv.h" #include "tests.h" -assert_cc(IS_SYNTHETIC_ERRNO(SYNTHETIC_ERRNO(EINVAL))); -assert_cc(!IS_SYNTHETIC_ERRNO(EINVAL)); -assert_cc(IS_SYNTHETIC_ERRNO(SYNTHETIC_ERRNO(0))); -assert_cc(!IS_SYNTHETIC_ERRNO(0)); - #define X10(x) x x x x x x x x x x #define X100(x) X10(X10(x)) #define X1000(x) X100(X10(x)) @@ -227,6 +222,15 @@ static void test_log_prefix(void) { int main(int argc, char* argv[]) { test_setup_logging(LOG_DEBUG); + ASSERT_TRUE(IS_SYNTHETIC_ERRNO(SYNTHETIC_ERRNO(EINVAL))); + ASSERT_TRUE(IS_SYNTHETIC_ERRNO(SYNTHETIC_ERRNO(-EINVAL))); + assert_cc(!IS_SYNTHETIC_ERRNO(EINVAL)); + assert_cc(!IS_SYNTHETIC_ERRNO(-EINVAL)); + ASSERT_TRUE(IS_SYNTHETIC_ERRNO(SYNTHETIC_ERRNO(0))); + assert_cc(!IS_SYNTHETIC_ERRNO(0)); + ASSERT_EQ(ERRNO_VALUE(EINVAL), EINVAL); + ASSERT_EQ(ERRNO_VALUE(SYNTHETIC_ERRNO(-EINVAL)), EINVAL); + test_assert_return_is_critical(); test_file();