#include "errno-util.h"
#include "fd-util.h"
#include "format-util.h"
-#include "io-util.h"
+#include "iovec-util.h"
#include "log.h"
#include "macro.h"
#include "missing_syscall.h"
static bool ratelimit_kmsg = true;
static int console_fd = STDERR_FILENO;
+static int console_fd_is_tty = -1; /* tri-state: -1 means don't know */
static int syslog_fd = -EBADF;
static int kmsg_fd = -EBADF;
static int journal_fd = -EBADF;
static bool always_reopen_console = false;
static bool open_when_needed = false;
static bool prohibit_ipc = false;
+static bool assert_return_is_critical = BUILD_MODE_DEVELOPER;
/* Akin to glibc's __abort_msg; which is private and we hence cannot
* use here. */
static void log_close_console(void) {
/* See comment in log_close_journal() */
(void) safe_close_above_stdio(TAKE_FD(console_fd));
+ console_fd_is_tty = -1;
}
static int log_open_console(void) {
if (!always_reopen_console) {
console_fd = STDERR_FILENO;
+ console_fd_is_tty = -1;
return 0;
}
return fd;
console_fd = fd_move_above_stdio(fd);
+ console_fd_is_tty = true;
}
return 0;
/* Do not call from library code. */
console_fd = kmsg_fd = syslog_fd = journal_fd = -EBADF;
+ console_fd_is_tty = -1;
}
void log_set_max_level(int level) {
log_facility = facility;
}
+static bool check_console_fd_is_tty(void) {
+ if (console_fd < 0)
+ return false;
+
+ if (console_fd_is_tty < 0)
+ console_fd_is_tty = isatty_safe(console_fd);
+
+ return console_fd_is_tty;
+}
+
static int write_to_console(
int level,
int error,
iovec[n++] = IOVEC_MAKE_STRING(buffer);
if (off)
iovec[n++] = IOVEC_MAKE_STRING(off);
- iovec[n++] = IOVEC_MAKE_STRING("\n");
+
+ /* When writing to a TTY we output an extra '\r' (i.e. CR) first, to generate CRNL rather than just
+ * NL. This is a robustness thing in case the TTY is currently in raw mode (specifically: has the
+ * ONLCR flag off). We want that subsequent output definitely starts at the beginning of the line
+ * again, after all. If the TTY is not in raw mode the extra CR should not hurt. */
+ iovec[n++] = IOVEC_MAKE_STRING(check_console_fd_is_tty() ? "\r\n" : "\n");
if (writev(console_fd, iovec, n) < 0) {
if (!syslog_is_stream)
break;
- if (IOVEC_INCREMENT(iovec, ELEMENTSOF(iovec), n))
+ if (iovec_increment(iovec, ELEMENTSOF(iovec), n))
break;
}
const char *file,
int line,
const char *func) {
+
+ if (assert_return_is_critical)
+ log_assert_failed(text, file, line, func);
+
PROTECT_ERRNO;
log_assert(LOG_DEBUG, text, file, line, func,
"Assertion '%s' failed at %s:%u, function %s(). Ignoring.");
}
int log_set_max_level_from_string(const char *e) {
- int t;
+ int r;
- t = log_level_from_string(e);
- if (t < 0)
- return t;
+ r = log_level_from_string(e);
+ if (r < 0)
+ return r;
- log_set_max_level(t);
+ log_set_max_level(r);
return 0;
}
return 0;
}
+void log_set_assert_return_is_critical(bool b) {
+ assert_return_is_critical = b;
+}
+
+bool log_get_assert_return_is_critical(void) {
+ return assert_return_is_critical;
+}
+
static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
/*
if (getpid_cached() == 1)
return true;
- /* Otherwise, parse the commandline if invoked directly by systemd. */
+ /* Otherwise, parse the command line if invoked directly by systemd. */
return invoked_by_systemd();
}
}
int log_show_color_from_string(const char *e) {
- int t;
+ int r;
- t = parse_boolean(e);
- if (t < 0)
- return t;
+ r = parse_boolean(e);
+ if (r < 0)
+ return r;
- log_show_color(t);
+ log_show_color(r);
return 0;
}
int log_show_location_from_string(const char *e) {
- int t;
+ int r;
- t = parse_boolean(e);
- if (t < 0)
- return t;
+ r = parse_boolean(e);
+ if (r < 0)
+ return r;
- log_show_location(t);
+ log_show_location(r);
return 0;
}
int log_show_time_from_string(const char *e) {
- int t;
+ int r;
- t = parse_boolean(e);
- if (t < 0)
- return t;
+ r = parse_boolean(e);
+ if (r < 0)
+ return r;
- log_show_time(t);
+ log_show_time(r);
return 0;
}
int log_show_tid_from_string(const char *e) {
- int t;
+ int r;
- t = parse_boolean(e);
- if (t < 0)
- return t;
+ r = parse_boolean(e);
+ if (r < 0)
+ return r;
- log_show_tid(t);
+ log_show_tid(r);
return 0;
}
if (pid_is_valid(si->ssi_pid)) {
_cleanup_free_ char *p = NULL;
- (void) get_process_comm(si->ssi_pid, &p);
+ (void) pid_get_comm(si->ssi_pid, &p);
log_full(level,
"Received SIG%s from PID %"PRIu32" (%s).",
if (saved_log_context_enabled >= 0)
return saved_log_context_enabled;
- r = getenv_bool_secure("SYSTEMD_ENABLE_LOG_CONTEXT");
+ r = secure_getenv_bool("SYSTEMD_ENABLE_LOG_CONTEXT");
if (r < 0 && r != -ENXIO)
log_debug_errno(r, "Failed to parse $SYSTEMD_ENABLE_LOG_CONTEXT, ignoring: %m");