hardshutdown.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /* Including <unistd.h> makes sure that on a glibc system
  2. * <features.h> is included, which again defines __GLIBC__
  3. */
  4. #include <unistd.h>
  5. #include <stdio.h> /* puts */
  6. #include <time.h> /* nanosleep */
  7. #include <errno.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. /*
  11. * Magic values required to use _reboot() system call.
  12. */
  13. #define LINUX_REBOOT_MAGIC1 0xfee1dead
  14. #define LINUX_REBOOT_MAGIC2 672274793
  15. #define LINUX_REBOOT_MAGIC2A 85072278
  16. #define LINUX_REBOOT_MAGIC2B 369367448
  17. /*
  18. * Commands accepted by the _reboot() system call.
  19. *
  20. * RESTART Restart system using default command and mode.
  21. * HALT Stop OS and give system control to ROM monitor, if any.
  22. * CAD_ON Ctrl-Alt-Del sequence causes RESTART command.
  23. * CAD_OFF Ctrl-Alt-Del sequence sends SIGINT to init task.
  24. * POWER_OFF Stop OS and remove all power from system, if possible.
  25. * RESTART2 Restart system using given command string.
  26. */
  27. #define LINUX_REBOOT_CMD_RESTART 0x01234567
  28. #define LINUX_REBOOT_CMD_HALT 0xCDEF0123
  29. #define LINUX_REBOOT_CMD_CAD_ON 0x89ABCDEF
  30. #define LINUX_REBOOT_CMD_CAD_OFF 0x00000000
  31. #define LINUX_REBOOT_CMD_POWER_OFF 0x4321FEDC
  32. #define LINUX_REBOOT_CMD_RESTART2 0xA1B2C3D4
  33. #define USE_LIBC
  34. #ifdef USE_LIBC
  35. /* libc version */
  36. #if defined __GLIBC__ && __GLIBC__ >= 2
  37. # include <sys/reboot.h>
  38. # define REBOOT(cmd) reboot(cmd)
  39. #else
  40. extern int reboot(int, int, int);
  41. # define REBOOT(cmd) reboot(LINUX_REBOOT_MAGIC1,LINUX_REBOOT_MAGIC2,(cmd))
  42. #endif
  43. static int my_reboot(int cmd)
  44. {
  45. return REBOOT(cmd);
  46. }
  47. #else /* no USE_LIBC */
  48. /* direct syscall version */
  49. #include <linux/unistd.h>
  50. #ifdef _syscall3
  51. _syscall3(int, reboot, int, magic, int, magic_too, int, cmd);
  52. #else
  53. /* Let us hope we have a 3-argument reboot here */
  54. extern int reboot(int, int, int);
  55. #endif
  56. static int my_reboot(int cmd)
  57. {
  58. return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd);
  59. }
  60. #endif
  61. static void do_reboot(void)
  62. {
  63. my_reboot(LINUX_REBOOT_CMD_RESTART);
  64. }
  65. static void do_poweroff(void)
  66. {
  67. my_reboot(LINUX_REBOOT_CMD_POWER_OFF);
  68. }
  69. static void do_halt(void)
  70. {
  71. my_reboot(LINUX_REBOOT_CMD_HALT);
  72. }
  73. static void usage(void)
  74. {
  75. puts(
  76. "Usage: hardshutdown -h|-r|-p [NN]\n"
  77. " NN - seconds to sleep before requested action"
  78. );
  79. exit(1);
  80. }
  81. enum action_t {
  82. SHUTDOWN, // do nothing
  83. HALT,
  84. POWEROFF,
  85. REBOOT
  86. };
  87. int main(int argc, char **argv)
  88. {
  89. struct timespec t = {0,0};
  90. enum action_t action = SHUTDOWN;
  91. int c, i;
  92. char *prog, *ptr;
  93. //if (*argv[0] == '-') argv[0]++; /* allow shutdown as login shell */
  94. prog = argv[0];
  95. ptr = strrchr(prog,'/');
  96. if (ptr)
  97. prog = ptr+1;
  98. for (c = 1; c < argc; c++) {
  99. if (argv[c][0] >= '0' && argv[c][0] <= '9') {
  100. t.tv_sec = strtol(argv[c], NULL, 10);
  101. continue;
  102. }
  103. if (argv[c][0] != '-') {
  104. usage();
  105. return 1;
  106. }
  107. for (i = 1; argv[c][i]; i++) {
  108. switch (argv[c][i]) {
  109. case 'h':
  110. action = HALT;
  111. break;
  112. case 'p':
  113. action = POWEROFF;
  114. break;
  115. case 'r':
  116. action = REBOOT;
  117. break;
  118. default:
  119. usage();
  120. return 1;
  121. }
  122. }
  123. }
  124. if (action==SHUTDOWN) {
  125. usage();
  126. return 1;
  127. }
  128. chdir("/");
  129. while (nanosleep(&t,&t)<0)
  130. if (errno!=EINTR) break;
  131. switch (action) {
  132. case HALT:
  133. do_halt();
  134. break;
  135. case POWEROFF:
  136. do_poweroff();
  137. break;
  138. case REBOOT:
  139. do_reboot();
  140. break;
  141. default: /* SHUTDOWN */
  142. break;
  143. }
  144. return 1;
  145. }