summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/basic/log.c82
-rw-r--r--src/basic/log.h9
-rw-r--r--src/test/test-log.c26
3 files changed, 51 insertions, 66 deletions
diff --git a/src/basic/log.c b/src/basic/log.c
index f24431eef2..71e7031bc4 100644
--- a/src/basic/log.c
+++ b/src/basic/log.c
@@ -484,6 +484,8 @@ static int log_do_header(
const char *extra_field, const char *extra) {
int r;
+ error = IS_SYNTHETIC_ERRNO(error) ? 0 : ERRNO_VALUE(error);
+
r = snprintf(header, size,
"PRIORITY=%i\n"
"SYSLOG_FACILITY=%i\n"
@@ -569,15 +571,12 @@ int log_dispatch_internal(
assert_raw(buffer);
- if (error < 0)
- error = -error;
-
if (log_target == LOG_TARGET_NULL)
- return -error;
+ return -ERRNO_VALUE(error);
/* Patch in LOG_DAEMON facility if necessary */
if ((level & LOG_FACMASK) == 0)
- level = log_facility | LOG_PRI(level);
+ level |= log_facility;
if (open_when_needed)
log_open();
@@ -636,7 +635,7 @@ int log_dispatch_internal(
if (open_when_needed)
log_close();
- return -error;
+ return -ERRNO_VALUE(error);
}
int log_dump_internal(
@@ -652,11 +651,8 @@ int log_dump_internal(
/* This modifies the buffer... */
- if (error < 0)
- error = -error;
-
if (_likely_(LOG_PRI(level) > log_max_level[realm]))
- return -error;
+ return -ERRNO_VALUE(error);
return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
}
@@ -674,14 +670,11 @@ int log_internalv_realm(
char buffer[LINE_MAX];
PROTECT_ERRNO;
- if (error < 0)
- error = -error;
-
if (_likely_(LOG_PRI(level) > log_max_level[realm]))
- return -error;
+ return -ERRNO_VALUE(error);
/* Make sure that %m maps to the specified error (or "Success"). */
- errno = error;
+ errno = ERRNO_VALUE(error);
(void) vsnprintf(buffer, sizeof buffer, format, ap);
@@ -723,14 +716,11 @@ static int log_object_internalv(
PROTECT_ERRNO;
char *buffer, *b;
- if (error < 0)
- error = -error;
-
if (_likely_(LOG_PRI(level) > log_max_level[LOG_REALM_SYSTEMD]))
- return -error;
+ return -ERRNO_VALUE(error);
/* Make sure that %m maps to the specified error (or "Success"). */
- errno = error;
+ errno = ERRNO_VALUE(error);
/* Prepend the object name before the message */
if (object) {
@@ -853,7 +843,7 @@ int log_format_iovec(
* since vasprintf() leaves it afterwards at
* an undefined location */
- errno = error;
+ errno = ERRNO_VALUE(error);
va_copy(aq, ap);
r = vasprintf(&m, format, aq);
@@ -892,17 +882,12 @@ int log_struct_internal(
PROTECT_ERRNO;
va_list ap;
- if (error < 0)
- error = -error;
-
- if (_likely_(LOG_PRI(level) > log_max_level[realm]))
- return -error;
-
- if (log_target == LOG_TARGET_NULL)
- return -error;
+ if (_likely_(LOG_PRI(level) > log_max_level[realm]) ||
+ log_target == LOG_TARGET_NULL)
+ return -ERRNO_VALUE(error);
if ((level & LOG_FACMASK) == 0)
- level = log_facility | LOG_PRI(level);
+ level |= log_facility;
if (IN_SET(log_target,
LOG_TARGET_AUTO,
@@ -922,7 +907,8 @@ int log_struct_internal(
};
bool fallback = false;
- /* If the journal is available do structured logging */
+ /* If the journal is available do structured logging.
+ * Do not report the errno if it is synthetic. */
log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL, NULL, NULL);
iovec[n++] = IOVEC_MAKE_STRING(header);
@@ -943,7 +929,7 @@ int log_struct_internal(
if (open_when_needed)
log_close();
- return -error;
+ return -ERRNO_VALUE(error);
}
}
}
@@ -954,7 +940,7 @@ int log_struct_internal(
while (format) {
va_list aq;
- errno = error;
+ errno = ERRNO_VALUE(error);
va_copy(aq, ap);
(void) vsnprintf(buf, sizeof buf, format, aq);
@@ -975,7 +961,7 @@ int log_struct_internal(
if (open_when_needed)
log_close();
- return -error;
+ return -ERRNO_VALUE(error);
}
return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buf + 8);
@@ -995,17 +981,12 @@ int log_struct_iovec_internal(
size_t i;
char *m;
- if (error < 0)
- error = -error;
-
- if (_likely_(LOG_PRI(level) > log_max_level[realm]))
- return -error;
-
- if (log_target == LOG_TARGET_NULL)
- return -error;
+ if (_likely_(LOG_PRI(level) > log_max_level[realm]) ||
+ log_target == LOG_TARGET_NULL)
+ return -ERRNO_VALUE(error);
if ((level & LOG_FACMASK) == 0)
- level = log_facility | LOG_PRI(level);
+ level |= log_facility;
if (IN_SET(log_target, LOG_TARGET_AUTO,
LOG_TARGET_JOURNAL_OR_KMSG,
@@ -1028,7 +1009,7 @@ int log_struct_iovec_internal(
}
if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) >= 0)
- return -error;
+ return -ERRNO_VALUE(error);
}
for (i = 0; i < n_input_iovec; i++)
@@ -1036,7 +1017,7 @@ int log_struct_iovec_internal(
break;
if (_unlikely_(i >= n_input_iovec)) /* Couldn't find MESSAGE=? */
- return -error;
+ return -ERRNO_VALUE(error);
m = strndupa(input_iovec[i].iov_base + STRLEN("MESSAGE="),
input_iovec[i].iov_len - STRLEN("MESSAGE="));
@@ -1239,14 +1220,9 @@ int log_syntax_internal(
va_list ap;
const char *unit_fmt = NULL;
- if (error < 0)
- error = -error;
-
- if (_likely_(LOG_PRI(level) > log_max_level[LOG_REALM_SYSTEMD]))
- return -error;
-
- if (log_target == LOG_TARGET_NULL)
- return -error;
+ if (_likely_(LOG_PRI(level) > log_max_level[LOG_REALM_SYSTEMD]) ||
+ log_target == LOG_TARGET_NULL)
+ return -ERRNO_VALUE(error);
errno = error;
diff --git a/src/basic/log.h b/src/basic/log.h
index 683f97b942..ddec8116ff 100644
--- a/src/basic/log.h
+++ b/src/basic/log.h
@@ -36,10 +36,11 @@ typedef enum LogTarget{
_LOG_TARGET_INVALID = -1
} LogTarget;
-#define LOG_REALM_PLUS_LEVEL(realm, level) \
- ((realm) << 10 | (level))
-#define LOG_REALM_REMOVE_LEVEL(realm_level) \
- ((realm_level >> 10))
+#define LOG_REALM_PLUS_LEVEL(realm, level) ((realm) << 10 | (level))
+#define LOG_REALM_REMOVE_LEVEL(realm_level) ((realm_level) >> 10)
+#define SYNTHETIC_ERRNO(num) (1 << 30 | (num))
+#define IS_SYNTHETIC_ERRNO(val) ((val) >> 30 & 1)
+#define ERRNO_VALUE(val) (abs(val) & 255)
void log_set_target(LogTarget target);
void log_set_max_level_realm(LogRealm realm, int level);
diff --git a/src/test/test-log.c b/src/test/test-log.c
index c09f40c356..1e010c08fb 100644
--- a/src/test/test-log.c
+++ b/src/test/test-log.c
@@ -17,20 +17,27 @@ assert_cc((LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, LOG_LOCAL3 | LOG_DEBUG) & LOG
assert_cc((LOG_REALM_PLUS_LEVEL(LOG_REALM_UDEV, LOG_USER | LOG_INFO) & LOG_PRIMASK)
== LOG_INFO);
+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))
-static void test_log_console(void) {
+static void test_log_struct(void) {
log_struct(LOG_INFO,
- "MESSAGE=Waldo PID="PID_FMT, getpid_cached(),
+ "MESSAGE=Waldo PID="PID_FMT" (no errno)", getpid_cached(),
"SERVICE=piepapo");
-}
-static void test_log_journal(void) {
- log_struct(LOG_INFO,
- "MESSAGE=Foobar PID="PID_FMT, getpid_cached(),
- "SERVICE=foobar");
+ log_struct_errno(LOG_INFO, EILSEQ,
+ "MESSAGE=Waldo PID="PID_FMT": %m (normal)", getpid_cached(),
+ "SERVICE=piepapo");
+
+ log_struct_errno(LOG_INFO, SYNTHETIC_ERRNO(EILSEQ),
+ "MESSAGE=Waldo PID="PID_FMT": %m (synthetic)", getpid_cached(),
+ "SERVICE=piepapo");
log_struct(LOG_INFO,
"MESSAGE=Foobar PID="PID_FMT, getpid_cached(),
@@ -59,10 +66,11 @@ int main(int argc, char* argv[]) {
log_set_target(target);
log_open();
- test_log_console();
- test_log_journal();
+ test_log_struct();
test_long_lines();
}
+ assert_se(log_info_errno(SYNTHETIC_ERRNO(EUCLEAN), "foo") == -EUCLEAN);
+
return 0;
}