summaryrefslogtreecommitdiffstats
path: root/usr/utils/halt.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/utils/halt.c')
-rw-r--r--usr/utils/halt.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/usr/utils/halt.c b/usr/utils/halt.c
new file mode 100644
index 0000000..368f095
--- /dev/null
+++ b/usr/utils/halt.c
@@ -0,0 +1,64 @@
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/reboot.h>
+#include <klibc/compiler.h>
+
+static __noreturn usage(void)
+{
+ static char mesg[] = "Usage: {halt|reboot|poweroff} [-n] [reboot-arg]\n";
+ write(2, mesg, sizeof(mesg) - 1);
+ exit(1);
+}
+
+int main(int argc, char *argv[])
+{
+ int cmd = 0; /* initalize to shut gcc up */
+ int do_sync = 1;
+ char *ptr, *ptr2;
+ char *reboot_arg = NULL;
+
+ /* Which action (program name)? */
+ ptr2 = ptr = argv[0];
+ while (*ptr2)
+ if (*ptr2++ == '/')
+ ptr = ptr2;
+ if (*ptr == 'r')
+ cmd = LINUX_REBOOT_CMD_RESTART;
+ else if (*ptr == 'h')
+ cmd = LINUX_REBOOT_CMD_HALT;
+ else if (*ptr == 'p')
+ cmd = LINUX_REBOOT_CMD_POWER_OFF;
+ else
+ usage();
+
+ /* Walk options */
+ while (*++argv)
+ if (**argv == '-') {
+ switch (*++*argv) {
+ case 'f':
+ break; /* -f assumed */
+ case 'n':
+ do_sync = 0;
+ break;
+ default:
+ usage();
+ }
+ } else if (cmd == LINUX_REBOOT_CMD_RESTART) {
+ reboot_arg = *argv;
+ cmd = LINUX_REBOOT_CMD_RESTART2;
+ } else {
+ usage(); /* args, not reboot == error */
+ }
+
+ if (do_sync)
+ sync();
+ reboot(LINUX_REBOOT_CMD_CAD_OFF, NULL); /* Enable CTRL+ALT+DEL */
+ if (!reboot(cmd, reboot_arg)) {
+ /* Success. Currently, CMD_HALT returns, so stop the world */
+ /* kill(-1, SIGSTOP); */
+ kill(getpid(), SIGSTOP);
+ }
+ write(2, "failed.\n", 8);
+ return 1;
+}