This enables us to write things like this:
int open_some_file(void) {
fd = open("/dev/foobar", O_RDWR|O_CLOEXEC);
if (fd < 0)
return log_error_errno(errno, "Failed to reboot: %m");
return fd;
}
Which is function that returns -errno on failure, as well as printing an
error message, all in one line.
const char *object,
char *buffer) {
const char *object,
char *buffer) {
if (log_target == LOG_TARGET_NULL)
if (log_target == LOG_TARGET_NULL)
/* Patch in LOG_DAEMON facility if necessary */
if ((level & LOG_FACMASK) == 0)
/* Patch in LOG_DAEMON facility if necessary */
if ((level & LOG_FACMASK) == 0)
if (k != -EAGAIN)
log_close_journal();
log_open_kmsg();
if (k != -EAGAIN)
log_close_journal();
log_open_kmsg();
- } else if (k > 0)
- r++;
}
if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
}
if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
if (k != -EAGAIN)
log_close_syslog();
log_open_kmsg();
if (k != -EAGAIN)
log_close_syslog();
log_open_kmsg();
- } else if (k > 0)
- r++;
if (k < 0) {
log_close_kmsg();
log_open_console();
if (k < 0) {
log_close_kmsg();
log_open_console();
- } else if (k > 0)
- r++;
- if (k <= 0) {
- k = write_to_console(level, error, file, line, func, object_field, object, buffer);
- if (k < 0)
- return k;
- }
+ if (k <= 0)
+ (void) write_to_console(level, error, file, line, func, object_field, object, buffer);
buffer = e;
} while (buffer);
buffer = e;
} while (buffer);
}
int log_dump_internal(
int level,
int error,
}
int log_dump_internal(
int level,
int error,
int line,
const char *func,
char *buffer) {
int line,
const char *func,
char *buffer) {
/* This modifies the buffer... */
/* This modifies the buffer... */
+ if (error < 0)
+ error = -error;
+
if (_likely_(LOG_PRI(level) > log_max_level))
if (_likely_(LOG_PRI(level) > log_max_level))
return log_dispatch(level, error, file, line, func, NULL, NULL, buffer);
}
return log_dispatch(level, error, file, line, func, NULL, NULL, buffer);
}
PROTECT_ERRNO;
char buffer[LINE_MAX];
PROTECT_ERRNO;
char buffer[LINE_MAX];
+ if (error < 0)
+ error = -error;
+
if (_likely_(LOG_PRI(level) > log_max_level))
if (_likely_(LOG_PRI(level) > log_max_level))
/* Make sure that %m maps to the specified error */
if (error != 0)
/* Make sure that %m maps to the specified error */
if (error != 0)
vsnprintf(buffer, sizeof(buffer), format, ap);
char_array_0(buffer);
vsnprintf(buffer, sizeof(buffer), format, ap);
char_array_0(buffer);
const char *func,
const char *format, ...) {
const char *func,
const char *format, ...) {
va_start(ap, format);
r = log_internalv(level, error, file, line, func, format, ap);
va_start(ap, format);
r = log_internalv(level, error, file, line, func, format, ap);
PROTECT_ERRNO;
char buffer[LINE_MAX];
PROTECT_ERRNO;
char buffer[LINE_MAX];
+ if (error < 0)
+ error = -error;
+
if (_likely_(LOG_PRI(level) > log_max_level))
if (_likely_(LOG_PRI(level) > log_max_level))
/* Make sure that %m maps to the specified error */
if (error != 0)
/* Make sure that %m maps to the specified error */
if (error != 0)
vsnprintf(buffer, sizeof(buffer), format, ap);
char_array_0(buffer);
vsnprintf(buffer, sizeof(buffer), format, ap);
char_array_0(buffer);
const char *object,
const char *format, ...) {
const char *object,
const char *format, ...) {
va_start(ap, format);
r = log_object_internalv(level, error, file, line, func, object_field, object, format, ap);
va_start(ap, format);
r = log_object_internalv(level, error, file, line, func, object_field, object, format, ap);
const char *func,
const char *format, ...) {
const char *func,
const char *format, ...) {
+ char buf[LINE_MAX];
+ bool found = false;
PROTECT_ERRNO;
va_list ap;
PROTECT_ERRNO;
va_list ap;
+
+ if (error < 0)
+ error = -error;
if (_likely_(LOG_PRI(level) > log_max_level))
if (_likely_(LOG_PRI(level) > log_max_level))
if (log_target == LOG_TARGET_NULL)
if (log_target == LOG_TARGET_NULL)
if ((level & LOG_FACMASK) == 0)
level = log_facility | LOG_PRI(level);
if ((level & LOG_FACMASK) == 0)
level = log_facility | LOG_PRI(level);
- if (error < 0)
- error = -error;
-
if ((log_target == LOG_TARGET_AUTO ||
log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
log_target == LOG_TARGET_JOURNAL) &&
journal_fd >= 0) {
if ((log_target == LOG_TARGET_AUTO ||
log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
log_target == LOG_TARGET_JOURNAL) &&
journal_fd >= 0) {
char header[LINE_MAX];
struct iovec iovec[17] = {};
unsigned n = 0, i;
char header[LINE_MAX];
struct iovec iovec[17] = {};
unsigned n = 0, i;
.msg_iov = iovec,
};
static const char nl = '\n';
.msg_iov = iovec,
};
static const char nl = '\n';
/* If the journal is available do structured logging */
log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL);
/* If the journal is available do structured logging */
log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL);
va_start(ap, format);
while (format && n + 1 < ELEMENTSOF(iovec)) {
va_start(ap, format);
while (format && n + 1 < ELEMENTSOF(iovec)) {
/* We need to copy the va_list structure,
* since vasprintf() leaves it afterwards at
/* We need to copy the va_list structure,
* since vasprintf() leaves it afterwards at
errno = error;
va_copy(aq, ap);
errno = error;
va_copy(aq, ap);
- if (vasprintf(&buf, format, aq) < 0) {
+ if (vasprintf(&m, format, aq) < 0) {
goto finish;
}
va_end(aq);
goto finish;
}
va_end(aq);
* the next format string */
VA_FORMAT_ADVANCE(format, ap);
* the next format string */
VA_FORMAT_ADVANCE(format, ap);
- IOVEC_SET_STRING(iovec[n++], buf);
+ IOVEC_SET_STRING(iovec[n++], m);
iovec[n].iov_base = (char*) &nl;
iovec[n].iov_len = 1;
iovec[n].iov_base = (char*) &nl;
iovec[n].iov_len = 1;
- if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) < 0)
- r = -errno;
- else
- r = 1;
+ (void) sendmsg(journal_fd, &mh, MSG_NOSIGNAL);
finish:
va_end(ap);
for (i = 1; i < n; i += 2)
free(iovec[i].iov_base);
finish:
va_end(ap);
for (i = 1; i < n; i += 2)
free(iovec[i].iov_base);
- } else {
- char buf[LINE_MAX];
- bool found = false;
-
- /* Fallback if journal logging is not available */
-
- va_start(ap, format);
- while (format) {
- va_list aq;
+ if (!fallback)
+ return -error;
+ }
- if (error != 0)
- errno = error;
+ /* Fallback if journal logging is not available or didn't work. */
- va_copy(aq, ap);
- vsnprintf(buf, sizeof(buf), format, aq);
- va_end(aq);
- char_array_0(buf);
+ va_start(ap, format);
+ while (format) {
+ va_list aq;
- if (startswith(buf, "MESSAGE=")) {
- found = true;
- break;
- }
+ if (error != 0)
+ errno = error;
- VA_FORMAT_ADVANCE(format, ap);
+ va_copy(aq, ap);
+ vsnprintf(buf, sizeof(buf), format, aq);
+ va_end(aq);
+ char_array_0(buf);
- format = va_arg(ap, char *);
+ if (startswith(buf, "MESSAGE=")) {
+ found = true;
+ break;
- if (found)
- r = log_dispatch(level, error, file, line, func, NULL, NULL, buf + 8);
- else
- r = -EINVAL;
+ VA_FORMAT_ADVANCE(format, ap);
+
+ format = va_arg(ap, char *);
+ if (!found)
+ return -error;
+
+ return log_dispatch(level, error, file, line, func, NULL, NULL, buf + 8);
}
int log_set_target_from_string(const char *e) {
}
int log_set_target_from_string(const char *e) {
const char *func);
/* Logging with level */
const char *func);
/* Logging with level */
-#define log_full_errno(level, error, ...) \
- do { \
- if (log_get_max_level() >= (level)) \
- log_internal((level), error, __FILE__, __LINE__, __func__, __VA_ARGS__); \
- } while (false)
+#define log_full_errno(level, error, ...) \
+ ({ \
+ int _l = (level), _e = (error); \
+ (log_get_max_level() >= _l) \
+ ? log_internal(_l, _e, __FILE__, __LINE__, __func__, __VA_ARGS__) \
+ : -abs(_e); \
+ })
#define log_full(level, ...) log_full_errno(level, 0, __VA_ARGS__)
#define log_full(level, ...) log_full_errno(level, 0, __VA_ARGS__)