--- rules/99-systemd.rules.in | 2 - src/core/manager.c | 24 +++++++++++--- src/shared/util.c | 77 ++++++++++++++++++++++++++++++++++++++++++++-- src/shared/util.h | 1 4 files changed, 95 insertions(+), 9 deletions(-) --- systemd-208/rules/99-systemd.rules.in +++ systemd-208/rules/99-systemd.rules.in 2014-02-05 10:34:17.346235540 +0000 @@ -7,7 +7,7 @@ ACTION=="remove", GOTO="systemd_end" -SUBSYSTEM=="tty", KERNEL=="tty[a-zA-Z]*|hvc*|xvc*|hvsi*|ttysclp*|sclp_line*", TAG+="systemd" +SUBSYSTEM=="tty", KERNEL=="tty[a-zA-Z]*|hvc*|xvc*|hvsi*|ttysclp*|sclp_line*|3270/tty*", TAG+="systemd" KERNEL=="vport*", TAG+="systemd" --- systemd-210/src/core/manager.c +++ systemd-210/src/core/manager.c 2014-04-30 10:51:43.398735332 +0000 @@ -110,7 +110,7 @@ static int manager_watch_jobs_in_progres #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); @@ -119,12 +119,14 @@ static void draw_cylon(char buffer[], si 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++ = '*'; } @@ -135,7 +137,8 @@ static void draw_cylon(char buffer[], si *p++ = '*'; if (pos < width-1) p = mempset(p, ' ', width-1-pos); - strcpy(p, ANSI_HIGHLIGHT_OFF); + if (ansi_console) + strcpy(p, ANSI_HIGHLIGHT_OFF); } } @@ -150,6 +153,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; @@ -174,10 +178,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++; --- systemd-210/src/shared/util.c +++ systemd-210/src/shared/util.c 2014-04-30 10:39:17.154736438 +0000 @@ -2886,6 +2886,7 @@ int status_vprintf(const char *status, b struct iovec iovec[6] = {}; int n = 0; static bool prev_ephemeral; + static int is_ansi_console = -1; assert(format); @@ -2899,6 +2900,41 @@ int status_vprintf(const char *status, b 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; @@ -2921,8 +2957,12 @@ int status_vprintf(const char *status, b } } - 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) { @@ -3169,12 +3209,43 @@ 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 (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; + } + } + } return cached_on_tty; } +bool ansi_console(int fd) { + static int cached_ansi_console = -1; + + if (_unlikely_(cached_ansi_console < 0)) { + cached_ansi_console = isatty(fd) > 0; + if (cached_ansi_console) { + const char *e = getenv("TERM"); + if (e && (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_ansi_console = 0; + } + } + } + + return cached_ansi_console; +} + int running_in_chroot(void) { struct stat a = {}, b = {}; --- systemd-210/src/shared/util.h +++ systemd-210/src/shared/util.h 2014-04-30 10:24:51.134235665 +0000 @@ -418,6 +418,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 : "";