aboutsummaryrefslogtreecommitdiff
path: root/init/init.c
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>1999-11-04 01:13:21 +0000
committerEric Andersen <andersen@codepoet.org>1999-11-04 01:13:21 +0000
commit3ae0c789627a29dbd76793eb666efe19144b30f0 (patch)
treee3b6a9393ea44e1391cbdf9075e6edc266530a49 /init/init.c
parentbe971d6b693ca9cd1c9aa9eb6053aa2592c40547 (diff)
downloadbusybox-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.c180
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
57static char *console = CONSOLE; 54#define LOG 0x1
55#define CONSOLE 0x2
56static char *console = VT_CONSOLE;
58static char *second_console = VT_SECONDARY; 57static char *second_console = VT_SECONDARY;
59static char *log = VT_LOG; 58static 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:
83void message(char *device, char *fmt, ...) 82 * device may be bitwise-or'd from LOG | CONSOLE */
83void 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 */
103void set_term( int fd) 123void 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 */
164void 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? */
133static int mem_total() 202static 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
203static int waitfor(int pid) 272static 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
298goodnight: 367goodnight:
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
336static void halt_signal(int sig) 401static 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)
347static void reboot_signal(int sig) 414static 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;