RemoteDrawingEngine: Reduce RP_READ_BITMAP result timeout.
[haiku.git] / src / bin / shutdown.cpp
blob128d13c253dfe589c2da1c187556986c2ec74976
1 /*
2 * Copyright 2002-2010, Haiku.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Francois Revol (mmu_man@users.sf.net)
7 */
10 /*! Shuts down the system, either halting or rebooting. */
13 #include <syscalls.h>
15 #include <OS.h>
16 #include <Roster.h>
17 #include <RosterPrivate.h>
19 #include <signal.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include <ctype.h>
27 uint32 gTimeToSleep = 0;
28 bool gReboot = false;
31 /*! We get here when shutdown is cancelled.
32 Then sleep() returns.
34 void
35 handle_usr1(int sig)
37 while (0);
41 bool
42 parseTime(char *arg, char *argv, int32 *_i)
44 char *unit;
46 if (isdigit(arg[0])) {
47 gTimeToSleep = strtoul(arg, &unit, 10);
48 } else if (argv && isdigit(argv[0])) {
49 (*_i)++;
50 gTimeToSleep = strtoul(argv, &unit, 10);
51 } else
52 return false;
54 if (unit[0] == '\0' || strcmp(unit, "s") == 0)
55 return true;
56 if (strcmp(unit, "m") == 0) {
57 gTimeToSleep *= 60;
58 return true;
61 return false;
65 void
66 usage(const char *program)
68 fprintf(stderr, "usage: %s [-rqca] [-d time]\n"
69 "\t-r reboot,\n"
70 "\t-q quick shutdown (don't broadcast apps),\n"
71 "\t-a ask user to confirm the shutdown (ignored when -q is given),\n"
72 "\t-c cancel a running shutdown,\n"
73 "\t-s run shutdown synchronously (only returns if shutdown is cancelled)\n"
74 "\t-d delay shutdown by <time> seconds.\n", program);
75 exit(1);
79 int
80 main(int argc, char **argv)
82 bool askUser = false;
83 bool quick = false;
84 bool async = true;
86 const char *program = strrchr(argv[0], '/');
87 if (program == NULL)
88 program = argv[0];
89 else
90 program++;
92 // handle 'halt' and 'reboot' symlinks
93 if (strcmp(program, "reboot") == 0)
94 gReboot = true;
95 if (strcmp(program, "shutdown") != 0)
96 askUser = true;
98 for (int32 i = 1; i < argc; i++) {
99 char *arg = argv[i];
100 if (arg[0] == '-') {
101 if (!isalpha(arg[1]))
102 usage(program);
104 while (arg && isalpha((++arg)[0])) {
105 switch (arg[0]) {
106 case 'a':
107 askUser = true;
108 break;
109 case 'q':
110 quick = true;
111 break;
112 case 'r':
113 gReboot = true;
114 break;
115 case 's':
116 async = false;
117 break;
118 case 'c':
120 // find all running shutdown commands and signal their
121 // shutdown threads
123 thread_info threadInfo;
124 get_thread_info(find_thread(NULL), &threadInfo);
126 team_id thisTeam = threadInfo.team;
128 int32 team_cookie = 0;
129 team_info teamInfo;
130 while (get_next_team_info(&team_cookie, &teamInfo)
131 == B_OK) {
132 if (strstr(teamInfo.args, "shutdown") != NULL
133 && teamInfo.team != thisTeam) {
134 int32 thread_cookie = 0;
135 while (get_next_thread_info(teamInfo.team,
136 &thread_cookie, &threadInfo) == B_OK) {
137 if (strcmp(threadInfo.name, "shutdown") == 0)
138 kill(threadInfo.thread, SIGUSR1);
142 exit(0);
143 break;
145 case 'd':
146 if (parseTime(arg + 1, argv[i + 1], &i)) {
147 arg = NULL;
148 break;
150 // supposed to fall through
152 default:
153 usage(program);
156 } else
157 usage(program);
160 if (gTimeToSleep > 0) {
161 int32 left;
163 signal(SIGUSR1, handle_usr1);
165 printf("Delaying %s by %lu seconds...\n",
166 gReboot ? "reboot" : "shutdown", gTimeToSleep);
168 left = sleep(gTimeToSleep);
170 if (left > 0) {
171 fprintf(stderr, "Shutdown cancelled.\n");
172 exit(0);
176 if (quick) {
177 #ifdef __HAIKU__
178 _kern_shutdown(gReboot);
179 #endif // __HAIKU__
180 fprintf(stderr, "Shutdown failed! (Do you have ACPI enabled?)\n");
181 return 2;
182 } else {
183 BRoster roster;
184 BRoster::Private rosterPrivate(roster);
185 status_t error = rosterPrivate.ShutDown(gReboot, askUser, !async);
186 if (error != B_OK)
187 fprintf(stderr, "Shutdown failed: %s\n", strerror(error));
188 return 2;
191 return 0;