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