X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fsystemctl%2Fsystemctl.c;h=6170cc93d56aa7695621c80eee25b7a902a07a8d;hb=37185ec80ad372907a2a9388735655a7334babb6;hp=9f5e2735ac512f3cb83f88de193824cbf56ce34a;hpb=76fdc9669a639db042d0e8bf57f525f008495535;p=elogind.git diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 9f5e2735a..6170cc93d 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -20,6 +20,8 @@ ***/ #include +#include +#include #include #include #include @@ -4804,7 +4806,7 @@ static int systemctl_help(void) { " emergency Enter system emergency mode\n" " halt Shut down and halt the system\n" " poweroff Shut down and power-off the system\n" - " reboot Shut down and reboot the system\n" + " reboot [ARG] Shut down and reboot the system\n" " kexec Shut down and reboot the system with kexec\n" " exit Request user instance exit\n" " switch-root [ROOT] [INIT] Change to a different root file system\n" @@ -4818,7 +4820,7 @@ static int systemctl_help(void) { static int halt_help(void) { - printf("%s [OPTIONS...]\n\n" + printf("%s [OPTIONS...]%s\n\n" "%s the system.\n\n" " --help Show this help\n" " --halt Halt the machine\n" @@ -4829,6 +4831,7 @@ static int halt_help(void) { " -d --no-wtmp Don't write wtmp record\n" " --no-wall Don't send wall message before halt/power-off/reboot\n", program_invocation_short_name, + arg_action == ACTION_REBOOT ? " [ARG]" : "", arg_action == ACTION_REBOOT ? "Reboot" : arg_action == ACTION_POWEROFF ? "Power off" : "Halt"); @@ -4961,7 +4964,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) { { "output", required_argument, NULL, 'o' }, { "plain", no_argument, NULL, ARG_PLAIN }, { "state", required_argument, NULL, ARG_STATE }, - { NULL, 0, NULL, 0 } + {} }; int c; @@ -4974,8 +4977,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) { switch (c) { case 'h': - systemctl_help(); - return 0; + return systemctl_help(); case ARG_VERSION: puts(PACKAGE_STRING); @@ -5221,8 +5223,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) { return -EINVAL; default: - log_error("Unknown option code '%c'.", c); - return -EINVAL; + assert_not_reached("Unhandled option"); } } @@ -5252,10 +5253,10 @@ static int halt_parse_argv(int argc, char *argv[]) { { "wtmp-only", no_argument, NULL, 'w' }, { "no-wtmp", no_argument, NULL, 'd' }, { "no-wall", no_argument, NULL, ARG_NO_WALL }, - { NULL, 0, NULL, 0 } + {} }; - int c, runlevel; + int c, r, runlevel; assert(argc >= 0); assert(argv); @@ -5268,8 +5269,7 @@ static int halt_parse_argv(int argc, char *argv[]) { switch (c) { case ARG_HELP: - halt_help(); - return 0; + return halt_help(); case ARG_HALT: arg_action = ACTION_HALT; @@ -5310,12 +5310,18 @@ static int halt_parse_argv(int argc, char *argv[]) { return -EINVAL; default: - log_error("Unknown option code '%c'.", c); - return -EINVAL; + assert_not_reached("Unhandled option"); } } - if (optind < argc) { + if (arg_action == ACTION_REBOOT && argc == optind + 1) { + r = write_string_file(REBOOT_PARAM_FILE, argv[optind]); + if (r < 0) { + log_error("Failed to write reboot param to " + REBOOT_PARAM_FILE": %s", strerror(-r)); + return r; + } + } else if (optind < argc) { log_error("Too many arguments."); return -EINVAL; } @@ -5386,7 +5392,7 @@ static int shutdown_parse_argv(int argc, char *argv[]) { { "reboot", no_argument, NULL, 'r' }, { "kexec", no_argument, NULL, 'K' }, /* not documented extension */ { "no-wall", no_argument, NULL, ARG_NO_WALL }, - { NULL, 0, NULL, 0 } + {} }; int c, r; @@ -5398,8 +5404,7 @@ static int shutdown_parse_argv(int argc, char *argv[]) { switch (c) { case ARG_HELP: - shutdown_help(); - return 0; + return shutdown_help(); case 'H': arg_action = ACTION_HALT; @@ -5446,8 +5451,7 @@ static int shutdown_parse_argv(int argc, char *argv[]) { return -EINVAL; default: - log_error("Unknown option code '%c'.", c); - return -EINVAL; + assert_not_reached("Unhandled option"); } } @@ -5482,7 +5486,7 @@ static int telinit_parse_argv(int argc, char *argv[]) { static const struct option options[] = { { "help", no_argument, NULL, ARG_HELP }, { "no-wall", no_argument, NULL, ARG_NO_WALL }, - { NULL, 0, NULL, 0 } + {} }; static const struct { @@ -5514,8 +5518,7 @@ static int telinit_parse_argv(int argc, char *argv[]) { switch (c) { case ARG_HELP: - telinit_help(); - return 0; + return telinit_help(); case ARG_NO_WALL: arg_no_wall = true; @@ -5525,8 +5528,7 @@ static int telinit_parse_argv(int argc, char *argv[]) { return -EINVAL; default: - log_error("Unknown option code '%c'.", c); - return -EINVAL; + assert_not_reached("Unhandled option"); } } @@ -5569,7 +5571,7 @@ static int runlevel_parse_argv(int argc, char *argv[]) { static const struct option options[] = { { "help", no_argument, NULL, ARG_HELP }, - { NULL, 0, NULL, 0 } + {} }; int c; @@ -5581,15 +5583,14 @@ static int runlevel_parse_argv(int argc, char *argv[]) { switch (c) { case ARG_HELP: - runlevel_help(); + return runlevel_help(); return 0; case '?': return -EINVAL; default: - log_error("Unknown option code '%c'.", c); - return -EINVAL; + assert_not_reached("Unhandled option"); } } @@ -5953,6 +5954,8 @@ done: static _noreturn_ void halt_now(enum action a) { + _cleanup_free_ char *param = NULL; + /* Make sure C-A-D is handled by the kernel from this * point on... */ reboot(RB_ENABLE_CAD); @@ -5970,8 +5973,14 @@ static _noreturn_ void halt_now(enum action a) { break; case ACTION_REBOOT: - log_info("Rebooting."); - reboot(RB_AUTOBOOT); + if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) == 0) { + log_info("Rebooting with arg '%s'.", param); + syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, + LINUX_REBOOT_CMD_RESTART2, param); + } else { + log_info("Rebooting."); + reboot(RB_AUTOBOOT); + } break; default: