diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/show-status.c | 78 | ||||
-rw-r--r-- | src/core/show-status.h | 7 |
2 files changed, 85 insertions, 0 deletions
diff --git a/src/core/show-status.c b/src/core/show-status.c index 9509b21ccb..91f8f8e5ad 100644 --- a/src/core/show-status.c +++ b/src/core/show-status.c @@ -44,3 +44,81 @@ int parse_show_status(const char *v, ShowStatus *ret) { *ret = r ? SHOW_STATUS_YES : SHOW_STATUS_NO; return 0; } + +int status_vprintf(const char *status, bool ellipse, bool ephemeral, const char *format, va_list ap) { + static const char status_indent[] = " "; /* "[" STATUS "] " */ + _cleanup_free_ char *s = NULL; + _cleanup_close_ int fd = -1; + struct iovec iovec[6] = {}; + int n = 0; + static bool prev_ephemeral; + + assert(format); + + /* This is independent of logging, as status messages are + * optional and go exclusively to the console. */ + + if (vasprintf(&s, format, ap) < 0) + return log_oom(); + + fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return fd; + + if (ellipse) { + char *e; + size_t emax, sl; + int c; + + c = fd_columns(fd); + if (c <= 0) + c = 80; + + sl = status ? sizeof(status_indent)-1 : 0; + + emax = c - sl - 1; + if (emax < 3) + emax = 3; + + e = ellipsize(s, emax, 50); + if (e) { + free(s); + s = e; + } + } + + if (prev_ephemeral) + IOVEC_SET_STRING(iovec[n++], "\r" ANSI_ERASE_TO_END_OF_LINE); + prev_ephemeral = ephemeral; + + if (status) { + if (!isempty(status)) { + IOVEC_SET_STRING(iovec[n++], "["); + IOVEC_SET_STRING(iovec[n++], status); + IOVEC_SET_STRING(iovec[n++], "] "); + } else + IOVEC_SET_STRING(iovec[n++], status_indent); + } + + IOVEC_SET_STRING(iovec[n++], s); + if (!ephemeral) + IOVEC_SET_STRING(iovec[n++], "\n"); + + if (writev(fd, iovec, n) < 0) + return -errno; + + return 0; +} + +int status_printf(const char *status, bool ellipse, bool ephemeral, const char *format, ...) { + va_list ap; + int r; + + assert(format); + + va_start(ap, format); + r = status_vprintf(status, ellipse, ephemeral, format, ap); + va_end(ap); + + return r; +} diff --git a/src/core/show-status.h b/src/core/show-status.h index a2b2153746..c79d4acb66 100644 --- a/src/core/show-status.h +++ b/src/core/show-status.h @@ -21,6 +21,10 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <stdbool.h> + +#include "macro.h" + /* Manager status */ typedef enum ShowStatus { @@ -32,3 +36,6 @@ typedef enum ShowStatus { } ShowStatus; int parse_show_status(const char *v, ShowStatus *ret); + +int status_vprintf(const char *status, bool ellipse, bool ephemeral, const char *format, va_list ap) _printf_(4,0); +int status_printf(const char *status, bool ellipse, bool ephemeral, const char *format, ...) _printf_(4,5); |