mirror of
https://github.com/systemd/systemd.git
synced 2024-10-26 17:27:41 +03:00
Merge pull request #33707 from poettering/terminal-size-by-ansi-seq
pid1: try to initialize terminal dimensions from data gathered via ANSI sequences + many clean-ups/refactorings
This commit is contained in:
commit
32dee192a6
@ -3322,7 +3322,8 @@ StandardInputData=V2XigLJyZSBubyBzdHJhbmdlcnMgdG8gbG92ZQpZb3Uga25vdyB0aGUgcnVsZX
|
||||
<term><varname>TTYReset=</varname></term>
|
||||
|
||||
<listitem><para>Reset the terminal device specified with <varname>TTYPath=</varname> before and after
|
||||
execution. Defaults to <literal>no</literal>.</para></listitem>
|
||||
execution. This does not erase the screen (see <varname>TTYVTDisallocate=</varname> below for
|
||||
that). Defaults to <literal>no</literal>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
@ -3333,11 +3334,12 @@ StandardInputData=V2XigLJyZSBubyBzdHJhbmdlcnMgdG8gbG92ZQpZb3Uga25vdyB0aGUgcnVsZX
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>TTYRows=</varname></term>
|
||||
<term><varname>TTYColumns=</varname></term>
|
||||
<term><varname>TTYRows=</varname></term>
|
||||
|
||||
<listitem><para>Configure the size of the TTY specified with <varname>TTYPath=</varname>. If unset or
|
||||
set to the empty string, the kernel default is used.</para>
|
||||
set to the empty string, it is attempted to retrieve the dimensions of the terminal screen via ANSI
|
||||
sequences, and if that fails the kernel defaults (typically 80x24) are used.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v250"/></listitem>
|
||||
</varlistentry>
|
||||
@ -3345,9 +3347,10 @@ StandardInputData=V2XigLJyZSBubyBzdHJhbmdlcnMgdG8gbG92ZQpZb3Uga25vdyB0aGUgcnVsZX
|
||||
<varlistentry>
|
||||
<term><varname>TTYVTDisallocate=</varname></term>
|
||||
|
||||
<listitem><para>If the terminal device specified with <varname>TTYPath=</varname> is a virtual console
|
||||
terminal, try to deallocate the TTY before and after execution. This ensures that the screen and scrollback
|
||||
buffer is cleared. Defaults to <literal>no</literal>.</para></listitem>
|
||||
<listitem><para>If the terminal device specified with <varname>TTYPath=</varname> is a virtual
|
||||
console terminal, try to deallocate the TTY before and after execution. This ensures that the screen
|
||||
and scrollback buffer is cleared. If the terminal device is of any other type of TTY an attempt is
|
||||
made to clear the screen via ANSI sequences. Defaults to <literal>no</literal>.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
162
src/basic/ansi-color.h
Normal file
162
src/basic/ansi-color.h
Normal file
@ -0,0 +1,162 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include "terminal-util.h"
|
||||
|
||||
/* Regular colors */
|
||||
#define ANSI_BLACK "\x1B[0;30m" /* Some type of grey usually. */
|
||||
#define ANSI_RED "\x1B[0;31m"
|
||||
#define ANSI_GREEN "\x1B[0;32m"
|
||||
#define ANSI_YELLOW "\x1B[0;33m"
|
||||
#define ANSI_BLUE "\x1B[0;34m"
|
||||
#define ANSI_MAGENTA "\x1B[0;35m"
|
||||
#define ANSI_CYAN "\x1B[0;36m"
|
||||
#define ANSI_WHITE "\x1B[0;37m" /* This is actually rendered as light grey, legible even on a white
|
||||
* background. See ANSI_HIGHLIGHT_WHITE for real white. */
|
||||
|
||||
#define ANSI_BRIGHT_BLACK "\x1B[0;90m"
|
||||
#define ANSI_BRIGHT_RED "\x1B[0;91m"
|
||||
#define ANSI_BRIGHT_GREEN "\x1B[0;92m"
|
||||
#define ANSI_BRIGHT_YELLOW "\x1B[0;93m"
|
||||
#define ANSI_BRIGHT_BLUE "\x1B[0;94m"
|
||||
#define ANSI_BRIGHT_MAGENTA "\x1B[0;95m"
|
||||
#define ANSI_BRIGHT_CYAN "\x1B[0;96m"
|
||||
#define ANSI_BRIGHT_WHITE "\x1B[0;97m"
|
||||
|
||||
#define ANSI_GREY "\x1B[0;38;5;245m"
|
||||
|
||||
/* Bold/highlighted */
|
||||
#define ANSI_HIGHLIGHT_BLACK "\x1B[0;1;30m"
|
||||
#define ANSI_HIGHLIGHT_RED "\x1B[0;1;31m"
|
||||
#define ANSI_HIGHLIGHT_GREEN "\x1B[0;1;32m"
|
||||
#define _ANSI_HIGHLIGHT_YELLOW "\x1B[0;1;33m" /* This yellow is currently not displayed well by some terminals */
|
||||
#define ANSI_HIGHLIGHT_BLUE "\x1B[0;1;34m"
|
||||
#define ANSI_HIGHLIGHT_MAGENTA "\x1B[0;1;35m"
|
||||
#define ANSI_HIGHLIGHT_CYAN "\x1B[0;1;36m"
|
||||
#define ANSI_HIGHLIGHT_WHITE "\x1B[0;1;37m"
|
||||
#define ANSI_HIGHLIGHT_YELLOW4 "\x1B[0;1;38:5:100m"
|
||||
#define ANSI_HIGHLIGHT_KHAKI3 "\x1B[0;1;38:5:185m"
|
||||
#define ANSI_HIGHLIGHT_GREY "\x1B[0;1;38:5:245m"
|
||||
|
||||
#define ANSI_HIGHLIGHT_YELLOW ANSI_HIGHLIGHT_KHAKI3 /* Replacement yellow that is more legible */
|
||||
|
||||
/* Underlined */
|
||||
#define ANSI_GREY_UNDERLINE "\x1B[0;4;38:5:245m"
|
||||
#define ANSI_BRIGHT_BLACK_UNDERLINE "\x1B[0;4;90m"
|
||||
#define ANSI_HIGHLIGHT_RED_UNDERLINE "\x1B[0;1;4;31m"
|
||||
#define ANSI_HIGHLIGHT_GREEN_UNDERLINE "\x1B[0;1;4;32m"
|
||||
#define ANSI_HIGHLIGHT_YELLOW_UNDERLINE "\x1B[0;1;4;38:5:185m"
|
||||
#define ANSI_HIGHLIGHT_BLUE_UNDERLINE "\x1B[0;1;4;34m"
|
||||
#define ANSI_HIGHLIGHT_MAGENTA_UNDERLINE "\x1B[0;1;4;35m"
|
||||
#define ANSI_HIGHLIGHT_GREY_UNDERLINE "\x1B[0;1;4;38:5:245m"
|
||||
|
||||
/* Other ANSI codes */
|
||||
#define ANSI_UNDERLINE "\x1B[0;4m"
|
||||
#define ANSI_ADD_UNDERLINE "\x1B[4m"
|
||||
#define ANSI_ADD_UNDERLINE_GREY ANSI_ADD_UNDERLINE "\x1B[58:5:245m"
|
||||
#define ANSI_HIGHLIGHT "\x1B[0;1;39m"
|
||||
#define ANSI_HIGHLIGHT_UNDERLINE "\x1B[0;1;4m"
|
||||
|
||||
/* Fallback colors: 256 → 16 */
|
||||
#define ANSI_HIGHLIGHT_GREY_FALLBACK "\x1B[0;1;90m"
|
||||
#define ANSI_HIGHLIGHT_GREY_FALLBACK_UNDERLINE "\x1B[0;1;4;90m"
|
||||
#define ANSI_HIGHLIGHT_YELLOW_FALLBACK "\x1B[0;1;33m"
|
||||
#define ANSI_HIGHLIGHT_YELLOW_FALLBACK_UNDERLINE "\x1B[0;1;4;33m"
|
||||
|
||||
/* Background colors */
|
||||
#define ANSI_BACKGROUND_BLUE "\x1B[44m"
|
||||
|
||||
/* Reset/clear ANSI styles */
|
||||
#define ANSI_NORMAL "\x1B[0m"
|
||||
|
||||
#define DEFINE_ANSI_FUNC(name, NAME) \
|
||||
static inline const char* ansi_##name(void) { \
|
||||
return colors_enabled() ? ANSI_##NAME : ""; \
|
||||
}
|
||||
|
||||
#define DEFINE_ANSI_FUNC_256(name, NAME, FALLBACK) \
|
||||
static inline const char* ansi_##name(void) { \
|
||||
switch (get_color_mode()) { \
|
||||
case COLOR_OFF: return ""; \
|
||||
case COLOR_16: return ANSI_##FALLBACK; \
|
||||
default : return ANSI_##NAME; \
|
||||
} \
|
||||
}
|
||||
|
||||
static inline const char* ansi_underline(void) {
|
||||
return underline_enabled() ? ANSI_UNDERLINE : "";
|
||||
}
|
||||
|
||||
static inline const char* ansi_add_underline(void) {
|
||||
return underline_enabled() ? ANSI_ADD_UNDERLINE : "";
|
||||
}
|
||||
|
||||
static inline const char* ansi_add_underline_grey(void) {
|
||||
return underline_enabled() ?
|
||||
(colors_enabled() ? ANSI_ADD_UNDERLINE_GREY : ANSI_ADD_UNDERLINE) : "";
|
||||
}
|
||||
|
||||
#define DEFINE_ANSI_FUNC_UNDERLINE(name, NAME) \
|
||||
static inline const char* ansi_##name(void) { \
|
||||
return underline_enabled() ? ANSI_##NAME##_UNDERLINE : \
|
||||
colors_enabled() ? ANSI_##NAME : ""; \
|
||||
}
|
||||
|
||||
|
||||
#define DEFINE_ANSI_FUNC_UNDERLINE_256(name, NAME, FALLBACK) \
|
||||
static inline const char* ansi_##name(void) { \
|
||||
switch (get_color_mode()) { \
|
||||
case COLOR_OFF: return ""; \
|
||||
case COLOR_16: return underline_enabled() ? ANSI_##FALLBACK##_UNDERLINE : ANSI_##FALLBACK; \
|
||||
default : return underline_enabled() ? ANSI_##NAME##_UNDERLINE: ANSI_##NAME; \
|
||||
} \
|
||||
}
|
||||
|
||||
DEFINE_ANSI_FUNC(normal, NORMAL);
|
||||
DEFINE_ANSI_FUNC(highlight, HIGHLIGHT);
|
||||
DEFINE_ANSI_FUNC(black, BLACK);
|
||||
DEFINE_ANSI_FUNC(red, RED);
|
||||
DEFINE_ANSI_FUNC(green, GREEN);
|
||||
DEFINE_ANSI_FUNC(yellow, YELLOW);
|
||||
DEFINE_ANSI_FUNC(blue, BLUE);
|
||||
DEFINE_ANSI_FUNC(magenta, MAGENTA);
|
||||
DEFINE_ANSI_FUNC(cyan, CYAN);
|
||||
DEFINE_ANSI_FUNC(white, WHITE);
|
||||
DEFINE_ANSI_FUNC_256(grey, GREY, BRIGHT_BLACK);
|
||||
|
||||
DEFINE_ANSI_FUNC(bright_black, BRIGHT_BLACK);
|
||||
DEFINE_ANSI_FUNC(bright_red, BRIGHT_RED);
|
||||
DEFINE_ANSI_FUNC(bright_green, BRIGHT_GREEN);
|
||||
DEFINE_ANSI_FUNC(bright_yellow, BRIGHT_YELLOW);
|
||||
DEFINE_ANSI_FUNC(bright_blue, BRIGHT_BLUE);
|
||||
DEFINE_ANSI_FUNC(bright_magenta, BRIGHT_MAGENTA);
|
||||
DEFINE_ANSI_FUNC(bright_cyan, BRIGHT_CYAN);
|
||||
DEFINE_ANSI_FUNC(bright_white, BRIGHT_WHITE);
|
||||
|
||||
DEFINE_ANSI_FUNC(highlight_black, HIGHLIGHT_BLACK);
|
||||
DEFINE_ANSI_FUNC(highlight_red, HIGHLIGHT_RED);
|
||||
DEFINE_ANSI_FUNC(highlight_green, HIGHLIGHT_GREEN);
|
||||
DEFINE_ANSI_FUNC_256(highlight_yellow, HIGHLIGHT_YELLOW, HIGHLIGHT_YELLOW_FALLBACK);
|
||||
DEFINE_ANSI_FUNC_256(highlight_yellow4, HIGHLIGHT_YELLOW4, HIGHLIGHT_YELLOW_FALLBACK);
|
||||
DEFINE_ANSI_FUNC(highlight_blue, HIGHLIGHT_BLUE);
|
||||
DEFINE_ANSI_FUNC(highlight_magenta, HIGHLIGHT_MAGENTA);
|
||||
DEFINE_ANSI_FUNC(highlight_cyan, HIGHLIGHT_CYAN);
|
||||
DEFINE_ANSI_FUNC_256(highlight_grey, HIGHLIGHT_GREY, HIGHLIGHT_GREY_FALLBACK);
|
||||
DEFINE_ANSI_FUNC(highlight_white, HIGHLIGHT_WHITE);
|
||||
|
||||
static inline const char* _ansi_highlight_yellow(void) {
|
||||
return colors_enabled() ? _ANSI_HIGHLIGHT_YELLOW : "";
|
||||
}
|
||||
|
||||
DEFINE_ANSI_FUNC_UNDERLINE(highlight_underline, HIGHLIGHT);
|
||||
DEFINE_ANSI_FUNC_UNDERLINE_256(grey_underline, GREY, BRIGHT_BLACK);
|
||||
DEFINE_ANSI_FUNC_UNDERLINE(highlight_red_underline, HIGHLIGHT_RED);
|
||||
DEFINE_ANSI_FUNC_UNDERLINE(highlight_green_underline, HIGHLIGHT_GREEN);
|
||||
DEFINE_ANSI_FUNC_UNDERLINE_256(highlight_yellow_underline, HIGHLIGHT_YELLOW, HIGHLIGHT_YELLOW_FALLBACK);
|
||||
DEFINE_ANSI_FUNC_UNDERLINE(highlight_blue_underline, HIGHLIGHT_BLUE);
|
||||
DEFINE_ANSI_FUNC_UNDERLINE(highlight_magenta_underline, HIGHLIGHT_MAGENTA);
|
||||
DEFINE_ANSI_FUNC_UNDERLINE_256(highlight_grey_underline, HIGHLIGHT_GREY, HIGHLIGHT_GREY_FALLBACK);
|
||||
|
||||
static inline const char* ansi_highlight_green_red(bool b) {
|
||||
return b ? ansi_highlight_green() : ansi_highlight_red();
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "ansi-color.h"
|
||||
#include "build.h"
|
||||
#include "extract-word.h"
|
||||
#include "macro.h"
|
||||
|
@ -1146,5 +1146,10 @@ int setenvf(const char *name, bool overwrite, const char *valuef, ...) {
|
||||
if (r < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Try to suppress writes if the value is already set correctly (simply because memory management of
|
||||
* environment variables sucks a bit. */
|
||||
if (streq_ptr(getenv(name), value))
|
||||
return 0;
|
||||
|
||||
return RET_NERRNO(setenv(name, value, overwrite));
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "sd-messages.h"
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "ansi-color.h"
|
||||
#include "argv-util.h"
|
||||
#include "env-util.h"
|
||||
#include "errno-util.h"
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -11,72 +11,6 @@
|
||||
#include "macro.h"
|
||||
#include "time-util.h"
|
||||
|
||||
/* Regular colors */
|
||||
#define ANSI_BLACK "\x1B[0;30m" /* Some type of grey usually. */
|
||||
#define ANSI_RED "\x1B[0;31m"
|
||||
#define ANSI_GREEN "\x1B[0;32m"
|
||||
#define ANSI_YELLOW "\x1B[0;33m"
|
||||
#define ANSI_BLUE "\x1B[0;34m"
|
||||
#define ANSI_MAGENTA "\x1B[0;35m"
|
||||
#define ANSI_CYAN "\x1B[0;36m"
|
||||
#define ANSI_WHITE "\x1B[0;37m" /* This is actually rendered as light grey, legible even on a white
|
||||
* background. See ANSI_HIGHLIGHT_WHITE for real white. */
|
||||
|
||||
#define ANSI_BRIGHT_BLACK "\x1B[0;90m"
|
||||
#define ANSI_BRIGHT_RED "\x1B[0;91m"
|
||||
#define ANSI_BRIGHT_GREEN "\x1B[0;92m"
|
||||
#define ANSI_BRIGHT_YELLOW "\x1B[0;93m"
|
||||
#define ANSI_BRIGHT_BLUE "\x1B[0;94m"
|
||||
#define ANSI_BRIGHT_MAGENTA "\x1B[0;95m"
|
||||
#define ANSI_BRIGHT_CYAN "\x1B[0;96m"
|
||||
#define ANSI_BRIGHT_WHITE "\x1B[0;97m"
|
||||
|
||||
#define ANSI_GREY "\x1B[0;38;5;245m"
|
||||
|
||||
/* Bold/highlighted */
|
||||
#define ANSI_HIGHLIGHT_BLACK "\x1B[0;1;30m"
|
||||
#define ANSI_HIGHLIGHT_RED "\x1B[0;1;31m"
|
||||
#define ANSI_HIGHLIGHT_GREEN "\x1B[0;1;32m"
|
||||
#define _ANSI_HIGHLIGHT_YELLOW "\x1B[0;1;33m" /* This yellow is currently not displayed well by some terminals */
|
||||
#define ANSI_HIGHLIGHT_BLUE "\x1B[0;1;34m"
|
||||
#define ANSI_HIGHLIGHT_MAGENTA "\x1B[0;1;35m"
|
||||
#define ANSI_HIGHLIGHT_CYAN "\x1B[0;1;36m"
|
||||
#define ANSI_HIGHLIGHT_WHITE "\x1B[0;1;37m"
|
||||
#define ANSI_HIGHLIGHT_YELLOW4 "\x1B[0;1;38:5:100m"
|
||||
#define ANSI_HIGHLIGHT_KHAKI3 "\x1B[0;1;38:5:185m"
|
||||
#define ANSI_HIGHLIGHT_GREY "\x1B[0;1;38:5:245m"
|
||||
|
||||
#define ANSI_HIGHLIGHT_YELLOW ANSI_HIGHLIGHT_KHAKI3 /* Replacement yellow that is more legible */
|
||||
|
||||
/* Underlined */
|
||||
#define ANSI_GREY_UNDERLINE "\x1B[0;4;38:5:245m"
|
||||
#define ANSI_BRIGHT_BLACK_UNDERLINE "\x1B[0;4;90m"
|
||||
#define ANSI_HIGHLIGHT_RED_UNDERLINE "\x1B[0;1;4;31m"
|
||||
#define ANSI_HIGHLIGHT_GREEN_UNDERLINE "\x1B[0;1;4;32m"
|
||||
#define ANSI_HIGHLIGHT_YELLOW_UNDERLINE "\x1B[0;1;4;38:5:185m"
|
||||
#define ANSI_HIGHLIGHT_BLUE_UNDERLINE "\x1B[0;1;4;34m"
|
||||
#define ANSI_HIGHLIGHT_MAGENTA_UNDERLINE "\x1B[0;1;4;35m"
|
||||
#define ANSI_HIGHLIGHT_GREY_UNDERLINE "\x1B[0;1;4;38:5:245m"
|
||||
|
||||
/* Other ANSI codes */
|
||||
#define ANSI_UNDERLINE "\x1B[0;4m"
|
||||
#define ANSI_ADD_UNDERLINE "\x1B[4m"
|
||||
#define ANSI_ADD_UNDERLINE_GREY ANSI_ADD_UNDERLINE "\x1B[58:5:245m"
|
||||
#define ANSI_HIGHLIGHT "\x1B[0;1;39m"
|
||||
#define ANSI_HIGHLIGHT_UNDERLINE "\x1B[0;1;4m"
|
||||
|
||||
/* Fallback colors: 256 -> 16 */
|
||||
#define ANSI_HIGHLIGHT_GREY_FALLBACK "\x1B[0;1;90m"
|
||||
#define ANSI_HIGHLIGHT_GREY_FALLBACK_UNDERLINE "\x1B[0;1;4;90m"
|
||||
#define ANSI_HIGHLIGHT_YELLOW_FALLBACK "\x1B[0;1;33m"
|
||||
#define ANSI_HIGHLIGHT_YELLOW_FALLBACK_UNDERLINE "\x1B[0;1;4;33m"
|
||||
|
||||
/* Background colors */
|
||||
#define ANSI_BACKGROUND_BLUE "\x1B[44m"
|
||||
|
||||
/* Reset/clear ANSI styles */
|
||||
#define ANSI_NORMAL "\x1B[0m"
|
||||
|
||||
/* Erase characters until the end of the line */
|
||||
#define ANSI_ERASE_TO_END_OF_LINE "\x1B[K"
|
||||
|
||||
@ -95,10 +29,10 @@
|
||||
|
||||
bool isatty_safe(int fd);
|
||||
|
||||
int reset_terminal_fd(int fd, bool switch_to_text);
|
||||
int reset_terminal(const char *name);
|
||||
int set_terminal_cursor_position(int fd, unsigned int row, unsigned int column);
|
||||
int terminal_reset_ansi_seq(int fd);
|
||||
int terminal_reset_defensive(int fd, bool switch_to_text);
|
||||
int terminal_reset_defensive_locked(int fd, bool switch_to_text);
|
||||
|
||||
int terminal_set_cursor_position(int fd, unsigned row, unsigned column);
|
||||
|
||||
int open_terminal(const char *name, int mode);
|
||||
|
||||
@ -117,6 +51,9 @@ typedef enum AcquireTerminalFlags {
|
||||
ACQUIRE_TERMINAL_PERMISSIVE = 1 << 2,
|
||||
} AcquireTerminalFlags;
|
||||
|
||||
int acquire_terminal(const char *name, AcquireTerminalFlags flags, usec_t timeout);
|
||||
int release_terminal(void);
|
||||
|
||||
/* Limits the use of ANSI colors to a subset. */
|
||||
typedef enum ColorMode {
|
||||
COLOR_OFF, /* No colors, monochrome output. */
|
||||
@ -130,11 +67,7 @@ typedef enum ColorMode {
|
||||
const char* color_mode_to_string(ColorMode m) _const_;
|
||||
ColorMode color_mode_from_string(const char *s) _pure_;
|
||||
|
||||
int acquire_terminal(const char *name, AcquireTerminalFlags flags, usec_t timeout);
|
||||
int release_terminal(void);
|
||||
|
||||
int terminal_vhangup_fd(int fd);
|
||||
int terminal_vhangup(const char *name);
|
||||
|
||||
int terminal_set_size_fd(int fd, const char *ident, unsigned rows, unsigned cols);
|
||||
int proc_cmdline_tty_size(const char *tty, unsigned *ret_rows, unsigned *ret_cols);
|
||||
@ -155,6 +88,8 @@ bool tty_is_console(const char *tty) _pure_;
|
||||
int vtnr_from_tty(const char *tty);
|
||||
const char* default_term_for_tty(const char *tty);
|
||||
|
||||
void reset_dev_console_fd(int fd, bool switch_to_text);
|
||||
int lock_dev_console(void);
|
||||
int make_console_stdio(void);
|
||||
|
||||
int fd_columns(int fd);
|
||||
@ -177,99 +112,11 @@ static inline bool colors_enabled(void) {
|
||||
return get_color_mode() != COLOR_OFF;
|
||||
}
|
||||
|
||||
#define DEFINE_ANSI_FUNC(name, NAME) \
|
||||
static inline const char *ansi_##name(void) { \
|
||||
return colors_enabled() ? ANSI_##NAME : ""; \
|
||||
}
|
||||
int get_ctty_devnr(pid_t pid, dev_t *ret);
|
||||
int get_ctty(pid_t, dev_t *ret_devnr, char **ret);
|
||||
|
||||
#define DEFINE_ANSI_FUNC_256(name, NAME, FALLBACK) \
|
||||
static inline const char *ansi_##name(void) { \
|
||||
switch (get_color_mode()) { \
|
||||
case COLOR_OFF: return ""; \
|
||||
case COLOR_16: return ANSI_##FALLBACK; \
|
||||
default : return ANSI_##NAME; \
|
||||
} \
|
||||
}
|
||||
|
||||
static inline const char* ansi_underline(void) {
|
||||
return underline_enabled() ? ANSI_UNDERLINE : "";
|
||||
}
|
||||
|
||||
static inline const char* ansi_add_underline(void) {
|
||||
return underline_enabled() ? ANSI_ADD_UNDERLINE : "";
|
||||
}
|
||||
|
||||
static inline const char* ansi_add_underline_grey(void) {
|
||||
return underline_enabled() ?
|
||||
(colors_enabled() ? ANSI_ADD_UNDERLINE_GREY : ANSI_ADD_UNDERLINE) : "";
|
||||
}
|
||||
|
||||
#define DEFINE_ANSI_FUNC_UNDERLINE(name, NAME) \
|
||||
static inline const char *ansi_##name(void) { \
|
||||
return underline_enabled() ? ANSI_##NAME##_UNDERLINE : \
|
||||
colors_enabled() ? ANSI_##NAME : ""; \
|
||||
}
|
||||
|
||||
|
||||
#define DEFINE_ANSI_FUNC_UNDERLINE_256(name, NAME, FALLBACK) \
|
||||
static inline const char *ansi_##name(void) { \
|
||||
switch (get_color_mode()) { \
|
||||
case COLOR_OFF: return ""; \
|
||||
case COLOR_16: return underline_enabled() ? ANSI_##FALLBACK##_UNDERLINE : ANSI_##FALLBACK; \
|
||||
default : return underline_enabled() ? ANSI_##NAME##_UNDERLINE: ANSI_##NAME; \
|
||||
} \
|
||||
}
|
||||
|
||||
DEFINE_ANSI_FUNC(normal, NORMAL);
|
||||
DEFINE_ANSI_FUNC(highlight, HIGHLIGHT);
|
||||
DEFINE_ANSI_FUNC(black, BLACK);
|
||||
DEFINE_ANSI_FUNC(red, RED);
|
||||
DEFINE_ANSI_FUNC(green, GREEN);
|
||||
DEFINE_ANSI_FUNC(yellow, YELLOW);
|
||||
DEFINE_ANSI_FUNC(blue, BLUE);
|
||||
DEFINE_ANSI_FUNC(magenta, MAGENTA);
|
||||
DEFINE_ANSI_FUNC(cyan, CYAN);
|
||||
DEFINE_ANSI_FUNC(white, WHITE);
|
||||
DEFINE_ANSI_FUNC_256(grey, GREY, BRIGHT_BLACK);
|
||||
|
||||
DEFINE_ANSI_FUNC(bright_black, BRIGHT_BLACK);
|
||||
DEFINE_ANSI_FUNC(bright_red, BRIGHT_RED);
|
||||
DEFINE_ANSI_FUNC(bright_green, BRIGHT_GREEN);
|
||||
DEFINE_ANSI_FUNC(bright_yellow, BRIGHT_YELLOW);
|
||||
DEFINE_ANSI_FUNC(bright_blue, BRIGHT_BLUE);
|
||||
DEFINE_ANSI_FUNC(bright_magenta, BRIGHT_MAGENTA);
|
||||
DEFINE_ANSI_FUNC(bright_cyan, BRIGHT_CYAN);
|
||||
DEFINE_ANSI_FUNC(bright_white, BRIGHT_WHITE);
|
||||
|
||||
DEFINE_ANSI_FUNC(highlight_black, HIGHLIGHT_BLACK);
|
||||
DEFINE_ANSI_FUNC(highlight_red, HIGHLIGHT_RED);
|
||||
DEFINE_ANSI_FUNC(highlight_green, HIGHLIGHT_GREEN);
|
||||
DEFINE_ANSI_FUNC_256(highlight_yellow, HIGHLIGHT_YELLOW, HIGHLIGHT_YELLOW_FALLBACK);
|
||||
DEFINE_ANSI_FUNC_256(highlight_yellow4, HIGHLIGHT_YELLOW4, HIGHLIGHT_YELLOW_FALLBACK);
|
||||
DEFINE_ANSI_FUNC(highlight_blue, HIGHLIGHT_BLUE);
|
||||
DEFINE_ANSI_FUNC(highlight_magenta, HIGHLIGHT_MAGENTA);
|
||||
DEFINE_ANSI_FUNC(highlight_cyan, HIGHLIGHT_CYAN);
|
||||
DEFINE_ANSI_FUNC_256(highlight_grey, HIGHLIGHT_GREY, HIGHLIGHT_GREY_FALLBACK);
|
||||
DEFINE_ANSI_FUNC(highlight_white, HIGHLIGHT_WHITE);
|
||||
|
||||
static inline const char* _ansi_highlight_yellow(void) {
|
||||
return colors_enabled() ? _ANSI_HIGHLIGHT_YELLOW : "";
|
||||
}
|
||||
|
||||
DEFINE_ANSI_FUNC_UNDERLINE(highlight_underline, HIGHLIGHT);
|
||||
DEFINE_ANSI_FUNC_UNDERLINE_256(grey_underline, GREY, BRIGHT_BLACK);
|
||||
DEFINE_ANSI_FUNC_UNDERLINE(highlight_red_underline, HIGHLIGHT_RED);
|
||||
DEFINE_ANSI_FUNC_UNDERLINE(highlight_green_underline, HIGHLIGHT_GREEN);
|
||||
DEFINE_ANSI_FUNC_UNDERLINE_256(highlight_yellow_underline, HIGHLIGHT_YELLOW, HIGHLIGHT_YELLOW_FALLBACK);
|
||||
DEFINE_ANSI_FUNC_UNDERLINE(highlight_blue_underline, HIGHLIGHT_BLUE);
|
||||
DEFINE_ANSI_FUNC_UNDERLINE(highlight_magenta_underline, HIGHLIGHT_MAGENTA);
|
||||
DEFINE_ANSI_FUNC_UNDERLINE_256(highlight_grey_underline, HIGHLIGHT_GREY, HIGHLIGHT_GREY_FALLBACK);
|
||||
|
||||
int get_ctty_devnr(pid_t pid, dev_t *d);
|
||||
int get_ctty(pid_t, dev_t *_devnr, char **r);
|
||||
|
||||
int getttyname_malloc(int fd, char **r);
|
||||
int getttyname_harder(int fd, char **r);
|
||||
int getttyname_malloc(int fd, char **ret);
|
||||
int getttyname_harder(int fd, char **ret);
|
||||
|
||||
int ptsname_malloc(int fd, char **ret);
|
||||
|
||||
@ -277,20 +124,19 @@ int openpt_allocate(int flags, char **ret_slave);
|
||||
int openpt_allocate_in_namespace(pid_t pid, int flags, char **ret_slave);
|
||||
int open_terminal_in_namespace(pid_t pid, const char *name, int mode);
|
||||
|
||||
int vt_default_utf8(void);
|
||||
int vt_reset_keyboard(int fd);
|
||||
int vt_restore(int fd);
|
||||
int vt_release(int fd, bool restore_vt);
|
||||
|
||||
void get_log_colors(int priority, const char **on, const char **off, const char **highlight);
|
||||
|
||||
static inline const char* ansi_highlight_green_red(bool b) {
|
||||
return b ? ansi_highlight_green() : ansi_highlight_red();
|
||||
}
|
||||
|
||||
/* This assumes there is a 'tty' group */
|
||||
#define TTY_MODE 0620
|
||||
|
||||
void termios_disable_echo(struct termios *termios);
|
||||
|
||||
int get_default_background_color(double *ret_red, double *ret_green, double *ret_blue);
|
||||
int terminal_get_size_by_dsr(int input_fd, int output_fd, unsigned *ret_rows, unsigned *ret_columns);
|
||||
|
||||
int terminal_fix_size(int input_fd, int output_fd);
|
||||
|
||||
int terminal_is_pty_fd(int fd);
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <sys/reboot.h>
|
||||
|
||||
#include "ansi-color.h"
|
||||
#include "bus-error.h"
|
||||
#include "bus-util.h"
|
||||
#include "emergency-action.h"
|
||||
|
@ -353,16 +353,10 @@ static int setup_input(
|
||||
if (dup2(params->stdin_fd, STDIN_FILENO) < 0)
|
||||
return -errno;
|
||||
|
||||
/* Try to make this the controlling tty, if it is a tty, and reset it */
|
||||
if (isatty(STDIN_FILENO)) {
|
||||
/* Try to make this the controlling tty, if it is a tty */
|
||||
if (isatty(STDIN_FILENO))
|
||||
(void) ioctl(STDIN_FILENO, TIOCSCTTY, context->std_input == EXEC_INPUT_TTY_FORCE);
|
||||
|
||||
if (context->tty_reset)
|
||||
(void) reset_terminal_fd(STDIN_FILENO, /* switch_to_text= */ true);
|
||||
|
||||
(void) exec_context_apply_tty_size(context, STDIN_FILENO, /* tty_path= */ NULL);
|
||||
}
|
||||
|
||||
return STDIN_FILENO;
|
||||
}
|
||||
|
||||
@ -389,10 +383,6 @@ static int setup_input(
|
||||
if (tty_fd < 0)
|
||||
return tty_fd;
|
||||
|
||||
r = exec_context_apply_tty_size(context, tty_fd, tty_path);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = move_fd(tty_fd, STDIN_FILENO, /* cloexec= */ false);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -554,7 +544,6 @@ static int setup_output(
|
||||
if (is_terminal_input(i))
|
||||
return RET_NERRNO(dup2(STDIN_FILENO, fileno));
|
||||
|
||||
/* We don't reset the terminal if this is just about output */
|
||||
return open_terminal_as(exec_context_tty_path(context), O_WRONLY, fileno);
|
||||
|
||||
case EXEC_OUTPUT_KMSG:
|
||||
@ -659,11 +648,11 @@ static int setup_confirm_stdio(
|
||||
assert(ret_saved_stdin);
|
||||
assert(ret_saved_stdout);
|
||||
|
||||
saved_stdin = fcntl(STDIN_FILENO, F_DUPFD, 3);
|
||||
saved_stdin = fcntl(STDIN_FILENO, F_DUPFD_CLOEXEC, 3);
|
||||
if (saved_stdin < 0)
|
||||
return -errno;
|
||||
|
||||
saved_stdout = fcntl(STDOUT_FILENO, F_DUPFD, 3);
|
||||
saved_stdout = fcntl(STDOUT_FILENO, F_DUPFD_CLOEXEC, 3);
|
||||
if (saved_stdout < 0)
|
||||
return -errno;
|
||||
|
||||
@ -671,15 +660,19 @@ static int setup_confirm_stdio(
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
_cleanup_close_ int lock_fd = lock_dev_console();
|
||||
if (lock_fd < 0)
|
||||
log_debug_errno(lock_fd, "Failed to lock /dev/console, ignoring: %m");
|
||||
|
||||
r = chown_terminal(fd, getuid());
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = reset_terminal_fd(fd, /* switch_to_text= */ true);
|
||||
r = terminal_reset_defensive(fd, /* switch_to_text= */ true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = exec_context_apply_tty_size(context, fd, vc);
|
||||
r = exec_context_apply_tty_size(context, fd, fd, vc);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -694,15 +687,16 @@ static int setup_confirm_stdio(
|
||||
}
|
||||
|
||||
static void write_confirm_error_fd(int err, int fd, const char *unit_id) {
|
||||
assert(err < 0);
|
||||
assert(err != 0);
|
||||
assert(fd >= 0);
|
||||
assert(unit_id);
|
||||
|
||||
if (err == -ETIMEDOUT)
|
||||
errno = abs(err);
|
||||
|
||||
if (errno == ETIMEDOUT)
|
||||
dprintf(fd, "Confirmation question timed out for %s, assuming positive response.\n", unit_id);
|
||||
else {
|
||||
errno = -err;
|
||||
dprintf(fd, "Couldn't ask confirmation for %s: %m, assuming positive response.\n", unit_id);
|
||||
}
|
||||
else
|
||||
dprintf(fd, "Couldn't ask confirmation for %s, assuming positive response: %m\n", unit_id);
|
||||
}
|
||||
|
||||
static void write_confirm_error(int err, const char *vc, const char *unit_id) {
|
||||
@ -750,7 +744,7 @@ static bool confirm_spawn_disabled(void) {
|
||||
}
|
||||
|
||||
static int ask_for_confirmation(const ExecContext *context, const ExecParameters *params, const char *cmdline) {
|
||||
int saved_stdout = -1, saved_stdin = -1, r;
|
||||
int saved_stdout = -EBADF, saved_stdin = -EBADF, r;
|
||||
_cleanup_free_ char *e = NULL;
|
||||
char c;
|
||||
|
||||
@ -4031,6 +4025,39 @@ static int send_handoff_timestamp(
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void prepare_terminal(
|
||||
const ExecContext *context,
|
||||
ExecParameters *p) {
|
||||
|
||||
_cleanup_close_ int lock_fd = -EBADF;
|
||||
|
||||
/* This is the "constructive" reset, i.e. is about preparing things for our invocation rather than
|
||||
* cleaning up things from older invocations. */
|
||||
|
||||
assert(context);
|
||||
assert(p);
|
||||
|
||||
/* We only try to reset things if we there's the chance our stdout points to a TTY */
|
||||
if (!(is_terminal_output(context->std_output) ||
|
||||
(context->std_output == EXEC_OUTPUT_INHERIT && is_terminal_input(context->std_input)) ||
|
||||
context->std_output == EXEC_OUTPUT_NAMED_FD ||
|
||||
p->stdout_fd >= 0))
|
||||
return;
|
||||
|
||||
if (context->tty_reset) {
|
||||
/* When we are resetting the TTY, then let's create a lock first, to synchronize access. This
|
||||
* in particular matters as concurrent resets and the TTY size ANSI DSR logic done by the
|
||||
* exec_context_apply_tty_size() below might interfere */
|
||||
lock_fd = lock_dev_console();
|
||||
if (lock_fd < 0)
|
||||
log_exec_debug_errno(context, p, lock_fd, "Failed to lock /dev/console, ignoring: %m");
|
||||
|
||||
(void) terminal_reset_defensive(STDOUT_FILENO, /* switch_to_text= */ false);
|
||||
}
|
||||
|
||||
(void) exec_context_apply_tty_size(context, STDIN_FILENO, STDOUT_FILENO, /* tty_path= */ NULL);
|
||||
}
|
||||
|
||||
int exec_invoke(
|
||||
const ExecCommand *command,
|
||||
const ExecContext *context,
|
||||
@ -4198,6 +4225,11 @@ int exec_invoke(
|
||||
return log_exec_error_errno(context, params, errno, "Failed to create new process session: %m");
|
||||
}
|
||||
|
||||
/* Now, reset the TTY associated to this service "destructively" (i.e. possibly even hang up or
|
||||
* disallocate the VT), to get rid of any prior uses of the device. Note that we do not keep any fd
|
||||
* open here, hence some of the settings made here might vanish again, depending on the TTY driver
|
||||
* used. A 2nd ("constructive") initialization after we opened the input/output fds we actually want
|
||||
* will fix this. */
|
||||
exec_context_tty_reset(context, params);
|
||||
|
||||
if (params->shall_confirm_spawn && exec_context_shall_confirm_spawn(context)) {
|
||||
@ -4381,6 +4413,12 @@ int exec_invoke(
|
||||
return log_exec_error_errno(context, params, r, "Failed to set up standard error output: %m");
|
||||
}
|
||||
|
||||
/* Now that stdin/stdout are definiely opened, properly initialize it with our desired
|
||||
* settings. Note: this is a "constructive" reset, it prepares things for us to use. This is
|
||||
* different from the "destructive" TTY reset further up. Also note: we apply this on stdin/stdout in
|
||||
* case this is a tty, regardless if we opened it ourselves or got it passed in pre-opened. */
|
||||
prepare_terminal(context, params);
|
||||
|
||||
if (context->oom_score_adjust_set) {
|
||||
/* When we can't make this change due to EPERM, then let's silently skip over it. User
|
||||
* namespaces prohibit write access to this file, and we shouldn't trip up over that. */
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include "cgroup-setup.h"
|
||||
#include "constants.h"
|
||||
#include "cpu-set-util.h"
|
||||
#include "dev-setup.h"
|
||||
#include "env-file.h"
|
||||
#include "env-util.h"
|
||||
#include "errno-list.h"
|
||||
@ -99,56 +98,65 @@ const char* exec_context_tty_path(const ExecContext *context) {
|
||||
return "/dev/console";
|
||||
}
|
||||
|
||||
static void exec_context_determine_tty_size(
|
||||
int exec_context_apply_tty_size(
|
||||
const ExecContext *context,
|
||||
const char *tty_path,
|
||||
unsigned *ret_rows,
|
||||
unsigned *ret_cols) {
|
||||
int input_fd,
|
||||
int output_fd,
|
||||
const char *tty_path) {
|
||||
|
||||
unsigned rows, cols;
|
||||
int r;
|
||||
|
||||
assert(context);
|
||||
assert(ret_rows);
|
||||
assert(ret_cols);
|
||||
assert(input_fd >= 0);
|
||||
assert(output_fd >= 0);
|
||||
|
||||
if (!isatty_safe(output_fd))
|
||||
return 0;
|
||||
|
||||
if (!tty_path)
|
||||
tty_path = exec_context_tty_path(context);
|
||||
|
||||
/* Preferably use explicitly configured data */
|
||||
rows = context->tty_rows;
|
||||
cols = context->tty_cols;
|
||||
|
||||
/* Fill in data from kernel command line if anything is unspecified */
|
||||
if (tty_path && (rows == UINT_MAX || cols == UINT_MAX))
|
||||
(void) proc_cmdline_tty_size(
|
||||
tty_path,
|
||||
rows == UINT_MAX ? &rows : NULL,
|
||||
cols == UINT_MAX ? &cols : NULL);
|
||||
|
||||
*ret_rows = rows;
|
||||
*ret_cols = cols;
|
||||
}
|
||||
|
||||
int exec_context_apply_tty_size(
|
||||
const ExecContext *context,
|
||||
int tty_fd,
|
||||
const char *tty_path) {
|
||||
|
||||
unsigned rows, cols;
|
||||
|
||||
exec_context_determine_tty_size(context, tty_path, &rows, &cols);
|
||||
|
||||
return terminal_set_size_fd(tty_fd, tty_path, rows, cols);
|
||||
/* If we got nothing so far and we are talking to a physical device, and the TTY reset logic is on,
|
||||
* then let's query dimensions from the ANSI driver. */
|
||||
if (rows == UINT_MAX && cols == UINT_MAX &&
|
||||
context->tty_reset &&
|
||||
terminal_is_pty_fd(output_fd) == 0 &&
|
||||
isatty_safe(input_fd)) {
|
||||
r = terminal_get_size_by_dsr(input_fd, output_fd, &rows, &cols);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to get terminal size by DSR, ignoring: %m");
|
||||
}
|
||||
|
||||
return terminal_set_size_fd(output_fd, tty_path, rows, cols);
|
||||
}
|
||||
|
||||
void exec_context_tty_reset(const ExecContext *context, const ExecParameters *p) {
|
||||
_cleanup_close_ int _fd = -EBADF, lock_fd = -EBADF;
|
||||
int fd;
|
||||
int fd, r;
|
||||
|
||||
assert(context);
|
||||
|
||||
/* Note that this is potentially a "destructive" reset of a TTY device. It's about getting rid of the
|
||||
* remains of previous uses of the TTY. It's *not* about getting things set up for coming uses. We'll
|
||||
* potentially invalidate the TTY here through hangups or VT disallocations, and hence do not keep a
|
||||
* continous fd open. */
|
||||
|
||||
const char *path = exec_context_tty_path(context);
|
||||
|
||||
if (p && p->stdin_fd >= 0 && isatty_safe(p->stdin_fd))
|
||||
fd = p->stdin_fd;
|
||||
if (p && p->stdout_fd >= 0 && isatty_safe(p->stdout_fd))
|
||||
fd = p->stdout_fd;
|
||||
else if (path && (context->tty_path || is_terminal_input(context->std_input) ||
|
||||
is_terminal_output(context->std_output) || is_terminal_output(context->std_error))) {
|
||||
fd = _fd = open_terminal(path, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
|
||||
@ -168,13 +176,19 @@ void exec_context_tty_reset(const ExecContext *context, const ExecParameters *p)
|
||||
else if (lock_fd < 0)
|
||||
log_warning_errno(lock_fd, "Failed to lock /dev/console, proceeding without lock: %m");
|
||||
|
||||
if (context->tty_reset)
|
||||
(void) terminal_reset_defensive(fd, /* switch_to_text= */ true);
|
||||
|
||||
r = exec_context_apply_tty_size(context, fd, fd, path);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to configure TTY dimensions, ignoring: %m");
|
||||
|
||||
if (context->tty_vhangup)
|
||||
(void) terminal_vhangup_fd(fd);
|
||||
|
||||
if (context->tty_reset)
|
||||
(void) reset_terminal_fd(fd, /* switch_to_text= */ true);
|
||||
|
||||
(void) exec_context_apply_tty_size(context, fd, path);
|
||||
/* We don't need the fd anymore now, and it potentially points to a hungup TTY anyway, let's close it
|
||||
* hence. */
|
||||
_fd = safe_close(_fd);
|
||||
|
||||
if (context->tty_vt_disallocate && path)
|
||||
(void) vt_disallocate(path);
|
||||
|
@ -526,7 +526,7 @@ int exec_context_get_clean_directories(ExecContext *c, char **prefix, ExecCleanM
|
||||
int exec_context_get_clean_mask(ExecContext *c, ExecCleanMask *ret);
|
||||
|
||||
const char* exec_context_tty_path(const ExecContext *context);
|
||||
int exec_context_apply_tty_size(const ExecContext *context, int tty_fd, const char *tty_path);
|
||||
int exec_context_apply_tty_size(const ExecContext *context, int input_fd, int output_fd, const char *tty_path);
|
||||
void exec_context_tty_reset(const ExecContext *context, const ExecParameters *p);
|
||||
|
||||
uint64_t exec_context_get_rlimit(const ExecContext *c, const char *name);
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "sd-messages.h"
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "ansi-color.h"
|
||||
#include "async.h"
|
||||
#include "cgroup.h"
|
||||
#include "dbus-job.h"
|
||||
|
@ -204,33 +204,58 @@ static int manager_find_user_config_paths(char ***ret_files, char ***ret_dirs) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int console_setup(void) {
|
||||
_cleanup_close_ int tty_fd = -EBADF;
|
||||
unsigned rows, cols;
|
||||
static int save_console_winsize_in_environment(int tty_fd) {
|
||||
int r;
|
||||
|
||||
tty_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
|
||||
assert(tty_fd >= 0);
|
||||
|
||||
struct winsize ws = {};
|
||||
if (ioctl(tty_fd, TIOCGWINSZ, &ws) < 0) {
|
||||
log_debug_errno(errno, "Failed to acquire console window size, ignoring.");
|
||||
goto unset;
|
||||
}
|
||||
|
||||
if (ws.ws_col <= 0 && ws.ws_row <= 0) {
|
||||
log_debug("No console window size set, ignoring.");
|
||||
goto unset;
|
||||
}
|
||||
|
||||
r = setenvf("COLUMNS", /* overwrite= */ true, "%u", ws.ws_col);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to set $COLUMNS, ignoring: %m");
|
||||
goto unset;
|
||||
}
|
||||
|
||||
r = setenvf("LINES", /* overwrite= */ true, "%u", ws.ws_row);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to set $LINES, ignoring: %m");
|
||||
goto unset;
|
||||
}
|
||||
|
||||
log_debug("Recorded console dimensions in environment: $COLUMNS=%u $LINES=%u.", ws.ws_col, ws.ws_row);
|
||||
return 1;
|
||||
|
||||
unset:
|
||||
(void) unsetenv("COLUMNS");
|
||||
(void) unsetenv("LINES");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int console_setup(void) {
|
||||
|
||||
if (getpid_cached() != 1)
|
||||
return 0;
|
||||
|
||||
_cleanup_close_ int tty_fd = -EBADF;
|
||||
|
||||
tty_fd = open_terminal("/dev/console", O_RDWR|O_NOCTTY|O_CLOEXEC);
|
||||
if (tty_fd < 0)
|
||||
return log_error_errno(tty_fd, "Failed to open /dev/console: %m");
|
||||
|
||||
/* We don't want to force text mode. plymouth may be showing
|
||||
* pictures already from initrd. */
|
||||
r = reset_terminal_fd(tty_fd, false);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to reset /dev/console: %m");
|
||||
/* We don't want to force text mode. Plymouth may be showing pictures already from initrd. */
|
||||
reset_dev_console_fd(tty_fd, /* switch_to_text= */ false);
|
||||
|
||||
r = proc_cmdline_tty_size("/dev/console", &rows, &cols);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to get /dev/console size, ignoring: %m");
|
||||
else {
|
||||
r = terminal_set_size_fd(tty_fd, NULL, rows, cols);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to set /dev/console size, ignoring: %m");
|
||||
}
|
||||
|
||||
r = terminal_reset_ansi_seq(tty_fd);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to reset /dev/console using ANSI sequences, ignoring: %m");
|
||||
save_console_winsize_in_environment(tty_fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2910,7 +2935,7 @@ static void setup_console_terminal(bool skip_setup) {
|
||||
(void) release_terminal();
|
||||
|
||||
/* Reset the console, but only if this is really init and we are freshly booted */
|
||||
if (getpid_cached() == 1 && !skip_setup)
|
||||
if (!skip_setup)
|
||||
(void) console_setup();
|
||||
}
|
||||
|
||||
|
@ -72,8 +72,14 @@ int status_vprintf(const char *status, ShowStatusFlags flags, const char *format
|
||||
int c;
|
||||
|
||||
c = fd_columns(fd);
|
||||
if (c <= 0) {
|
||||
const char *env = getenv("COLUMNS");
|
||||
if (env)
|
||||
(void) safe_atoi(env, &c);
|
||||
|
||||
if (c <= 0)
|
||||
c = 80;
|
||||
}
|
||||
|
||||
sl = status ? strlen(status_indent) : 0;
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "ansi-color.h"
|
||||
#include "bus-common-errors.h"
|
||||
#include "bus-error.h"
|
||||
#include "dbus-unit.h"
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "all-units.h"
|
||||
#include "alloc-util.h"
|
||||
#include "ansi-color.h"
|
||||
#include "bpf-firewall.h"
|
||||
#include "bpf-foreign.h"
|
||||
#include "bpf-socket-bind.h"
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "ansi-color.h"
|
||||
#include "cryptenroll-recovery.h"
|
||||
#include "glyph-util.h"
|
||||
#include "json-util.h"
|
||||
|
@ -133,7 +133,7 @@ static void print_welcome(int rfd) {
|
||||
pn = os_release_pretty_name(pretty_name, os_name);
|
||||
ac = isempty(ansi_color) ? "0" : ansi_color;
|
||||
|
||||
(void) reset_terminal_fd(STDIN_FILENO, /* switch_to_text= */ false);
|
||||
(void) terminal_reset_defensive_locked(STDOUT_FILENO, /* switch_to_text= */ false);
|
||||
|
||||
if (colors_enabled())
|
||||
printf("\nWelcome to your new installation of \x1B[%sm%s\x1B[0m!\n", ac, pn);
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "ansi-color.h"
|
||||
#include "errno-util.h"
|
||||
#include "glyph-util.h"
|
||||
#include "homectl-recovery-key.h"
|
||||
|
@ -2438,7 +2438,7 @@ static int create_interactively(void) {
|
||||
|
||||
(void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
|
||||
|
||||
(void) reset_terminal_fd(STDIN_FILENO, /* switch_to_text= */ false);
|
||||
(void) terminal_reset_defensive_locked(STDOUT_FILENO, /* switch_to_text= */ false);
|
||||
|
||||
for (;;) {
|
||||
username = mfree(username);
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "sd-id128.h"
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "ansi-color.h"
|
||||
#include "build.h"
|
||||
#include "discover-image.h"
|
||||
#include "export-raw.h"
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <locale.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "ansi-color.h"
|
||||
#include "build.h"
|
||||
#include "btrfs-util.h"
|
||||
#include "discover-image.h"
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "sd-id128.h"
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "ansi-color.h"
|
||||
#include "build.h"
|
||||
#include "discover-image.h"
|
||||
#include "env-util.h"
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "sd-id128.h"
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "ansi-color.h"
|
||||
#include "build.h"
|
||||
#include "discover-image.h"
|
||||
#include "env-util.h"
|
||||
|
@ -185,7 +185,7 @@ static int display_emergency_message_fullscreen(const char *message) {
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to clear terminal, ignoring: %m");
|
||||
|
||||
r = set_terminal_cursor_position(fd, 2, 4);
|
||||
r = terminal_set_cursor_position(fd, 2, 4);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to move terminal cursor position, ignoring: %m");
|
||||
|
||||
@ -197,7 +197,7 @@ static int display_emergency_message_fullscreen(const char *message) {
|
||||
|
||||
qr_code_start_row = w.ws_row * 3U / 5U;
|
||||
qr_code_start_column = w.ws_col * 3U / 4U;
|
||||
r = set_terminal_cursor_position(fd, 4, 4);
|
||||
r = terminal_set_cursor_position(fd, 4, 4);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to move terminal cursor position, ignoring: %m");
|
||||
|
||||
@ -217,7 +217,7 @@ static int display_emergency_message_fullscreen(const char *message) {
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "QR code could not be printed, ignoring: %m");
|
||||
|
||||
r = set_terminal_cursor_position(fd, w.ws_row - 1, w.ws_col * 2U / 5U);
|
||||
r = terminal_set_cursor_position(fd, w.ws_row - 1, w.ws_col * 2U / 5U);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to move terminal cursor position, ignoring: %m");
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "ansi-color.h"
|
||||
#include "chattr-util.h"
|
||||
#include "errno-util.h"
|
||||
#include "fd-util.h"
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "sd-event.h"
|
||||
|
||||
#include "ansi-color.h"
|
||||
#include "fileio.h"
|
||||
#include "journalctl.h"
|
||||
#include "journalctl-filter.h"
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "ansi-color.h"
|
||||
#include "bus-dump.h"
|
||||
#include "bus-internal.h"
|
||||
#include "bus-message.h"
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "ansi-color.h"
|
||||
#include "compress.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "ansi-color.h"
|
||||
#include "chattr-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "iovec-util.h"
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "sd-messages.h"
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "ansi-color.h"
|
||||
#include "errno-util.h"
|
||||
#include "escape.h"
|
||||
#include "ether-addr-util.h"
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "sd-varlink-idl.h"
|
||||
|
||||
#include "ansi-color.h"
|
||||
#include "json-util.h"
|
||||
#include "memstream-util.h"
|
||||
#include "set.h"
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "ansi-color.h"
|
||||
#include "ask-password-api.h"
|
||||
#include "creds-util.h"
|
||||
#include "fd-util.h"
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "sd-device.h"
|
||||
|
||||
#include "ansi-color.h"
|
||||
#include "blockdev-list.h"
|
||||
#include "blockdev-util.h"
|
||||
#include "device-util.h"
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "ansi-color.h"
|
||||
#include "bus-locator.h"
|
||||
#include "bus-unit-procs.h"
|
||||
#include "glyph-util.h"
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "ansi-color.h"
|
||||
#include "bus-error.h"
|
||||
#include "bus-util.h"
|
||||
#include "cgroup-show.h"
|
||||
|
@ -18,23 +18,6 @@
|
||||
#include "umask-util.h"
|
||||
#include "user-util.h"
|
||||
|
||||
int lock_dev_console(void) {
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
int r;
|
||||
|
||||
/* NB: We do not use O_NOFOLLOW here, because some container managers might place a symlink to some
|
||||
* pty in /dev/console, in which case it should be fine to lock the target TTY. */
|
||||
fd = open_terminal("/dev/console", O_RDONLY|O_CLOEXEC|O_NOCTTY);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
r = lock_generic(fd, LOCK_BSD, LOCK_EX);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return TAKE_FD(fd);
|
||||
}
|
||||
|
||||
int dev_setup(const char *prefix, uid_t uid, gid_t gid) {
|
||||
static const char symlinks[] =
|
||||
"-/proc/kcore\0" "/dev/core\0"
|
||||
|
@ -3,8 +3,6 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
int lock_dev_console(void);
|
||||
|
||||
int dev_setup(const char *prefix, uid_t uid, gid_t gid);
|
||||
|
||||
int make_inaccessible_nodes(const char *parent_dir, uid_t uid, gid_t gid);
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include "ansi-color.h"
|
||||
#include "glyph-util.h"
|
||||
#include "terminal-util.h"
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "sd-event.h"
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "ansi-color.h"
|
||||
#include "env-util.h"
|
||||
#include "errno-util.h"
|
||||
#include "extract-word.h"
|
||||
|
@ -5,6 +5,7 @@
|
||||
#if HAVE_QRENCODE
|
||||
#include <qrencode.h>
|
||||
|
||||
#include "ansi-color.h"
|
||||
#include "dlfcn-util.h"
|
||||
#include "locale-util.h"
|
||||
#include "log.h"
|
||||
@ -52,7 +53,7 @@ static void print_border(FILE *output, unsigned width, unsigned row, unsigned co
|
||||
if (fd < 0)
|
||||
return (void)log_debug_errno(errno, "Failed to get file descriptor from the file stream: %m");
|
||||
|
||||
r = set_terminal_cursor_position(fd, row, column);
|
||||
r = terminal_set_cursor_position(fd, row, column);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to move terminal cursor position, ignoring: %m");
|
||||
|
||||
@ -64,7 +65,7 @@ static void print_border(FILE *output, unsigned width, unsigned row, unsigned co
|
||||
fputs(UNICODE_FULL_BLOCK, output);
|
||||
|
||||
fputs(ANSI_NORMAL "\n", output);
|
||||
r = set_terminal_cursor_position(fd, row + 1, column);
|
||||
r = terminal_set_cursor_position(fd, row + 1, column);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to move terminal cursor position, ignoring: %m");
|
||||
}
|
||||
@ -96,7 +97,7 @@ static void write_qrcode(FILE *output, QRcode *qr, unsigned int row, unsigned in
|
||||
if (fd < 0)
|
||||
return (void)log_debug_errno(errno, "Failed to get file descriptor from the file stream: %m");
|
||||
|
||||
r = set_terminal_cursor_position(fd, row + move_down, column);
|
||||
r = terminal_set_cursor_position(fd, row + move_down, column);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to move terminal cursor position, ignoring: %m");
|
||||
|
||||
@ -127,7 +128,7 @@ static void write_qrcode(FILE *output, QRcode *qr, unsigned int row, unsigned in
|
||||
|
||||
for (unsigned x = 0; x < 4; x++)
|
||||
fputs(UNICODE_FULL_BLOCK, output);
|
||||
r = set_terminal_cursor_position(fd, row + move_down, column);
|
||||
r = terminal_set_cursor_position(fd, row + move_down, column);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to move terminal cursor position, ignoring: %m");
|
||||
move_down += 1;
|
||||
@ -206,7 +207,7 @@ int print_qrcode_full(FILE *out, const char *header, const char *string, unsigne
|
||||
row = tty_height - (qr_code_height / 2 ) - 1;
|
||||
|
||||
if (header) {
|
||||
r = set_terminal_cursor_position(fd, row - 2, tty_width - qr_code_width - 2);
|
||||
r = terminal_set_cursor_position(fd, row - 2, tty_width - qr_code_width - 2);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to move terminal cursor position, ignoring: %m");
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "ansi-color.h"
|
||||
#include "locale-util.h"
|
||||
#include "sort-util.h"
|
||||
#include "special.h"
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "ansi-color.h"
|
||||
#include "bus-error.h"
|
||||
#include "bus-locator.h"
|
||||
#include "locale-util.h"
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "sd-login.h"
|
||||
|
||||
#include "ansi-color.h"
|
||||
#include "bus-map-properties.h"
|
||||
#include "hostname-util.h"
|
||||
#include "locale-util.h"
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "ansi-color.h"
|
||||
#include "bus-error.h"
|
||||
#include "bus-locator.h"
|
||||
#include "sort-util.h"
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "sd-login.h"
|
||||
|
||||
#include "ansi-color.h"
|
||||
#include "bus-error.h"
|
||||
#include "bus-locator.h"
|
||||
#include "format-table.h"
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "sd-bus.h"
|
||||
|
||||
#include "ansi-color.h"
|
||||
#include "bus-common-errors.h"
|
||||
#include "bus-error.h"
|
||||
#include "bus-locator.h"
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "ansi-color.h"
|
||||
#include "glyph-util.h"
|
||||
#include "sysupdate-update-set-flags.h"
|
||||
#include "terminal-util.h"
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "ansi-color.h"
|
||||
#include "alloc-util.h"
|
||||
#include "string-util.h"
|
||||
#include "sysupdate-update-set.h"
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "ansi-color.h"
|
||||
#include "constants.h"
|
||||
#include "escape.h"
|
||||
#include "string-util.h"
|
||||
|
@ -3,10 +3,13 @@
|
||||
#include <fcntl.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "ansi-color.h"
|
||||
#include "fd-util.h"
|
||||
#include "fs-util.h"
|
||||
#include "macro.h"
|
||||
@ -176,6 +179,77 @@ TEST(get_default_background_color) {
|
||||
log_notice("R=%g G=%g B=%g", red, green, blue);
|
||||
}
|
||||
|
||||
TEST(terminal_get_size_by_dsr) {
|
||||
unsigned rows, columns;
|
||||
int r;
|
||||
|
||||
r = terminal_get_size_by_dsr(STDIN_FILENO, STDOUT_FILENO, &rows, &columns);
|
||||
if (r < 0)
|
||||
log_notice_errno(r, "Can't get screen dimensions via DSR: %m");
|
||||
else {
|
||||
log_notice("terminal size via DSR: rows=%u columns=%u", rows, columns);
|
||||
|
||||
struct winsize ws = {};
|
||||
|
||||
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) < 0)
|
||||
log_warning_errno(errno, "Can't get terminal size via ioctl, ignoring: %m");
|
||||
else
|
||||
log_notice("terminal size via ioctl: rows=%u columns=%u", ws.ws_row, ws.ws_col);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(terminal_fix_size) {
|
||||
int r;
|
||||
|
||||
r = terminal_fix_size(STDIN_FILENO, STDOUT_FILENO);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to fix terminal size: %m");
|
||||
else if (r == 0)
|
||||
log_notice("Not fixing terminal size, nothing to do.");
|
||||
else
|
||||
log_notice("Fixed terminal size.");
|
||||
}
|
||||
|
||||
TEST(terminal_is_pty_fd) {
|
||||
_cleanup_close_ int fd1 = -EBADF, fd2 = -EBADF;
|
||||
_cleanup_free_ char *peer = NULL;
|
||||
int r;
|
||||
|
||||
fd1 = openpt_allocate(O_RDWR, &peer);
|
||||
assert_se(fd1 >= 0);
|
||||
assert_se(terminal_is_pty_fd(fd1) > 0);
|
||||
|
||||
fd2 = open_terminal(peer, O_RDWR|O_CLOEXEC|O_NOCTTY);
|
||||
assert_se(fd2 >= 0);
|
||||
assert_se(terminal_is_pty_fd(fd2) > 0);
|
||||
|
||||
fd1 = safe_close(fd1);
|
||||
fd2 = safe_close(fd2);
|
||||
|
||||
fd1 = open("/dev/null", O_RDONLY|O_CLOEXEC);
|
||||
assert_se(fd1 >= 0);
|
||||
assert_se(terminal_is_pty_fd(fd1) == 0);
|
||||
|
||||
/* In container managers real tty devices might be weird, avoid them. */
|
||||
r = path_is_read_only_fs("/sys");
|
||||
if (r != 0)
|
||||
return;
|
||||
|
||||
FOREACH_STRING(p, "/dev/ttyS0", "/dev/tty1") {
|
||||
_cleanup_close_ int tfd = -EBADF;
|
||||
|
||||
tfd = open_terminal(p, O_CLOEXEC|O_NOCTTY|O_RDONLY|O_NONBLOCK);
|
||||
if (tfd == -ENOENT)
|
||||
continue;
|
||||
if (tfd < 0) {
|
||||
log_notice_errno(tfd, "Failed to open '%s', skipping: %m", p);
|
||||
continue;
|
||||
}
|
||||
|
||||
assert_se(terminal_is_pty_fd(tfd) <= 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_get_color_mode_with_env(const char *key, const char *val, ColorMode expected) {
|
||||
ASSERT_OK(setenv(key, val, true));
|
||||
reset_terminal_feature_caches();
|
||||
@ -209,4 +283,12 @@ TEST(get_color_mode) {
|
||||
reset_terminal_feature_caches();
|
||||
}
|
||||
|
||||
TEST(terminal_reset_defensive) {
|
||||
int r;
|
||||
|
||||
r = terminal_reset_defensive(STDOUT_FILENO, /* switch_to_text= */ false);
|
||||
if (r < 0)
|
||||
log_notice_errno(r, "Failed to reset terminal: %m");
|
||||
}
|
||||
|
||||
DEFINE_TEST_MAIN(LOG_INFO);
|
||||
|
@ -150,9 +150,7 @@ static int agent_ask_password_tty(
|
||||
if (tty_fd < 0)
|
||||
return log_error_errno(tty_fd, "Failed to acquire %s: %m", con);
|
||||
|
||||
r = reset_terminal_fd(tty_fd, true);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to reset terminal, ignoring: %m");
|
||||
(void) terminal_reset_defensive_locked(tty_fd, /* switch_to_text= */ true);
|
||||
|
||||
log_info("Starting password query on %s.", con);
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "sd-json.h"
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "ansi-color.h"
|
||||
#include "device-enumerator-private.h"
|
||||
#include "device-private.h"
|
||||
#include "device-util.h"
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include "sd-device.h"
|
||||
|
||||
#include "ansi-color.h"
|
||||
#include "device-private.h"
|
||||
#include "device-util.h"
|
||||
#include "format-util.h"
|
||||
|
@ -20,9 +20,10 @@ Before=getty.target
|
||||
ConditionPathExists=/dev/console
|
||||
|
||||
[Service]
|
||||
# The '-o' option value tells agetty to replace 'login' arguments with an option to preserve environment (-p),
|
||||
# followed by '--' for safety, and then the entered username.
|
||||
ExecStart=-/sbin/agetty -o '-p -- \\u' --noclear --keep-baud - 115200,38400,9600 $TERM
|
||||
# The '-o' option value tells agetty to replace 'login' arguments with an
|
||||
# option to preserve environment (-p), followed by '--' for safety, and then
|
||||
# the entered username.
|
||||
ExecStart=-/sbin/agetty -o '-p -- \\u' --noreset --noclear --keep-baud 115200,57600,38400,9600 - ${TERM}
|
||||
Type=idle
|
||||
Restart=always
|
||||
UtmpIdentifier=cons
|
||||
|
@ -25,9 +25,10 @@ Conflicts=rescue.service
|
||||
Before=rescue.service
|
||||
|
||||
[Service]
|
||||
# The '-o' option value tells agetty to replace 'login' arguments with an option to preserve environment (-p),
|
||||
# followed by '--' for safety, and then the entered username.
|
||||
ExecStart=-/sbin/agetty -o '-p -- \\u' --noclear - $TERM
|
||||
# The '-o' option value tells agetty to replace 'login' arguments with an
|
||||
# option to preserve environment (-p), followed by '--' for safety, and then
|
||||
# the entered username.
|
||||
ExecStart=-/sbin/agetty -o '-p -- \\u' --noreset --noclear - ${TERM}
|
||||
Type=idle
|
||||
Restart=always
|
||||
RestartSec=0
|
||||
|
@ -34,11 +34,10 @@ Before=rescue.service
|
||||
ConditionPathExists=/dev/tty0
|
||||
|
||||
[Service]
|
||||
# the VT is cleared by TTYVTDisallocate
|
||||
# The '-o' option value tells agetty to replace 'login' arguments with an
|
||||
# option to preserve environment (-p), followed by '--' for safety, and then
|
||||
# the entered username.
|
||||
ExecStart=-/sbin/agetty -o '-p -- \\u' --noclear - $TERM
|
||||
ExecStart=-/sbin/agetty -o '-p -- \\u' --noreset --noclear - ${TERM}
|
||||
Type=idle
|
||||
Restart=always
|
||||
RestartSec=0
|
||||
|
@ -33,7 +33,7 @@ Before=rescue.service
|
||||
# The '-o' option value tells agetty to replace 'login' arguments with an
|
||||
# option to preserve environment (-p), followed by '--' for safety, and then
|
||||
# the entered username.
|
||||
ExecStart=-/sbin/agetty -o '-p -- \\u' --keep-baud 115200,57600,38400,9600 - $TERM
|
||||
ExecStart=-/sbin/agetty -o '-p -- \\u' --noreset --noclear --keep-baud 115200,57600,38400,9600 - ${TERM}
|
||||
Type=idle
|
||||
Restart=always
|
||||
UtmpIdentifier=%I
|
||||
|
Loading…
Reference in New Issue
Block a user