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;
}
static void pager_open_if_enabled(void) {
+
+ /* Cache result before we open the pager */
on_tty();
if (arg_no_pager)
}
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;
} 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, "");
-
- if (arg_full || !arg_no_pager)
- printf(" %s", u->description);
- else
- printf(" %.*s", columns() - a - b - 1, u->description);
- }
+ printf("%s\n", 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"
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;
}
}
static int load_unit(DBusConnection *bus, char **args) {
- DBusMessage *m = NULL, *reply = NULL;
+ DBusMessage *m = NULL;
DBusError error;
int r;
char **name;
assert(args);
STRV_FOREACH(name, args+1) {
+ DBusMessage *reply;
if (!(m = dbus_message_new_method_call(
"org.freedesktop.systemd1",
if (m)
dbus_message_unref(m);
- if (reply)
- dbus_message_unref(reply);
-
dbus_error_free(&error);
return r;
}
static int kill_unit(DBusConnection *bus, char **args) {
- DBusMessage *m = NULL, *reply = NULL;
+ DBusMessage *m = NULL;
int r = 0;
DBusError error;
char **name;
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",
if (m)
dbus_message_unref(m);
- if (reply)
- dbus_message_unref(reply);
-
dbus_error_free(&error);
return r;
const char *load_state;
const char *active_state;
const char *sub_state;
+ const char *unit_file_state;
const char *description;
const char *following;
if (i->load_error)
printf("\t Loaded: %s%s%s (Reason: %s)\n", on, strna(i->load_state), off, i->load_error);
+ else if (i->path && i->unit_file_state)
+ printf("\t Loaded: %s%s%s (%s; %s)\n", on, strna(i->load_state), off, i->path, i->unit_file_state);
else if (i->path)
printf("\t Loaded: %s%s%s (%s)\n", on, strna(i->load_state), off, i->path);
else
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)
if (i->running) {
char *t = NULL;
- get_process_name(i->main_pid, &t);
+ get_process_comm(i->main_pid, &t);
if (t) {
printf(" (%s)", t);
free(t);
printf(" Control: %u", (unsigned) i->control_pid);
- get_process_name(i->control_pid, &t);
+ get_process_comm(i->control_pid, &t);
if (t) {
printf(" (%s)", t);
free(t);
i->what = s;
else if (streq(name, "Following"))
i->following = s;
+ else if (streq(name, "UnitFileState"))
+ i->unit_file_state = s;
}
break;
} else if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING && streq(name, "LoadError")) {
const char *a = NULL, *b = NULL;
- if (bus_iter_get_basic_and_next(&sub, DBUS_TYPE_STRING, &a, true) > 0)
+ if (bus_iter_get_basic_and_next(&sub, DBUS_TYPE_STRING, &a, true) >= 0)
bus_iter_get_basic_and_next(&sub, DBUS_TYPE_STRING, &b, false);
if (arg_all || !isempty(a) || !isempty(b))
printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
+
+ return 0;
}
break;
return 0;
+ } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "ControlGroupAttributes")) {
+ DBusMessageIter sub, sub2;
+
+ dbus_message_iter_recurse(iter, &sub);
+ while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) {
+ const char *controller, *attr, *value;
+
+ dbus_message_iter_recurse(&sub, &sub2);
+
+ if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &controller, true) >= 0 &&
+ bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &attr, true) >= 0 &&
+ bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &value, false) >= 0) {
+
+ printf("ControlGroupAttribute={ controller=%s ; attribute=%s ; value=\"%s\" }\n",
+ controller,
+ attr,
+ value);
+ }
+
+ dbus_message_iter_next(&sub);
+ }
+
+ return 0;
+
} else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && startswith(name, "Exec")) {
DBusMessageIter sub;
}
static int reset_failed(DBusConnection *bus, char **args) {
- DBusMessage *m = NULL, *reply = NULL;
+ DBusMessage *m = NULL;
int r;
DBusError error;
char **name;
return daemon_reload(bus, args);
STRV_FOREACH(name, args+1) {
+ DBusMessage *reply;
if (!(m = dbus_message_new_method_call(
"org.freedesktop.systemd1",
if (m)
dbus_message_unref(m);
- if (reply)
- dbus_message_unref(reply);
-
dbus_error_free(&error);
return r;
" --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"
ARG_SYSTEM,
ARG_GLOBAL,
ARG_NO_BLOCK,
+ ARG_NO_LEGEND,
ARG_NO_PAGER,
ARG_NO_WALL,
ARG_ORDER,
{ "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' },
arg_no_block = true;
break;
+ case ARG_NO_LEGEND:
+ arg_no_legend = true;
+ break;
+
case ARG_NO_PAGER:
arg_no_pager = true;
break;
return 0;
}
-static bool kexec_loaded(void) {
- bool loaded = false;
- char *s;
-
- if (read_one_line_file("/sys/kernel/kexec_loaded", &s) >= 0) {
- if (s[0] == '1')
- loaded = true;
- free(s);
- }
- return loaded;
-}
-
static int shutdown_parse_argv(int argc, char *argv[]) {
enum {
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;
}
}
if (bus) {
/* First, try systemd via D-Bus. */
- if (daemon_reload(bus, NULL) > 0)
+ if (daemon_reload(bus, NULL) >= 0)
return 0;
}