summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrantisek Sumsal <frantisek@sumsal.cz>2020-01-03 13:01:26 +0100
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2020-01-14 15:26:21 +0100
commitde9a8fe18e0168b65ae50b6dde2865f647fc92a2 (patch)
tree33938cfd82c5488166d7d658992bd7171dab6f50
parent7c286cd6a615fa9bce8a2830133bcf89becfbf9f (diff)
downloadsystemd-de9a8fe18e0168b65ae50b6dde2865f647fc92a2.tar.gz
systemctl: use format-table.[ch] for tables
-rw-r--r--src/systemctl/systemctl.c593
1 files changed, 226 insertions, 367 deletions
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 64c1401afc..60872bc537 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -39,6 +39,7 @@
#include "exec-util.h"
#include "exit-status.h"
#include "fd-util.h"
+#include "format-table.h"
#include "format-util.h"
#include "fs-util.h"
#include "glob-util.h"
@@ -389,122 +390,42 @@ static bool output_show_unit(const UnitInfo *u, char **patterns) {
}
static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
- unsigned circle_len = 0, id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len, max_desc_len;
+ _cleanup_(table_unrefp) Table *table = NULL;
const UnitInfo *u;
- unsigned n_shown = 0;
int job_count = 0;
- bool full = arg_full || FLAGS_SET(arg_pager_flags, PAGER_DISABLE);
-
- max_id_len = STRLEN("UNIT");
- load_len = STRLEN("LOAD");
- active_len = STRLEN("ACTIVE");
- sub_len = STRLEN("SUB");
- job_len = STRLEN("JOB");
- max_desc_len = STRLEN("DESCRIPTION");
-
- for (u = unit_infos; u < unit_infos + c; u++) {
- max_id_len = MAX(max_id_len, strlen(u->id) + (u->machine ? strlen(u->machine)+1 : 0));
- load_len = MAX(load_len, strlen(u->load_state));
- active_len = MAX(active_len, strlen(u->active_state));
- sub_len = MAX(sub_len, strlen(u->sub_state));
- max_desc_len = MAX(max_desc_len, strlen(u->description));
-
- if (u->job_id != 0) {
- job_len = MAX(job_len, strlen(u->job_type));
- job_count++;
- }
-
- if (!arg_no_legend &&
- (streq(u->active_state, "failed") ||
- STR_IN_SET(u->load_state, "error", "not-found", "bad-setting", "masked")))
- circle_len = 2;
- }
-
- if (!arg_full && original_stdout_is_tty) {
- unsigned basic_len;
-
- id_len = MIN(max_id_len, 25u); /* as much as it needs, but at most 25 for now */
- basic_len = circle_len + 1 + id_len + 1 + load_len + 1 + active_len + 1 + sub_len + 1;
-
- if (job_count)
- basic_len += job_len + 1;
+ int r;
- if (basic_len < (unsigned) columns()) {
- unsigned extra_len, incr;
- extra_len = columns() - basic_len;
+ table = table_new("", "unit", "load", "active", "sub", "job", "description");
+ if (!table)
+ return log_oom();
- /* Either UNIT already got 25, or is fully satisfied.
- * Grant up to 25 to DESC now. */
- incr = MIN(extra_len, 25u);
- desc_len = incr;
- extra_len -= incr;
-
- /* Of the remainder give as much as the ID needs to the ID, and give the rest to the
- * description but not more than it needs. */
- if (extra_len > 0) {
- incr = MIN(max_id_len - id_len, extra_len);
- id_len += incr;
- desc_len += MIN(extra_len - incr, max_desc_len - desc_len);
- }
- } else
- desc_len = 0;
- } else {
- id_len = max_id_len;
- desc_len = max_desc_len;
- }
+ table_set_header(table, !arg_no_legend);
+ if (arg_full)
+ table_set_width(table, 0);
for (u = unit_infos; u < unit_infos + c; u++) {
- _cleanup_free_ char *e = NULL, *j = NULL;
- const char *on_underline = "", *off_underline = "";
- const char *on_loaded = "", *off_loaded = "";
- const char *on_active = "", *off_active = "";
- const char *on_circle = "", *off_circle = "";
- const char *id;
+ _cleanup_free_ char *j = NULL;
+ const char *on_underline = "", *on_loaded = "", *on_active = "";
+ const char *on_circle = "", *id;
bool circle = false, underline = false;
- if (!n_shown && !arg_no_legend) {
-
- if (circle_len > 0)
- fputs(" ", stdout);
-
- printf("%s%-*s %-*s %-*s %-*s ",
- ansi_underline(),
- id_len, "UNIT",
- load_len, "LOAD",
- active_len, "ACTIVE",
- sub_len, "SUB");
-
- if (job_count)
- printf("%-*s ", job_len, "JOB");
-
- printf("%-*.*s%s\n",
- desc_len,
- full ? -1 : (int) desc_len,
- "DESCRIPTION",
- ansi_normal());
- }
-
- n_shown++;
-
if (u + 1 < unit_infos + c &&
!streq(unit_type_suffix(u->id), unit_type_suffix((u + 1)->id))) {
on_underline = ansi_underline();
- off_underline = ansi_normal();
underline = true;
}
if (STR_IN_SET(u->load_state, "error", "not-found", "bad-setting", "masked") && !arg_plain) {
on_circle = ansi_highlight_yellow();
- off_circle = ansi_normal();
circle = true;
on_loaded = underline ? ansi_highlight_red_underline() : ansi_highlight_red();
- off_loaded = underline ? on_underline : ansi_normal();
} else if (streq(u->active_state, "failed") && !arg_plain) {
on_circle = ansi_highlight_red();
- off_circle = ansi_normal();
circle = true;
on_active = underline ? ansi_highlight_red_underline() : ansi_highlight_red();
- off_active = underline ? on_underline : ansi_normal();
+ } else {
+ on_active = on_underline;
+ on_loaded = on_underline;
}
if (u->machine) {
@@ -516,36 +437,47 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
} else
id = u->id;
- if (arg_full) {
- e = ellipsize(id, id_len, 33);
- if (!e)
- return log_oom();
-
- id = e;
- }
-
- if (circle_len > 0)
- printf("%s%s%s ", on_circle, circle ? special_glyph(SPECIAL_GLYPH_BLACK_CIRCLE) : " ", off_circle);
+ r = table_add_many(table,
+ TABLE_STRING, circle ? special_glyph(SPECIAL_GLYPH_BLACK_CIRCLE) : " ",
+ TABLE_SET_COLOR, on_circle,
+ TABLE_STRING, id,
+ TABLE_SET_COLOR, on_active,
+ TABLE_STRING, u->load_state,
+ TABLE_SET_COLOR, on_loaded,
+ TABLE_STRING, u->active_state,
+ TABLE_SET_COLOR, on_active,
+ TABLE_STRING, u->sub_state,
+ TABLE_SET_COLOR, on_active,
+ TABLE_STRING, u->job_id ? u->job_type: "",
+ TABLE_SET_COLOR, u->job_id ? on_underline : "",
+ TABLE_STRING, u->description,
+ TABLE_SET_COLOR, on_underline);
+ if (r < 0)
+ return table_log_add_error(r);
- printf("%s%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
- on_underline,
- on_active, id_len, id, off_active,
- on_loaded, load_len, u->load_state, off_loaded,
- on_active, active_len, u->active_state,
- sub_len, u->sub_state, off_active,
- job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
+ if (u->job_id != 0)
+ job_count++;
+ }
- printf("%-*.*s%s\n",
- desc_len,
- full ? -1 : (int) desc_len,
- u->description,
- off_underline);
+ if (job_count == 0) {
+ /* There's no data in the JOB column, so let's hide it */
+ /* Also, convert all number constants to size_t so va_arg()
+ * in table_set_display() fetches a correct number of bytes from
+ * the stack */
+ r = table_set_display(table, (size_t) 0, (size_t) 1, (size_t) 2, (size_t) 3, (size_t) 4, (size_t) 6, (size_t) -1);
+ if (r < 0)
+ return log_error_errno(r, "Failed to set columns to display: %m");
}
+ r = table_print(table, NULL);
+ if (r < 0)
+ return log_error_errno(r, "Failed to print the table: %m");
+
if (!arg_no_legend) {
const char *on, *off;
+ size_t records = table_get_rows(table) - 1;
- if (n_shown) {
+ if (records > 0) {
puts("\n"
"LOAD = Reflects whether the unit definition was properly loaded.\n"
"ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
@@ -559,15 +491,15 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
}
if (arg_all || strv_contains(arg_states, "inactive"))
- printf("%s%u loaded units listed.%s\n"
+ printf("%s%zu loaded units listed.%s\n"
"To show all installed unit files use 'systemctl list-unit-files'.\n",
- on, n_shown, off);
+ on, records, off);
else if (!arg_states)
- printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
+ printf("%s%zu loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
"To show all installed unit files use 'systemctl list-unit-files'.\n",
- on, n_shown, off);
+ on, records, off);
else
- printf("%u loaded units listed.\n", n_shown);
+ printf("%zu loaded units listed.\n", records);
}
return 0;
@@ -1048,39 +980,30 @@ static int socket_info_compare(const struct socket_info *a, const struct socket_
}
static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
+ _cleanup_(table_unrefp) Table *table = NULL;
struct socket_info *s;
- unsigned pathlen = STRLEN("LISTEN"),
- typelen = STRLEN("TYPE") * arg_show_types,
- socklen = STRLEN("UNIT"),
- servlen = STRLEN("ACTIVATES");
const char *on, *off;
+ int r;
- for (s = socket_infos; s < socket_infos + cs; s++) {
- unsigned tmp = 0;
- char **a;
-
- socklen = MAX(socklen, strlen(s->id));
- if (arg_show_types)
- typelen = MAX(typelen, strlen(s->type));
- pathlen = MAX(pathlen, strlen(s->path) + (s->machine ? strlen(s->machine)+1 : 0));
+ table = table_new("listen", "type", "units", "activates");
+ if (!table)
+ return log_oom();
- STRV_FOREACH(a, s->triggered)
- tmp += strlen(*a) + 2*(a != s->triggered);
- servlen = MAX(servlen, tmp);
+ if (!arg_show_types) {
+ /* Hide the second (TYPE) column */
+ r = table_set_display(table, 0, 2, 3, (size_t) -1);
+ if (r < 0)
+ return log_error_errno(r, "Failed to set columns to display: %m");
}
- if (cs) {
- if (!arg_no_legend)
- printf("%-*s %-*.*s%-*s %s\n",
- pathlen, "LISTEN",
- typelen + arg_show_types, typelen + arg_show_types, "TYPE ",
- socklen, "UNIT",
- "ACTIVATES");
+ table_set_header(table, !arg_no_legend);
+ if (arg_full)
+ table_set_width(table, 0);
+ if (cs) {
for (s = socket_infos; s < socket_infos + cs; s++) {
- _cleanup_free_ char *j = NULL;
+ _cleanup_free_ char *j = NULL, *activates = NULL;
const char *path;
- char **a;
if (s->machine) {
j = strjoin(s->machine, ":", s->path);
@@ -1090,29 +1013,32 @@ static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
} else
path = s->path;
- if (arg_show_types)
- printf("%-*s %-*s %-*s",
- pathlen, path, typelen, s->type, socklen, s->id);
- else
- printf("%-*s %-*s",
- pathlen, path, socklen, s->id);
- STRV_FOREACH(a, s->triggered)
- printf("%s %s",
- a == s->triggered ? "" : ",", *a);
- printf("\n");
+ activates = strv_join(s->triggered, ", ");
+ if (!activates)
+ return log_oom();
+
+ r = table_add_many(table,
+ TABLE_STRING, path,
+ TABLE_STRING, s->type,
+ TABLE_STRING, s->id,
+ TABLE_STRING, activates);
+ if (r < 0)
+ return table_log_add_error(r);
}
on = ansi_highlight();
off = ansi_normal();
- if (!arg_no_legend)
- printf("\n");
} else {
on = ansi_highlight_red();
off = ansi_normal();
}
+ r = table_print(table, NULL);
+ if (r < 0)
+ return log_error_errno(r, "Failed to print the table: %m");
+
if (!arg_no_legend) {
- printf("%s%u sockets listed.%s\n", on, cs, off);
+ printf("\n%s%u sockets listed.%s\n", on, cs, off);
if (!arg_all)
printf("Pass --all to see loaded but inactive sockets, too.\n");
}
@@ -1303,73 +1229,25 @@ static int timer_info_compare(const struct timer_info *a, const struct timer_inf
}
static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
+ _cleanup_(table_unrefp) Table *table = NULL;
struct timer_info *t;
- unsigned
- nextlen = STRLEN("NEXT"),
- leftlen = STRLEN("LEFT"),
- lastlen = STRLEN("LAST"),
- passedlen = STRLEN("PASSED"),
- unitlen = STRLEN("UNIT"),
- activatelen = STRLEN("ACTIVATES");
-
const char *on, *off;
+ int r;
assert(timer_infos || n == 0);
- for (t = timer_infos; t < timer_infos + n; t++) {
- unsigned ul = 0;
- char **a;
-
- if (t->next_elapse > 0) {
- char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
-
- format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
- nextlen = MAX(nextlen, strlen(tstamp) + 1);
-
- format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
- leftlen = MAX(leftlen, strlen(trel));
- }
-
- if (t->last_trigger > 0) {
- char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
-
- format_timestamp(tstamp, sizeof(tstamp), t->last_trigger);
- lastlen = MAX(lastlen, strlen(tstamp) + 1);
-
- format_timestamp_relative(trel, sizeof(trel), t->last_trigger);
- passedlen = MAX(passedlen, strlen(trel));
- }
-
- unitlen = MAX(unitlen, strlen(t->id) + (t->machine ? strlen(t->machine)+1 : 0));
-
- STRV_FOREACH(a, t->triggered)
- ul += strlen(*a) + 2*(a != t->triggered);
+ table = table_new("next", "left", "last", "passed", "unit", "activates");
+ if (!table)
+ return log_oom();
- activatelen = MAX(activatelen, ul);
- }
+ table_set_header(table, !arg_no_legend);
+ if (arg_full)
+ table_set_width(table, 0);
if (n > 0) {
- if (!arg_no_legend)
- printf("%-*s %-*s %-*s %-*s %-*s %s\n",
- nextlen, "NEXT",
- leftlen, "LEFT",
- lastlen, "LAST",
- passedlen, "PASSED",
- unitlen, "UNIT",
- "ACTIVATES");
-
for (t = timer_infos; t < timer_infos + n; t++) {
- _cleanup_free_ char *j = NULL;
+ _cleanup_free_ char *j = NULL, *activates = NULL;
const char *unit;
- char tstamp1[FORMAT_TIMESTAMP_MAX] = "n/a", trel1[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
- char tstamp2[FORMAT_TIMESTAMP_MAX] = "n/a", trel2[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
- char **a;
-
- format_timestamp(tstamp1, sizeof(tstamp1), t->next_elapse);
- format_timestamp_relative(trel1, sizeof(trel1), t->next_elapse);
-
- format_timestamp(tstamp2, sizeof(tstamp2), t->last_trigger);
- format_timestamp_relative(trel2, sizeof(trel2), t->last_trigger);
if (t->machine) {
j = strjoin(t->machine, ":", t->id);
@@ -1379,26 +1257,34 @@ static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
} else
unit = t->id;
- printf("%-*s %-*s %-*s %-*s %-*s",
- nextlen, tstamp1, leftlen, trel1, lastlen, tstamp2, passedlen, trel2, unitlen, unit);
+ activates = strv_join(t->triggered, ", ");
+ if (!activates)
+ return log_oom();
- STRV_FOREACH(a, t->triggered)
- printf("%s %s",
- a == t->triggered ? "" : ",", *a);
- printf("\n");
+ r = table_add_many(table,
+ TABLE_TIMESTAMP, t->next_elapse,
+ TABLE_TIMESTAMP_RELATIVE, t->next_elapse,
+ TABLE_TIMESTAMP, t->last_trigger,
+ TABLE_TIMESTAMP_RELATIVE, t->last_trigger,
+ TABLE_STRING, unit,
+ TABLE_STRING, activates);
+ if (r < 0)
+ return table_log_add_error(r);
}
on = ansi_highlight();
off = ansi_normal();
- if (!arg_no_legend)
- printf("\n");
} else {
on = ansi_highlight_red();
off = ansi_normal();
}
+ r = table_print(table, NULL);
+ if (r < 0)
+ return log_error_errno(r, "Failed to print the table: %m");
+
if (!arg_no_legend) {
- printf("%s%u timers listed.%s\n", on, n, off);
+ printf("\n%s%u timers listed.%s\n", on, n, off);
if (!arg_all)
printf("Pass --all to see loaded but inactive timers, too.\n");
}
@@ -1549,42 +1435,22 @@ static bool output_show_unit_file(const UnitFileList *u, char **states, char **p
return true;
}
-static void output_unit_file_list(const UnitFileList *units, unsigned c) {
- unsigned max_id_len, id_cols, state_cols, preset_cols;
+static int output_unit_file_list(const UnitFileList *units, unsigned c) {
+ _cleanup_(table_unrefp) Table *table = NULL;
const UnitFileList *u;
+ int r;
- max_id_len = STRLEN("UNIT FILE");
- state_cols = STRLEN("STATE");
- preset_cols = STRLEN("VENDOR PRESET");
-
- for (u = units; u < units + c; u++) {
- max_id_len = MAX(max_id_len, strlen(basename(u->path)));
- state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
- }
-
- if (!arg_full) {
- unsigned basic_cols;
-
- id_cols = MIN(max_id_len, 25u);
- basic_cols = 1 + id_cols + state_cols;
- if (basic_cols < (unsigned) columns())
- id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
- } else
- id_cols = max_id_len;
+ table = table_new("unit file", "state", "vendor preset");
+ if (!table)
+ return log_oom();
- if (!arg_no_legend && c > 0)
- printf("%s%-*s %-*s %-*s%s\n",
- ansi_underline(),
- id_cols, "UNIT FILE",
- state_cols, "STATE",
- preset_cols, "VENDOR PRESET",
- ansi_normal());
+ table_set_header(table, !arg_no_legend);
+ if (arg_full)
+ table_set_width(table, 0);
for (u = units; u < units + c; u++) {
const char *on_underline = NULL, *on_unit_color = NULL, *id;
- const char *on_preset_color = NULL, *off_preset = NULL, *unit_preset_str;
- _cleanup_free_ char *e = NULL;
- int r;
+ const char *on_preset_color = NULL, *unit_preset_str;
bool underline;
underline = u + 1 < units + c &&
@@ -1601,6 +1467,8 @@ static void output_unit_file_list(const UnitFileList *units, unsigned c) {
on_unit_color = underline ? ansi_highlight_red_underline() : ansi_highlight_red();
else if (u->state == UNIT_FILE_ENABLED)
on_unit_color = underline ? ansi_highlight_green_underline() : ansi_highlight_green();
+ else
+ on_unit_color = on_underline;
id = basename(u->path);
@@ -1616,20 +1484,25 @@ static void output_unit_file_list(const UnitFileList *units, unsigned c) {
on_preset_color = underline ? ansi_highlight_green_underline() : ansi_highlight_green();
}
- if (on_underline || on_preset_color)
- off_preset = ansi_normal();
-
- e = arg_full ? NULL : ellipsize(id, id_cols, 33);
-
- printf("%s%-*s %s%-*s %s%-*s%s\n",
- strempty(on_underline),
- id_cols, e ? e : id,
- strempty(on_unit_color), state_cols, unit_file_state_to_string(u->state),
- strempty(on_preset_color), preset_cols, unit_preset_str, strempty(off_preset));
+ r = table_add_many(table,
+ TABLE_STRING, id,
+ TABLE_SET_COLOR, strempty(on_underline),
+ TABLE_STRING, unit_file_state_to_string(u->state),
+ TABLE_SET_COLOR, strempty(on_unit_color),
+ TABLE_STRING, unit_preset_str,
+ TABLE_SET_COLOR, strempty(on_preset_color));
+ if (r < 0)
+ return table_log_add_error(r);
}
+ r = table_print(table, NULL);
+ if (r < 0)
+ return log_error_errno(r, "Failed to print the table: %m");
+
if (!arg_no_legend)
printf("\n%u unit files listed.\n", c);
+
+ return 0;
}
static int list_unit_files(int argc, char *argv[], void *userdata) {
@@ -1772,7 +1645,9 @@ static int list_unit_files(int argc, char *argv[], void *userdata) {
(void) pager_open(arg_pager_flags);
typesafe_qsort(units, c, compare_unit_file_list);
- output_unit_file_list(units, c);
+ r = output_unit_file_list(units, c);
+ if (r < 0)
+ return r;
if (install_client_side())
for (unit = units; unit < units + c; unit++)
@@ -2081,94 +1956,77 @@ static int get_machine_list(
return c;
}
-static void output_machines_list(struct machine_info *machine_infos, unsigned n) {
+static int output_machines_list(struct machine_info *machine_infos, unsigned n) {
+ _cleanup_(table_unrefp) Table *table = NULL;
struct machine_info *m;
- unsigned
- circle_len = 0,
- namelen = STRLEN("NAME"),
- statelen = STRLEN("STATE"),
- failedlen = STRLEN("FAILED"),
- jobslen = STRLEN("JOBS");
bool state_missing = false;
+ int r;
assert(machine_infos || n == 0);
- for (m = machine_infos; m < machine_infos + n; m++) {
- namelen = MAX(namelen,
- strlen(m->name) + (m->is_host ? STRLEN(" (host)") : 0));
- statelen = MAX(statelen, strlen_ptr(m->state));
- failedlen = MAX(failedlen, DECIMAL_STR_WIDTH(m->n_failed_units));
- jobslen = MAX(jobslen, DECIMAL_STR_WIDTH(m->n_jobs));
-
- if (!arg_plain && m->state && !streq(m->state, "running"))
- circle_len = 2;
- }
-
- if (!arg_no_legend) {
- if (circle_len > 0)
- fputs(" ", stdout);
+ table = table_new("", "name", "state", "failed", "jobs");
+ if (!table)
+ return log_oom();
- printf("%-*s %-*s %-*s %-*s\n",
- namelen, "NAME",
- statelen, "STATE",
- failedlen, "FAILED",
- jobslen, "JOBS");
- }
+ table_set_header(table, !arg_no_legend);
+ if (arg_full)
+ table_set_width(table, 0);
for (m = machine_infos; m < machine_infos + n; m++) {
- const char *on_state = "", *off_state = "";
- const char *on_failed = "", *off_failed = "";
+ _cleanup_free_ char *mname = NULL;
+ const char *on_state = "", *on_failed = "";
bool circle = false;
if (streq_ptr(m->state, "degraded")) {
on_state = ansi_highlight_red();
- off_state = ansi_normal();
circle = true;
} else if (!streq_ptr(m->state, "running")) {
on_state = ansi_highlight_yellow();
- off_state = ansi_normal();
circle = true;
}
- if (m->n_failed_units > 0) {
+ if (m->n_failed_units > 0)
on_failed = ansi_highlight_red();
- off_failed = ansi_normal();
- } else
- on_failed = off_failed = "";
-
- if (circle_len > 0)
- printf("%s%s%s ", on_state, circle ? special_glyph(SPECIAL_GLYPH_BLACK_CIRCLE) : " ", off_state);
+ else
+ on_failed = "";
if (!m->state)
state_missing = true;
if (m->is_host)
- printf("%-*s (host) %s%-*s%s %s%*" PRIu32 "%s %*" PRIu32 "\n",
- (int) (namelen - strlen(" (host)")),
- strna(m->name),
- on_state, statelen, strna(m->state), off_state,
- on_failed, failedlen, m->n_failed_units, off_failed,
- jobslen, m->n_jobs);
- else
- printf("%-*s %s%-*s%s %s%*" PRIu32 "%s %*" PRIu32 "\n",
- namelen, strna(m->name),
- on_state, statelen, strna(m->state), off_state,
- on_failed, failedlen, m->n_failed_units, off_failed,
- jobslen, m->n_jobs);
+ mname = strjoin(strna(m->name), " (host)");
+
+ r = table_add_many(table,
+ TABLE_STRING, circle ? special_glyph(SPECIAL_GLYPH_BLACK_CIRCLE) : " ",
+ TABLE_SET_COLOR, on_state,
+ TABLE_STRING, m->is_host ? mname : strna(m->name),
+ TABLE_STRING, strna(m->state),
+ TABLE_SET_COLOR, on_state,
+ TABLE_UINT32, m->n_failed_units,
+ TABLE_SET_COLOR, on_failed,
+ TABLE_UINT32, m->n_jobs);
+ if (r < 0)
+ return table_log_add_error(r);
}
+ r = table_print(table, NULL);
+ if (r < 0)
+ return log_error_errno(r, "Failed to print the table: %m");
+
if (!arg_no_legend) {
printf("\n");
if (state_missing && geteuid() != 0)
printf("Notice: some information only available to privileged users was not shown.\n");
printf("%u machines listed.\n", n);
}
+
+ return 0;
}
static int list_machines(int argc, char *argv[], void *userdata) {
struct machine_info *machine_infos = NULL;
sd_bus *bus;
- int r;
+ int r, rc;
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
@@ -2181,10 +2039,10 @@ static int list_machines(int argc, char *argv[], void *userdata) {
(void) pager_open(arg_pager_flags);
typesafe_qsort(machine_infos, r, compare_machine_info);
- output_machines_list(machine_infos, r);
+ rc = output_machines_list(machine_infos, r);
free_machines_list(machine_infos, r);
- return 0;
+ return rc;
}
static int get_default(int argc, char *argv[], void *userdata) {
@@ -2292,7 +2150,7 @@ finish:
return r;
}
-static int output_waiting_jobs(sd_bus *bus, uint32_t id, const char *method, const char *prefix) {
+static int output_waiting_jobs(sd_bus *bus, Table *table, uint32_t id, const char *method, const char *prefix) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
const char *name, *type;
@@ -2317,8 +2175,22 @@ static int output_waiting_jobs(sd_bus *bus, uint32_t id, const char *method, con
if (r < 0)
return bus_log_parse_error(r);
- while ((r = sd_bus_message_read(reply, "(usssoo)", &other_id, &name, &type, NULL, NULL, NULL)) > 0)
- printf("%s %u (%s/%s)\n", prefix, other_id, name, type);
+ while ((r = sd_bus_message_read(reply, "(usssoo)", &other_id, &name, &type, NULL, NULL, NULL)) > 0) {
+ _cleanup_free_ char *row = NULL;
+ int rc;
+
+ if (asprintf(&row, "%s %u (%s/%s)", prefix, other_id, name, type) < 0)
+ return log_oom();
+
+ rc = table_add_many(table,
+ TABLE_STRING, special_glyph(SPECIAL_GLYPH_TREE_RIGHT),
+ TABLE_STRING, row,
+ TABLE_EMPTY,
+ TABLE_EMPTY);
+ if (rc < 0)
+ return table_log_add_error(r);
+ }
+
if (r < 0)
return bus_log_parse_error(r);
@@ -2334,11 +2206,11 @@ struct job_info {
const char *name, *type, *state;
};
-static void output_jobs_list(sd_bus *bus, const struct job_info* jobs, unsigned n, bool skipped) {
- unsigned id_len, unit_len, type_len, state_len;
+static int output_jobs_list(sd_bus *bus, const struct job_info* jobs, unsigned n, bool skipped) {
+ _cleanup_(table_unrefp) Table *table = NULL;
const struct job_info *j;
const char *on, *off;
- bool shorten = false;
+ int r;
assert(n == 0 || jobs);
@@ -2349,66 +2221,54 @@ static void output_jobs_list(sd_bus *bus, const struct job_info* jobs, unsigned
printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
}
- return;
+ return 0;
}
(void) pager_open(arg_pager_flags);
- id_len = STRLEN("JOB");
- unit_len = STRLEN("UNIT");
- type_len = STRLEN("TYPE");
- state_len = STRLEN("STATE");
-
- for (j = jobs; j < jobs + n; j++) {
- uint32_t id = j->id;
- assert(j->name && j->type && j->state);
-
- id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
- unit_len = MAX(unit_len, strlen(j->name));
- type_len = MAX(type_len, strlen(j->type));
- state_len = MAX(state_len, strlen(j->state));
- }
-
- if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
- unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
- shorten = true;
- }
+ table = table_new("job", "unit", "type", "state");
+ if (!table)
+ return log_oom();
- if (!arg_no_legend)
- printf("%*s %-*s %-*s %-*s\n",
- id_len, "JOB",
- unit_len, "UNIT",
- type_len, "TYPE",
- state_len, "STATE");
+ table_set_header(table, !arg_no_legend);
+ if (arg_full)
+ table_set_width(table, 0);
for (j = jobs; j < jobs + n; j++) {
- _cleanup_free_ char *e = NULL;
-
- if (streq(j->state, "running")) {
+ if (streq(j->state, "running"))
on = ansi_highlight();
- off = ansi_normal();
- } else
- on = off = "";
+ else
+ on = "";
+
- e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
- printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
- id_len, j->id,
- on, unit_len, e ? e : j->name, off,
- type_len, j->type,
- on, state_len, j->state, off);
+ r = table_add_many(table,
+ TABLE_UINT, j->id,
+ TABLE_STRING, j->name,
+ TABLE_SET_COLOR, on,
+ TABLE_STRING, j->type,
+ TABLE_STRING, j->state,
+ TABLE_SET_COLOR, on);
+ if (r < 0)
+ return table_log_add_error(r);
if (arg_jobs_after)
- output_waiting_jobs(bus, j->id, "GetJobAfter", "\twaiting for job");
+ output_waiting_jobs(bus, table, j->id, "GetJobAfter", "\twaiting for job");
if (arg_jobs_before)
- output_waiting_jobs(bus, j->id, "GetJobBefore", "\tblocking job");
+ output_waiting_jobs(bus, table, j->id, "GetJobBefore", "\tblocking job");
}
+ r = table_print(table, NULL);
+ if (r < 0)
+ return log_error_errno(r, "Failed to print the table: %m");
+
if (!arg_no_legend) {
on = ansi_highlight();
off = ansi_normal();
printf("\n%s%u jobs listed%s.\n", on, n, off);
}
+
+ return 0;
}
static bool output_show_job(struct job_info *job, char **patterns) {
@@ -2469,8 +2329,7 @@ static int list_jobs(int argc, char *argv[], void *userdata) {
(void) pager_open(arg_pager_flags);
- output_jobs_list(bus, jobs, c, skipped);
- return 0;
+ return output_jobs_list(bus, jobs, c, skipped);
}
static int cancel_job(int argc, char *argv[], void *userdata) {