#include "logs-show.h"
#include "path-util.h"
#include "socket-util.h"
+#include "fileio.h"
static const char *arg_type = NULL;
static const char *arg_load_state = NULL;
ACTION_CANCEL_SHUTDOWN,
_ACTION_MAX
} arg_action = ACTION_SYSTEMCTL;
-static enum dot {
- DOT_ALL,
- DOT_ORDER,
- DOT_REQUIRE
-} arg_dot = DOT_ALL;
static enum transport {
TRANSPORT_NORMAL,
TRANSPORT_SSH,
if (arg_no_pager)
return;
- pager_open();
+ pager_open(false);
}
static void ask_password_agent_open_if_enabled(void) {
return false;
}
-struct unit_info {
- const char *id;
- const char *description;
- const char *load_state;
- const char *active_state;
- const char *sub_state;
- const char *following;
- const char *unit_path;
- uint32_t job_id;
- const char *job_type;
- const char *job_path;
-};
-
static int compare_unit_info(const void *a, const void *b) {
const char *d1, *d2;
const struct unit_info *u = a, *v = b;
id_len = max_id_len;
for (u = unit_infos; u < unit_infos + c; u++) {
- char *e;
+ char _cleanup_free_ *e = NULL;
const char *on_loaded, *off_loaded;
const char *on_active, *off_active;
printf("%.*s\n", desc_len, u->description);
else
printf("%s\n", u->description);
-
- free(e);
}
if (!arg_no_legend) {
}
}
-static int list_units(DBusConnection *bus, char **args) {
- _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
- _cleanup_free_ struct unit_info *unit_infos = NULL;
- DBusMessageIter iter, sub, sub2;
- unsigned c = 0, n_units = 0;
+static int get_unit_list(DBusConnection *bus, DBusMessage **reply,
+ struct unit_info **unit_infos, unsigned *c) {
+ DBusMessageIter iter, sub;
+ unsigned n_units = 0;
int r;
- pager_open_if_enabled();
+ assert(bus);
+ assert(unit_infos);
+ assert(c);
r = bus_method_call_with_reply(
bus,
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
"ListUnits",
- &reply,
+ reply,
NULL,
DBUS_TYPE_INVALID);
if (r < 0)
return r;
- if (!dbus_message_iter_init(reply, &iter) ||
+ if (!dbus_message_iter_init(*reply, &iter) ||
dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT) {
log_error("Failed to parse reply.");
while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
struct unit_info *u;
- assert(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT);
-
- if (c >= n_units) {
+ if (*c >= n_units) {
struct unit_info *w;
- n_units = MAX(2*c, 16);
- w = realloc(unit_infos, sizeof(struct unit_info) * n_units);
+ n_units = MAX(2 * *c, 16);
+ w = realloc(*unit_infos, sizeof(struct unit_info) * n_units);
if (!w)
return log_oom();
- unit_infos = w;
+ *unit_infos = w;
}
- u = unit_infos + c;
-
- dbus_message_iter_recurse(&sub, &sub2);
+ u = *unit_infos + *c;
- if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &u->id, true) < 0 ||
- bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &u->description, true) < 0 ||
- bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &u->load_state, true) < 0 ||
- bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &u->active_state, true) < 0 ||
- bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &u->sub_state, true) < 0 ||
- bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &u->following, true) < 0 ||
- bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &u->unit_path, true) < 0 ||
- bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &u->job_id, true) < 0 ||
- bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &u->job_type, true) < 0 ||
- bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &u->job_path, false) < 0) {
- log_error("Failed to parse reply.");
- return -EIO;
- }
+ bus_parse_unit_info(&sub, u);
dbus_message_iter_next(&sub);
- c++;
+ (*c)++;
}
- if (c > 0) {
- qsort(unit_infos, c, sizeof(struct unit_info), compare_unit_info);
+ if (*c > 0)
+ qsort(*unit_infos, *c, sizeof(struct unit_info), compare_unit_info);
+
+ return 0;
+}
+
+static int list_units(DBusConnection *bus, char **args) {
+ _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
+ _cleanup_free_ struct unit_info *unit_infos = NULL;
+ unsigned c = 0;
+ int r;
+
+ pager_open_if_enabled();
+
+ r = get_unit_list(bus, &reply, &unit_infos, &c);
+ if (r < 0)
+ return r;
+
+ if (c > 0)
output_units_list(unit_infos, c);
- }
return 0;
}
printf("%-*s %-*s\n", id_cols, "UNIT FILE", state_cols, "STATE");
for (u = units; u < units + c; u++) {
- char *e;
+ char _cleanup_free_ *e = NULL;
const char *on, *off;
const char *id;
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 (!arg_no_legend)
int r = 0;
char **ret = NULL;
- char **c;
assert(bus);
assert(name);
while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
const char *prop;
- if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_DICT_ENTRY) {
- log_error("Failed to parse reply.");
- r = -EIO;
- goto finish;
- }
-
+ assert(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_DICT_ENTRY);
dbus_message_iter_recurse(&sub, &sub2);
if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &prop, true) < 0) {
assert(dbus_message_iter_get_arg_type(&sub4) == DBUS_TYPE_STRING);
dbus_message_iter_get_basic(&sub4, &s);
- c = strv_append(ret, s);
- if (c == NULL) {
- r = log_oom();
+
+ r = strv_extend(&ret, s);
+ if (r < 0) {
+ log_oom();
goto finish;
}
- strv_free(ret);
- ret = c;
+
dbus_message_iter_next(&sub4);
}
}
}
finish:
if (r < 0)
- strv_freep(&ret);
- *deps = ret;
+ strv_free(ret);
+ else
+ *deps = ret;
return r;
}
}
static int list_dependencies_one(DBusConnection *bus, const char *name, int level, char **units, unsigned int branches) {
- char **deps = NULL;
+ char _cleanup_strv_free_ **deps = NULL, **u;
char **c;
- char **u = NULL;
int r = 0;
u = strv_append(units, name);
- if(!u)
+ if (!u)
return log_oom();
r = list_dependencies_get_dependencies(bus, name, &deps);
if (r < 0)
- goto finish;
+ return r;
qsort(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
STRV_FOREACH(c, deps) {
if (strv_contains(u, *c)) {
r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
- if(r < 0)
- goto finish;
+ if (r < 0)
+ return r;
continue;
}
r = list_dependencies_print(*c, level, branches, c[1] == NULL);
- if(r < 0)
- goto finish;
+ if (r < 0)
+ return r;
if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
r = list_dependencies_one(bus, *c, level + 1, u, (branches << 1) | (c[1] == NULL ? 0 : 1));
if(r < 0)
- goto finish;
+ return r;
}
}
- r = 0;
-finish:
- strv_free(deps);
- strv_free(u);
- return r;
+ return 0;
}
static int list_dependencies(DBusConnection *bus, char **args) {
- int r = 0;
_cleanup_free_ char *unit = NULL;
+ const char *u;
assert(bus);
- assert(args[1]);
- unit = unit_name_mangle(args[1]);
- if (!unit)
- return log_oom();
+ if (args[1]) {
+ unit = unit_name_mangle(args[1]);
+ if (!unit)
+ return log_oom();
+ u = unit;
+ } else
+ u = SPECIAL_DEFAULT_TARGET;
pager_open_if_enabled();
- printf("%s\n", unit);
- r = list_dependencies_one(bus, unit, 0, NULL, 0);
- return r;
-}
-
-static int dot_one_property(const char *name, const char *prop, DBusMessageIter *iter) {
-
- static const char * const colors[] = {
- "Requires", "[color=\"black\"]",
- "RequiresOverridable", "[color=\"black\"]",
- "Requisite", "[color=\"darkblue\"]",
- "RequisiteOverridable", "[color=\"darkblue\"]",
- "Wants", "[color=\"grey66\"]",
- "Conflicts", "[color=\"red\"]",
- "ConflictedBy", "[color=\"red\"]",
- "After", "[color=\"green\"]"
- };
-
- const char *c = NULL;
- unsigned i;
-
- assert(name);
- assert(prop);
- assert(iter);
-
- for (i = 0; i < ELEMENTSOF(colors); i += 2)
- if (streq(colors[i], prop)) {
- c = colors[i+1];
- break;
- }
-
- if (!c)
- return 0;
-
- if (arg_dot != DOT_ALL)
- if ((arg_dot == DOT_ORDER) != streq(prop, "After"))
- return 0;
-
- switch (dbus_message_iter_get_arg_type(iter)) {
-
- case DBUS_TYPE_ARRAY:
-
- if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRING) {
- DBusMessageIter sub;
- dbus_message_iter_recurse(iter, &sub);
-
- while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
- const char *s;
-
- assert(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING);
- dbus_message_iter_get_basic(&sub, &s);
- printf("\t\"%s\"->\"%s\" %s;\n", name, s, c);
-
- dbus_message_iter_next(&sub);
- }
+ puts(u);
- return 0;
- }
- }
-
- return 0;
-}
-
-static int dot_one(DBusConnection *bus, const char *name, const char *path) {
- _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
- const char *interface = "org.freedesktop.systemd1.Unit";
- int r;
- DBusMessageIter iter, sub, sub2, sub3;
-
- assert(bus);
- assert(path);
-
- r = bus_method_call_with_reply(
- bus,
- "org.freedesktop.systemd1",
- path,
- "org.freedesktop.DBus.Properties",
- "GetAll",
- &reply,
- NULL,
- DBUS_TYPE_STRING, &interface,
- DBUS_TYPE_INVALID);
- if (r < 0)
- return r;
-
- if (!dbus_message_iter_init(reply, &iter) ||
- dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
- dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_DICT_ENTRY) {
- log_error("Failed to parse reply.");
- return -EIO;
- }
-
- dbus_message_iter_recurse(&iter, &sub);
-
- while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
- const char *prop;
-
- assert(dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_DICT_ENTRY);
- dbus_message_iter_recurse(&sub, &sub2);
-
- if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &prop, true) < 0 ||
- dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_VARIANT) {
- log_error("Failed to parse reply.");
- return -EIO;
- }
-
- dbus_message_iter_recurse(&sub2, &sub3);
- r = dot_one_property(name, prop, &sub3);
- if (r < 0)
- return r;
-
- dbus_message_iter_next(&sub);
- }
-
- return 0;
-}
-
-static int dot(DBusConnection *bus, char **args) {
- _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
- DBusMessageIter iter, sub, sub2;
- int r;
-
- r = bus_method_call_with_reply(
- bus,
- "org.freedesktop.systemd1",
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
- "ListUnits",
- &reply,
- NULL,
- DBUS_TYPE_INVALID);
- if (r < 0)
- return r;
-
- if (!dbus_message_iter_init(reply, &iter) ||
- dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
- dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT) {
- log_error("Failed to parse reply.");
- return -EIO;
- }
-
- printf("digraph systemd {\n");
-
- dbus_message_iter_recurse(&iter, &sub);
- while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
- const char *id, *description, *load_state, *active_state, *sub_state, *following, *unit_path;
-
- if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) {
- log_error("Failed to parse reply.");
- return -EIO;
- }
-
- dbus_message_iter_recurse(&sub, &sub2);
-
- if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &id, true) < 0 ||
- bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &description, true) < 0 ||
- bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &load_state, true) < 0 ||
- bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &active_state, true) < 0 ||
- bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &sub_state, true) < 0 ||
- bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &following, true) < 0 ||
- bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &unit_path, true) < 0) {
- log_error("Failed to parse reply.");
- return -EIO;
- }
-
- r = dot_one(bus, id, unit_path);
- if (r < 0)
- return r;
-
- /* printf("\t\"%s\";\n", id); */
- dbus_message_iter_next(&sub);
- }
-
- printf("}\n");
-
- log_info(" Color legend: black = Requires\n"
- " dark blue = Requisite\n"
- " dark grey = Wants\n"
- " red = Conflicts\n"
- " green = After\n");
-
- if (on_tty())
- log_notice("-- You probably want to process this output with graphviz' dot tool.\n"
- "-- Try a shell pipeline like 'systemctl dot | dot -Tsvg > systemd.svg'!\n");
-
- return 0;
+ return list_dependencies_one(bus, u, 0, NULL, 0);
}
static int list_jobs(DBusConnection *bus, char **args) {
while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
const char *name, *type, *state, *job_path, *unit_path;
uint32_t id;
- char *e;
+ char _cleanup_free_ *e = NULL;
if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) {
log_error("Failed to parse reply.");
e = arg_full ? NULL : ellipsize(name, 25, 33);
printf("%4u %-25s %-15s %-7s\n", id, e ? e : name, type, state);
- free(e);
k++;
if (!n)
return log_oom();
- r = bus_method_call_with_reply (
+ r = bus_method_call_with_reply(
bus,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
} WaitData;
static DBusHandlerResult wait_filter(DBusConnection *connection, DBusMessage *message, void *data) {
- DBusError error;
+ DBusError _cleanup_dbus_error_free_ error;
WaitData *d = data;
+ dbus_error_init(&error);
+
assert(connection);
assert(message);
assert(d);
- dbus_error_init(&error);
-
log_debug("Got D-Bus request: %s.%s() on %s",
dbus_message_get_interface(message),
dbus_message_get_member(message),
if (!isempty(unit))
d->name = strdup(unit);
- goto finish;
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
#ifndef LEGACY
dbus_error_free(&error);
if (*result)
d->result = strdup(result);
- goto finish;
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
#endif
log_error("Failed to parse message: %s", bus_error_message(&error));
}
-finish:
- dbus_error_free(&error);
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
_cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
DBusMessageIter iter, sub;
const char *interface = "org.freedesktop.systemd1.Unit",
- *triggered_by_property = "TriggeredBy";
+ *load_state_property = "LoadState",
+ *triggered_by_property = "TriggeredBy",
+ *state;
char _cleanup_free_ *unit_path = NULL, *n = NULL;
bool print_warning_label = true;
int r;
return;
}
+ r = bus_method_call_with_reply(
+ bus,
+ "org.freedesktop.systemd1",
+ unit_path,
+ "org.freedesktop.DBus.Properties",
+ "Get",
+ &reply,
+ NULL,
+ DBUS_TYPE_STRING, &interface,
+ DBUS_TYPE_STRING, &load_state_property,
+ DBUS_TYPE_INVALID);
+ if (r < 0)
+ return;
+
+ if (!dbus_message_iter_init(reply, &iter) ||
+ dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) {
+ log_error("Failed to parse reply.");
+ return;
+ }
+
+ dbus_message_iter_recurse(&iter, &sub);
+
+ if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) {
+ log_error("Failed to parse reply.");
+ return;
+ }
+
+ dbus_message_iter_get_basic(&sub, &state);
+
+ if (streq(state, "masked"))
+ return;
+
+ dbus_message_unref(reply);
+ reply = NULL;
+
r = bus_method_call_with_reply(
bus,
"org.freedesktop.systemd1",
return 0;
}
+static const struct {
+ const char *target;
+ const char *verb;
+ const char *mode;
+} action_table[_ACTION_MAX] = {
+ [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
+ [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
+ [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
+ [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
+ [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
+ [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
+ [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
+ [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
+ [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
+ [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
+ [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
+ [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
+ [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
+ [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
+ [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
+};
+
static enum action verb_to_action(const char *verb) {
- if (streq(verb, "halt"))
- return ACTION_HALT;
- else if (streq(verb, "poweroff"))
- return ACTION_POWEROFF;
- else if (streq(verb, "reboot"))
- return ACTION_REBOOT;
- else if (streq(verb, "kexec"))
- return ACTION_KEXEC;
- else if (streq(verb, "rescue"))
- return ACTION_RESCUE;
- else if (streq(verb, "emergency"))
- return ACTION_EMERGENCY;
- else if (streq(verb, "default"))
- return ACTION_DEFAULT;
- else if (streq(verb, "exit"))
- return ACTION_EXIT;
- else if (streq(verb, "suspend"))
- return ACTION_SUSPEND;
- else if (streq(verb, "hibernate"))
- return ACTION_HIBERNATE;
- else if (streq(verb, "hybrid-sleep"))
- return ACTION_HYBRID_SLEEP;
- else
- return ACTION_INVALID;
+ enum action i;
+
+ for (i = ACTION_INVALID; i < _ACTION_MAX; i++)
+ if (action_table[i].verb && streq(verb, action_table[i].verb))
+ return i;
+ return ACTION_INVALID;
}
static int start_unit(DBusConnection *bus, char **args) {
- static const char * const table[_ACTION_MAX] = {
- [ACTION_HALT] = SPECIAL_HALT_TARGET,
- [ACTION_POWEROFF] = SPECIAL_POWEROFF_TARGET,
- [ACTION_REBOOT] = SPECIAL_REBOOT_TARGET,
- [ACTION_KEXEC] = SPECIAL_KEXEC_TARGET,
- [ACTION_RUNLEVEL2] = SPECIAL_RUNLEVEL2_TARGET,
- [ACTION_RUNLEVEL3] = SPECIAL_RUNLEVEL3_TARGET,
- [ACTION_RUNLEVEL4] = SPECIAL_RUNLEVEL4_TARGET,
- [ACTION_RUNLEVEL5] = SPECIAL_RUNLEVEL5_TARGET,
- [ACTION_RESCUE] = SPECIAL_RESCUE_TARGET,
- [ACTION_EMERGENCY] = SPECIAL_EMERGENCY_TARGET,
- [ACTION_DEFAULT] = SPECIAL_DEFAULT_TARGET,
- [ACTION_EXIT] = SPECIAL_EXIT_TARGET,
- [ACTION_SUSPEND] = SPECIAL_SUSPEND_TARGET,
- [ACTION_HIBERNATE] = SPECIAL_HIBERNATE_TARGET,
- [ACTION_HYBRID_SLEEP] = SPECIAL_HYBRID_SLEEP_TARGET
- };
-
int r, ret = 0;
const char *method, *mode, *one_name;
- Set *s = NULL;
- DBusError error;
+ Set _cleanup_set_free_free_ *s = NULL;
+ DBusError _cleanup_dbus_error_free_ error;
char **name;
dbus_error_init(&error);
ask_password_agent_open_if_enabled();
if (arg_action == ACTION_SYSTEMCTL) {
+ enum action action;
method =
streq(args[0], "stop") ||
streq(args[0], "condstop") ? "StopUnit" :
streq(args[0], "force-reload") ? "ReloadOrTryRestartUnit" :
"StartUnit";
+ action = verb_to_action(args[0]);
- mode =
- (streq(args[0], "isolate") ||
- streq(args[0], "rescue") ||
- streq(args[0], "emergency")) ? "isolate" : arg_job_mode;
+ mode = streq(args[0], "isolate") ? "isolate" :
+ action_table[action].mode ?: arg_job_mode;
- one_name = table[verb_to_action(args[0])];
+ one_name = action_table[action].target;
} else {
- assert(arg_action < ELEMENTSOF(table));
- assert(table[arg_action]);
+ assert(arg_action < ELEMENTSOF(action_table));
+ assert(action_table[arg_action].target);
method = "StartUnit";
- mode = (arg_action == ACTION_EMERGENCY ||
- arg_action == ACTION_RESCUE ||
- arg_action == ACTION_RUNLEVEL2 ||
- arg_action == ACTION_RUNLEVEL3 ||
- arg_action == ACTION_RUNLEVEL4 ||
- arg_action == ACTION_RUNLEVEL5) ? "isolate" : "replace";
-
- one_name = table[arg_action];
+ mode = action_table[arg_action].mode;
+ one_name = action_table[arg_action].target;
}
if (!arg_no_block) {
ret = enable_wait_for_jobs(bus);
if (ret < 0) {
log_error("Could not watch jobs: %s", strerror(-ret));
- goto finish;
+ return ret;
}
s = set_new(string_hash_func, string_compare_func);
- if (!s) {
- ret = log_oom();
- goto finish;
- }
+ if (!s)
+ return log_oom();
}
if (one_name) {
if (!arg_no_block) {
r = wait_for_jobs(bus, s);
- if (r < 0) {
- ret = r;
- goto finish;
- }
+ if (r < 0)
+ return r;
/* When stopping units, warn if they can still be triggered by
* another active unit (socket, path, timer) */
}
}
-finish:
- set_free_free(s);
- dbus_error_free(&error);
-
return ret;
}
return 0;
log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
- a == ACTION_HALT ? "halt" :
- a == ACTION_POWEROFF ? "poweroff" :
- a == ACTION_REBOOT ? "reboot" :
- a == ACTION_KEXEC ? "kexec" :
- a == ACTION_SUSPEND ? "suspend" :
- a == ACTION_HIBERNATE ? "hibernate" : "hybrid-sleep");
+ action_table[a].verb);
return -EPERM;
#else
}
r = start_unit(bus, args);
- if (r >= 0)
+ if (r == EXIT_SUCCESS)
warn_wall(a);
return r;
}
static int set_cgroup(DBusConnection *bus, char **args) {
+ _cleanup_free_ char *n = NULL;
+ const char *method, *runtime;
+ char **argument;
+ int r;
+
+ assert(bus);
+ assert(args);
+
+ method =
+ streq(args[0], "set-cgroup") ? "SetUnitControlGroup" :
+ streq(args[0], "unset-cgroup") ? "UnsetUnitControlGroup"
+ : "UnsetUnitControlGroupAttribute";
+
+ runtime = arg_runtime ? "runtime" : "persistent";
+
+ n = unit_name_mangle(args[1]);
+ if (!n)
+ return log_oom();
+
+ STRV_FOREACH(argument, args + 2) {
+
+ r = bus_method_call_with_reply(
+ bus,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ method,
+ NULL,
+ NULL,
+ DBUS_TYPE_STRING, &n,
+ DBUS_TYPE_STRING, argument,
+ DBUS_TYPE_STRING, &runtime,
+ DBUS_TYPE_INVALID);
+ if (r < 0)
+ return r;
+ }
+
+ return 0;
+}
+
+static int set_cgroup_attr(DBusConnection *bus, char **args) {
_cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL;
DBusError error;
- const char *method;
DBusMessageIter iter;
- int r;
_cleanup_free_ char *n = NULL;
+ const char *runtime;
+ int r;
assert(bus);
assert(args);
dbus_error_init(&error);
- method =
- streq(args[0], "set-cgroup") ? "SetUnitControlGroups" :
- streq(args[0], "unset-group") ? "UnsetUnitControlGroups"
- : "UnsetUnitControlGroupAttributes";
+ runtime = arg_runtime ? "runtime" : "persistent";
n = unit_name_mangle(args[1]);
if (!n)
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
- method);
+ "SetUnitControlGroupAttribute");
if (!m)
return log_oom();
dbus_message_iter_init_append(m, &iter);
- if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &n))
+ if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &n) ||
+ !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &args[2]))
return log_oom();
- r = bus_append_strv_iter(&iter, args + 2);
+ r = bus_append_strv_iter(&iter, args + 3);
if (r < 0)
return log_oom();
+ if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &runtime))
+ return log_oom();
+
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));
return 0;
}
-static int set_cgroup_attr(DBusConnection *bus, char **args) {
- _cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL;
- DBusError error;
- DBusMessageIter iter, sub, sub2;
- char **x, **y;
+static int get_cgroup_attr(DBusConnection *bus, char **args) {
+ _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
_cleanup_free_ char *n = NULL;
+ char **argument;
+ int r;
assert(bus);
assert(args);
- dbus_error_init(&error);
-
- if (strv_length(args) % 2 != 0) {
- log_error("Expecting an uneven number of arguments!");
- return -EINVAL;
- }
-
n = unit_name_mangle(args[1]);
if (!n)
return log_oom();
- m = dbus_message_new_method_call(
- "org.freedesktop.systemd1",
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
- "SetUnitControlGroupAttributes");
- if (!m)
- return log_oom();
+ STRV_FOREACH(argument, args + 2) {
+ _cleanup_strv_free_ char **list = NULL;
+ DBusMessageIter iter;
+ char **a;
- dbus_message_iter_init_append(m, &iter);
- if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &n) ||
- !dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(ss)", &sub))
- return log_oom();
+ r = bus_method_call_with_reply(
+ bus,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "GetUnitControlGroupAttribute",
+ &reply,
+ NULL,
+ DBUS_TYPE_STRING, &n,
+ DBUS_TYPE_STRING, argument,
+ DBUS_TYPE_INVALID);
+ if (r < 0)
+ return r;
- STRV_FOREACH_PAIR(x, y, args + 2) {
- if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) ||
- !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, x) ||
- !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, y) ||
- !dbus_message_iter_close_container(&sub, &sub2))
- return log_oom();
- }
+ if (!dbus_message_iter_init(reply, &iter)) {
+ log_error("Failed to initialize iterator.");
+ return -EIO;
+ }
- if (!dbus_message_iter_close_container(&iter, &sub))
- return -ENOMEM;
+ r = bus_parse_strv_iter(&iter, &list);
+ if (r < 0) {
+ log_error("Failed to parse value list.");
+ return r;
+ }
- 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));
- dbus_error_free(&error);
- return -EIO;
+ STRV_FOREACH(a, list) {
+ if (endswith(*a, "\n"))
+ fputs(*a, stdout);
+ else
+ puts(*a);
+ }
}
return 0;
0,
i->inactive_exit_timestamp_monotonic,
arg_lines,
- flags);
+ getuid(),
+ flags,
+ arg_scope == UNIT_FILE_SYSTEM);
}
if (i->need_daemon_reload)
if (startswith(*p, "man:")) {
size_t k;
char *e = NULL;
- char *page = NULL, *section = NULL;
+ char _cleanup_free_ *page = NULL, *section = NULL;
const char *args[4] = { "man", NULL, NULL, NULL };
pid_t pid;
if (e) {
page = strndup((*p) + 4, e - *p - 4);
- if (!page) {
- log_oom();
- return;
- }
-
section = strndup(e + 1, *p + k - e - 2);
- if (!section) {
- free(page);
+ if (!page || !section) {
log_oom();
return;
}
pid = fork();
if (pid < 0) {
log_error("Failed to fork: %m");
- free(page);
- free(section);
continue;
}
_exit(EXIT_FAILURE);
}
- free(page);
- free(section);
-
wait_for_terminate(pid, NULL);
} else
log_info("Can't show: %s", *p);
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",
+ printf("ControlGroupAttributes={ controller=%s ; attribute=%s ; value=\"%s\" }\n",
controller,
attr,
value);
zero(info);
if (exec_status_info_deserialize(&sub, &info) >= 0) {
char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
- char *t;
+ char _cleanup_free_ *t;
t = strv_join(info.argv, " ");
info.status,
info.code == CLD_EXITED ? "" : "/",
strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
-
- free(t);
}
free(info.path);
static int show_one_by_pid(const char *verb, DBusConnection *bus, uint32_t pid, bool *new_line) {
_cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
const char *path = NULL;
- DBusError error;
+ DBusError _cleanup_dbus_error_free_ error;
int r;
dbus_error_init(&error);
DBUS_TYPE_UINT32, &pid,
DBUS_TYPE_INVALID);
if (r < 0)
- goto finish;
+ return r;
if (!dbus_message_get_args(reply, &error,
DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_INVALID)) {
log_error("Failed to parse reply: %s", bus_error_message(&error));
- r = -EIO;
- goto finish;
+ return -EIO;
}
r = show_one(verb, bus, path, false, new_line);
+ return r;
+}
-finish:
- dbus_error_free(&error);
+static int show_all(const char* verb, DBusConnection *bus, bool show_properties, bool *new_line) {
+ _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
+ _cleanup_free_ struct unit_info *unit_infos = NULL;
+ unsigned c = 0;
+ const struct unit_info *u;
+ int r;
- return r;
+ r = get_unit_list(bus, &reply, &unit_infos, &c);
+ if (r < 0)
+ return r;
+
+ for (u = unit_infos; u < unit_infos + c; u++) {
+ char _cleanup_free_ *p = NULL;
+
+ if (!output_show_unit(u))
+ continue;
+
+ p = unit_dbus_path_from_name(u->id);
+ if (!p)
+ return log_oom();
+
+ printf("%s -> '%s'\n", u->id, p);
+
+ r = show_one(verb, bus, p, show_properties, new_line);
+ if (r != 0)
+ return r;
+ }
+
+ return 0;
}
static int show(DBusConnection *bus, char **args) {
int r, ret = 0;
- bool show_properties, new_line = false;
+ bool show_properties, show_status, new_line = false;
char **name;
assert(bus);
assert(args);
show_properties = streq(args[0], "show");
+ show_status = streq(args[0], "status");
if (show_properties)
pager_open_if_enabled();
if (show_properties && strv_length(args) <= 1)
return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line);
+ if (show_status && strv_length(args) <= 1)
+ return show_all(args[0], bus, false, &new_line);
+
STRV_FOREACH(name, args+1) {
uint32_t id;
UnitFileChange *changes = NULL;
unsigned n_changes = 0, i;
int carries_install_info = -1;
- DBusMessage *m = NULL, *reply = NULL;
+ DBusMessage _cleanup_dbus_message_unref_ *m = NULL, *reply = NULL;
int r;
- DBusError error;
- char **mangled_names = NULL;
+ DBusError _cleanup_dbus_error_free_ error;
+ char _cleanup_strv_free_ **mangled_names = NULL;
+
+ dbus_error_init(&error);
r = enable_sysv_units(args);
if (r < 0)
if (!args[1])
return 0;
- dbus_error_init(&error);
-
if (!bus || avoid_bus()) {
if (streq(verb, "enable")) {
r = unit_file_enable(arg_scope, arg_runtime, arg_root, args+1, arg_force, &changes, &n_changes);
}
if (carries_install_info == 0)
- log_warning(
-"The unit files have no [Install] section. They are not meant to be enabled\n"
-"using systemctl.\n"
-"Possible reasons for having this kind of units are:\n"
-"1) A unit may be statically enabled by being symlinked from another unit's\n"
-" .wants/ or .requires/ directory.\n"
-"2) A unit's purpose may be to act as a helper for some other unit which has\n"
-" a requirement dependency on it.\n"
-"3) A unit may be started when needed via activation (socket, path, timer,\n"
-" D-Bus, udev, scripted systemctl call, ...).\n");
+ log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
+ "using systemctl.\n"
+ "Possible reasons for having this kind of units are:\n"
+ "1) A unit may be statically enabled by being symlinked from another unit's\n"
+ " .wants/ or .requires/ directory.\n"
+ "2) A unit's purpose may be to act as a helper for some other unit which has\n"
+ " a requirement dependency on it.\n"
+ "3) A unit may be started when needed via activation (socket, path, timer,\n"
+ " D-Bus, udev, scripted systemctl call, ...).\n");
finish:
- if (m)
- dbus_message_unref(m);
-
- if (reply)
- dbus_message_unref(reply);
-
unit_file_changes_free(changes, n_changes);
- dbus_error_free(&error);
-
- strv_free(mangled_names);
-
return r;
}
static int unit_is_enabled(DBusConnection *bus, char **args) {
- DBusError error;
+ DBusError _cleanup_dbus_error_free_ error;
int r;
- DBusMessage *reply = NULL;
+ DBusMessage _cleanup_dbus_message_unref_ *reply = NULL;
bool enabled;
char **name;
+ char *n;
dbus_error_init(&error);
STRV_FOREACH(name, args+1) {
UnitFileState state;
- state = unit_file_get_state(arg_scope, arg_root, *name);
- if (state < 0) {
- r = state;
- goto finish;
- }
+ n = unit_name_mangle(*name);
+ if (!n)
+ return log_oom();
+
+ state = unit_file_get_state(arg_scope, arg_root, n);
+
+ free(n);
+
+ if (state < 0)
+ return state;
if (state == UNIT_FILE_ENABLED ||
state == UNIT_FILE_ENABLED_RUNTIME ||
STRV_FOREACH(name, args+1) {
const char *s;
+ n = unit_name_mangle(*name);
+ if (!n)
+ return log_oom();
+
r = bus_method_call_with_reply (
bus,
"org.freedesktop.systemd1",
"GetUnitFileState",
&reply,
NULL,
- DBUS_TYPE_STRING, name,
+ DBUS_TYPE_STRING, &n,
DBUS_TYPE_INVALID);
+
+ free(n);
+
if (r)
- goto finish;
+ return r;
if (!dbus_message_get_args(reply, &error,
DBUS_TYPE_STRING, &s,
DBUS_TYPE_INVALID)) {
log_error("Failed to parse reply: %s", bus_error_message(&error));
- r = -EIO;
- goto finish;
+ return -EIO;
}
dbus_message_unref(reply);
}
}
- r = enabled ? 0 : 1;
-
-finish:
- if (reply)
- dbus_message_unref(reply);
-
- dbus_error_free(&error);
- return r;
+ return enabled ? 0 : 1;
}
static int systemctl_help(void) {
" --no-pager Do not pipe output into a pager\n"
" --no-ask-password\n"
" Do not ask for system passwords\n"
- " --order When generating graph for dot, show only order\n"
- " --require When generating graph for dot, show only requirement\n"
" --system Connect to system manager\n"
" --user Connect to user service manager\n"
" --global Enable/disable unit files globally\n"
" help [NAME...|PID...] Show manual for one or more units\n"
" reset-failed [NAME...] Reset failed state for all, one, or more\n"
" units\n"
- " set-cgroup [NAME] [CGROUP...] Add unit to a control group\n"
- " unset-cgroup [NAME] [CGROUP...] Remove unit from a control group\n"
+ " get-cgroup-attr [NAME] [ATTR] ...\n"
+ " Get control group attrubute\n"
" set-cgroup-attr [NAME] [ATTR] [VALUE] ...\n"
" Set control group attribute\n"
" unset-cgroup-attr [NAME] [ATTR...]\n"
" Unset control group attribute\n"
+ " set-cgroup [NAME] [CGROUP...] Add unit to a control group\n"
+ " unset-cgroup [NAME] [CGROUP...] Remove unit from a control group\n"
" load [NAME...] Load one or more units\n"
" list-dependencies [NAME] Recursively show units which are required\n"
" or wanted by this unit\n\n"
" cancel [JOB...] Cancel all, one, or more jobs\n\n"
"Status Commands:\n"
" dump Dump server status\n"
- " dot Dump dependency graph for dot(1)\n\n"
"Snapshot Commands:\n"
" snapshot [NAME] Create a snapshot\n"
" delete [NAME...] Remove one or more snapshots\n\n"
enum {
ARG_FAIL = 0x100,
+ ARG_IRREVERSIBLE,
ARG_IGNORE_DEPENDENCIES,
ARG_VERSION,
ARG_USER,
ARG_NO_LEGEND,
ARG_NO_PAGER,
ARG_NO_WALL,
- ARG_ORDER,
- ARG_REQUIRE,
ARG_ROOT,
ARG_FULL,
ARG_NO_RELOAD,
{ "failed", no_argument, NULL, ARG_FAILED },
{ "full", no_argument, NULL, ARG_FULL },
{ "fail", no_argument, NULL, ARG_FAIL },
+ { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE },
{ "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES },
{ "ignore-inhibitors", no_argument, NULL, 'i' },
{ "user", no_argument, NULL, ARG_USER },
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
{ "no-wall", no_argument, NULL, ARG_NO_WALL },
{ "quiet", no_argument, NULL, 'q' },
- { "order", no_argument, NULL, ARG_ORDER },
- { "require", no_argument, NULL, ARG_REQUIRE },
{ "root", required_argument, NULL, ARG_ROOT },
{ "force", no_argument, NULL, ARG_FORCE },
{ "no-reload", no_argument, NULL, ARG_NO_RELOAD },
log_info("Use -t help to see a list of allowed values.");
return -EINVAL;
case 'p': {
- char **l;
+ char *word, *state;
+ size_t size;
+ /* Make sure that if the empty property list
+ was specified, we won't show any properties. */
+ const char *source = isempty(optarg) ? " " : optarg;
+
+ FOREACH_WORD_SEPARATOR(word, size, source, ",", state) {
+ char _cleanup_free_ *prop;
+ char **tmp;
+
+ prop = strndup(word, size);
+ if (!prop)
+ return -ENOMEM;
- if (!(l = strv_append(arg_property, optarg)))
- return -ENOMEM;
+ tmp = strv_append(arg_property, prop);
+ if (!tmp)
+ return -ENOMEM;
- strv_free(arg_property);
- arg_property = l;
+ strv_free(arg_property);
+ arg_property = tmp;
+ }
/* If the user asked for a particular
* property, show it to him, even if it is
* empty. */
arg_all = true;
+
break;
}
arg_job_mode = "fail";
break;
+ case ARG_IRREVERSIBLE:
+ arg_job_mode = "replace-irreversibly";
+ break;
+
case ARG_IGNORE_DEPENDENCIES:
arg_job_mode = "ignore-dependencies";
break;
arg_no_wall = true;
break;
- case ARG_ORDER:
- arg_dot = DOT_ORDER;
- break;
-
- case ARG_REQUIRE:
- arg_dot = DOT_REQUIRE;
- break;
-
case ARG_ROOT:
arg_root = optarg;
break;
}
static int talk_upstart(void) {
- DBusMessage *m = NULL, *reply = NULL;
- DBusError error;
+ DBusMessage _cleanup_dbus_message_unref_ *m = NULL, *reply = NULL;
+ DBusError _cleanup_dbus_error_free_ error;
int previous, rl, r;
char
env1_buf[] = "RUNLEVEL=X",
r = 1;
finish:
- if (m)
- dbus_message_unref(m);
-
- if (reply)
- dbus_message_unref(reply);
-
if (bus) {
dbus_connection_flush(bus);
dbus_connection_close(bus);
dbus_connection_unref(bus);
}
- dbus_error_free(&error);
-
return r;
}
static int talk_initctl(void) {
- struct init_request request;
- int r, fd;
+ struct init_request request = {0};
+ int r;
+ int _cleanup_close_ fd = -1;
char rl;
- if (!(rl = action_to_runlevel()))
+ rl = action_to_runlevel();
+ if (!rl)
return 0;
- zero(request);
request.magic = INIT_MAGIC;
request.sleeptime = 0;
request.cmd = INIT_CMD_RUNLVL;
request.runlevel = rl;
- if ((fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY)) < 0) {
-
+ fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
+ if (fd < 0) {
if (errno == ENOENT)
return 0;
errno = 0;
r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
- close_nointr_nofail(fd);
-
- if (r < 0) {
+ if (r) {
log_error("Failed to write to "INIT_FIFO": %m");
return errno ? -errno : -EIO;
}
{ "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
{ "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
{ "isolate", EQUAL, 2, start_unit },
- { "set-cgroup", MORE, 2, set_cgroup },
- { "unset-cgroup", MORE, 2, set_cgroup },
- { "set-cgroup-attr", MORE, 2, set_cgroup_attr },
- { "unset-cgroup-attr", MORE, 2, set_cgroup },
+ { "set-cgroup", MORE, 3, set_cgroup },
+ { "unset-cgroup", MORE, 3, set_cgroup },
+ { "get-cgroup-attr", MORE, 3, get_cgroup_attr },
+ { "set-cgroup-attr", MORE, 4, set_cgroup_attr },
+ { "unset-cgroup-attr", MORE, 3, set_cgroup },
{ "kill", MORE, 2, kill_unit },
{ "is-active", MORE, 2, check_unit_active },
{ "check", MORE, 2, check_unit_active },
{ "is-failed", MORE, 2, check_unit_failed },
{ "show", MORE, 1, show },
- { "status", MORE, 2, show },
+ { "status", MORE, 1, show },
{ "help", MORE, 2, show },
{ "dump", EQUAL, 1, dump },
- { "dot", EQUAL, 1, dot },
{ "snapshot", LESS, 2, snapshot },
{ "delete", MORE, 2, delete_snapshot },
{ "daemon-reload", EQUAL, 1, daemon_reload },
{ "unmask", MORE, 2, enable_unit },
{ "link", MORE, 2, enable_unit },
{ "switch-root", MORE, 2, switch_root },
- { "list-dependencies", EQUAL, 2, list_dependencies },
+ { "list-dependencies", LESS, 2, list_dependencies },
};
int left;
}
static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
- int fd;
+ int _cleanup_close_ fd;
struct msghdr msghdr;
struct iovec iovec[2];
union sockaddr_union sockaddr;
}
msghdr.msg_iov = iovec;
- if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0) {
- close_nointr_nofail(fd);
+ if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
return -errno;
- }
- close_nointr_nofail(fd);
return 0;
}
}
if (arg_when > 0) {
- char *m;
+ char _cleanup_free_ *m;
m = strv_join(arg_wall, " ");
r = send_shutdownd(arg_when,
arg_dry,
!arg_no_wall,
m);
- free(m);
if (r < 0)
log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
int main(int argc, char*argv[]) {
int r, retval = EXIT_FAILURE;
DBusConnection *bus = NULL;
- DBusError error;
+ DBusError _cleanup_dbus_error_free_ error;
dbus_error_init(&error);
dbus_connection_unref(bus);
}
- dbus_error_free(&error);
-
dbus_shutdown();
strv_free(arg_property);