aboutsummaryrefslogtreecommitdiff
path: root/init.c
diff options
context:
space:
mode:
Diffstat (limited to 'init.c')
-rw-r--r--init.c483
1 files changed, 274 insertions, 209 deletions
diff --git a/init.c b/init.c
index b71c9f74e..be04ec34f 100644
--- a/init.c
+++ b/init.c
@@ -23,6 +23,7 @@
23 23
24#include "internal.h" 24#include "internal.h"
25#include <stdio.h> 25#include <stdio.h>
26#include <string.h>
26#include <stdlib.h> 27#include <stdlib.h>
27#include <stdarg.h> 28#include <stdarg.h>
28#include <unistd.h> 29#include <unistd.h>
@@ -55,22 +56,57 @@
55#endif 56#endif
56 57
57 58
58#define VT_PRIMARY "/dev/tty1" /* Primary virtual console */ 59#define VT_PRIMARY "/dev/tty1" /* Primary virtual console */
59#define VT_SECONDARY "/dev/tty2" /* Virtual console */ 60#define VT_SECONDARY "/dev/tty2" /* Virtual console */
60#define VT_LOG "/dev/tty3" /* Virtual console */ 61#define VT_LOG "/dev/tty3" /* Virtual console */
61#define SERIAL_CON0 "/dev/ttyS0" /* Primary serial console */ 62#define SERIAL_CON0 "/dev/ttyS0" /* Primary serial console */
62#define SERIAL_CON1 "/dev/ttyS1" /* Serial console */ 63#define SERIAL_CON1 "/dev/ttyS1" /* Serial console */
63#define GETTY "/sbin/getty" /* Default location of getty */ 64#define SHELL "/bin/sh" /* Default shell */
64#define SHELL "/bin/sh" /* Default shell */ 65#define REBOOT "/sbin/reboot" /* Default ctrl-alt-del command */
65#define INITTAB "/etc/inittab" /* inittab file location */ 66#define INITTAB "/etc/inittab" /* inittab file location */
66#ifndef BB_INIT_SCRIPT 67#define INIT_SCRIPT "/etc/init.d/rcS" /* Default sysinit script. */
67#define BB_INIT_SCRIPT "/etc/init.d/rcS" /* Initscript. */
68#endif
69
70#if 1
71 68
72#define LOG 0x1 69#define LOG 0x1
73#define CONSOLE 0x2 70#define CONSOLE 0x2
71
72/* Allowed init action types */
73typedef enum {
74 SYSINIT=1,
75 CTRLALTDEL,
76 RESPAWN,
77 ASKFIRST,
78 WAIT,
79 ONCE
80} initActionEnum;
81
82/* And now a list of the actions we support in the version of init */
83typedef struct initActionType{
84 const char* name;
85 initActionEnum action;
86} initActionType;
87
88static const struct initActionType actions[] = {
89 {"sysinit", SYSINIT},
90 {"ctrlaltdel", CTRLALTDEL},
91 {"respawn", RESPAWN},
92 {"askfirst", ASKFIRST},
93 {"wait", WAIT},
94 {"once", ONCE},
95 {0}
96};
97
98/* Set up a linked list of initactions, to be read from inittab */
99typedef struct initActionTag initAction;
100struct initActionTag {
101 pid_t pid;
102 char process[256];
103 char *console;
104 initAction *nextPtr;
105 initActionEnum action;
106};
107initAction* initActionList = NULL;
108
109
74static char *console = _PATH_CONSOLE; 110static char *console = _PATH_CONSOLE;
75static char *second_console = VT_SECONDARY; 111static char *second_console = VT_SECONDARY;
76static char *log = VT_LOG; 112static char *log = VT_LOG;
@@ -100,8 +136,9 @@ int device_open(char *device, int mode)
100 * device may be bitwise-or'd from LOG | CONSOLE */ 136 * device may be bitwise-or'd from LOG | CONSOLE */
101void message(int device, char *fmt, ...) 137void message(int device, char *fmt, ...)
102{ 138{
103 int fd;
104 va_list arguments; 139 va_list arguments;
140 int fd;
141
105#ifdef BB_SYSLOGD 142#ifdef BB_SYSLOGD
106 143
107 /* Log the message to syslogd */ 144 /* Log the message to syslogd */
@@ -298,16 +335,18 @@ static int waitfor(int pid)
298} 335}
299 336
300 337
301static pid_t run(const char * const* command, 338static pid_t run(char* command,
302 char *terminal, int get_enter) 339 char *terminal, int get_enter)
303{ 340{
304 int fd; 341 int i;
305 pid_t pid; 342 pid_t pid;
306 const char * const* cmd = command+1; 343 char* tmpCmd;
344 char* cmd[255];
307 static const char press_enter[] = 345 static const char press_enter[] =
308 "\nPlease press Enter to activate this console. "; 346 "\nPlease press Enter to activate this console. ";
309 347
310 if ((pid = fork()) == 0) { 348 if ((pid = fork()) == 0) {
349 int fd;
311 /* Clean up */ 350 /* Clean up */
312 close(0); 351 close(0);
313 close(1); 352 close(1);
@@ -321,7 +360,7 @@ static pid_t run(const char * const* command,
321 signal(SIGTERM, SIG_DFL); 360 signal(SIGTERM, SIG_DFL);
322 361
323 if ((fd = device_open(terminal, O_RDWR)) < 0) { 362 if ((fd = device_open(terminal, O_RDWR)) < 0) {
324 message(LOG, "Bummer, can't open %s\r\n", terminal); 363 message(LOG|CONSOLE, "Bummer, can't open %s\r\n", terminal);
325 exit(-1); 364 exit(-1);
326 } 365 }
327 dup(fd); 366 dup(fd);
@@ -340,21 +379,32 @@ static pid_t run(const char * const* command,
340 */ 379 */
341 char c; 380 char c;
342 message(LOG, "Waiting for enter to start '%s' (pid %d, console %s)\r\n", 381 message(LOG, "Waiting for enter to start '%s' (pid %d, console %s)\r\n",
343 *cmd, getpid(), terminal ); 382 command, getpid(), terminal );
344 write(1, press_enter, sizeof(press_enter) - 1); 383 write(fileno(stdout), press_enter, sizeof(press_enter) - 1);
345 read(0, &c, 1); 384 read(fileno(stdin), &c, 1);
346 } 385 }
347 386
387 /* Convert command (char*) into cmd (char**, one word per string) */
388 for (tmpCmd=command, i=0; (tmpCmd=strsep(&command, " \t")) != NULL;) {
389 if (*tmpCmd != '\0') {
390 cmd[i] = tmpCmd;
391 tmpCmd++;
392 i++;
393 }
394 }
395 cmd[i] = NULL;
396
348 /* Log the process name and args */ 397 /* Log the process name and args */
349 message(LOG|CONSOLE, "Starting pid %d, console %s: '", getpid(), terminal); 398 message(LOG, "Starting pid %d, console %s: '%s'\r\n",
350 while ( *cmd) message(LOG|CONSOLE, "%s ", *cmd++); 399 getpid(), terminal, cmd[0]);
351 message(LOG|CONSOLE, "'\r\n"); 400
352
353 /* Now run it. The new program will take over this PID, 401 /* Now run it. The new program will take over this PID,
354 * so nothing further in init.c should be run. */ 402 * so nothing further in init.c should be run. */
355 execvp(*command, (char**)command+1); 403 execvp(cmd[0], cmd);
356 404
357 message(LOG, "Bummer, could not run '%s'\n", command); 405 /* We're still here? Some error happened. */
406 message(LOG|CONSOLE, "Bummer, could not run '%s': %s\n", cmd[0],
407 strerror(errno));
358 exit(-1); 408 exit(-1);
359 } 409 }
360 return pid; 410 return pid;
@@ -365,15 +415,13 @@ static pid_t run(const char * const* command,
365static void check_memory() 415static void check_memory()
366{ 416{
367 struct stat statbuf; 417 struct stat statbuf;
368 const char* const swap_on_cmd[] =
369 { "/bin/swapon", "swapon", "-a", 0};
370 418
371 if (mem_total() > 3500) 419 if (mem_total() > 3500)
372 return; 420 return;
373 421
374 if (stat("/etc/fstab", &statbuf) == 0) { 422 if (stat("/etc/fstab", &statbuf) == 0) {
375 /* Try to turn on swap */ 423 /* Try to turn on swap */
376 waitfor(run(swap_on_cmd, log, FALSE)); 424 waitfor(run("/bin/swapon swapon -a", log, FALSE));
377 if (mem_total() < 3500) 425 if (mem_total() < 3500)
378 goto goodnight; 426 goto goodnight;
379 } else 427 } else
@@ -385,33 +433,28 @@ goodnight:
385 while (1) sleep(1); 433 while (1) sleep(1);
386} 434}
387 435
436#ifndef DEBUG_INIT
388static void shutdown_system(void) 437static void shutdown_system(void)
389{ 438{
390 const char* const swap_off_cmd[] = { "swapoff", "swapoff", "-a", 0};
391 const char* const umount_cmd[] = { "umount", "umount", "-a", 0};
392
393#ifndef DEBUG_INIT
394 /* Allow Ctrl-Alt-Del to reboot system. */ 439 /* Allow Ctrl-Alt-Del to reboot system. */
395 reboot(RB_ENABLE_CAD); 440 reboot(RB_ENABLE_CAD);
396#endif
397 message(CONSOLE, "\r\nThe system is going down NOW !!\r\n"); 441 message(CONSOLE, "\r\nThe system is going down NOW !!\r\n");
398 sync(); 442 sync();
443
399 /* Send signals to every process _except_ pid 1 */ 444 /* Send signals to every process _except_ pid 1 */
400 message(CONSOLE, "Sending SIGHUP to all processes.\r\n"); 445 message(CONSOLE, "Sending SIGHUP to all processes.\r\n");
401#ifndef DEBUG_INIT
402 kill(-1, SIGHUP); 446 kill(-1, SIGHUP);
403#endif
404 sleep(2); 447 sleep(2);
405 sync(); 448 sync();
449
406 message(CONSOLE, "Sending SIGKILL to all processes.\r\n"); 450 message(CONSOLE, "Sending SIGKILL to all processes.\r\n");
407#ifndef DEBUG_INIT
408 kill(-1, SIGKILL); 451 kill(-1, SIGKILL);
409#endif
410 sleep(1); 452 sleep(1);
453
411 message(CONSOLE, "Disabling swap.\r\n"); 454 message(CONSOLE, "Disabling swap.\r\n");
412 waitfor(run( swap_off_cmd, console, FALSE)); 455 waitfor(run( "swapoff -a", console, FALSE));
413 message(CONSOLE, "Unmounting filesystems.\r\n"); 456 message(CONSOLE, "Unmounting filesystems.\r\n");
414 waitfor(run( umount_cmd, console, FALSE)); 457 waitfor(run( "umount -a", console, FALSE));
415 sync(); 458 sync();
416 if (kernel_version > 0 && kernel_version <= 2 * 65536 + 2 * 256 + 11) { 459 if (kernel_version > 0 && kernel_version <= 2 * 65536 + 2 * 256 + 11) {
417 /* bdflush, kupdate not needed for kernels >2.2.11 */ 460 /* bdflush, kupdate not needed for kernels >2.2.11 */
@@ -427,14 +470,12 @@ static void halt_signal(int sig)
427 message(CONSOLE, 470 message(CONSOLE,
428 "The system is halted. Press CTRL-ALT-DEL or turn off power\r\n"); 471 "The system is halted. Press CTRL-ALT-DEL or turn off power\r\n");
429 sync(); 472 sync();
430#ifndef DEBUG_INIT
431#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) 473#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
432 if (sig == SIGUSR2) 474 if (sig == SIGUSR2)
433 reboot(RB_POWER_OFF); 475 reboot(RB_POWER_OFF);
434 else 476 else
435#endif 477#endif
436 reboot(RB_HALT_SYSTEM); 478 reboot(RB_HALT_SYSTEM);
437#endif
438 exit(0); 479 exit(0);
439} 480}
440 481
@@ -443,64 +484,157 @@ static void reboot_signal(int sig)
443 shutdown_system(); 484 shutdown_system();
444 message(CONSOLE, "Please stand by while rebooting the system.\r\n"); 485 message(CONSOLE, "Please stand by while rebooting the system.\r\n");
445 sync(); 486 sync();
446#ifndef DEBUG_INIT
447 reboot(RB_AUTOBOOT); 487 reboot(RB_AUTOBOOT);
448#endif
449 exit(0); 488 exit(0);
450} 489}
451 490
491static void ctrl_alt_del_signal(int sig)
492{
493 initAction* a;
494 /* Run whatever we are supposed to run */
495 for( a=initActionList ; a; a=a->nextPtr) {
496 if (a->action == CTRLALTDEL) {
497 waitfor(run(a->process, console, FALSE));
498 }
499 }
500}
501#endif
502
503void new_initAction (const struct initActionType *a,
504 char* process, char* console)
505{
506 initAction* newAction;
507 newAction = calloc ((size_t)(1), sizeof(initAction));
508 if (!newAction) {
509 fprintf(stderr, "Memory allocation failure\n");
510 while (1) sleep(1);
511 }
512 newAction->nextPtr = initActionList;
513 initActionList = newAction;
514 strncpy( newAction->process, process, 255);
515 newAction->action = a->action;
516 newAction->console = console;
517 newAction->pid = 0;
518}
519
520void delete_initAction (initAction *action)
521{
522 initAction *a, *b=NULL;
523 for( a=initActionList ; a; b=a, a=a->nextPtr) {
524 if (a == action && b != NULL) {
525 b->nextPtr=a->nextPtr;
526 free( a);
527 break;
528 }
529 }
530}
531
532void parse_inittab(void)
533{
534 FILE* file;
535 char buf[256];
536 char *p, *q, *r;
537 const struct initActionType *a = actions;
538 int foundIt;
539
540
541 file = fopen(INITTAB, "r");
542 if (file == NULL) {
543 /* No inittab file -- set up some default behavior */
544
545 /* Askfirst shell on tty1 */
546 new_initAction( &(actions[3]), SHELL, console );
547 /* Askfirst shell on tty2 */
548 if (second_console != NULL)
549 new_initAction( &(actions[3]), SHELL, second_console );
550 /* Control-alt-del */
551 new_initAction( &(actions[1]), REBOOT, console );
552 /* sysinit */
553 new_initAction( &(actions[0]), INIT_SCRIPT, console );
554
555 return;
556 }
557
558 while ( fgets(buf, 255, file) != NULL) {
559 foundIt=FALSE;
560 for(p = buf; *p == ' ' || *p == '\t'; p++);
561 if (*p == '#' || *p == '\n') continue;
562
563 /* Trim the trailing \n */
564 q = strrchr( p, '\n');
565 if (q != NULL)
566 *q='\0';
567
568 /* Skip past the ID field and the runlevel
569 * field (both are ignored) */
570 p = strchr( p, ':');
571
572 /* Now peal off the process field from the end
573 * of the string */
574 q = strrchr( p, ':');
575 if ( q == NULL || *(q+1) == '\0' ) {
576 fprintf(stderr, "Bad inittab entry: %s\n", buf);
577 continue;
578 } else {
579 *q='\0';
580 ++q;
581 }
582
583 /* Now peal off the action field */
584 r = strrchr( p, ':');
585 if ( r == NULL || *(r+1) == '\0') {
586 fprintf(stderr, "Bad inittab entry: %s\n", buf);
587 continue;
588 } else {
589 ++r;
590 }
591
592 /* Ok, now process it */
593 a = actions;
594 while (a->name != 0) {
595 if (strcmp(a->name, r) == 0) {
596 new_initAction( a, q, NULL);
597 foundIt=TRUE;
598 }
599 a++;
600 }
601 if (foundIt==TRUE)
602 continue;
603 else {
604 /* Choke on an unknown action */
605 fprintf(stderr, "Bad inittab entry: %s\n", buf);
606 }
607 }
608 return;
609}
610
611
452extern int init_main(int argc, char **argv) 612extern int init_main(int argc, char **argv)
453{ 613{
454 int run_rc = FALSE; 614 initAction *a;
615 pid_t wpid;
616 int status;
455 int single = FALSE; 617 int single = FALSE;
456 int wait_for_enter_tty1 = TRUE;
457 int wait_for_enter_tty2 = TRUE;
458 pid_t pid1 = 0;
459 pid_t pid2 = 0;
460 struct stat statbuf;
461 char which_vt1[30];
462 char which_vt2[30];
463 const char* const rc_script_command[] = { BB_INIT_SCRIPT, BB_INIT_SCRIPT, 0};
464 const char* const getty1_command[] = { GETTY, GETTY, "38400", which_vt1, 0};
465 const char* const getty2_command[] = { GETTY, GETTY, "38400", which_vt2, 0};
466 const char* const shell_command[] = { SHELL, "-" SHELL, 0};
467 const char* const* tty1_command = shell_command;
468 const char* const* tty2_command = shell_command;
469#ifdef BB_INIT_CMD_IF_RC_SCRIPT_EXITS
470 const char* const rc_exit_command[] = { "BB_INIT_CMD_IF_RC_SCRIPT_EXITS",
471 "BB_INIT_CMD_IF_RC_SCRIPT_EXITS", 0 };
472#endif
473 618
474#ifdef DEBUG_INIT
475 char *hello_msg_format =
476 "init(%d) started: BusyBox v%s (%s) multi-call binary\r\n";
477#else
478 char *hello_msg_format =
479 "init started: BusyBox v%s (%s) multi-call binary\r\n";
480#endif
481 619
482
483#ifndef DEBUG_INIT 620#ifndef DEBUG_INIT
484 /* Expect to be PID 1 iff we are run as init (not linuxrc) */ 621 /* Expect to be PID 1 iff we are run as init (not linuxrc) */
485 if (getpid() != 1 && strstr(argv[0], "init")!=NULL ) { 622 if (getpid() != 1 && strstr(argv[0], "init")!=NULL ) {
486 usage( "init\n\nInit is the parent of all processes.\n\n" 623 usage( "init\n\nInit is the parent of all processes.\n\n"
487 "This version of init is designed to be run only by the kernel\n"); 624 "This version of init is designed to be run only by the kernel\n");
488 } 625 }
489#endif
490 626
491 /* Set up sig handlers -- be sure to 627 /* Set up sig handlers -- be sure to clear all of these in run() */
492 * clear all of these in run() */
493 signal(SIGUSR1, halt_signal); 628 signal(SIGUSR1, halt_signal);
494 signal(SIGUSR2, reboot_signal); 629 signal(SIGUSR2, reboot_signal);
495 signal(SIGINT, reboot_signal); 630 signal(SIGINT, ctrl_alt_del_signal);
496 signal(SIGTERM, reboot_signal); 631 signal(SIGTERM, reboot_signal);
497 632
498 /* Turn off rebooting via CTL-ALT-DEL -- we get a 633 /* Turn off rebooting via CTL-ALT-DEL -- we get a
499 * SIGINT on CAD so we can shut things down gracefully... */ 634 * SIGINT on CAD so we can shut things down gracefully... */
500#ifndef DEBUG_INIT
501 reboot(RB_DISABLE_CAD); 635 reboot(RB_DISABLE_CAD);
502#endif 636#endif
503 637
504 /* Figure out where the default console should be */ 638 /* Figure out where the default console should be */
505 console_init(); 639 console_init();
506 640
@@ -517,9 +651,13 @@ extern int init_main(int argc, char **argv)
517 651
518 /* Hello world */ 652 /* Hello world */
519#ifndef DEBUG_INIT 653#ifndef DEBUG_INIT
520 message(CONSOLE|LOG, hello_msg_format, BB_VER, BB_BT); 654 message(CONSOLE|LOG,
655 "init started: BusyBox v%s (%s) multi-call binary\r\n",
656 BB_VER, BB_BT);
521#else 657#else
522 message(CONSOLE|LOG, hello_msg_format, getpid(), BB_VER, BB_BT); 658 message(CONSOLE|LOG,
659 "init(%d) started: BusyBox v%s (%s) multi-call binary\r\n",
660 getpid(), BB_VER, BB_BT);
523#endif 661#endif
524 662
525 663
@@ -537,150 +675,77 @@ extern int init_main(int argc, char **argv)
537 if ( argc > 1 && (!strcmp(argv[1], "single") || 675 if ( argc > 1 && (!strcmp(argv[1], "single") ||
538 !strcmp(argv[1], "-s") || !strcmp(argv[1], "1"))) { 676 !strcmp(argv[1], "-s") || !strcmp(argv[1], "1"))) {
539 single = TRUE; 677 single = TRUE;
540 tty1_command = shell_command; 678 /* Ask first then start a shell on tty2 */
541 tty2_command = shell_command; 679 if (second_console != NULL)
680 new_initAction( &(actions[3]), SHELL, second_console);
681 /* Ask first then start a shell on tty1 */
682 new_initAction( &(actions[3]), SHELL, console);
683 } else {
684 /* Not in single user mode -- see what inittab says */
685 parse_inittab();
542 } 686 }
543 687
544 /* Make sure an init script exists before trying to run it */ 688 /* Now run everything that needs to be run */
545 if (single==FALSE && stat(BB_INIT_SCRIPT, &statbuf)==0) { 689
546 run_rc = TRUE; 690 /* First run sysinit */
547 wait_for_enter_tty1 = FALSE; 691 for( a=initActionList ; a; a=a->nextPtr) {
548 tty1_command = rc_script_command; 692 if (a->action == SYSINIT) {
693 waitfor(run(a->process, console, FALSE));
694 /* Now remove the "sysinit" entry from the list */
695 delete_initAction( a);
696 }
549 } 697 }
550 698 /* Next run anything that wants to block */
551 /* Make sure /sbin/getty exists before trying to run it */ 699 for( a=initActionList ; a; a=a->nextPtr) {
552 if (stat(GETTY, &statbuf)==0) { 700 if (a->action == WAIT) {
553 char* where; 701 waitfor(run(a->process, console, FALSE));
554 /* First do tty2 */ 702 /* Now remove the "wait" entry from the list */
555 wait_for_enter_tty2 = FALSE; 703 delete_initAction( a);
556 where = strrchr( second_console, '/');
557 if ( where != NULL) {
558 where++;
559 strncpy( which_vt2, where, sizeof(which_vt2));
560 } 704 }
561 tty2_command = getty2_command; 705 }
562 706 /* Next run anything to be run only once */
563 /* Check on hooking a getty onto tty1 */ 707 for( a=initActionList ; a; a=a->nextPtr) {
564 if (run_rc == FALSE && single==FALSE) { 708 if (a->action == ONCE) {
565 wait_for_enter_tty1 = FALSE; 709 run(a->process, console, FALSE);
566 where = strrchr( console, '/'); 710 /* Now remove the "once" entry from the list */
567 if ( where != NULL) { 711 delete_initAction( a);
568 where++;
569 strncpy( which_vt1, where, sizeof(which_vt1));
570 }
571 tty1_command = getty1_command;
572 } 712 }
573 } 713 }
574
575 714
576 /* Ok, now launch the tty1_command and tty2_command */ 715 /* Now run the looping stuff */
577 for (;;) { 716 for (;;) {
578 pid_t wpid; 717 for( a=initActionList ; a; a=a->nextPtr) {
579 int status; 718 /* Only run stuff with pid==0. If they have
580 719 * a pid, that means they are still running */
581 if (pid1 == 0 && tty1_command) { 720 if (a->pid == 0) {
582 pid1 = run(tty1_command, console, wait_for_enter_tty1); 721 switch(a->action) {
583 } 722 case RESPAWN:
584#ifdef BB_FEATURE_INIT_SECOND_CONSOLE 723 /* run the respawn stuff */
585 if (pid2 == 0 && tty2_command && second_console) { 724 a->pid = run(a->process, console, FALSE);
586 pid2 = run(tty2_command, second_console, wait_for_enter_tty2); 725 break;
726 case ASKFIRST:
727 /* run the askfirst stuff */
728 a->pid = waitfor(run(a->process, console, TRUE));
729 break;
730 /* silence the compiler's whining */
731 default:
732 break;
733 }
734 }
587 } 735 }
588#endif 736
589 wpid = wait(&status); 737 wpid = wait(&status);
738 /* Find out who died and clean up their corpse */
590 if (wpid > 0 ) { 739 if (wpid > 0 ) {
591 message(LOG, "pid %d exited, status=%x.\n", wpid, status); 740 message(LOG, "pid %d exited, status=%x.\n", wpid, status);
592 } 741 for( a=initActionList ; a; a=a->nextPtr) {
593 /* Don't respawn init script if it exits */ 742 if (a->pid==wpid) {
594 if (wpid == pid1) { 743 a->pid=0;
595 if (run_rc == FALSE) { 744 }
596 pid1 = 0;
597 } 745 }
598#ifdef BB_INIT_CMD_IF_RC_SCRIPT_EXITS
599 else {
600 pid1 = 0;
601 run_rc=FALSE;
602 wait_for_enter_tty1=TRUE;
603 tty1_command=rc_exit_command;
604 }
605#endif
606 } 746 }
607#ifdef BB_FEATURE_INIT_SECOND_CONSOLE
608 if (wpid == pid2) {
609 pid2 = 0;
610 }
611#endif
612 sleep(1);
613 }
614}
615
616#else
617
618
619void parse_inittab(void)
620{
621 FILE* file;
622 char buf[256];
623 char action[256]="";
624 char process[256]="";
625 char *p, *q;
626
627
628 if ((file = fopen(INITTAB, "r")) < 0) {
629 /* No inittab file -- set up some default behavior */
630
631 /* FIXME */
632 return;
633 }
634
635 while ( fgets(buf, 255, file) != NULL) {
636 for(p = buf; *p == ' ' || *p == '\t'; p++);
637 if (*p == '#' || *p == '\n') continue;
638
639 /* Trim the trailing \n */
640 q = strrchr( p, '\n');
641 if (q != NULL)
642 *q='\0';
643
644 /* Skip past the ID field and the runlevel
645 * field (both are ignored) */
646 p = strchr( p, ':');
647
648 /* Now peal off the process field from the end
649 * of the string */
650 q = strrchr( p, ':');
651 if ( q == NULL || q+1 == NULL)
652 goto choke;
653 *q='\0';
654 strcpy( process, ++q);
655 fprintf(stderr, "process=%s\n", process);
656
657
658 /* Now peal off the action field */
659 q = strrchr( p, ':');
660 if ( q == NULL || q+1 == NULL)
661 goto choke;
662 strcpy( action, ++q);
663 fprintf(stderr, "action=%s\n", action);
664
665
666 /* Ok, now do the right thing */
667 747
748 sleep(1);
668 } 749 }
669 return;
670
671choke:
672 //message(CONSOLE, "Bad entry:");
673 fprintf(stderr, "Bad inittab entry: %s", buf);
674 while (1) sleep(1);
675
676}
677
678
679extern int init_main(int argc, char **argv)
680{
681 parse_inittab();
682 exit( TRUE);
683} 750}
684 751
685
686#endif