static usec_t arg_when = 0;
static char *argv_cmdline = NULL;
static enum action {
- _ACTION_INVALID,
ACTION_SYSTEMCTL,
ACTION_HALT,
ACTION_POWEROFF,
ACTION_REEXEC,
ACTION_RUNLEVEL,
ACTION_CANCEL_SHUTDOWN,
- _ACTION_MAX
+ _ACTION_MAX,
+ _ACTION_INVALID = -1
} arg_action = ACTION_SYSTEMCTL;
static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
static const char *arg_host = NULL;
static enum action verb_to_action(const char *verb) {
enum action i;
- for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
+ for (i = 0; i < _ACTION_MAX; i++)
if (streq_ptr(action_table[i].verb, verb))
return i;
char **name;
int r = 0;
- if (arg_wait && !strstr(argv[0], "start")) {
- log_error("--wait may only be used with a command that starts units.");
+ if (arg_wait && !STR_IN_SET(argv[0], "start", "restart")) {
+ log_error("--wait may only be used with the 'start' or 'restart' commands.");
return -EINVAL;
}
if (arg_action == ACTION_SYSTEMCTL) {
enum action action;
- method = verb_to_method(argv[0]);
action = verb_to_action(argv[0]);
- if (streq(argv[0], "isolate")) {
- mode = "isolate";
- suffix = ".target";
- } else
- mode = action_table[action].mode ?: arg_job_mode;
+ if (action != _ACTION_INVALID) {
+ method = "StartUnit";
+ mode = action_table[action].mode;
+ one_name = action_table[action].target;
+ } else {
+ if (streq(argv[0], "isolate")) {
+ method = "StartUnit";
+ mode = "isolate";
- one_name = action_table[action].target;
+ suffix = ".target";
+ } else {
+ method = verb_to_method(argv[0]);
+ mode = arg_job_mode;
+ }
+ one_name = NULL;
+ }
} else {
- assert(arg_action < ELEMENTSOF(action_table));
+ assert(arg_action >= 0 && arg_action < _ACTION_MAX);
assert(action_table[arg_action].target);
+ assert(action_table[arg_action].mode);
method = "StartUnit";
-
mode = action_table[arg_action].mode;
one_name = action_table[arg_action].target;
}
if (!sv)
return log_oom();
- if ((pid_t) pid < 0)
- return log_error_errno(ERANGE, "Bad PID %"PRIu32": %m", pid);
+ if (!pid_is_valid((pid_t) pid)) {
+ log_error("Invalid PID %" PRIu32 ".", pid);
+ return -ERANGE;
+ }
if (!strv_contains(sv,
IN_SET(a,
[ACTION_RESCUE] = '1'
};
- assert(arg_action < _ACTION_MAX);
+ assert(arg_action >= 0 && arg_action < _ACTION_MAX);
return table[arg_action];
}
r = systemctl_main(argc, argv);
break;
+ /* Legacy command aliases set arg_action. They provide some fallbacks,
+ * e.g. to tell sysvinit to reboot after you have installed systemd
+ * binaries. */
+
case ACTION_HALT:
case ACTION_POWEROFF:
case ACTION_REBOOT:
case ACTION_RUNLEVEL4:
case ACTION_RUNLEVEL5:
case ACTION_RESCUE:
- case ACTION_EMERGENCY:
- case ACTION_DEFAULT:
r = start_with_fallback();
break;
r = runlevel_main();
break;
+ case ACTION_EXIT:
+ case ACTION_SUSPEND:
+ case ACTION_HIBERNATE:
+ case ACTION_HYBRID_SLEEP:
+ case ACTION_EMERGENCY:
+ case ACTION_DEFAULT:
+ /* systemctl verbs with no equivalent in the legacy commands.
+ * These cannot appear in arg_action. Fall through. */
+
case _ACTION_INVALID:
default:
assert_not_reached("Unknown action");