aboutsummaryrefslogtreecommitdiff
path: root/init/init.c
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>1999-11-02 19:43:01 +0000
committerEric Andersen <andersen@codepoet.org>1999-11-02 19:43:01 +0000
commit219d6f5e0cb4c8e1a9a5f554a8768c7afb12b0b4 (patch)
treeb57f1359fdb218ed9de072327ce65143c40ac6da /init/init.c
parent2f6c04f63c55a03366dfd5848f00bda664c9a90d (diff)
downloadbusybox-w32-219d6f5e0cb4c8e1a9a5f554a8768c7afb12b0b4.tar.gz
busybox-w32-219d6f5e0cb4c8e1a9a5f554a8768c7afb12b0b4.tar.bz2
busybox-w32-219d6f5e0cb4c8e1a9a5f554a8768c7afb12b0b4.zip
Stuf
Diffstat (limited to 'init/init.c')
-rw-r--r--init/init.c186
1 files changed, 97 insertions, 89 deletions
diff --git a/init/init.c b/init/init.c
index 0850cf810..34eca8b77 100644
--- a/init/init.c
+++ b/init/init.c
@@ -45,17 +45,17 @@
45//#define DEBUG_INIT 45//#define DEBUG_INIT
46 46
47#define CONSOLE "/dev/console" /* Logical system console */ 47#define CONSOLE "/dev/console" /* Logical system console */
48#define VT_PRIMARY "/dev/tty0" /* Virtual console master */ 48#define VT_PRIMARY "/dev/tty0" /* Primary virtual console */
49#define VT_SECONDARY "/dev/tty1" /* Virtual console master */ 49#define VT_SECONDARY "/dev/tty1" /* Virtual console */
50#define VT_LOG "/dev/tty2" /* Virtual console master */ 50#define VT_LOG "/dev/tty2" /* Virtual console */
51#define SERIAL_CON0 "/dev/ttyS0" /* Primary serial console */
52#define SERIAL_CON1 "/dev/ttyS1" /* Serial console */
51#define SHELL "/bin/sh" /* Default shell */ 53#define SHELL "/bin/sh" /* Default shell */
52//#define INITSCRIPT "/etc/init.d/rcS" /* Initscript. */ 54#define INITSCRIPT "/etc/init.d/rcS" /* Initscript. */
53#define INITSCRIPT "/tmp/foo.sh"
54#define PATH_DEFAULT "PATH=/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin" 55#define PATH_DEFAULT "PATH=/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin"
55 56
56static char *console = CONSOLE; 57static char *console = VT_PRIMARY;
57//static char *first_terminal = "/dev/tty1"; 58static char *second_terminal = VT_SECONDARY;
58static char *second_terminal = "/dev/tty2";
59static char *log = "/dev/tty3"; 59static char *log = "/dev/tty3";
60 60
61 61
@@ -114,7 +114,7 @@ void set_term( int fd)
114 /* input modes */ 114 /* input modes */
115 tty.c_iflag = IGNPAR|ICRNL|IXON|IXOFF|IXANY; 115 tty.c_iflag = IGNPAR|ICRNL|IXON|IXOFF|IXANY;
116 116
117 /* use lineo dicipline 0 */ 117 /* use line dicipline 0 */
118 tty.c_line = 0; 118 tty.c_line = 0;
119 119
120 /* output modes */ 120 /* output modes */
@@ -129,14 +129,18 @@ void set_term( int fd)
129 tcsetattr(fd, TCSANOW, &tty); 129 tcsetattr(fd, TCSANOW, &tty);
130} 130}
131 131
132/* How much memory does this machine have? */
132static int mem_total() 133static int mem_total()
133{ 134{
134 char s[80]; 135 char s[80];
135 char *p; 136 char *p = "/proc/meminfo";
136 FILE *f; 137 FILE *f;
137 const char pattern[] = "MemTotal:"; 138 const char pattern[] = "MemTotal:";
138 139
139 f = fopen("/proc/meminfo", "r"); 140 if ((f = fopen(p, "r")) < 0) {
141 message(log, "Error opening %s: %s\n", p, strerror( errno));
142 return -1;
143 }
140 while (NULL != fgets(s, 79, f)) { 144 while (NULL != fgets(s, 79, f)) {
141 p = strstr(s, pattern); 145 p = strstr(s, pattern);
142 if (NULL != p) { 146 if (NULL != p) {
@@ -147,60 +151,53 @@ static int mem_total()
147 return -1; 151 return -1;
148} 152}
149 153
150static void set_free_pages()
151{
152 char s[80];
153 FILE *f;
154
155 f = fopen("/proc/sys/vm/freepages", "r");
156 fgets(s, 79, f);
157 if (atoi(s) < 32) {
158 fclose(f);
159 f = fopen("/proc/sys/vm/freepages", "w");
160 fprintf(f, "30\t40\t50\n");
161 message(log, "\nIncreased /proc/sys/vm/freepages values to 30/40/50\n");
162 }
163 fclose(f);
164}
165
166
167static void console_init() 154static void console_init()
168{ 155{
169 int fd; 156 int fd;
170 struct stat statbuf;
171 int tried_devcons = 0; 157 int tried_devcons = 0;
172 int tried_vtmaster = 0; 158 int tried_vtprimary = 0;
173 char *s; 159 char *s;
174 160
175 if ((s = getenv("CONSOLE")) != NULL) 161 if ((s = getenv("CONSOLE")) != NULL) {
176 console = s; 162 console = s;
177 else { 163/* Apparently the sparc does wierd things... */
178 console = CONSOLE; 164#if defined (__sparc__)
179 tried_devcons++; 165 if (strncmp( s, "/dev/tty", 8 )==0) {
166 switch( s[8]) {
167 case 'a':
168 s=SERIAL_CON0;
169 break;
170 case 'b':
171 s=SERIAL_CON1;
172 }
173 }
174#endif
175 } else {
176 console = VT_PRIMARY;
177 tried_vtprimary++;
180 } 178 }
181 179
182 if ( stat(CONSOLE, &statbuf) && S_ISLNK(statbuf.st_mode)) {
183 fprintf(stderr, "Yikes! /dev/console does not exist or is a symlink.\n");
184 message(log, "Yikes! /dev/console does not exist or is a symlink.\n");
185 }
186 while ((fd = open(console, O_RDONLY | O_NONBLOCK)) < 0) { 180 while ((fd = open(console, O_RDONLY | O_NONBLOCK)) < 0) {
181 /* Can't open selected console -- try vt1 */
182 if (!tried_vtprimary) {
183 tried_vtprimary++;
184 console = VT_PRIMARY;
185 continue;
186 }
187 /* Can't open selected console -- try /dev/console */
187 if (!tried_devcons) { 188 if (!tried_devcons) {
188 tried_devcons++; 189 tried_devcons++;
189 console = CONSOLE; 190 console = CONSOLE;
190 continue; 191 continue;
191 } 192 }
192 if (!tried_vtmaster) {
193 tried_vtmaster++;
194 console = VT_PRIMARY;
195 continue;
196 }
197 break; 193 break;
198 } 194 }
199 if (fd < 0) 195 if (fd < 0)
196 /* Perhaps we should panic here? */
200 console = "/dev/null"; 197 console = "/dev/null";
201 else 198 else
202 close(fd); 199 close(fd);
203 message(log, "console=%s\n", console); 200 message(log, "console=%s\n", console );
204} 201}
205 202
206static int waitfor(int pid) 203static int waitfor(int pid)
@@ -221,7 +218,7 @@ static pid_t run(const char * const* command,
221{ 218{
222 int fd; 219 int fd;
223 pid_t pid; 220 pid_t pid;
224 const char * const* cmd = command; 221 const char * const* cmd = command+1;
225 static const char press_enter[] = 222 static const char press_enter[] =
226 "\nPlease press Enter to activate this console. "; 223 "\nPlease press Enter to activate this console. ";
227 224
@@ -262,7 +259,7 @@ static pid_t run(const char * const* command,
262 } 259 }
263 260
264 /* Log the process name and args */ 261 /* Log the process name and args */
265 message(log, "Executing pid(%d): '", getpid()); 262 message(log, "Starting pid(%d): '", getpid());
266 while ( *cmd) message(log, "%s ", *cmd++); 263 while ( *cmd) message(log, "%s ", *cmd++);
267 message(log, "'\r\n"); 264 message(log, "'\r\n");
268 265
@@ -270,12 +267,39 @@ static pid_t run(const char * const* command,
270 * so nothing further in init.c should be run. */ 267 * so nothing further in init.c should be run. */
271 execvp(*command, (char**)command+1); 268 execvp(*command, (char**)command+1);
272 269
273 message(log, "Bummer, could not execute '%s'\n", command); 270 message(log, "Bummer, could not run '%s'\n", command);
274 exit(-1); 271 exit(-1);
275 } 272 }
276 return pid; 273 return pid;
277} 274}
278 275
276/* Make sure there is enough memory to do something useful. *
277 * Calls swapon if needed so be sure /proc is mounted. */
278static void check_memory()
279{
280 struct stat statbuf;
281 const char* const swap_on_cmd[] =
282 { "/bin/swapon", "swapon", "-a", 0};
283 const char *no_memory =
284 "Sorry, your computer does not have enough memory.\r\n";
285
286 if (mem_total() > 3500)
287 return;
288
289 if (stat("/etc/fstab", &statbuf) == 0) {
290 /* Try to turn on swap */
291 waitfor(run(swap_on_cmd, log, FALSE));
292 if (mem_total() < 3500)
293 goto goodnight;
294 } else
295 goto goodnight;
296 return;
297
298goodnight:
299 message(console, "%s", no_memory);
300 while (1) sleep(1);
301}
302
279static void shutdown_system(void) 303static void shutdown_system(void)
280{ 304{
281 const char* const swap_off_cmd[] = { "swapoff", "swapoff", "-a", 0}; 305 const char* const swap_off_cmd[] = { "swapoff", "swapoff", "-a", 0};
@@ -333,14 +357,13 @@ static void reboot_signal(int sig)
333extern int init_main(int argc, char **argv) 357extern int init_main(int argc, char **argv)
334{ 358{
335 int run_rc = TRUE; 359 int run_rc = TRUE;
336 int wait_for_enter = FALSE; 360 int wait_for_enter = TRUE;
337 pid_t pid1 = 0; 361 pid_t pid1 = 0;
338 pid_t pid2 = 0; 362 pid_t pid2 = 0;
339 struct stat statbuf; 363 struct stat statbuf;
340 const char* const swap_on_cmd[] = { "/bin/swapon", "swapon", "-a", 0};
341 const char* const init_commands[] = { INITSCRIPT, INITSCRIPT, 0}; 364 const char* const init_commands[] = { INITSCRIPT, INITSCRIPT, 0};
342 const char* const shell_commands[] = { SHELL, "-" SHELL, 0}; 365 const char* const shell_commands[] = { SHELL, "-" SHELL, 0};
343 const char* const* tty0_commands = init_commands; 366 const char* const* tty0_commands = shell_commands;
344 const char* const* tty1_commands = shell_commands; 367 const char* const* tty1_commands = shell_commands;
345#ifdef DEBUG_INIT 368#ifdef DEBUG_INIT
346 char *hello_msg_format = 369 char *hello_msg_format =
@@ -349,9 +372,15 @@ extern int init_main(int argc, char **argv)
349 char *hello_msg_format = 372 char *hello_msg_format =
350 "init started: BusyBox v%s (%s) multi-call binary\r\n"; 373 "init started: BusyBox v%s (%s) multi-call binary\r\n";
351#endif 374#endif
352 const char *no_memory =
353 "Sorry, your computer does not have enough memory.\r\n";
354 375
376
377 /* Check if we are supposed to be in single user mode */
378 if ( argc > 1 && (!strcmp(argv[1], "single") ||
379 !strcmp(argv[1], "-s") || !strcmp(argv[1], "1"))) {
380 run_rc = FALSE;
381 }
382
383
355 /* Set up sig handlers -- be sure to 384 /* Set up sig handlers -- be sure to
356 * clear all of these in run() */ 385 * clear all of these in run() */
357 signal(SIGUSR1, halt_signal); 386 signal(SIGUSR1, halt_signal);
@@ -364,6 +393,7 @@ extern int init_main(int argc, char **argv)
364#ifndef DEBUG_INIT 393#ifndef DEBUG_INIT
365 reboot(RB_DISABLE_CAD); 394 reboot(RB_DISABLE_CAD);
366#endif 395#endif
396
367 /* Figure out where the default console should be */ 397 /* Figure out where the default console should be */
368 console_init(); 398 console_init();
369 399
@@ -375,9 +405,9 @@ extern int init_main(int argc, char **argv)
375 setsid(); 405 setsid();
376 406
377 /* Make sure PATH is set to something sane */ 407 /* Make sure PATH is set to something sane */
378 if (getenv("PATH") == NULL) 408 putenv(PATH_DEFAULT);
379 putenv(PATH_DEFAULT);
380 409
410
381 /* Hello world */ 411 /* Hello world */
382#ifndef DEBUG_INIT 412#ifndef DEBUG_INIT
383 message(log, hello_msg_format, BB_VER, BB_BT); 413 message(log, hello_msg_format, BB_VER, BB_BT);
@@ -397,44 +427,17 @@ extern int init_main(int argc, char **argv)
397 message(console, "Mounting /proc: failed!\n"); 427 message(console, "Mounting /proc: failed!\n");
398 } 428 }
399 429
400 /* Make sure there is enough memory to do something useful */ 430 /* Make sure there is enough memory to do something useful. */
401 set_free_pages(); 431 check_memory();
402 if (mem_total() < 3500) {
403 int retval;
404 retval = stat("/etc/fstab", &statbuf);
405 if (retval) {
406 message(console, "%s", no_memory);
407 while (1) {
408 sleep(1);
409 }
410 } else {
411 /* Try to turn on swap */
412 waitfor(run(swap_on_cmd, log, FALSE));
413 if (mem_total() < 2000) {
414 message(console, "%s", no_memory);
415 while (1) {
416 sleep(1);
417 }
418 }
419 }
420 }
421 432
422 /* Check if we are supposed to be in single user mode */
423 if ( argc > 1 && (!strcmp(argv[1], "single") ||
424 !strcmp(argv[1], "-s") || !strcmp(argv[1], "1"))) {
425 run_rc = FALSE;
426 wait_for_enter = TRUE;
427 tty0_commands = shell_commands;
428 tty1_commands = shell_commands;
429 }
430 433
431 /* Make sure an init script exists before trying to run it */ 434 /* Make sure an init script exists before trying to run it */
432 if (run_rc == TRUE && stat(INITSCRIPT, &statbuf)) { 435 if (run_rc == TRUE && stat(INITSCRIPT, &statbuf)==0) {
433 wait_for_enter = TRUE; 436 wait_for_enter = FALSE;
434 tty0_commands = shell_commands; 437 tty0_commands = init_commands;
435 tty1_commands = shell_commands;
436 } 438 }
437 439
440
438 /* Ok, now launch the rc script and/or prepare to 441 /* Ok, now launch the rc script and/or prepare to
439 * start up some VTs if somebody hits enter... 442 * start up some VTs if somebody hits enter...
440 */ 443 */
@@ -452,9 +455,14 @@ extern int init_main(int argc, char **argv)
452 if (wpid > 0 ) { 455 if (wpid > 0 ) {
453 message(log, "pid %d exited, status=%x.\n", wpid, status); 456 message(log, "pid %d exited, status=%x.\n", wpid, status);
454 } 457 }
455 /* Don't respawn an init script if it exits */ 458 if (wpid == pid1) {
456 if (run_rc == FALSE && wpid == pid1) {
457 pid1 = 0; 459 pid1 = 0;
460 if (run_rc == TRUE) {
461 /* Don't respawn init script if it exits. */
462 run_rc=FALSE;
463 wait_for_enter=TRUE;
464 tty0_commands=shell_commands;
465 }
458 } 466 }
459 if (wpid == pid2) { 467 if (wpid == pid2) {
460 pid2 = 0; 468 pid2 = 0;