From 81beb7508e72b29ae7cec60b50231cbe0c1d582e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 5 Jan 2012 03:24:39 +0100 Subject: [PATCH] util: when printing status updates during boot, take terminal width into account --- src/unit.c | 18 +----------- src/util.c | 85 ++++++++++++++++++++++++++++++++++++++++++++---------- src/util.h | 5 ++-- 3 files changed, 73 insertions(+), 35 deletions(-) diff --git a/src/unit.c b/src/unit.c index 03c90f58..dea8f4a7 100644 --- a/src/unit.c +++ b/src/unit.c @@ -2441,9 +2441,6 @@ int unit_coldplug(Unit *u) { void unit_status_printf(Unit *u, const char *status, const char *format, ...) { va_list ap; - char *s, *e; - int err; - const unsigned emax = status ? 80 - (sizeof("[ OK ]")-1) : 80; assert(u); assert(format); @@ -2458,21 +2455,8 @@ void unit_status_printf(Unit *u, const char *status, const char *format, ...) { return; va_start(ap, format); - err = vasprintf(&s, format, ap); + status_vprintf(status, format, ap); va_end(ap); - if (err < 0) - return; - - e = ellipsize(s, emax, 100); - free(s); - if (!e) - return; - - if (status) - status_printf("%s%*s[%s]\n", e, emax - strlen(e), "", status); - else - status_printf("%s\n", e); - free(e); } bool unit_need_daemon_reload(Unit *u) { diff --git a/src/util.c b/src/util.c index 8a6c3bb5..72eb0595 100644 --- a/src/util.c +++ b/src/util.c @@ -3577,9 +3577,12 @@ cpu_set_t* cpu_set_malloc(unsigned *ncpus) { } } -void status_vprintf(const char *format, va_list ap) { - char *s = NULL; - int fd = -1; +void status_vprintf(const char *status, const char *format, va_list ap) { + char *s = NULL, *spaces = NULL, *e; + int fd = -1, c; + size_t emax, sl, left; + struct iovec iovec[5]; + int n = 0; assert(format); @@ -3589,25 +3592,65 @@ void status_vprintf(const char *format, va_list ap) { if (vasprintf(&s, format, ap) < 0) goto finish; - if ((fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC)) < 0) + fd = open_terminal("/dev/tty", O_WRONLY|O_NOCTTY|O_CLOEXEC); + if (fd < 0) goto finish; - write(fd, s, strlen(s)); + c = fd_columns(fd); + if (c <= 0) + c = 80; + + if (status) { + sl = 2 + 6 + 1; /* " [" status "]" */ + emax = (size_t) c > sl ? c - sl - 1 : 0; + } else + emax = c - 1; + + e = ellipsize(s, emax, 75); + if (e) { + free(s); + s = e; + } + + zero(iovec); + IOVEC_SET_STRING(iovec[n++], s); + + sl = strlen(s); + left = emax > sl ? emax - sl : 0; + if (left > 0) { + spaces = malloc(left); + if (spaces) { + memset(spaces, ' ', left); + iovec[n].iov_base = spaces; + iovec[n].iov_len = left; + n++; + } + } + + if (status) { + IOVEC_SET_STRING(iovec[n++], " ["); + IOVEC_SET_STRING(iovec[n++], status); + IOVEC_SET_STRING(iovec[n++], "]\n"); + } else + IOVEC_SET_STRING(iovec[n++], "\n"); + + writev(fd, iovec, n); finish: free(s); + free(spaces); if (fd >= 0) close_nointr_nofail(fd); } -void status_printf(const char *format, ...) { +void status_printf(const char *status, const char *format, ...) { va_list ap; assert(format); va_start(ap, format); - status_vprintf(format, ap); + status_vprintf(status, format, ap); va_end(ap); } @@ -3764,7 +3807,8 @@ void status_welcome(void) { if (!ansi_color && !const_color) const_color = "1"; - status_printf("\nWelcome to \x1B[%sm%s\x1B[0m!\n\n", + status_printf(NULL, + "\nWelcome to \x1B[%sm%s\x1B[0m!\n", const_color ? const_color : ansi_color, const_pretty ? const_pretty : pretty_name); @@ -3906,6 +3950,19 @@ char **replace_env_argv(char **argv, char **env) { return r; } +int fd_columns(int fd) { + struct winsize ws; + zero(ws); + + if (ioctl(fd, TIOCGWINSZ, &ws) < 0) + return -errno; + + if (ws.ws_col <= 0) + return -EIO; + + return ws.ws_col; +} + unsigned columns(void) { static __thread int parsed_columns = 0; const char *e; @@ -3913,16 +3970,12 @@ unsigned columns(void) { if (_likely_(parsed_columns > 0)) return parsed_columns; - if ((e = getenv("COLUMNS"))) + e = getenv("COLUMNS"); + if (e) parsed_columns = atoi(e); - if (parsed_columns <= 0) { - struct winsize ws; - zero(ws); - - if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) >= 0) - parsed_columns = ws.ws_col; - } + if (parsed_columns <= 0) + parsed_columns = fd_columns(STDOUT_FILENO); if (parsed_columns <= 0) parsed_columns = 80; diff --git a/src/util.h b/src/util.h index e285ec77..d96ce7e7 100644 --- a/src/util.h +++ b/src/util.h @@ -374,10 +374,11 @@ int pipe_eof(int fd); cpu_set_t* cpu_set_malloc(unsigned *ncpus); -void status_vprintf(const char *format, va_list ap); -void status_printf(const char *format, ...); +void status_vprintf(const char *status, const char *format, va_list ap); +void status_printf(const char *status, const char *format, ...); void status_welcome(void); +int fd_columns(int fd); unsigned columns(void); int running_in_chroot(void); -- 2.39.5