diff --git a/src/basic/log.c b/src/basic/log.c index f0472032716..8bcc18bc809 100644 --- a/src/basic/log.c +++ b/src/basic/log.c @@ -87,11 +87,13 @@ static int log_open_console(void) { } if (console_fd < 3) { - console_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC); - if (console_fd < 0) - return console_fd; + int fd; - console_fd = fd_move_above_stdio(console_fd); + fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return fd; + + console_fd = fd_move_above_stdio(fd); } return 0; @@ -372,13 +374,11 @@ static int write_to_console( if (errno == EIO && getpid_cached() == 1) { - /* If somebody tried to kick us from our - * console tty (via vhangup() or suchlike), - * try to reconnect */ + /* If somebody tried to kick us from our console tty (via vhangup() or suchlike), try + * to reconnect. */ log_close_console(); - log_open_console(); - + (void) log_open_console(); if (console_fd < 0) return 0; @@ -586,7 +586,7 @@ int log_dispatch_internal( level |= log_facility; if (open_when_needed) - log_open(); + (void) log_open(); do { char *e; @@ -629,7 +629,7 @@ int log_dispatch_internal( k = write_to_kmsg(level, error, file, line, func, buffer); if (k < 0) { log_close_kmsg(); - log_open_console(); + (void) log_open_console(); } } @@ -795,7 +795,7 @@ _noreturn_ void log_assert_failed_realm( const char *file, int line, const char *func) { - log_open(); + (void) log_open(); log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_CRIT), text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Aborting."); abort(); @@ -807,7 +807,7 @@ _noreturn_ void log_assert_failed_unreachable_realm( const char *file, int line, const char *func) { - log_open(); + (void) log_open(); log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_CRIT), text, file, line, func, "Code should not be reached '%s' at %s:%u, function %s(). Aborting."); abort(); @@ -1356,5 +1356,5 @@ void log_setup_service(void) { log_set_target(LOG_TARGET_AUTO); log_parse_environment(); - log_open(); + (void) log_open(); } diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c index cf6af45fbb4..c732e8021cf 100644 --- a/src/basic/terminal-util.c +++ b/src/basic/terminal-util.c @@ -578,22 +578,29 @@ int vt_disallocate(const char *name) { int make_console_stdio(void) { int fd, r; - /* Make /dev/console the controlling terminal and stdin/stdout/stderr */ + /* Make /dev/console the controlling terminal and stdin/stdout/stderr, if we can. If we can't use + * /dev/null instead. This is particularly useful if /dev/console is turned off, e.g. if console=null + * is specified on the kernel command line. */ fd = acquire_terminal("/dev/console", ACQUIRE_TERMINAL_FORCE|ACQUIRE_TERMINAL_PERMISSIVE, USEC_INFINITY); - if (fd < 0) - return log_error_errno(fd, "Failed to acquire terminal: %m"); + if (fd < 0) { + log_warning_errno(fd, "Failed to acquire terminal, using /dev/null stdin/stdout/stderr instead: %m"); - r = reset_terminal_fd(fd, true); - if (r < 0) - log_warning_errno(r, "Failed to reset terminal, ignoring: %m"); + r = make_null_stdio(); + if (r < 0) + return log_error_errno(r, "Failed to make /dev/null stdin/stdout/stderr: %m"); - r = rearrange_stdio(fd, fd, fd); /* This invalidates 'fd' both on success and on failure. */ - if (r < 0) - return log_error_errno(r, "Failed to make terminal stdin/stdout/stderr: %m"); + } else { + r = reset_terminal_fd(fd, true); + if (r < 0) + log_warning_errno(r, "Failed to reset terminal, ignoring: %m"); + + r = rearrange_stdio(fd, fd, fd); /* This invalidates 'fd' both on success and on failure. */ + if (r < 0) + return log_error_errno(r, "Failed to make terminal stdin/stdout/stderr: %m"); + } reset_terminal_feature_caches(); - return 0; } diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 20079e1fb12..c7827df95d2 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -98,14 +98,12 @@ int parse_confirm_spawn(const char *value, char **console) { if (r == 0) { *console = NULL; return 0; - } - - if (r > 0) /* on with default tty */ + } else if (r > 0) /* on with default tty */ s = strdup("/dev/console"); else if (is_path(value)) /* on with fully qualified path */ s = strdup(value); else /* on with only a tty file name, not a fully qualified path */ - s = strjoin("/dev/", value); + s = path_join("/dev/", value); if (!s) return -ENOMEM; diff --git a/src/core/manager.c b/src/core/manager.c index dfe8997f9d1..8d691a19c3d 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -4072,10 +4072,11 @@ static bool manager_get_show_status(Manager *m, StatusType type) { const char *manager_get_confirm_spawn(Manager *m) { static int last_errno = 0; - const char *vc = m->confirm_spawn; struct stat st; int r; + assert(m); + /* Here's the deal: we want to test the validity of the console but don't want * PID1 to go through the whole console process which might block. But we also * want to warn the user only once if something is wrong with the console so we @@ -4091,25 +4092,26 @@ const char *manager_get_confirm_spawn(Manager *m) { * reason the configured console is not ready, we fallback to the default * console. */ - if (!vc || path_equal(vc, "/dev/console")) - return vc; + if (!m->confirm_spawn || path_equal(m->confirm_spawn, "/dev/console")) + return m->confirm_spawn; - r = stat(vc, &st); - if (r < 0) + if (stat(m->confirm_spawn, &st) < 0) { + r = -errno; goto fail; + } if (!S_ISCHR(st.st_mode)) { - errno = ENOTTY; + r = -ENOTTY; goto fail; } last_errno = 0; - return vc; + return m->confirm_spawn; + fail: - if (last_errno != errno) { - last_errno = errno; - log_warning_errno(errno, "Failed to open %s: %m, using default console", vc); - } + if (last_errno != r) + last_errno = log_warning_errno(r, "Failed to open %s, using default console: %m", m->confirm_spawn); + return "/dev/console"; } diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c index 0a5863667c0..935dce9d218 100644 --- a/src/fsck/fsck.c +++ b/src/fsck/fsck.c @@ -169,12 +169,12 @@ static int process_progress(int fd) { f = fdopen(fd, "r"); if (!f) { safe_close(fd); - return -errno; + return log_debug_errno(errno, "Failed to use pipe: %m"); } console = fopen("/dev/console", "we"); if (!console) - return -ENOMEM; + return log_debug_errno(errno, "Failed to open /dev/console, can't print progress output: %m"); for (;;) { int pass, m; @@ -189,10 +189,9 @@ static int process_progress(int fd) { r = log_warning_errno(errno, "Failed to read from progress pipe: %m"); else if (feof(f)) r = 0; - else { - log_warning("Failed to parse progress pipe data"); - r = -EBADMSG; - } + else + r = log_warning_errno(SYNTHETIC_ERRNO(errno), "Failed to parse progress pipe data"); + break; }