From 9e29521e27b8f48c7817b18bf155736daf9a8a2f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 Nov 2017 21:04:08 +0100 Subject: [PATCH 1/6] loginctl: invoke sigbus_install() We show journal data, hence we should install the SIGBUS handler. Similar for machinectl, where the same applies. --- src/login/loginctl.c | 2 ++ src/machine/machinectl.c | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/login/loginctl.c b/src/login/loginctl.c index 905003ea872..f3231bc0e4e 100644 --- a/src/login/loginctl.c +++ b/src/login/loginctl.c @@ -37,6 +37,7 @@ #include "pager.h" #include "parse-util.h" #include "process-util.h" +#include "sigbus.h" #include "signal-util.h" #include "spawn-polkit-agent.h" #include "strv.h" @@ -1589,6 +1590,7 @@ int main(int argc, char *argv[]) { setlocale(LC_ALL, ""); log_parse_environment(); log_open(); + sigbus_install(); r = parse_argv(argc, argv); if (r <= 0) diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c index a6542d5a16f..a44d75604ae 100644 --- a/src/machine/machinectl.c +++ b/src/machine/machinectl.c @@ -52,15 +52,16 @@ #include "path-util.h" #include "process-util.h" #include "ptyfwd.h" +#include "sigbus.h" #include "signal-util.h" #include "spawn-polkit-agent.h" +#include "stdio-util.h" #include "strv.h" #include "terminal-util.h" #include "unit-name.h" #include "util.h" #include "verbs.h" #include "web-util.h" -#include "stdio-util.h" #define ALL_IP_ADDRESSES -1 @@ -3051,6 +3052,7 @@ int main(int argc, char*argv[]) { setlocale(LC_ALL, ""); log_parse_environment(); log_open(); + sigbus_install(); r = parse_argv(argc, argv); if (r <= 0) From d13b522751504e6ff5720200622265870dc9c1ad Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 Nov 2017 21:10:17 +0100 Subject: [PATCH 2/6] pager: cache not only number of columns but also of lines before we open pager Not that we need it, but let's do this as matter of completeness. --- src/shared/pager.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/shared/pager.c b/src/shared/pager.c index 0661ff0bb9b..da49f9a22d4 100644 --- a/src/shared/pager.c +++ b/src/shared/pager.c @@ -80,9 +80,10 @@ int pager_open(bool no_pager, bool jump_to_end) { if (pager && STR_IN_SET(pager, "", "cat")) return 0; - /* Determine and cache number of columns before we spawn the - * pager so that we get the value from the actual tty */ + /* Determine and cache number of columns/lines before we spawn the pager so that we get the value from the + * actual tty */ (void) columns(); + (void) lines(); if (pipe2(fd, O_CLOEXEC) < 0) return log_error_errno(errno, "Failed to create pager pipe: %m"); From 0b3c84eb7da3a8c28ac248a68228f6a7edbb2e19 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 Nov 2017 21:15:44 +0100 Subject: [PATCH 3/6] tree-wide: use _cleanup_(sd_bus_flush_close_unrefp) at various appropriate places Let's shorten the code a bit. --- src/busctl/busctl.c | 3 +-- src/locale/localectl.c | 3 +-- src/login/loginctl.c | 4 +--- src/machine/machinectl.c | 3 +-- src/mount/mount-tool.c | 2 -- src/timedate/timedatectl.c | 3 +-- 6 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/busctl/busctl.c b/src/busctl/busctl.c index b38d6c7267a..d41ccf30feb 100644 --- a/src/busctl/busctl.c +++ b/src/busctl/busctl.c @@ -2010,7 +2010,7 @@ static int busctl_main(sd_bus *bus, int argc, char *argv[]) { } int main(int argc, char *argv[]) { - sd_bus *bus = NULL; + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; int r; log_parse_environment(); @@ -2100,7 +2100,6 @@ int main(int argc, char *argv[]) { r = busctl_main(bus, argc, argv); finish: - sd_bus_flush_close_unref(bus); pager_close(); strv_free(arg_matches); diff --git a/src/locale/localectl.c b/src/locale/localectl.c index d9b060972d3..2fef7d8c09d 100644 --- a/src/locale/localectl.c +++ b/src/locale/localectl.c @@ -594,7 +594,7 @@ static int localectl_main(sd_bus *bus, int argc, char *argv[]) { } int main(int argc, char*argv[]) { - sd_bus *bus = NULL; + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; int r; setlocale(LC_ALL, ""); @@ -614,7 +614,6 @@ int main(int argc, char*argv[]) { r = localectl_main(bus, argc, argv); finish: - sd_bus_flush_close_unref(bus); pager_close(); return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; diff --git a/src/login/loginctl.c b/src/login/loginctl.c index f3231bc0e4e..3e917cb3f57 100644 --- a/src/login/loginctl.c +++ b/src/login/loginctl.c @@ -1584,7 +1584,7 @@ static int loginctl_main(int argc, char *argv[], sd_bus *bus) { } int main(int argc, char *argv[]) { - sd_bus *bus = NULL; + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; int r; setlocale(LC_ALL, ""); @@ -1607,8 +1607,6 @@ int main(int argc, char *argv[]) { r = loginctl_main(argc, argv, bus); finish: - sd_bus_flush_close_unref(bus); - pager_close(); polkit_agent_close(); diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c index a44d75604ae..8d78a0d3c0a 100644 --- a/src/machine/machinectl.c +++ b/src/machine/machinectl.c @@ -3046,7 +3046,7 @@ static int machinectl_main(int argc, char *argv[], sd_bus *bus) { } int main(int argc, char*argv[]) { - sd_bus *bus = NULL; + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; int r; setlocale(LC_ALL, ""); @@ -3069,7 +3069,6 @@ int main(int argc, char*argv[]) { r = machinectl_main(argc, argv, bus); finish: - sd_bus_flush_close_unref(bus); pager_close(); polkit_agent_close(); diff --git a/src/mount/mount-tool.c b/src/mount/mount-tool.c index 599abf093f7..79dab5037a2 100644 --- a/src/mount/mount-tool.c +++ b/src/mount/mount-tool.c @@ -1619,8 +1619,6 @@ int main(int argc, char* argv[]) { } finish: - bus = sd_bus_flush_close_unref(bus); - pager_close(); free(arg_mount_what); diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c index 6fe9422f943..5121dd153a4 100644 --- a/src/timedate/timedatectl.c +++ b/src/timedate/timedatectl.c @@ -472,7 +472,7 @@ static int timedatectl_main(sd_bus *bus, int argc, char *argv[]) { } int main(int argc, char *argv[]) { - sd_bus *bus = NULL; + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; int r; setlocale(LC_ALL, ""); @@ -492,7 +492,6 @@ int main(int argc, char *argv[]) { r = timedatectl_main(bus, argc, argv); finish: - sd_bus_flush_close_unref(bus); pager_close(); return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; From 459b9f9ff7852144cf3ba380d9374acb3d46b328 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 Nov 2017 21:40:47 +0100 Subject: [PATCH 4/6] merge two lines in our get_output_flags() functions loginctl, machinectl, systemctl all have very similar implementations of a get_output_flags() functions. Simplify it by merging two lines that set the same flag. --- src/login/loginctl.c | 3 +-- src/machine/machinectl.c | 3 +-- src/systemctl/systemctl.c | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/login/loginctl.c b/src/login/loginctl.c index 3e917cb3f57..c849db7b086 100644 --- a/src/login/loginctl.c +++ b/src/login/loginctl.c @@ -66,8 +66,7 @@ static OutputFlags get_output_flags(void) { return arg_all * OUTPUT_SHOW_ALL | - arg_full * OUTPUT_FULL_WIDTH | - (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH | + (arg_full || !on_tty() || pager_have()) * OUTPUT_FULL_WIDTH | colors_enabled() * OUTPUT_COLOR; } diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c index 8d78a0d3c0a..968be322dd3 100644 --- a/src/machine/machinectl.c +++ b/src/machine/machinectl.c @@ -93,8 +93,7 @@ static int print_addresses(sd_bus *bus, const char *name, int, const char *pr1, static OutputFlags get_output_flags(void) { return arg_all * OUTPUT_SHOW_ALL | - arg_full * OUTPUT_FULL_WIDTH | - (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH | + (arg_full || !on_tty() || pager_have()) * OUTPUT_FULL_WIDTH | colors_enabled() * OUTPUT_COLOR | !arg_quiet * OUTPUT_WARN_CUTOFF; } diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 7730c06ba24..670bff999c9 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -280,8 +280,7 @@ static void polkit_agent_open_maybe(void) { static OutputFlags get_output_flags(void) { return arg_all * OUTPUT_SHOW_ALL | - arg_full * OUTPUT_FULL_WIDTH | - (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH | + (arg_full || !on_tty() || pager_have()) * OUTPUT_FULL_WIDTH | colors_enabled() * OUTPUT_COLOR | !arg_quiet * OUTPUT_WARN_CUTOFF; } From ddbc931986bac931a07a1aeb507a1a30153ac7ed Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 Nov 2017 21:41:53 +0100 Subject: [PATCH 5/6] string-util: when ellipsizing to a length if (size_t) -1, become a NOP Let's say that (size_t) -1 (i.e. SIZE_T_MAX) is equivalent to "unbounded" ellipsation, i.e. ellipsation as NOP. In which case the relevant functions become little more than strdup()/strndup(). This is useful to simplify caller code in case we want to turn off ellipsation in certain code paths with minimal caller-side handling for this. --- src/basic/string-util.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/basic/string-util.c b/src/basic/string-util.c index 3179fba3ba9..6fb4134ae93 100644 --- a/src/basic/string-util.c +++ b/src/basic/string-util.c @@ -472,6 +472,10 @@ char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigne assert(s); assert(percent <= 100); + + if (new_length == (size_t) -1) + return strndup(s, old_length); + assert(new_length >= 3); /* if no multibyte characters use ascii_ellipsize_mem for speed */ @@ -539,6 +543,10 @@ char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigne } char *ellipsize(const char *s, size_t length, unsigned percent) { + + if (length == (size_t) -1) + return strdup(s); + return ellipsize_mem(s, strlen(s), length, percent); } From 3850319be55d3e45df1af07323d283248cbbe88d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 Nov 2017 21:44:29 +0100 Subject: [PATCH 6/6] loginctl: rework sysfs tree dump, to honour --full and friends Let's hook up the sysfs tree output with the output flags logic, already used when dumping log lines or process trees. This way we get very similar output handling for line breaking/ellipsation in all three outputs of structured data. Fixes: #7095 --- src/login/loginctl.c | 2 +- src/login/sysfs-show.c | 27 +++++++++++++++++++-------- src/login/sysfs-show.h | 6 +++++- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/login/loginctl.c b/src/login/loginctl.c index c849db7b086..49624ba7d06 100644 --- a/src/login/loginctl.c +++ b/src/login/loginctl.c @@ -714,7 +714,7 @@ static int print_seat_status_info(sd_bus *bus, const char *path, bool *new_line) printf("\t Devices:\n"); - show_sysfs(i.id, "\t\t ", c); + show_sysfs(i.id, "\t\t ", c, get_output_flags()); } return 0; diff --git a/src/login/sysfs-show.c b/src/login/sysfs-show.c index 29785e2f11d..bf6feaa0d9b 100644 --- a/src/login/sysfs-show.c +++ b/src/login/sysfs-show.c @@ -37,13 +37,23 @@ static int show_sysfs_one( struct udev_list_entry **item, const char *sub, const char *prefix, - unsigned n_columns) { + unsigned n_columns, + OutputFlags flags) { + + size_t max_width; assert(udev); assert(seat); assert(item); assert(prefix); + if (flags & OUTPUT_FULL_WIDTH) + max_width = (size_t) -1; + else if (n_columns < 10) + max_width = 10; + else + max_width = n_columns; + while (*item) { _cleanup_udev_device_unref_ struct udev_device *d = NULL; struct udev_list_entry *next, *lookahead; @@ -106,7 +116,7 @@ static int show_sysfs_one( lookahead = udev_list_entry_get_next(lookahead); } - k = ellipsize(sysfs, n_columns, 20); + k = ellipsize(sysfs, max_width, 20); if (!k) return -ENOMEM; @@ -120,7 +130,7 @@ static int show_sysfs_one( return -ENOMEM; free(k); - k = ellipsize(l, n_columns, 70); + k = ellipsize(l, max_width, 70); if (!k) return -ENOMEM; @@ -134,14 +144,16 @@ static int show_sysfs_one( if (!p) return -ENOMEM; - show_sysfs_one(udev, seat, item, sysfs, p, n_columns - 2); + show_sysfs_one(udev, seat, item, sysfs, p, + n_columns == (unsigned) -1 || n_columns < 2 ? n_columns : n_columns - 2, + flags); } } return 0; } -int show_sysfs(const char *seat, const char *prefix, unsigned n_columns) { +int show_sysfs(const char *seat, const char *prefix, unsigned n_columns, OutputFlags flags) { _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL; _cleanup_udev_unref_ struct udev *udev = NULL; struct udev_list_entry *first = NULL; @@ -150,8 +162,7 @@ int show_sysfs(const char *seat, const char *prefix, unsigned n_columns) { if (n_columns <= 0) n_columns = columns(); - if (!prefix) - prefix = ""; + prefix = strempty(prefix); if (isempty(seat)) seat = "seat0"; @@ -181,7 +192,7 @@ int show_sysfs(const char *seat, const char *prefix, unsigned n_columns) { first = udev_enumerate_get_list_entry(e); if (first) - show_sysfs_one(udev, seat, &first, "/", prefix, n_columns); + show_sysfs_one(udev, seat, &first, "/", prefix, n_columns, flags); else printf("%s%s%s\n", prefix, special_glyph(TREE_RIGHT), "(none)"); diff --git a/src/login/sysfs-show.h b/src/login/sysfs-show.h index 3e94bc3ed55..e19af4cd928 100644 --- a/src/login/sysfs-show.h +++ b/src/login/sysfs-show.h @@ -19,4 +19,8 @@ along with systemd; If not, see . ***/ -int show_sysfs(const char *seat, const char *prefix, unsigned columns); +#include + +#include "output-mode.h" + +int show_sysfs(const char *seat, const char *prefix, unsigned columns, OutputFlags flags);