summaryrefslogtreecommitdiff
path: root/src/systemctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/systemctl.c')
-rw-r--r--src/systemctl.c152
1 files changed, 96 insertions, 56 deletions
diff --git a/src/systemctl.c b/src/systemctl.c
index 7caeb6dd91..175159d68f 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -66,6 +66,7 @@ static const char *arg_job_mode = "replace";
static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
static bool arg_immediate = false;
static bool arg_no_block = false;
+static bool arg_no_legend = false;
static bool arg_no_pager = false;
static bool arg_no_wtmp = false;
static bool arg_no_sync = false;
@@ -137,6 +138,8 @@ static bool on_tty(void) {
}
static void pager_open_if_enabled(void) {
+
+ /* Cache result before we open the pager */
on_tty();
if (arg_no_pager)
@@ -312,35 +315,60 @@ static bool output_show_unit(const struct unit_info *u) {
}
static void output_units_list(const struct unit_info *unit_infos, unsigned c) {
- unsigned active_len, sub_len, job_len, n_shown = 0;
+ unsigned id_len, max_id_len, active_len, sub_len, job_len, desc_len, n_shown = 0;
const struct unit_info *u;
+ max_id_len = sizeof("UNIT")-1;
active_len = sizeof("ACTIVE")-1;
sub_len = sizeof("SUB")-1;
job_len = sizeof("JOB")-1;
+ desc_len = 0;
for (u = unit_infos; u < unit_infos + c; u++) {
if (!output_show_unit(u))
continue;
+ max_id_len = MAX(max_id_len, strlen(u->id));
active_len = MAX(active_len, strlen(u->active_state));
sub_len = MAX(sub_len, strlen(u->sub_state));
if (u->job_id != 0)
job_len = MAX(job_len, strlen(u->job_type));
}
- if (on_tty()) {
- printf("%-25s %-6s %-*s %-*s %-*s", "UNIT", "LOAD",
+ if (!arg_full) {
+ unsigned basic_len;
+ id_len = MIN(max_id_len, 25);
+ basic_len = 5 + id_len + 6 + active_len + sub_len + job_len;
+ if (basic_len < (unsigned) columns()) {
+ unsigned extra_len, incr;
+ extra_len = columns() - basic_len;
+ /* Either UNIT already got 25, or is fully satisfied.
+ * Grant up to 25 to DESC now. */
+ incr = MIN(extra_len, 25);
+ desc_len += incr;
+ extra_len -= incr;
+ /* split the remaining space between UNIT and DESC,
+ * but do not give UNIT more than it needs. */
+ if (extra_len > 0) {
+ incr = MIN(extra_len / 2, max_id_len - id_len);
+ id_len += incr;
+ desc_len += extra_len - incr;
+ }
+ }
+ } else
+ id_len = max_id_len;
+
+ if (!arg_no_legend) {
+ printf("%-*s %-6s %-*s %-*s %-*s ", id_len, "UNIT", "LOAD",
active_len, "ACTIVE", sub_len, "SUB", job_len, "JOB");
- if (columns() >= 80+12 || arg_full || !arg_no_pager)
- printf(" %s\n", "DESCRIPTION");
+ if (!arg_full && arg_no_pager)
+ printf("%.*s\n", desc_len, "DESCRIPTION");
else
- printf("\n");
+ printf("%s\n", "DESCRIPTION");
}
for (u = unit_infos; u < unit_infos + c; u++) {
char *e;
- int a = 0, b = 0;
const char *on_loaded, *off_loaded;
const char *on_active, *off_active;
@@ -362,39 +390,23 @@ static void output_units_list(const struct unit_info *unit_infos, unsigned c) {
} else
on_active = off_active = "";
- e = arg_full ? NULL : ellipsize(u->id, 25, 33);
+ e = arg_full ? NULL : ellipsize(u->id, id_len, 33);
- printf("%-25s %s%-6s%s %s%-*s %-*s%s%n",
- e ? e : u->id,
+ printf("%-*s %s%-6s%s %s%-*s %-*s%s %-*s ",
+ id_len, e ? e : u->id,
on_loaded, u->load_state, off_loaded,
on_active, active_len, u->active_state,
sub_len, u->sub_state, off_active,
- &a);
-
- free(e);
-
- a -= strlen(on_loaded) + strlen(off_loaded);
- a -= strlen(on_active) + strlen(off_active);
-
- if (u->job_id != 0)
- printf(" %-*s", job_len, u->job_type);
+ job_len, u->job_id ? u->job_type : "");
+ if (!arg_full && arg_no_pager)
+ printf("%.*s\n", desc_len, u->description);
else
- b = 1 + job_len;
-
- if (a + b + 1 < columns()) {
- if (u->job_id == 0)
- printf(" %-*s", job_len, "");
+ printf("%s\n", u->description);
- if (arg_full || !arg_no_pager)
- printf(" %s", u->description);
- else
- printf(" %.*s", columns() - a - b - 1, u->description);
- }
-
- fputs("\n", stdout);
+ free(e);
}
- if (on_tty()) {
+ if (!arg_no_legend) {
printf("\nLOAD = Reflects whether the unit definition was properly loaded.\n"
"ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
"SUB = The low-level unit activation state, values depend on unit type.\n"
@@ -539,11 +551,30 @@ static bool output_show_unit_file(const UnitFileList *u) {
}
static void output_unit_file_list(const UnitFileList *units, unsigned c) {
- unsigned n_shown = 0;
+ unsigned max_id_len, id_cols, state_cols, n_shown = 0;
const UnitFileList *u;
- if (on_tty())
- printf("%-25s %-6s\n", "UNIT FILE", "STATE");
+ max_id_len = sizeof("UNIT FILE")-1;
+ state_cols = sizeof("STATE")-1;
+ for (u = units; u < units + c; u++) {
+ if (!output_show_unit_file(u))
+ continue;
+
+ max_id_len = MAX(max_id_len, strlen(file_name_from_path(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, 25);
+ 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;
+
+ if (!arg_no_legend)
+ printf("%-*s %-*s\n", id_cols, "UNIT FILE", state_cols, "STATE");
for (u = units; u < units + c; u++) {
char *e;
@@ -568,16 +599,16 @@ static void output_unit_file_list(const UnitFileList *units, unsigned c) {
id = file_name_from_path(u->path);
- e = arg_full ? NULL : ellipsize(id, 25, 33);
+ e = arg_full ? NULL : ellipsize(id, id_cols, 33);
- printf("%-25s %s%-6s%s\n",
- e ? e : id,
- on, unit_file_state_to_string(u->state), off);
+ printf("%-*s %s%-*s%s\n",
+ id_cols, e ? e : id,
+ on, state_cols, unit_file_state_to_string(u->state), off);
free(e);
}
- if (on_tty())
+ if (!arg_no_legend)
printf("\n%u unit files listed.\n", n_shown);
}
@@ -608,6 +639,7 @@ static int list_unit_files(DBusConnection *bus, char **args) {
r = unit_file_get_list(arg_scope, arg_root, h);
if (r < 0) {
+ unit_file_list_free(h);
log_error("Failed to get unit file list: %s", strerror(-r));
return r;
}
@@ -1054,7 +1086,7 @@ finish:
}
static int load_unit(DBusConnection *bus, char **args) {
- DBusMessage *m = NULL, *reply = NULL;
+ DBusMessage *m = NULL;
DBusError error;
int r;
char **name;
@@ -1065,6 +1097,7 @@ static int load_unit(DBusConnection *bus, char **args) {
assert(args);
STRV_FOREACH(name, args+1) {
+ DBusMessage *reply;
if (!(m = dbus_message_new_method_call(
"org.freedesktop.systemd1",
@@ -1102,9 +1135,6 @@ finish:
if (m)
dbus_message_unref(m);
- if (reply)
- dbus_message_unref(reply);
-
dbus_error_free(&error);
return r;
@@ -1794,7 +1824,7 @@ finish:
}
static int kill_unit(DBusConnection *bus, char **args) {
- DBusMessage *m = NULL, *reply = NULL;
+ DBusMessage *m = NULL;
int r = 0;
DBusError error;
char **name;
@@ -1811,6 +1841,7 @@ static int kill_unit(DBusConnection *bus, char **args) {
arg_kill_mode = streq(arg_kill_who, "all") ? "control-group" : "process";
STRV_FOREACH(name, args+1) {
+ DBusMessage *reply;
if (!(m = dbus_message_new_method_call(
"org.freedesktop.systemd1",
@@ -1850,9 +1881,6 @@ finish:
if (m)
dbus_message_unref(m);
- if (reply)
- dbus_message_unref(reply);
-
dbus_error_free(&error);
return r;
@@ -2155,8 +2183,6 @@ static void print_status_info(UnitStatusInfo *i) {
printf(")%s\n", off);
- on = off = NULL;
-
if (i->main_pid == p->pid &&
i->start_timestamp == p->start_timestamp &&
i->exit_timestamp == p->start_timestamp)
@@ -3230,7 +3256,7 @@ finish:
}
static int reset_failed(DBusConnection *bus, char **args) {
- DBusMessage *m = NULL, *reply = NULL;
+ DBusMessage *m = NULL;
int r;
DBusError error;
char **name;
@@ -3242,6 +3268,7 @@ static int reset_failed(DBusConnection *bus, char **args) {
return daemon_reload(bus, args);
STRV_FOREACH(name, args+1) {
+ DBusMessage *reply;
if (!(m = dbus_message_new_method_call(
"org.freedesktop.systemd1",
@@ -3278,9 +3305,6 @@ finish:
if (m)
dbus_message_unref(m);
- if (reply)
- dbus_message_unref(reply);
-
dbus_error_free(&error);
return r;
@@ -3438,7 +3462,7 @@ finish:
static int enable_sysv_units(char **args) {
int r = 0;
-#if defined (HAVE_SYSV_COMPAT) && (defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) || defined(TARGET_SUSE) || defined(TARGET_MEEGO) || defined(TARGET_ALTLINUX))
+#if defined (HAVE_SYSV_COMPAT) && (defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) || defined(TARGET_SUSE) || defined(TARGET_MEEGO) || defined(TARGET_ALTLINUX) || defined(TARGET_MAGEIA))
const char *verb = args[0];
unsigned f = 1, t = 1;
LookupPaths paths;
@@ -3929,6 +3953,7 @@ static int systemctl_help(void) {
" --no-wall Don't send wall message before halt/power-off/reboot\n"
" --no-reload When enabling/disabling unit files, don't reload daemon\n"
" configuration\n"
+ " --no-legend Do not print a legend (column headers and hints)\n"
" --no-pager Do not pipe output into a pager\n"
" --no-ask-password\n"
" Do not ask for system passwords\n"
@@ -4079,6 +4104,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
ARG_SYSTEM,
ARG_GLOBAL,
ARG_NO_BLOCK,
+ ARG_NO_LEGEND,
ARG_NO_PAGER,
ARG_NO_WALL,
ARG_ORDER,
@@ -4107,6 +4133,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
{ "system", no_argument, NULL, ARG_SYSTEM },
{ "global", no_argument, NULL, ARG_GLOBAL },
{ "no-block", no_argument, NULL, ARG_NO_BLOCK },
+ { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
{ "no-wall", no_argument, NULL, ARG_NO_WALL },
{ "quiet", no_argument, NULL, 'q' },
@@ -4195,6 +4222,10 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
arg_no_block = true;
break;
+ case ARG_NO_LEGEND:
+ arg_no_legend = true;
+ break;
+
case ARG_NO_PAGER:
arg_no_pager = true;
break;
@@ -4981,8 +5012,17 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError
return 0;
}
+ if (!bus) {
+ log_error("Failed to get D-Bus connection: %s",
+ dbus_error_is_set(error) ? error->message : "No connection to service manager.");
+ return -EIO;
+ }
+
+ } else {
+
if (!bus && !avoid_bus()) {
- log_error("Failed to get D-Bus connection: %s", error->message);
+ log_error("Failed to get D-Bus connection: %s",
+ dbus_error_is_set(error) ? error->message : "No connection to service manager.");
return -EIO;
}
}