TRANSPORT_POLKIT
} arg_transport = TRANSPORT_NORMAL;
static const char *arg_host = NULL;
-static bool arg_follow = false;
static unsigned arg_lines = 10;
static OutputMode arg_output = OUTPUT_SHORT;
static int daemon_reload(DBusConnection *bus, char **args);
static void halt_now(enum action a);
-static bool on_tty(void) {
- static int t = -1;
-
- /* Note that this is invoked relatively early, before we start
- * the pager. That means the value we return reflects whether
- * we originally were started on a tty, not if we currently
- * are. But this is intended, since we want colour and so on
- * when run in our own pager. */
-
- if (_unlikely_(t < 0))
- t = isatty(STDOUT_FILENO) > 0;
-
- return t;
-}
-
static void pager_open_if_enabled(void) {
- /* Cache result before we open the pager */
- on_tty();
-
if (arg_no_pager)
return;
}
#endif
+static const char *ansi_highlight(bool b) {
+
+ if (!on_tty())
+ return "";
+
+ return b ? ANSI_HIGHLIGHT_ON : ANSI_HIGHLIGHT_OFF;
+}
+
static const char *ansi_highlight_red(bool b) {
if (!on_tty())
} 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 (!arg_full && arg_no_pager)
- printf("%.*s\n", desc_len, "DESCRIPTION");
- else
- printf("%s\n", "DESCRIPTION");
- }
-
for (u = unit_infos; u < unit_infos + c; u++) {
char *e;
const char *on_loaded, *off_loaded;
if (!output_show_unit(u))
continue;
+ if (!n_shown && !arg_no_legend) {
+ printf("%-*s %-6s %-*s %-*s %-*s ", id_len, "UNIT", "LOAD",
+ active_len, "ACTIVE", sub_len, "SUB", job_len, "JOB");
+ if (!arg_full && arg_no_pager)
+ printf("%.*s\n", desc_len, "DESCRIPTION");
+ else
+ printf("%s\n", "DESCRIPTION");
+ }
+
n_shown++;
if (streq(u->load_state, "error")) {
}
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"
- "JOB = Pending job for the unit.\n");
+ const char *on, *off;
+
+ if (n_shown) {
+ 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"
+ "JOB = Pending job for the unit.\n\n");
+ on = ansi_highlight(true);
+ off = ansi_highlight(false);
+ } else {
+ on = ansi_highlight_red(true);
+ off = ansi_highlight_red(false);
+ }
if (arg_all)
- printf("\n%u loaded units listed.\n"
- "To show all installed unit files use 'systemctl list-unit-files'.\n", n_shown);
+ printf("%s%u loaded units listed.%s\n"
+ "To show all installed unit files use 'systemctl list-unit-files'.\n",
+ on, n_shown, off);
else
- printf("\n%u loaded units listed. Pass --all to see loaded but inactive units, too.\n"
- "To show all installed unit files use 'systemctl list-unit-files'.\n", n_shown);
+ printf("%s%u 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);
}
}
return -ECONNREFUSED;
}
- if (!arg_quiet && d.result) {
+ if (!d.result)
+ goto free_name;
+
+ if (!arg_quiet) {
if (streq(d.result, "timeout"))
log_error("Job for %s timed out.", strna(d.name));
else if (streq(d.result, "canceled"))
free(d.result);
d.result = NULL;
+ free_name:
free(d.name);
d.name = NULL;
}
- /* This is slightly dirty, since we don't undo the filter registration. */
+ dbus_connection_remove_filter(bus, wait_filter, &d);
return r;
}
DBusConnection *bus,
const char *unit_name) {
- DBusMessage _cleanup_dbus_msg_unref_ *reply = NULL;
+ _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
DBusMessageIter iter, sub;
char *service_trigger = NULL;
const char *interface = "org.freedesktop.systemd1.Unit",
DBusError *error,
Set *s) {
- DBusMessage _cleanup_dbus_msg_unref_ *reply = NULL;
+ _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
const char *path;
int r;
_cleanup_free_ char *n, *p = NULL;
p = NULL;
}
- /* When stopping a unit warn if it can still be triggered by
- * another active unit (socket, path, timer) */
- if (!arg_quiet && streq(method, "StopUnit"))
- check_triggering_units(bus, name);
-
return 0;
}
ret = r;
goto finish;
}
+
+ /* When stopping units, warn if they can still be triggered by
+ * another active unit (socket, path, timer) */
+ if (!arg_quiet && streq(method, "StopUnit")) {
+ if (one_name)
+ check_triggering_units(bus, one_name);
+ else
+ STRV_FOREACH(name, args+1)
+ check_triggering_units(bus, *name);
+ }
}
finish:
if (i->id && arg_transport != TRANSPORT_SSH) {
int flags =
arg_all * OUTPUT_SHOW_ALL |
- arg_follow * OUTPUT_FOLLOW |
- !arg_quiet * OUTPUT_WARN_CUTOFF |
- on_tty() * OUTPUT_COLOR;
+ (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
+ on_tty() * OUTPUT_COLOR |
+ !arg_quiet * OUTPUT_WARN_CUTOFF;
printf("\n");
- show_journal_by_unit(i->id, arg_output, 0,
+ show_journal_by_unit(stdout,
+ i->id,
+ arg_output,
+ 0,
i->inactive_exit_timestamp_monotonic,
- arg_lines, flags);
+ arg_lines,
+ flags);
}
if (i->need_daemon_reload)
}
static int set_environment(DBusConnection *bus, char **args) {
- DBusMessage *m = NULL, *reply = NULL;
+ _cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL;
DBusError error;
- int r;
const char *method;
- DBusMessageIter iter, sub;
- char **name;
+ DBusMessageIter iter;
+ int r;
+
+ assert(bus);
dbus_error_init(&error);
? "SetEnvironment"
: "UnsetEnvironment";
- if (!(m = dbus_message_new_method_call(
- "org.freedesktop.systemd1",
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
- method))) {
-
- log_error("Could not allocate message.");
- return -ENOMEM;
- }
+ m = dbus_message_new_method_call(
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ method);
+ if (!m)
+ return log_oom();
dbus_message_iter_init_append(m, &iter);
- if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &sub)) {
- log_error("Could not append arguments to message.");
- r = -ENOMEM;
- goto finish;
- }
-
- STRV_FOREACH(name, args+1)
- if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, name)) {
- log_error("Could not append arguments to message.");
- r = -ENOMEM;
- goto finish;
- }
-
- if (!dbus_message_iter_close_container(&iter, &sub)) {
- log_error("Could not append arguments to message.");
- r = -ENOMEM;
- goto finish;
- }
+ r = bus_append_strv_iter(&iter, args + 1);
+ if (r < 0)
+ return log_oom();
- if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
+ reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
+ if (!reply) {
log_error("Failed to issue method call: %s", bus_error_message(&error));
r = -EIO;
goto finish;
r = 0;
finish:
- if (m)
- dbus_message_unref(m);
-
- if (reply)
- dbus_message_unref(reply);
-
dbus_error_free(&error);
-
return r;
}
i = l;
STRV_FOREACH(name, original_names) {
- *i = unit_name_mangle(*name);
+
+ /* When enabling units qualified path names are OK,
+ * too, hence allow them explicitly. */
+
+ if (is_path(*name))
+ *i = strdup(*name);
+ else
+ *i = unit_name_mangle(*name);
+
if (!*i) {
strv_free(l);
return log_oom();
}
}
+ r = 0;
} else {
const char *method;
bool send_force = true, expect_carries_install_info = false;
" --root=PATH Enable unit files in the specified root directory\n"
" --runtime Enable unit files only temporarily until next reboot\n"
" -n --lines=INTEGER Journal entries to show\n"
- " --follow Follow journal\n"
" -o --output=STRING Change journal output mode (short, short-monotonic,\n"
- " verbose, export, json, json-pretty, cat)\n\n"
+ " verbose, export, json, json-pretty, json-sse, cat)\n\n"
"Unit Commands:\n"
" list-units List loaded units\n"
" start [NAME...] Start (activate) one or more units\n"
ARG_NO_ASK_PASSWORD,
ARG_FAILED,
ARG_RUNTIME,
- ARG_FOLLOW,
ARG_FORCE
};
{ "privileged",no_argument, NULL, 'P' },
{ "runtime", no_argument, NULL, ARG_RUNTIME },
{ "lines", required_argument, NULL, 'n' },
- { "follow", no_argument, NULL, ARG_FOLLOW },
{ "output", required_argument, NULL, 'o' },
{ NULL, 0, NULL, 0 }
};
arg_force ++;
break;
- case ARG_FOLLOW:
- arg_follow = true;
- break;
-
case 'f':
- /* -f is short for both --follow and --force! */
arg_force ++;
- arg_follow = true;
break;
case ARG_NO_RELOAD: