diff options
author | Eric Andersen <andersen@codepoet.org> | 1999-10-26 00:18:56 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 1999-10-26 00:18:56 +0000 |
commit | 8a8fbb87f70dbfbcee4d64b3d82831e2ccc6a587 (patch) | |
tree | 0f78a6b6e67dad95ffce7e7df730a2588f0aaa87 /init/init.c | |
parent | 0460ff2e5d443b485c2f6447c8c2ece1b3bec9c3 (diff) | |
download | busybox-w32-8a8fbb87f70dbfbcee4d64b3d82831e2ccc6a587.tar.gz busybox-w32-8a8fbb87f70dbfbcee4d64b3d82831e2ccc6a587.tar.bz2 busybox-w32-8a8fbb87f70dbfbcee4d64b3d82831e2ccc6a587.zip |
Foo
Diffstat (limited to 'init/init.c')
-rw-r--r-- | init/init.c | 406 |
1 files changed, 194 insertions, 212 deletions
diff --git a/init/init.c b/init/init.c index 0676bf76d..2834a4a05 100644 --- a/init/init.c +++ b/init/init.c | |||
@@ -37,40 +37,39 @@ | |||
37 | #include <sys/reboot.h> | 37 | #include <sys/reboot.h> |
38 | #include <sys/kdaemon.h> | 38 | #include <sys/kdaemon.h> |
39 | #include <sys/sysmacros.h> | 39 | #include <sys/sysmacros.h> |
40 | #include <linux/serial.h> /* for serial_struct */ | 40 | #include <linux/serial.h> /* for serial_struct */ |
41 | #include <sys/vt.h> /* for vt_stat */ | 41 | #include <sys/vt.h> /* for vt_stat */ |
42 | #include <sys/ioctl.h> | 42 | #include <sys/ioctl.h> |
43 | 43 | ||
44 | #define DEBUG_INIT | 44 | #define DEBUG_INIT |
45 | 45 | ||
46 | #define CONSOLE "/dev/console" /* Logical system console */ | 46 | #define CONSOLE "/dev/console" /* Logical system console */ |
47 | #define VT_PRIMARY "/dev/tty0" /* Virtual console master */ | 47 | #define VT_PRIMARY "/dev/tty0" /* Virtual console master */ |
48 | #define VT_SECONDARY "/dev/tty1" /* Virtual console master */ | 48 | #define VT_SECONDARY "/dev/tty1" /* Virtual console master */ |
49 | #define VT_LOG "/dev/tty2" /* Virtual console master */ | 49 | #define VT_LOG "/dev/tty2" /* Virtual console master */ |
50 | #define SHELL "/bin/sh" /* Default shell */ | 50 | #define SHELL "/bin/sh" /* Default shell */ |
51 | #define INITSCRIPT "/etc/init.d/rcS" /* Initscript. */ | 51 | #define INITSCRIPT "/etc/init.d/rcS" /* Initscript. */ |
52 | #define PATH_DEFAULT "PATH=/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin" | 52 | #define PATH_DEFAULT "PATH=/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin" |
53 | 53 | ||
54 | static int maxproclen=0; | 54 | static char *console = CONSOLE; |
55 | static char* argv0; | 55 | static char *second_terminal = "/dev/tty2"; |
56 | 56 | static char *log = "/dev/tty3"; | |
57 | static char* console = CONSOLE; | ||
58 | static char* second_terminal = "/dev/tty2"; | ||
59 | static char* log = "/dev/tty3"; | ||
60 | 57 | ||
61 | 58 | ||
62 | 59 | ||
63 | /* try to open up the specified device */ | 60 | /* try to open up the specified device */ |
64 | int device_open(char* device, int mode) | 61 | int device_open(char *device, int mode) |
65 | { | 62 | { |
66 | int m, f, fd = -1; | 63 | int m, f, fd = -1; |
67 | 64 | ||
68 | mode = m | O_NONBLOCK; | 65 | mode = m | O_NONBLOCK; |
69 | 66 | ||
70 | /* Retry up to 5 times */ | 67 | /* Retry up to 5 times */ |
71 | for(f = 0; f < 5; f++) | 68 | for (f = 0; f < 5; f++) |
72 | if ((fd = open(device, m)) >= 0) break; | 69 | if ((fd = open(device, m)) >= 0) |
73 | if (fd < 0) return fd; | 70 | break; |
71 | if (fd < 0) | ||
72 | return fd; | ||
74 | /* Set original flags. */ | 73 | /* Set original flags. */ |
75 | if (m != mode) | 74 | if (m != mode) |
76 | fcntl(fd, F_SETFL, mode); | 75 | fcntl(fd, F_SETFL, mode); |
@@ -78,16 +77,18 @@ int device_open(char* device, int mode) | |||
78 | } | 77 | } |
79 | 78 | ||
80 | /* print a message to the specified device */ | 79 | /* print a message to the specified device */ |
81 | void message(char* device, char *fmt, ...) | 80 | void message(char *device, char *fmt, ...) |
82 | { | 81 | { |
83 | int fd; | 82 | int fd; |
84 | va_list arguments; | 83 | va_list arguments; |
85 | if ((fd = device_open(device, O_WRONLY|O_NOCTTY|O_NDELAY)) >= 0) { | 84 | |
85 | if ((fd = device_open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) { | ||
86 | va_start(arguments, fmt); | 86 | va_start(arguments, fmt); |
87 | vdprintf(fd, fmt, arguments); | 87 | vdprintf(fd, fmt, arguments); |
88 | va_end(arguments); | 88 | va_end(arguments); |
89 | } | 89 | close(fd); |
90 | close( fd); | 90 | } else |
91 | vprintf(fmt, arguments); | ||
91 | } | 92 | } |
92 | 93 | ||
93 | /* Set terminal settings to reasonable defaults */ | 94 | /* Set terminal settings to reasonable defaults */ |
@@ -96,74 +97,71 @@ void set_term() | |||
96 | int fd; | 97 | int fd; |
97 | struct termios tty; | 98 | struct termios tty; |
98 | 99 | ||
99 | if ((fd = device_open(console, O_RDWR|O_NOCTTY)) < 0) { | 100 | if ((fd = device_open(console, O_RDWR | O_NOCTTY)) < 0) { |
100 | message(log, "can't open %s", console); | 101 | message(log, "can't open %s\n", console); |
101 | return; | 102 | return; |
102 | } | 103 | } |
103 | ioctl(fd, TCGETS, &tty); | 104 | ioctl(fd, TCGETS, &tty); |
104 | tty.c_cflag &= CBAUD|CBAUDEX|CSIZE|CSTOPB|PARENB|PARODD; | 105 | tty.c_cflag &= CBAUD | CBAUDEX | CSIZE | CSTOPB | PARENB | PARODD; |
105 | tty.c_cflag |= HUPCL|CLOCAL; | 106 | tty.c_cflag |= HUPCL | CLOCAL; |
106 | 107 | ||
107 | tty.c_cc[VINTR] = 3; | 108 | tty.c_cc[VINTR] = 3; |
108 | tty.c_cc[VQUIT] = 28; | 109 | tty.c_cc[VQUIT] = 28; |
109 | tty.c_cc[VERASE] = 127; | 110 | tty.c_cc[VERASE] = 127; |
110 | tty.c_cc[VKILL] = 24; | 111 | tty.c_cc[VKILL] = 24; |
111 | tty.c_cc[VEOF] = 4; | 112 | tty.c_cc[VEOF] = 4; |
112 | tty.c_cc[VTIME] = 0; | 113 | tty.c_cc[VTIME] = 0; |
113 | tty.c_cc[VMIN] = 1; | 114 | tty.c_cc[VMIN] = 1; |
114 | tty.c_cc[VSTART] = 17; | 115 | tty.c_cc[VSTART] = 17; |
115 | tty.c_cc[VSTOP] = 19; | 116 | tty.c_cc[VSTOP] = 19; |
116 | tty.c_cc[VSUSP] = 26; | 117 | tty.c_cc[VSUSP] = 26; |
117 | 118 | ||
118 | /* Set pre and post processing */ | 119 | /* Set pre and post processing */ |
119 | tty.c_iflag = IGNPAR|ICRNL|IXON|IXANY; | 120 | tty.c_iflag = IGNPAR | ICRNL | IXON | IXANY; |
120 | tty.c_oflag = OPOST|ONLCR; | 121 | tty.c_oflag = OPOST | ONLCR; |
121 | tty.c_lflag = ISIG|ICANON|ECHO|ECHOCTL|ECHOPRT|ECHOKE; | 122 | tty.c_lflag = ISIG | ICANON | ECHO | ECHOCTL | ECHOPRT | ECHOKE; |
122 | 123 | ||
123 | /* Now set the terminal line. */ | 124 | /* Now set the terminal line. */ |
124 | ioctl(fd, TCSETS, &tty); | 125 | ioctl(fd, TCSETS, &tty); |
125 | close( fd); | 126 | close(fd); |
126 | } | 127 | } |
127 | 128 | ||
128 | static int | 129 | static int mem_total() |
129 | mem_total() | ||
130 | { | 130 | { |
131 | char s[80]; | 131 | char s[80]; |
132 | char *p; | 132 | char *p; |
133 | FILE *f; | 133 | FILE *f; |
134 | const char pattern[]="MemTotal:"; | 134 | const char pattern[] = "MemTotal:"; |
135 | 135 | ||
136 | f=fopen("/proc/meminfo","r"); | 136 | f = fopen("/proc/meminfo", "r"); |
137 | while (NULL != fgets(s,79,f)) { | 137 | while (NULL != fgets(s, 79, f)) { |
138 | p=strstr(s, pattern); | 138 | p = strstr(s, pattern); |
139 | if (NULL != p) { | 139 | if (NULL != p) { |
140 | fclose(f); | 140 | fclose(f); |
141 | return(atoi(p+strlen(pattern))); | 141 | return (atoi(p + strlen(pattern))); |
142 | } | 142 | } |
143 | } | 143 | } |
144 | return -1; | 144 | return -1; |
145 | } | 145 | } |
146 | 146 | ||
147 | static void | 147 | static void set_free_pages() |
148 | set_free_pages() | ||
149 | { | 148 | { |
150 | char s[80]; | 149 | char s[80]; |
151 | FILE *f; | 150 | FILE *f; |
152 | 151 | ||
153 | f=fopen("/proc/sys/vm/freepages","r"); | 152 | f = fopen("/proc/sys/vm/freepages", "r"); |
154 | fgets(s,79,f); | 153 | fgets(s, 79, f); |
155 | if (atoi(s) < 32) { | 154 | if (atoi(s) < 32) { |
156 | fclose(f); | 155 | fclose(f); |
157 | f=fopen("/proc/sys/vm/freepages","w"); | 156 | f = fopen("/proc/sys/vm/freepages", "w"); |
158 | fprintf(f,"30\t40\t50\n"); | 157 | fprintf(f, "30\t40\t50\n"); |
159 | printf("\nIncreased /proc/sys/vm/freepages values to 30/40/50\n"); | 158 | printf("\nIncreased /proc/sys/vm/freepages values to 30/40/50\n"); |
160 | } | 159 | } |
161 | fclose(f); | 160 | fclose(f); |
162 | } | 161 | } |
163 | 162 | ||
164 | 163 | ||
165 | static void | 164 | static void console_init() |
166 | console_init() | ||
167 | { | 165 | { |
168 | int fd; | 166 | int fd; |
169 | int tried_devcons = 0; | 167 | int tried_devcons = 0; |
@@ -176,7 +174,7 @@ console_init() | |||
176 | console = CONSOLE; | 174 | console = CONSOLE; |
177 | tried_devcons++; | 175 | tried_devcons++; |
178 | } | 176 | } |
179 | while ((fd = open(console, O_RDONLY|O_NONBLOCK)) < 0) { | 177 | while ((fd = open(console, O_RDONLY | O_NONBLOCK)) < 0) { |
180 | if (!tried_devcons) { | 178 | if (!tried_devcons) { |
181 | tried_devcons++; | 179 | tried_devcons++; |
182 | console = CONSOLE; | 180 | console = CONSOLE; |
@@ -195,41 +193,41 @@ console_init() | |||
195 | close(fd); | 193 | close(fd); |
196 | } | 194 | } |
197 | 195 | ||
198 | static int | 196 | static int waitfor(int pid) |
199 | waitfor(int pid) | ||
200 | { | 197 | { |
201 | int status, wpid; | 198 | int status, wpid; |
202 | 199 | ||
203 | message(log, "Waiting for process %d.\n", pid); | 200 | message(log, "Waiting for process %d.\n", pid); |
204 | while ( (wpid = wait(&status)) != pid ) { | 201 | while ((wpid = wait(&status)) != pid) { |
205 | if ( wpid > 0 ) | 202 | if (wpid > 0) |
206 | message(log,"pid %d exited, status=%x.\n", wpid, status); | 203 | message(log, "pid %d exited, status=%x.\n", wpid, status); |
207 | } | 204 | } |
208 | return wpid; | 205 | return wpid; |
209 | } | 206 | } |
210 | 207 | ||
211 | static int | 208 | static int run(const char *command, char *terminal, int get_enter) |
212 | run(const char* command, char* terminal, int get_enter) | ||
213 | { | 209 | { |
214 | int f, pid; | 210 | int f, pid; |
215 | char *args[16]; | 211 | char *args[16]; |
216 | char buf[256]; | 212 | char buf[256]; |
217 | char* ptr; | 213 | char *ptr; |
218 | static const char press_enter[] = | 214 | static const char press_enter[] = |
219 | "\nPlease press Enter to activate this console. "; | 215 | "\nPlease press Enter to activate this console. "; |
220 | 216 | ||
221 | 217 | ||
222 | /* Make a proper command from the command string */ | 218 | /* Make a proper command from the command string */ |
223 | strcpy(buf, command); | 219 | strcpy(buf, command); |
224 | ptr = buf; | 220 | ptr = buf; |
225 | for(f = 1; f < 15; f++) { | 221 | for (f = 1; f < 15; f++) { |
226 | /* Skip white space */ | 222 | /* Skip white space */ |
227 | while(*ptr == ' ' || *ptr == '\t') ptr++; | 223 | while (*ptr == ' ' || *ptr == '\t') |
224 | ptr++; | ||
228 | args[f] = ptr; | 225 | args[f] = ptr; |
229 | /* May be trailing space.. */ | 226 | /* May be trailing space.. */ |
230 | if (*ptr == 0) break; | 227 | if (*ptr == 0) |
228 | break; | ||
231 | /* Skip this `word' */ | 229 | /* Skip this `word' */ |
232 | while(*ptr && *ptr != ' ' && *ptr != '\t' && *ptr != '#') | 230 | while (*ptr && *ptr != ' ' && *ptr != '\t' && *ptr != '#') |
233 | ptr++; | 231 | ptr++; |
234 | /* If end-of-line, break */ | 232 | /* If end-of-line, break */ |
235 | if (*ptr == '#' || *ptr == 0) { | 233 | if (*ptr == '#' || *ptr == 0) { |
@@ -241,7 +239,7 @@ run(const char* command, char* terminal, int get_enter) | |||
241 | args[f] = NULL; | 239 | args[f] = NULL; |
242 | } | 240 | } |
243 | args[0] = args[1]; | 241 | args[0] = args[1]; |
244 | 242 | ||
245 | 243 | ||
246 | if ((pid = fork()) == 0) { | 244 | if ((pid = fork()) == 0) { |
247 | /* Clean up */ | 245 | /* Clean up */ |
@@ -250,8 +248,8 @@ run(const char* command, char* terminal, int get_enter) | |||
250 | close(2); | 248 | close(2); |
251 | setsid(); | 249 | setsid(); |
252 | 250 | ||
253 | if ((f = device_open(terminal, O_RDWR|O_NOCTTY)) < 0) { | 251 | if ((f = device_open(terminal, O_RDWR | O_NOCTTY)) < 0) { |
254 | message( log, "open(%s) failed: %s", terminal, strerror(errno)); | 252 | message(log, "open(%s) failed: %s\n", terminal, strerror(errno)); |
255 | return -1; | 253 | return -1; |
256 | } | 254 | } |
257 | dup(f); | 255 | dup(f); |
@@ -259,7 +257,7 @@ run(const char* command, char* terminal, int get_enter) | |||
259 | tcsetpgrp(0, getpgrp()); | 257 | tcsetpgrp(0, getpgrp()); |
260 | set_term(); | 258 | set_term(); |
261 | 259 | ||
262 | if ( get_enter ) { | 260 | if (get_enter) { |
263 | /* | 261 | /* |
264 | * Save memory by not exec-ing anything large (like a shell) | 262 | * Save memory by not exec-ing anything large (like a shell) |
265 | * before the user wants it. This is critical if swap is not | 263 | * before the user wants it. This is critical if swap is not |
@@ -268,18 +266,21 @@ run(const char* command, char* terminal, int get_enter) | |||
268 | * be allowed to start a shell or whatever an init script | 266 | * be allowed to start a shell or whatever an init script |
269 | * specifies. | 267 | * specifies. |
270 | */ | 268 | */ |
271 | char c; | 269 | char c; |
272 | write(1, press_enter, sizeof(press_enter) - 1); | 270 | write(1, press_enter, sizeof(press_enter) - 1); |
273 | read(0, &c, 1); | 271 | read(0, &c, 1); |
272 | message(console, "Got an enter\r\n"); | ||
274 | } | 273 | } |
275 | 274 | ||
276 | /* Log the process name and args */ | 275 | /* Log the process name and args */ |
277 | message(log, "Executing '%s'\n", command); | 276 | message(console, "Executing "); |
277 | message(console, "'%s'\r\n", command); | ||
278 | 278 | ||
279 | /* Now run it. This should take over the PID, so nothing | 279 | /* Now run it. This should take over the PID, so nothing |
280 | * further in init.c should be run by this PID. */ | 280 | * further in init.c should be run by this PID. */ |
281 | execvp(args[1], args + 1); | 281 | execvp(args[1], args + 1); |
282 | 282 | ||
283 | message(console, "Hmm. Trying as a script.\r\n"); | ||
283 | /* If shell scripts are not executed, force the issue */ | 284 | /* If shell scripts are not executed, force the issue */ |
284 | if (errno == ENOEXEC) { | 285 | if (errno == ENOEXEC) { |
285 | char buf[256]; | 286 | char buf[256]; |
@@ -291,18 +292,17 @@ run(const char* command, char* terminal, int get_enter) | |||
291 | args[4] = NULL; | 292 | args[4] = NULL; |
292 | execvp(args[1], args + 1); | 293 | execvp(args[1], args + 1); |
293 | } | 294 | } |
294 | message(log, "Could not execute '%s'\n", command, strerror(errno)); | 295 | message(console, "Could not execute '%s'\n", command); |
295 | exit(-1); | 296 | exit(-1); |
296 | } | 297 | } |
297 | return pid; | 298 | return pid; |
298 | } | 299 | } |
299 | 300 | ||
300 | #ifndef DEBUG_INIT | 301 | #ifndef DEBUG_INIT |
301 | static void | 302 | static void shutdown_system(void) |
302 | shutdown_system(void) | ||
303 | { | 303 | { |
304 | 304 | ||
305 | message(console, "The system is going down NOW !!"); | 305 | message(console, "The system is going down NOW !!\r\n"); |
306 | sync(); | 306 | sync(); |
307 | /* Allow Ctrl-Alt-Del to reboot system. */ | 307 | /* Allow Ctrl-Alt-Del to reboot system. */ |
308 | reboot(RB_ENABLE_CAD); | 308 | reboot(RB_ENABLE_CAD); |
@@ -318,169 +318,151 @@ shutdown_system(void) | |||
318 | waitfor(run("/bin/swapoff -a", console, 0)); | 318 | waitfor(run("/bin/swapoff -a", console, 0)); |
319 | waitfor(run("/bin/umount -a -n", console, 0)); | 319 | waitfor(run("/bin/umount -a -n", console, 0)); |
320 | sync(); | 320 | sync(); |
321 | if (get_kernel_revision() <= 2*65536+2*256+11) { | 321 | if (get_kernel_revision() <= 2 * 65536 + 2 * 256 + 11) { |
322 | /* Removed bdflush call, kupdate in kernels >2.2.11 */ | 322 | /* Removed bdflush call, kupdate in kernels >2.2.11 */ |
323 | bdflush(1, 0); | 323 | bdflush(1, 0); |
324 | sync(); | 324 | sync(); |
325 | } | 325 | } |
326 | } | 326 | } |
327 | 327 | ||
328 | static void | 328 | static void halt_signal(int sig) |
329 | halt_signal(int sig) | ||
330 | { | 329 | { |
331 | shutdown_system(); | 330 | shutdown_system(); |
332 | message(console, "The system is halted. Press CTRL-ALT-DEL or turn off power\r\n"); | 331 | message(console, |
333 | reboot( RB_POWER_OFF); | 332 | "The system is halted. Press CTRL-ALT-DEL or turn off power\r\n"); |
333 | reboot(RB_POWER_OFF); | ||
334 | exit(0); | 334 | exit(0); |
335 | } | 335 | } |
336 | 336 | ||
337 | static void | 337 | static void reboot_signal(int sig) |
338 | reboot_signal(int sig) | ||
339 | { | 338 | { |
340 | shutdown_system(); | 339 | shutdown_system(); |
341 | message(console, "Please stand by while rebooting the system.\r\n"); | 340 | message(console, "Please stand by while rebooting the system.\r\n"); |
342 | reboot( RB_AUTOBOOT); | 341 | reboot(RB_AUTOBOOT); |
343 | exit(0); | 342 | exit(0); |
344 | } | 343 | } |
345 | #endif | ||
346 | 344 | ||
347 | int setproctitle(char *fmt, ...) | 345 | #endif |
348 | { | ||
349 | va_list ap; | ||
350 | int len; | ||
351 | char buf[256]; | ||
352 | |||
353 | buf[0] = 0; | ||
354 | va_start(ap, fmt); | ||
355 | len = vsprintf(buf, fmt, ap); | ||
356 | va_end(ap); | ||
357 | memset(argv0, 0, maxproclen + 1); | ||
358 | strncpy(argv0, buf, maxproclen); | ||
359 | return len; | ||
360 | } | ||
361 | 346 | ||
362 | extern int | 347 | extern int init_main(int argc, char **argv) |
363 | init_main(int argc, char * * argv) | ||
364 | { | 348 | { |
365 | int run_rc = TRUE; | 349 | int run_rc = TRUE; |
366 | int pid1 = 0; | 350 | int pid1 = 0; |
367 | int pid2 = 0; | 351 | int pid2 = 0; |
368 | struct stat statbuf; | 352 | struct stat statbuf; |
369 | const char* init_commands = SHELL "-c exec " INITSCRIPT; | 353 | const char *init_commands = SHELL "-c exec " INITSCRIPT; |
370 | const char* shell_commands = SHELL; | 354 | const char *shell_commands = SHELL; |
371 | const char* tty0_commands = init_commands; | 355 | const char *tty0_commands = init_commands; |
372 | const char* tty1_commands = shell_commands; | 356 | const char *tty1_commands = shell_commands; |
373 | const char* no_memory = | 357 | char *hello_msg_format = |
374 | "Sorry, your computer does not have enough memory.\n"; | 358 | "init started: BusyBox v%s (%s) multi-call binary\r\n"; |
375 | 359 | const char *no_memory = | |
376 | /* For later use */ | 360 | "Sorry, your computer does not have enough memory.\r\n"; |
377 | argv0 = argv[0]; | ||
378 | maxproclen = strlen(argv[0]); | ||
379 | setproctitle("init [boot]"); | ||
380 | 361 | ||
381 | 362 | ||
382 | #ifndef DEBUG_INIT | 363 | #ifndef DEBUG_INIT |
383 | /* Set up sig handlers */ | 364 | /* Set up sig handlers */ |
384 | signal(SIGUSR1, halt_signal); | 365 | signal(SIGUSR1, halt_signal); |
385 | signal(SIGSEGV, halt_signal); | 366 | signal(SIGSEGV, halt_signal); |
386 | signal(SIGPWR, halt_signal); | 367 | signal(SIGPWR, halt_signal); |
387 | signal(SIGALRM, halt_signal); | 368 | signal(SIGALRM, halt_signal); |
388 | signal(SIGHUP, halt_signal); | 369 | signal(SIGHUP, halt_signal); |
389 | signal(SIGUSR2, reboot_signal); | 370 | signal(SIGUSR2, reboot_signal); |
390 | signal(SIGINT, reboot_signal); | 371 | signal(SIGINT, reboot_signal); |
391 | signal(SIGTERM, reboot_signal); | 372 | signal(SIGTERM, reboot_signal); |
392 | #endif | 373 | #endif |
393 | /* Figure out where the default console should be */ | 374 | /* Figure out where the default console should be */ |
394 | console_init(); | 375 | console_init(); |
395 | 376 | ||
396 | /* Turn off rebooting via CTL-ALT-DEL -- we get a | 377 | /* Turn off rebooting via CTL-ALT-DEL -- we get a |
397 | * SIGINT on CAD so we can shut things down gracefully... */ | 378 | * SIGINT on CAD so we can shut things down gracefully... */ |
398 | #ifndef DEBUG_INIT | 379 | #ifndef DEBUG_INIT |
399 | reboot(RB_DISABLE_CAD); | 380 | reboot(RB_DISABLE_CAD); |
400 | #endif | 381 | #endif |
401 | 382 | ||
402 | /* Close whatever files are open, and reset the console. */ | 383 | /* Close whatever files are open, and reset the console. */ |
403 | close(0); | 384 | close(0); |
404 | close(1); | 385 | close(1); |
405 | close(2); | 386 | close(2); |
406 | set_term(); | 387 | set_term(); |
407 | setsid(); | 388 | setsid(); |
408 | 389 | ||
409 | /* Make sure PATH is set to something sane */ | 390 | /* Make sure PATH is set to something sane */ |
410 | if (getenv("PATH") == NULL) | 391 | if (getenv("PATH") == NULL) |
411 | putenv(PATH_DEFAULT); | 392 | putenv(PATH_DEFAULT); |
412 | 393 | ||
413 | /* Hello world */ | 394 | /* Hello world */ |
414 | message(console, "%s started: BusyBox v%s (%s) multi-call binary", | 395 | message(log, hello_msg_format, BB_VER, BB_BT); |
415 | argv[0], BB_VER, BB_BT); | 396 | message(console, hello_msg_format, BB_VER, BB_BT); |
416 | message(log, "%s started: BusyBox v%s (%s) multi-call binary", | 397 | |
417 | argv[0], BB_VER, BB_BT); | 398 | /* Mount /proc */ |
418 | 399 | if (mount("/proc", "/proc", "proc", 0, 0)) { | |
419 | 400 | message(log, "Mounting /proc: failed!\n"); | |
420 | /* Mount /proc */ | 401 | message(console, "Mounting /proc: failed!\r\n"); |
421 | message(console, "Mounting /proc: \n"); | 402 | } else { |
422 | if (mount("/proc","/proc","proc",0,0)) { | 403 | message(console, "Mounting /proc: done.\r\n"); |
423 | message(log, "%s: could not mount /proc!\n", argv[0]); | 404 | } |
424 | message(console, "failed!\n"); | ||
425 | } | ||
426 | message(console, "done.\n"); | ||
427 | |||
428 | 405 | ||
429 | /* Make sure there is enough memory to do something useful*/ | 406 | /* Make sure there is enough memory to do something useful */ |
430 | set_free_pages(); | 407 | set_free_pages(); |
431 | if (mem_total() < 2000) { | 408 | if (mem_total() < 2000) { |
432 | int retval; | 409 | int retval; |
433 | retval= stat("/etc/fstab",&statbuf); | 410 | retval = stat("/etc/fstab", &statbuf); |
434 | if (retval) { | 411 | if (retval) { |
412 | message(console, "%s", no_memory); | ||
413 | while (1) { | ||
414 | sleep(1); | ||
415 | } | ||
416 | } else { | ||
417 | /* Try to turn on swap */ | ||
418 | waitfor(run("/bin/swapon -a", console, 0)); | ||
419 | if (mem_total() < 2000) { | ||
435 | message(console, "%s", no_memory); | 420 | message(console, "%s", no_memory); |
436 | while (1) { sleep(1);} | 421 | while (1) { |
437 | } else { | 422 | sleep(1); |
438 | /* Try to turn on swap */ | ||
439 | waitfor(run("/bin/swapon -a", console, 0)); | ||
440 | if (mem_total() < 2000) { | ||
441 | message(console, "%s", no_memory); | ||
442 | while (1) { sleep(1);} | ||
443 | } | 423 | } |
444 | } | 424 | } |
445 | } | 425 | } |
426 | } | ||
446 | 427 | ||
447 | /* Check if we are supposed to be in single user mode */ | 428 | /* Check if we are supposed to be in single user mode */ |
448 | if (!strcmp(argv[1], "single") || !strcmp(argv[1], "-s") || !strcmp(argv[1], "1")) { | 429 | if ( argc > 1 && (!strcmp(argv[1], "single") || |
449 | run_rc = FALSE; | 430 | !strcmp(argv[1], "-s") || !strcmp(argv[1], "1"))) { |
450 | tty0_commands = shell_commands; | 431 | run_rc = FALSE; |
451 | tty1_commands = 0; | 432 | tty0_commands = shell_commands; |
452 | setproctitle("init [S]"); | 433 | tty1_commands = 0; |
453 | } else { | 434 | } |
454 | setproctitle("init [1]"); | ||
455 | } | ||
456 | 435 | ||
457 | /* Make sure an init script exists before trying to run it */ | 436 | /* Make sure an init script exists before trying to run it */ |
458 | if ( run_rc == TRUE && stat( INITSCRIPT, &statbuf)) { | 437 | if (run_rc == TRUE && stat(INITSCRIPT, &statbuf)) { |
459 | tty0_commands = shell_commands; | 438 | tty0_commands = shell_commands; |
460 | tty1_commands = shell_commands; | 439 | tty1_commands = shell_commands; |
461 | } | 440 | } |
462 | 441 | ||
463 | /* Ok, now launch the rc script and/or prepare to | 442 | /* Ok, now launch the rc script and/or prepare to |
464 | * start up some VTs if somebody hits enter... | 443 | * start up some VTs if somebody hits enter... |
465 | */ | 444 | */ |
466 | for ( ; ; ) { | 445 | for (;;) { |
467 | int wpid; | 446 | int wpid; |
468 | int status; | 447 | int status; |
469 | 448 | ||
470 | if ( pid1 == 0 && *tty0_commands ) { | 449 | if (pid1 == 0 && tty0_commands) { |
471 | pid1 = run(tty0_commands, console, 1); | 450 | pid1 = run(tty0_commands, console, 1); |
472 | } | ||
473 | if ( pid2 == 0 && *tty1_commands ) { | ||
474 | pid2 = run(tty1_commands, second_terminal, 1); | ||
475 | } | ||
476 | wpid = wait(&status); | ||
477 | if ( wpid > 0 && wpid != pid1) { | ||
478 | message(log, "pid %d exited, status=%x.\n", wpid, status); | ||
479 | } | ||
480 | if ( wpid == pid2 ) { | ||
481 | pid2 = 0; | ||
482 | } | ||
483 | sleep(1); | ||
484 | } | 451 | } |
452 | if (pid2 == 0 && tty1_commands) { | ||
453 | pid2 = run(tty1_commands, second_terminal, 1); | ||
454 | } | ||
455 | wpid = wait(&status); | ||
456 | if (wpid > 0 && wpid != pid1) { | ||
457 | message(log, "pid %d exited, status=%x.\n", wpid, status); | ||
458 | } | ||
459 | /* Don't respawn an init script if it exits */ | ||
460 | if (run_rc == FALSE && wpid == pid1) { | ||
461 | pid1 = 0; | ||
462 | } | ||
463 | if (wpid == pid2) { | ||
464 | pid2 = 0; | ||
465 | } | ||
466 | sleep(1); | ||
467 | } | ||
485 | } | 468 | } |
486 | |||