chiark / gitweb /
util: when printing status updates during boot, take terminal width into account
authorLennart Poettering <lennart@poettering.net>
Thu, 5 Jan 2012 02:24:39 +0000 (03:24 +0100)
committerLennart Poettering <lennart@poettering.net>
Thu, 5 Jan 2012 13:55:35 +0000 (14:55 +0100)
src/unit.c
src/util.c
src/util.h

index 03c90f5..dea8f4a 100644 (file)
@@ -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) {
index 8a6c3bb..72eb059 100644 (file)
@@ -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;
index e285ec7..d96ce7e 100644 (file)
@@ -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);