diff options
Diffstat (limited to 'examples/shutdown-1.0/script/hardshutdown.c')
-rw-r--r-- | examples/shutdown-1.0/script/hardshutdown.c | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/examples/shutdown-1.0/script/hardshutdown.c b/examples/shutdown-1.0/script/hardshutdown.c new file mode 100644 index 000000000..c21ddad58 --- /dev/null +++ b/examples/shutdown-1.0/script/hardshutdown.c | |||
@@ -0,0 +1,168 @@ | |||
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 | ||
47 | extern int reboot(int, int, int); | ||
48 | # define REBOOT(cmd) reboot(LINUX_REBOOT_MAGIC1,LINUX_REBOOT_MAGIC2,(cmd)) | ||
49 | #endif | ||
50 | |||
51 | static 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 */ | ||
65 | extern int reboot(int, int, int); | ||
66 | #endif | ||
67 | |||
68 | static int my_reboot(int cmd) | ||
69 | { | ||
70 | return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd); | ||
71 | } | ||
72 | |||
73 | #endif | ||
74 | |||
75 | |||
76 | static void do_reboot(void) | ||
77 | { | ||
78 | my_reboot(LINUX_REBOOT_CMD_RESTART); | ||
79 | } | ||
80 | static void do_poweroff(void) | ||
81 | { | ||
82 | my_reboot(LINUX_REBOOT_CMD_POWER_OFF); | ||
83 | } | ||
84 | static void do_halt(void) | ||
85 | { | ||
86 | my_reboot(LINUX_REBOOT_CMD_HALT); | ||
87 | } | ||
88 | |||
89 | static 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 | |||
98 | enum action_t { | ||
99 | SHUTDOWN, // do nothing | ||
100 | HALT, | ||
101 | POWEROFF, | ||
102 | REBOOT | ||
103 | }; | ||
104 | |||
105 | int 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 | } | ||