--- rules/99-systemd.rules.in | 2 - src/basic/terminal-util.c | 55 ++++++++++++++++++++++++++++++++++++++++++++-- src/basic/terminal-util.h | 1 src/core/manager.c | 24 +++++++++++++++----- 4 files changed, 74 insertions(+), 8 deletions(-) Index: systemd-228/rules/99-systemd.rules.in =================================================================== --- systemd-228.orig/rules/99-systemd.rules.in +++ systemd-228/rules/99-systemd.rules.in @@ -7,7 +7,7 @@ ACTION=="remove", GOTO="systemd_end" -SUBSYSTEM=="tty", KERNEL=="tty[a-zA-Z]*|hvc*|xvc*|hvsi*|ttysclp*|sclp_line*|3270/tty[0-9]*", TAG+="systemd" +SUBSYSTEM=="tty", KERNEL=="tty[a-zA-Z]*|hvc*|xvc*|hvsi*|ttysclp*|sclp_line*|3270/tty*", TAG+="systemd" KERNEL=="vport*", TAG+="systemd" SUBSYSTEM=="block", TAG+="systemd" Index: systemd-228/src/basic/terminal-util.c =================================================================== --- systemd-228.orig/src/basic/terminal-util.c +++ systemd-228/src/basic/terminal-util.c @@ -717,10 +717,47 @@ bool tty_is_vc_resolve(const char *tty) return tty_is_vc(tty); } +bool ansi_console(int fd) { + static int cached_ansi_console = -1; + + if (_likely_(cached_ansi_console >= 0)) + return cached_ansi_console; + + cached_ansi_console = isatty(fd) > 0; +#if defined(__s390__) || defined(__s390x__) + if (cached_ansi_console) { + const char *e = getenv("TERM"); + if (e != NULL && (streq(e, "dumb") || strneq(e, "ibm3", 4))) { + _cleanup_free_ char *mode = NULL; + int r = parse_env_file("/proc/cmdline", WHITESPACE, + "conmode", &mode, NULL); + if (r < 0 || mode == NULL || !streq(mode, "3270")) + cached_ansi_console = 0; + } + } +#endif + return cached_ansi_console; +} + const char *default_term_for_tty(const char *tty) { assert(tty); - return tty_is_vc_resolve(tty) ? "TERM=linux" : "TERM=vt220"; + if (tty_is_vc_resolve(tty)) + return "TERM=linux"; + if (startswith(tty, "/dev/")) + tty += 5; +#if defined (__s390__) || defined (__s390x__) + if (streq(tty, "ttyS0")) { + _cleanup_free_ char *mode = NULL; + int r = parse_env_file("/proc/cmdline", WHITESPACE, "conmode", + &mode, NULL); + if (r < 0 || mode == NULL || !streq(mode, "3270")) + return "TERM=dumb"; + if (streq(mode, "3270")) + return "TERM=ibm327x"; + } +#endif + return "TERM=vt220"; } int fd_columns(int fd) { @@ -800,8 +837,22 @@ void columns_lines_cache_reset(int signu bool on_tty(void) { static int cached_on_tty = -1; - if (_unlikely_(cached_on_tty < 0)) + if (_unlikely_(cached_on_tty < 0)) { cached_on_tty = isatty(STDOUT_FILENO) > 0; +#if defined (__s390__) || defined (__s390x__) + if (cached_on_tty) { + const char *e = getenv("TERM"); + if (!e) + return cached_on_tty; + if (streq(e, "dumb") || strneq(e, "ibm3", 4)) { + char *mode = NULL; + int r = parse_env_file("/proc/cmdline", WHITESPACE, "conmode", &mode, NULL); + if (r < 0 || !mode || !streq(mode, "3270")) + cached_on_tty = 0; + } + } +#endif + } return cached_on_tty; } Index: systemd-228/src/basic/terminal-util.h =================================================================== --- systemd-228.orig/src/basic/terminal-util.h +++ systemd-228/src/basic/terminal-util.h @@ -78,6 +78,7 @@ unsigned lines(void); void columns_lines_cache_reset(int _unused_ signum); bool on_tty(void); +bool ansi_console(int fd); static inline const char *ansi_underline(void) { return on_tty() ? ANSI_UNDERLINE : ""; Index: systemd-228/src/core/manager.c =================================================================== --- systemd-228.orig/src/core/manager.c +++ systemd-228/src/core/manager.c @@ -126,7 +126,7 @@ static void manager_watch_jobs_in_progre #define CYLON_BUFFER_EXTRA (2*(sizeof(ANSI_RED)-1) + sizeof(ANSI_HIGHLIGHT_RED)-1 + 2*(sizeof(ANSI_NORMAL)-1)) -static void draw_cylon(char buffer[], size_t buflen, unsigned width, unsigned pos) { +static void draw_cylon(char buffer[], size_t buflen, unsigned width, unsigned pos, bool ansi_console) { char *p = buffer; assert(buflen >= CYLON_BUFFER_EXTRA + width + 1); @@ -135,12 +135,14 @@ static void draw_cylon(char buffer[], si if (pos > 1) { if (pos > 2) p = mempset(p, ' ', pos-2); - p = stpcpy(p, ANSI_RED); + if (ansi_console) + p = stpcpy(p, ANSI_RED); *p++ = '*'; } if (pos > 0 && pos <= width) { - p = stpcpy(p, ANSI_HIGHLIGHT_RED); + if (ansi_console) + p = stpcpy(p, ANSI_HIGHLIGHT_RED); *p++ = '*'; } @@ -151,7 +153,8 @@ static void draw_cylon(char buffer[], si *p++ = '*'; if (pos < width-1) p = mempset(p, ' ', width-1-pos); - strcpy(p, ANSI_NORMAL); + if (ansi_console) + strcpy(p, ANSI_NORMAL); } } @@ -168,6 +171,7 @@ void manager_flip_auto_status(Manager *m } static void manager_print_jobs_in_progress(Manager *m) { + static int is_ansi_console = -1; _cleanup_free_ char *job_of_n = NULL; Iterator i; Job *j; @@ -193,10 +197,20 @@ static void manager_print_jobs_in_progre assert(counter == print_nr + 1); assert(j); + if (_unlikely_(is_ansi_console < 0)) { + int fd = open_terminal("/dev/console", O_RDONLY|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + is_ansi_console = 0; + else { + is_ansi_console = (int)ansi_console(fd); + close(fd); + } + } + cylon_pos = m->jobs_in_progress_iteration % 14; if (cylon_pos >= 8) cylon_pos = 14 - cylon_pos; - draw_cylon(cylon, sizeof(cylon), 6, cylon_pos); + draw_cylon(cylon, sizeof(cylon), 6, cylon_pos, (bool)is_ansi_console); m->jobs_in_progress_iteration++;