]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
basic/log: do not treat all negative errnos as synthetic
authorMike Yuan <me@yhndnzj.com>
Wed, 24 Jul 2024 14:28:48 +0000 (16:28 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 25 Jul 2024 10:03:59 +0000 (12:03 +0200)
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

src/basic/log.h
src/test/test-log.c

index 0597bd1e84ba87e58d54e9cca0a4f7021946225b..2da6d5767d67d1884cef74ed131dc8fa0f8ef393 100644 (file)
@@ -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
index 97eb5e01990f3343405ecd2869f333b7f4cb6583..57cab6326903f13a0a73f3c9467585b49eae5d43 100644 (file)
 #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();