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 905003ea87..f3231bc0e4 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 a6542d5a16..a44d75604a 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 0661ff0bb9..da49f9a22d 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 b38d6c7267..d41ccf30fe 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 d9b060972d..2fef7d8c09 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 f3231bc0e4..3e917cb3f5 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 a44d75604a..8d78a0d3c0 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 599abf093f..79dab5037a 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 6fe9422f94..5121dd153a 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 3e917cb3f5..c849db7b08 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 8d78a0d3c0..968be322dd 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 7730c06ba2..670bff999c 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 3179fba3ba..6fb4134ae9 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 c849db7b08..49624ba7d0 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 29785e2f11..bf6feaa0d9 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 3e94bc3ed5..e19af4cd92 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);