diff options
author | Eric Andersen <andersen@codepoet.org> | 1999-11-04 01:13:21 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 1999-11-04 01:13:21 +0000 |
commit | 3ae0c789627a29dbd76793eb666efe19144b30f0 (patch) | |
tree | e3b6a9393ea44e1391cbdf9075e6edc266530a49 /init/init.c | |
parent | be971d6b693ca9cd1c9aa9eb6053aa2592c40547 (diff) | |
download | busybox-w32-3ae0c789627a29dbd76793eb666efe19144b30f0.tar.gz busybox-w32-3ae0c789627a29dbd76793eb666efe19144b30f0.tar.bz2 busybox-w32-3ae0c789627a29dbd76793eb666efe19144b30f0.zip |
Stuf
Diffstat (limited to 'init/init.c')
-rw-r--r-- | init/init.c | 180 |
1 files changed, 122 insertions, 58 deletions
diff --git a/init/init.c b/init/init.c index 899e43040..55c5c7318 100644 --- a/init/init.c +++ b/init/init.c | |||
@@ -41,10 +41,7 @@ | |||
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 | /* Turn this on to debug init so it won't reboot when killed */ | 44 | #define VT_CONSOLE "/dev/console" /* Logical system console */ |
45 | //#define DEBUG_INIT | ||
46 | |||
47 | #define CONSOLE "/dev/console" /* Logical system console */ | ||
48 | #define VT_PRIMARY "/dev/tty1" /* Primary virtual console */ | 45 | #define VT_PRIMARY "/dev/tty1" /* Primary virtual console */ |
49 | #define VT_SECONDARY "/dev/tty2" /* Virtual console */ | 46 | #define VT_SECONDARY "/dev/tty2" /* Virtual console */ |
50 | #define VT_LOG "/dev/tty3" /* Virtual console */ | 47 | #define VT_LOG "/dev/tty3" /* Virtual console */ |
@@ -54,7 +51,9 @@ | |||
54 | #define INITSCRIPT "/etc/init.d/rcS" /* Initscript. */ | 51 | #define INITSCRIPT "/etc/init.d/rcS" /* Initscript. */ |
55 | #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" |
56 | 53 | ||
57 | static char *console = CONSOLE; | 54 | #define LOG 0x1 |
55 | #define CONSOLE 0x2 | ||
56 | static char *console = VT_CONSOLE; | ||
58 | static char *second_console = VT_SECONDARY; | 57 | static char *second_console = VT_SECONDARY; |
59 | static char *log = VT_LOG; | 58 | static char *log = VT_LOG; |
60 | 59 | ||
@@ -73,44 +72,76 @@ int device_open(char *device, int mode) | |||
73 | break; | 72 | break; |
74 | if (fd < 0) | 73 | if (fd < 0) |
75 | return fd; | 74 | return fd; |
76 | /* Set original flags. */ | 75 | /* Reset original flags. */ |
77 | if (m != mode) | 76 | if (m != mode) |
78 | fcntl(fd, F_SETFL, mode); | 77 | fcntl(fd, F_SETFL, mode); |
79 | return fd; | 78 | return fd; |
80 | } | 79 | } |
81 | 80 | ||
82 | /* print a message to the specified device */ | 81 | /* print a message to the specified device: |
83 | void message(char *device, char *fmt, ...) | 82 | * device may be bitwise-or'd from LOG | CONSOLE */ |
83 | void message(int device, char *fmt, ...) | ||
84 | { | 84 | { |
85 | int fd; | 85 | int fd; |
86 | static int log_fd=-1; | ||
86 | va_list arguments; | 87 | va_list arguments; |
87 | 88 | ||
88 | if ((fd = device_open(device, O_WRONLY|O_NOCTTY|O_NDELAY)) >= 0) { | 89 | /* Take full control of the log tty, and never close it. |
89 | va_start(arguments, fmt); | 90 | * It's mine, all mine! Muhahahaha! */ |
90 | vdprintf(fd, fmt, arguments); | 91 | if (log_fd==-1) { |
91 | va_end(arguments); | 92 | if ((log_fd = device_open(log, O_RDWR|O_NDELAY)) < 0) { |
92 | close(fd); | 93 | log_fd=-1; |
93 | } else { | 94 | fprintf(stderr, "Bummer, can't write to log on %s!\r\n", log); |
94 | fprintf(stderr, "Bummer, can't print: "); | 95 | fflush(stderr); |
96 | return; | ||
97 | } | ||
98 | } | ||
99 | |||
100 | if ( (device & LOG) && (log_fd != -1) ) { | ||
95 | va_start(arguments, fmt); | 101 | va_start(arguments, fmt); |
96 | vfprintf(stderr, fmt, arguments); | 102 | vdprintf(log_fd, fmt, arguments); |
97 | fflush(stderr); | ||
98 | va_end(arguments); | 103 | va_end(arguments); |
99 | } | 104 | } |
105 | if (device & CONSOLE) { | ||
106 | if ((fd = device_open(console, O_WRONLY|O_NOCTTY|O_NDELAY)) >= 0) { | ||
107 | va_start(arguments, fmt); | ||
108 | vdprintf(fd, fmt, arguments); | ||
109 | va_end(arguments); | ||
110 | close(fd); | ||
111 | } else { | ||
112 | fprintf(stderr, "Bummer, can't print: "); | ||
113 | va_start(arguments, fmt); | ||
114 | vfprintf(stderr, fmt, arguments); | ||
115 | fflush(stderr); | ||
116 | va_end(arguments); | ||
117 | } | ||
118 | } | ||
100 | } | 119 | } |
101 | 120 | ||
121 | |||
102 | /* Set terminal settings to reasonable defaults */ | 122 | /* Set terminal settings to reasonable defaults */ |
103 | void set_term( int fd) | 123 | void set_term( int fd) |
104 | { | 124 | { |
105 | struct termios tty; | 125 | struct termios tty; |
126 | #if 0 | ||
106 | static const char control_characters[] = { | 127 | static const char control_characters[] = { |
107 | '\003', '\034', '\177', '\025', '\004', '\0', | 128 | '\003', '\034', '\177', '\025', '\004', '\0', |
108 | '\1', '\0', '\021', '\023', '\032', '\0', '\022', | 129 | '\1', '\0', '\021', '\023', '\032', '\0', '\022', |
109 | '\017', '\027', '\026', '\0' | 130 | '\017', '\027', '\026', '\0' |
110 | }; | 131 | }; |
132 | #endif | ||
133 | static const char control_characters[] = { | ||
134 | '\003', '\034', '\177', '\030', '\004', '\0', | ||
135 | '\1', '\0', '\021', '\023', '\032', '\0', '\022', | ||
136 | '\017', '\027', '\026', '\0' | ||
137 | }; | ||
111 | 138 | ||
112 | tcgetattr(fd, &tty); | 139 | tcgetattr(fd, &tty); |
113 | 140 | ||
141 | /* Make it be sane */ | ||
142 | tty.c_cflag &= CBAUD|CBAUDEX|CSIZE|CSTOPB|PARENB|PARODD; | ||
143 | tty.c_cflag |= HUPCL|CLOCAL; | ||
144 | |||
114 | /* input modes */ | 145 | /* input modes */ |
115 | tty.c_iflag = IGNPAR|ICRNL|IXON|IXOFF|IXANY; | 146 | tty.c_iflag = IGNPAR|ICRNL|IXON|IXOFF|IXANY; |
116 | 147 | ||
@@ -129,6 +160,44 @@ void set_term( int fd) | |||
129 | tcsetattr(fd, TCSANOW, &tty); | 160 | tcsetattr(fd, TCSANOW, &tty); |
130 | } | 161 | } |
131 | 162 | ||
163 | /* Set terminal settings to reasonable defaults */ | ||
164 | void set_term_old( int fd) | ||
165 | { | ||
166 | struct termios tty; | ||
167 | |||
168 | ioctl(fd, TCGETA, &tty); | ||
169 | |||
170 | tty.c_cflag &= CBAUD|CBAUDEX|CSIZE|CSTOPB|PARENB|PARODD; | ||
171 | tty.c_cflag |= HUPCL|CLOCAL; | ||
172 | |||
173 | tty.c_cc[VINTR] = 3; | ||
174 | tty.c_cc[VQUIT] = 28; | ||
175 | tty.c_cc[VERASE] = 127; | ||
176 | //tty.c_cc[VKILL] = 21; | ||
177 | tty.c_cc[VKILL] = 24; | ||
178 | tty.c_cc[VEOF] = 4; | ||
179 | tty.c_cc[VTIME] = 0; | ||
180 | tty.c_cc[VMIN] = 1; | ||
181 | tty.c_cc[VSWTC] = 0; | ||
182 | tty.c_cc[VSTART] = 17; | ||
183 | tty.c_cc[VSTOP] = 19; | ||
184 | tty.c_cc[VSUSP] = 26; | ||
185 | tty.c_cc[VEOL] = 0; | ||
186 | tty.c_cc[VREPRINT] = 18; | ||
187 | tty.c_cc[VDISCARD] = 15; | ||
188 | tty.c_cc[VWERASE] = 23; | ||
189 | tty.c_cc[VLNEXT] = 22; | ||
190 | tty.c_cc[VEOL2] = 0; | ||
191 | |||
192 | |||
193 | tty.c_line = 0; | ||
194 | tty.c_iflag = IGNPAR|ICRNL|IXON|IXOFF|IXANY; | ||
195 | tty.c_oflag = OPOST|ONLCR; | ||
196 | tty.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK|ECHOCTL|ECHOPRT|ECHOKE|IEXTEN; | ||
197 | |||
198 | ioctl(fd, TCSETA, &tty); | ||
199 | } | ||
200 | |||
132 | /* How much memory does this machine have? */ | 201 | /* How much memory does this machine have? */ |
133 | static int mem_total() | 202 | static int mem_total() |
134 | { | 203 | { |
@@ -138,7 +207,7 @@ static int mem_total() | |||
138 | const char pattern[] = "MemTotal:"; | 207 | const char pattern[] = "MemTotal:"; |
139 | 208 | ||
140 | if ((f = fopen(p, "r")) < 0) { | 209 | if ((f = fopen(p, "r")) < 0) { |
141 | message(log, "Error opening %s: %s\n", p, strerror( errno)); | 210 | message(LOG, "Error opening %s: %s\n", p, strerror( errno)); |
142 | return -1; | 211 | return -1; |
143 | } | 212 | } |
144 | while (NULL != fgets(s, 79, f)) { | 213 | while (NULL != fgets(s, 79, f)) { |
@@ -173,7 +242,7 @@ static void console_init() | |||
173 | } | 242 | } |
174 | #endif | 243 | #endif |
175 | } else { | 244 | } else { |
176 | console = CONSOLE; | 245 | console = VT_CONSOLE; |
177 | tried_devcons++; | 246 | tried_devcons++; |
178 | } | 247 | } |
179 | 248 | ||
@@ -181,7 +250,7 @@ static void console_init() | |||
181 | /* Can't open selected console -- try /dev/console */ | 250 | /* Can't open selected console -- try /dev/console */ |
182 | if (!tried_devcons) { | 251 | if (!tried_devcons) { |
183 | tried_devcons++; | 252 | tried_devcons++; |
184 | console = CONSOLE; | 253 | console = VT_CONSOLE; |
185 | continue; | 254 | continue; |
186 | } | 255 | } |
187 | /* Can't open selected console -- try vt1 */ | 256 | /* Can't open selected console -- try vt1 */ |
@@ -197,17 +266,17 @@ static void console_init() | |||
197 | console = "/dev/null"; | 266 | console = "/dev/null"; |
198 | else | 267 | else |
199 | close(fd); | 268 | close(fd); |
200 | message(log, "console=%s\n", console ); | 269 | message(LOG, "console=%s\n", console ); |
201 | } | 270 | } |
202 | 271 | ||
203 | static int waitfor(int pid) | 272 | static int waitfor(int pid) |
204 | { | 273 | { |
205 | int status, wpid; | 274 | int status, wpid; |
206 | 275 | ||
207 | message(log, "Waiting for process %d.\n", pid); | 276 | message(LOG, "Waiting for process %d.\n", pid); |
208 | while ((wpid = wait(&status)) != pid) { | 277 | while ((wpid = wait(&status)) != pid) { |
209 | if (wpid > 0) | 278 | if (wpid > 0) |
210 | message(log, "pid %d exited, status=%x.\n", wpid, status); | 279 | message(LOG, "pid %d exited, status=0x%x.\n", wpid, status); |
211 | } | 280 | } |
212 | return wpid; | 281 | return wpid; |
213 | } | 282 | } |
@@ -236,7 +305,7 @@ static pid_t run(const char * const* command, | |||
236 | signal(SIGTERM, SIG_DFL); | 305 | signal(SIGTERM, SIG_DFL); |
237 | 306 | ||
238 | if ((fd = device_open(terminal, O_RDWR)) < 0) { | 307 | if ((fd = device_open(terminal, O_RDWR)) < 0) { |
239 | message(log, "Bummer, can't open %s\r\n", terminal); | 308 | message(LOG, "Bummer, can't open %s\r\n", terminal); |
240 | exit(-1); | 309 | exit(-1); |
241 | } | 310 | } |
242 | dup(fd); | 311 | dup(fd); |
@@ -254,20 +323,22 @@ static pid_t run(const char * const* command, | |||
254 | * specifies. | 323 | * specifies. |
255 | */ | 324 | */ |
256 | char c; | 325 | char c; |
326 | message(LOG, "Waiting for enter to start '%s' (pid %d, console %s)\r\n", | ||
327 | *cmd, getpid(), terminal ); | ||
257 | write(1, press_enter, sizeof(press_enter) - 1); | 328 | write(1, press_enter, sizeof(press_enter) - 1); |
258 | read(0, &c, 1); | 329 | read(0, &c, 1); |
259 | } | 330 | } |
260 | 331 | ||
261 | /* Log the process name and args */ | 332 | /* Log the process name and args */ |
262 | message(log, "Starting pid(%d): '", getpid()); | 333 | message(LOG, "Starting pid %d, console %s: '", getpid(), terminal); |
263 | while ( *cmd) message(log, "%s ", *cmd++); | 334 | while ( *cmd) message(LOG, "%s ", *cmd++); |
264 | message(log, "'\r\n"); | 335 | message(LOG, "'\r\n"); |
265 | 336 | ||
266 | /* Now run it. The new program will take over this PID, | 337 | /* Now run it. The new program will take over this PID, |
267 | * so nothing further in init.c should be run. */ | 338 | * so nothing further in init.c should be run. */ |
268 | execvp(*command, (char**)command+1); | 339 | execvp(*command, (char**)command+1); |
269 | 340 | ||
270 | message(log, "Bummer, could not run '%s'\n", command); | 341 | message(LOG, "Bummer, could not run '%s'\n", command); |
271 | exit(-1); | 342 | exit(-1); |
272 | } | 343 | } |
273 | return pid; | 344 | return pid; |
@@ -280,8 +351,6 @@ static void check_memory() | |||
280 | struct stat statbuf; | 351 | struct stat statbuf; |
281 | const char* const swap_on_cmd[] = | 352 | const char* const swap_on_cmd[] = |
282 | { "/bin/swapon", "swapon", "-a", 0}; | 353 | { "/bin/swapon", "swapon", "-a", 0}; |
283 | const char *no_memory = | ||
284 | "Sorry, your computer does not have enough memory.\r\n"; | ||
285 | 354 | ||
286 | if (mem_total() > 3500) | 355 | if (mem_total() > 3500) |
287 | return; | 356 | return; |
@@ -296,7 +365,7 @@ static void check_memory() | |||
296 | return; | 365 | return; |
297 | 366 | ||
298 | goodnight: | 367 | goodnight: |
299 | message(console, "%s", no_memory); | 368 | message(CONSOLE, "Sorry, your computer does not have enough memory.\r\n"); |
300 | while (1) sleep(1); | 369 | while (1) sleep(1); |
301 | } | 370 | } |
302 | 371 | ||
@@ -305,41 +374,39 @@ static void shutdown_system(void) | |||
305 | const char* const swap_off_cmd[] = { "swapoff", "swapoff", "-a", 0}; | 374 | const char* const swap_off_cmd[] = { "swapoff", "swapoff", "-a", 0}; |
306 | const char* const umount_cmd[] = { "umount", "umount", "-a", "-n", 0}; | 375 | const char* const umount_cmd[] = { "umount", "umount", "-a", "-n", 0}; |
307 | 376 | ||
308 | message(console, "The system is going down NOW !!\r\n"); | ||
309 | sync(); | ||
310 | #ifndef DEBUG_INIT | 377 | #ifndef DEBUG_INIT |
311 | /* Allow Ctrl-Alt-Del to reboot system. */ | 378 | /* Allow Ctrl-Alt-Del to reboot system. */ |
312 | reboot(RB_ENABLE_CAD); | 379 | reboot(RB_ENABLE_CAD); |
313 | #endif | 380 | #endif |
381 | message(CONSOLE, "The system is going down NOW !!\r\n"); | ||
382 | sync(); | ||
314 | /* Send signals to every process _except_ pid 1 */ | 383 | /* Send signals to every process _except_ pid 1 */ |
315 | message(console, "Sending SIGHUP to all processes.\r\n"); | 384 | message(CONSOLE, "Sending SIGHUP to all processes.\r\n"); |
316 | #ifndef DEBUG_INIT | 385 | #ifndef DEBUG_INIT |
317 | kill(-1, SIGHUP); | 386 | kill(-1, SIGHUP); |
318 | #endif | 387 | #endif |
319 | sleep(2); | 388 | sleep(2); |
320 | sync(); | 389 | sync(); |
321 | message(console, "Sending SIGKILL to all processes.\r\n"); | 390 | message(CONSOLE, "Sending SIGKILL to all processes.\r\n"); |
322 | #ifndef DEBUG_INIT | 391 | #ifndef DEBUG_INIT |
323 | kill(-1, SIGKILL); | 392 | kill(-1, SIGKILL); |
324 | #endif | 393 | #endif |
325 | sleep(1); | 394 | sleep(1); |
326 | waitfor(run( swap_off_cmd, log, FALSE)); | 395 | waitfor(run( swap_off_cmd, console, FALSE)); |
327 | waitfor(run( umount_cmd, log, FALSE)); | 396 | waitfor(run( umount_cmd, console, FALSE)); |
328 | sync(); | 397 | sync(); |
329 | if (get_kernel_revision() <= 2 * 65536 + 2 * 256 + 11) { | 398 | bdflush(1, 0); |
330 | /* Removed bdflush call, kupdate in kernels >2.2.11 */ | ||
331 | bdflush(1, 0); | ||
332 | sync(); | ||
333 | } | ||
334 | } | 399 | } |
335 | 400 | ||
336 | static void halt_signal(int sig) | 401 | static void halt_signal(int sig) |
337 | { | 402 | { |
338 | shutdown_system(); | 403 | shutdown_system(); |
339 | message(console, | 404 | message(CONSOLE, |
340 | "The system is halted. Press CTRL-ALT-DEL or turn off power\r\n"); | 405 | "The system is halted. Press CTRL-ALT-DEL or turn off power\r\n"); |
406 | sync(); | ||
341 | #ifndef DEBUG_INIT | 407 | #ifndef DEBUG_INIT |
342 | reboot(RB_POWER_OFF); | 408 | reboot(RB_HALT_SYSTEM); |
409 | //reboot(RB_POWER_OFF); | ||
343 | #endif | 410 | #endif |
344 | exit(0); | 411 | exit(0); |
345 | } | 412 | } |
@@ -347,7 +414,8 @@ static void halt_signal(int sig) | |||
347 | static void reboot_signal(int sig) | 414 | static void reboot_signal(int sig) |
348 | { | 415 | { |
349 | shutdown_system(); | 416 | shutdown_system(); |
350 | message(console, "Please stand by while rebooting the system.\r\n"); | 417 | message(CONSOLE, "Please stand by while rebooting the system.\r\n"); |
418 | sync(); | ||
351 | #ifndef DEBUG_INIT | 419 | #ifndef DEBUG_INIT |
352 | reboot(RB_AUTOBOOT); | 420 | reboot(RB_AUTOBOOT); |
353 | #endif | 421 | #endif |
@@ -410,22 +478,17 @@ extern int init_main(int argc, char **argv) | |||
410 | 478 | ||
411 | /* Hello world */ | 479 | /* Hello world */ |
412 | #ifndef DEBUG_INIT | 480 | #ifndef DEBUG_INIT |
413 | message(log, hello_msg_format, BB_VER, BB_BT); | 481 | message(CONSOLE|LOG, hello_msg_format, BB_VER, BB_BT); |
414 | message(console, hello_msg_format, BB_VER, BB_BT); | ||
415 | #else | 482 | #else |
416 | message(log, hello_msg_format, getpid(), BB_VER, BB_BT); | 483 | message(CONSOLE|LOG, hello_msg_format, getpid(), BB_VER, BB_BT); |
417 | message(console, hello_msg_format, getpid(), BB_VER, BB_BT); | ||
418 | #endif | 484 | #endif |
419 | 485 | ||
420 | 486 | ||
421 | /* Mount /proc */ | 487 | /* Mount /proc */ |
422 | if (mount ("proc", "/proc", "proc", 0, 0) == 0) { | 488 | if (mount ("proc", "/proc", "proc", 0, 0) == 0) |
423 | message(log, "Mounting /proc: done.\n"); | 489 | message(CONSOLE|LOG, "Mounting /proc: done.\n"); |
424 | message(console, "Mounting /proc: done.\n"); | 490 | else |
425 | } else { | 491 | message(CONSOLE|LOG, "Mounting /proc: failed!\n"); |
426 | message(log, "Mounting /proc: failed!\n"); | ||
427 | message(console, "Mounting /proc: failed!\n"); | ||
428 | } | ||
429 | 492 | ||
430 | /* Make sure there is enough memory to do something useful. */ | 493 | /* Make sure there is enough memory to do something useful. */ |
431 | check_memory(); | 494 | check_memory(); |
@@ -453,12 +516,13 @@ extern int init_main(int argc, char **argv) | |||
453 | } | 516 | } |
454 | wpid = wait(&status); | 517 | wpid = wait(&status); |
455 | if (wpid > 0 ) { | 518 | if (wpid > 0 ) { |
456 | message(log, "pid %d exited, status=%x.\n", wpid, status); | 519 | message(LOG, "pid %d exited, status=%x.\n", wpid, status); |
457 | } | 520 | } |
458 | if (wpid == pid1) { | 521 | if (wpid == pid1) { |
459 | pid1 = 0; | 522 | pid1 = 0; |
460 | if (run_rc == TRUE) { | 523 | if (run_rc == TRUE) { |
461 | /* Don't respawn init script if it exits. */ | 524 | /* Don't respawn init script if it exits, |
525 | * Start a shell instead. */ | ||
462 | run_rc=FALSE; | 526 | run_rc=FALSE; |
463 | wait_for_enter=TRUE; | 527 | wait_for_enter=TRUE; |
464 | tty0_commands=shell_commands; | 528 | tty0_commands=shell_commands; |