Therefore strip off the ANSI escape sequences for 3215 consoles but support 3270 consoles if found.
--- src/core/manager.c | 24 ++++++++++++---- src/shared/util.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++--- src/shared/util.h | 1 + 3 files changed, 96 insertions(+), 9 deletions(-) diff --git src/core/manager.c src/core/manager.c index 0cb2044..f78ac18 100644 --- src/core/manager.c +++ src/core/manager.c @@ -112,7 +112,7 @@ static int manager_watch_jobs_in_progress(Manager *m) { #define CYLON_BUFFER_EXTRA (2*(sizeof(ANSI_RED_ON)-1) + sizeof(ANSI_HIGHLIGHT_RED_ON)-1 + 2*(sizeof(ANSI_HIGHLIGHT_OFF)-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); @@ -121,12 +121,14 @@ static void draw_cylon(char buffer[], size_t buflen, unsigned width, unsigned po if (pos > 1) { if (pos > 2) p = mempset(p, ' ', pos-2); - p = stpcpy(p, ANSI_RED_ON); + if (ansi_console) + p = stpcpy(p, ANSI_RED_ON); *p++ = '*'; } if (pos > 0 && pos <= width) { - p = stpcpy(p, ANSI_HIGHLIGHT_RED_ON); + if (ansi_console) + p = stpcpy(p, ANSI_HIGHLIGHT_RED_ON); *p++ = '*'; } @@ -137,7 +139,8 @@ static void draw_cylon(char buffer[], size_t buflen, unsigned width, unsigned po *p++ = '*'; if (pos < width-1) p = mempset(p, ' ', width-1-pos); - strcpy(p, ANSI_HIGHLIGHT_OFF); + if (ansi_console) + strcpy(p, ANSI_HIGHLIGHT_OFF); } } @@ -154,6 +157,7 @@ void manager_flip_auto_status(Manager *m, bool enable) { } 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; @@ -178,10 +182,20 @@ static void manager_print_jobs_in_progress(Manager *m) { 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++; diff --git src/shared/util.c src/shared/util.c index a7aec5c..03b01de 100644 --- src/shared/util.c +++ src/shared/util.c @@ -2937,6 +2937,7 @@ int status_vprintf(const char *status, bool ellipse, bool ephemeral, const char struct iovec iovec[6] = {}; int n = 0; static bool prev_ephemeral; + static int is_ansi_console = -1; assert(format); @@ -2950,6 +2951,41 @@ int status_vprintf(const char *status, bool ellipse, bool ephemeral, const char if (fd < 0) return fd; + if (_unlikely_(is_ansi_console < 0)) + is_ansi_console = (int)ansi_console(fd); + + if (status && !is_ansi_console) { + const char *esc, *ptr; + esc = strchr(status, 0x1B); + if (esc && (ptr = strpbrk(esc, "SOFDTI*"))) { + switch(*ptr) { + case 'S': + status = " SKIP "; + break; + case 'O': + status = " OK "; + break; + case 'F': + status = "FAILED"; + break; + case 'D': + status = "DEPEND"; + break; + case 'T': + status = " TIME "; + break; + case 'I': + status = " INFO "; + break; + case '*': + status = " BUSY "; + break; + default: + break; + } + } + } + if (ellipse) { char *e; size_t emax, sl; @@ -2972,8 +3008,12 @@ int status_vprintf(const char *status, bool ellipse, bool ephemeral, const char } } - if (prev_ephemeral) - IOVEC_SET_STRING(iovec[n++], "\r" ANSI_ERASE_TO_END_OF_LINE); + if (prev_ephemeral) { + if (is_ansi_console) + IOVEC_SET_STRING(iovec[n++], "\r" ANSI_ERASE_TO_END_OF_LINE); + else + IOVEC_SET_STRING(iovec[n++], "\r"); + } prev_ephemeral = ephemeral; if (status) { @@ -3220,8 +3260,22 @@ void columns_lines_cache_reset(int signum) { 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; } @@ -3711,7 +3765,25 @@ bool tty_is_vc_resolve(const char *tty) { const char *default_term_for_tty(const char *tty) { assert(tty); - return tty_is_vc_resolve(tty) ? "TERM=linux" : "TERM=vt102"; + if (tty_is_vc_resolve(tty)) + return "TERM=linux"; + + if (startswith(tty, "/dev/")) + tty += 5; + +#if defined (__s390__) || defined (__s390x__) + if (streq(tty, "ttyS0")) { + char *mode = NULL; + int r = parse_env_file("/proc/cmdline", WHITESPACE, "conmode", &mode, NULL); + if (r < 0 || !mode || !streq(mode, "3270")) + return "TERM=dumb"; + if (streq(mode, "3270")) + return "TERM=ibm327x"; + } + if (streq(tty, "ttyS1")) + return "TERM=vt220"; +#endif + return "TERM=vt102"; } bool dirent_is_file(const struct dirent *de) { diff --git src/shared/util.h src/shared/util.h index 1796014..2dc918d 100644 --- src/shared/util.h +++ src/shared/util.h @@ -446,6 +446,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_highlight(void) { return on_tty() ? ANSI_HIGHLIGHT_ON : ""; -- 1.7.9.2 _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel