diff options
| author | Eric Andersen <andersen@codepoet.org> | 2002-03-05 15:12:19 +0000 |
|---|---|---|
| committer | Eric Andersen <andersen@codepoet.org> | 2002-03-05 15:12:19 +0000 |
| commit | 0298be88aece2a10b04c71db34fb154bdbbc45c9 (patch) | |
| tree | 1cf3eb885a205ee40713b468a0b9a7687fa84cc5 | |
| parent | 684d745bf3551a0539b4e678b3d3de4f4f800c7a (diff) | |
| download | busybox-w32-0298be88aece2a10b04c71db34fb154bdbbc45c9.tar.gz busybox-w32-0298be88aece2a10b04c71db34fb154bdbbc45c9.tar.bz2 busybox-w32-0298be88aece2a10b04c71db34fb154bdbbc45c9.zip | |
Update init.c per my changes in the stable branch
-Erik
| -rw-r--r-- | init/init.c | 491 |
1 files changed, 269 insertions, 222 deletions
diff --git a/init/init.c b/init/init.c index e48dc50cc..408dd1f95 100644 --- a/init/init.c +++ b/init/init.c | |||
| @@ -47,6 +47,9 @@ | |||
| 47 | # include <sys/syslog.h> | 47 | # include <sys/syslog.h> |
| 48 | #endif | 48 | #endif |
| 49 | 49 | ||
| 50 | #if defined(__UCLIBC__) && !defined(__UCLIBC_HAS_MMU__) | ||
| 51 | #define fork vfork | ||
| 52 | #endif | ||
| 50 | 53 | ||
| 51 | /* From <linux/vt.h> */ | 54 | /* From <linux/vt.h> */ |
| 52 | struct vt_stat { | 55 | struct vt_stat { |
| @@ -82,19 +85,10 @@ struct serial_struct { | |||
| 82 | #define init_reboot(magic) reboot(0xfee1dead, 672274793, magic) | 85 | #define init_reboot(magic) reboot(0xfee1dead, 672274793, magic) |
| 83 | #endif | 86 | #endif |
| 84 | 87 | ||
| 85 | #ifndef RB_HALT_SYSTEM | ||
| 86 | static const int RB_HALT_SYSTEM = 0xcdef0123; | ||
| 87 | static const int RB_ENABLE_CAD = 0x89abcdef; | ||
| 88 | static const int RB_DISABLE_CAD = 0; | ||
| 89 | #define RB_POWER_OFF 0x4321fedc | ||
| 90 | static const int RB_AUTOBOOT = 0x01234567; | ||
| 91 | #endif | ||
| 92 | |||
| 93 | #ifndef _PATH_STDPATH | 88 | #ifndef _PATH_STDPATH |
| 94 | #define _PATH_STDPATH "/usr/bin:/bin:/usr/sbin:/sbin" | 89 | #define _PATH_STDPATH "/usr/bin:/bin:/usr/sbin:/sbin" |
| 95 | #endif | 90 | #endif |
| 96 | 91 | ||
| 97 | |||
| 98 | #if defined CONFIG_FEATURE_INIT_COREDUMPS | 92 | #if defined CONFIG_FEATURE_INIT_COREDUMPS |
| 99 | /* | 93 | /* |
| 100 | * When a file named CORE_ENABLE_FLAG_FILE exists, setrlimit is called | 94 | * When a file named CORE_ENABLE_FLAG_FILE exists, setrlimit is called |
| @@ -115,7 +109,6 @@ static const int RB_AUTOBOOT = 0x01234567; | |||
| 115 | extern int bdflush (int func, long int data); | 109 | extern int bdflush (int func, long int data); |
| 116 | #endif | 110 | #endif |
| 117 | 111 | ||
| 118 | |||
| 119 | #define SHELL "/bin/sh" /* Default shell */ | 112 | #define SHELL "/bin/sh" /* Default shell */ |
| 120 | #define LOGIN_SHELL "-" SHELL /* Default login shell */ | 113 | #define LOGIN_SHELL "-" SHELL /* Default login shell */ |
| 121 | #define INITTAB "/etc/inittab" /* inittab file location */ | 114 | #define INITTAB "/etc/inittab" /* inittab file location */ |
| @@ -124,35 +117,24 @@ static const int RB_AUTOBOOT = 0x01234567; | |||
| 124 | #endif | 117 | #endif |
| 125 | 118 | ||
| 126 | #define MAXENV 16 /* Number of env. vars */ | 119 | #define MAXENV 16 /* Number of env. vars */ |
| 127 | //static const int MAXENV = 16; /* Number of env. vars */ | ||
| 128 | static const int LOG = 0x1; | ||
| 129 | static const int CONSOLE = 0x2; | ||
| 130 | #if defined BB_FEATURE_EXTRA_QUIET | ||
| 131 | static const int MAYBE_CONSOLE = 0x0; | ||
| 132 | #else | ||
| 133 | #define MAYBE_CONSOLE CONSOLE | ||
| 134 | #endif | ||
| 135 | |||
| 136 | 120 | ||
| 137 | /* Allowed init action types */ | 121 | /* Allowed init action types */ |
| 138 | typedef enum { | 122 | #define SYSINIT 0x001 |
| 139 | SYSINIT = 1, | 123 | #define RESPAWN 0x002 |
| 140 | RESPAWN, | 124 | #define ASKFIRST 0x004 |
| 141 | ASKFIRST, | 125 | #define WAIT 0x008 |
| 142 | WAIT, | 126 | #define ONCE 0x010 |
| 143 | ONCE, | 127 | #define CTRLALTDEL 0x020 |
| 144 | CTRLALTDEL, | 128 | #define SHUTDOWN 0x040 |
| 145 | SHUTDOWN, | 129 | #define RESTART 0x080 |
| 146 | RESTART | ||
| 147 | } initActionEnum; | ||
| 148 | 130 | ||
| 149 | /* A mapping between "inittab" action name strings and action type codes. */ | 131 | /* A mapping between "inittab" action name strings and action type codes. */ |
| 150 | typedef struct initActionType { | 132 | struct init_action_type { |
| 151 | const char *name; | 133 | const char *name; |
| 152 | initActionEnum action; | 134 | int action; |
| 153 | } initActionType; | 135 | }; |
| 154 | 136 | ||
| 155 | static const struct initActionType actions[] = { | 137 | static const struct init_action_type actions[] = { |
| 156 | {"sysinit", SYSINIT}, | 138 | {"sysinit", SYSINIT}, |
| 157 | {"respawn", RESPAWN}, | 139 | {"respawn", RESPAWN}, |
| 158 | {"askfirst", ASKFIRST}, | 140 | {"askfirst", ASKFIRST}, |
| @@ -164,18 +146,17 @@ static const struct initActionType actions[] = { | |||
| 164 | {0, 0} | 146 | {0, 0} |
| 165 | }; | 147 | }; |
| 166 | 148 | ||
| 167 | /* Set up a linked list of initActions, to be read from inittab */ | 149 | /* Set up a linked list of init_actions, to be read from inittab */ |
| 168 | typedef struct initActionTag initAction; | 150 | struct init_action { |
| 169 | struct initActionTag { | ||
| 170 | pid_t pid; | 151 | pid_t pid; |
| 171 | char process[256]; | 152 | char command[256]; |
| 172 | char console[256]; | 153 | char terminal[256]; |
| 173 | initAction *nextPtr; | 154 | struct init_action *next; |
| 174 | initActionEnum action; | 155 | int action; |
| 175 | }; | 156 | }; |
| 176 | static initAction *initActionList = NULL; | ||
| 177 | |||
| 178 | 157 | ||
| 158 | /* Static variables */ | ||
| 159 | static struct init_action *init_action_list = NULL; | ||
| 179 | static char *secondConsole = VC_2; | 160 | static char *secondConsole = VC_2; |
| 180 | static char *thirdConsole = VC_3; | 161 | static char *thirdConsole = VC_3; |
| 181 | static char *fourthConsole = VC_4; | 162 | static char *fourthConsole = VC_4; |
| @@ -183,9 +164,26 @@ static char *log = VC_5; | |||
| 183 | static int kernelVersion = 0; | 164 | static int kernelVersion = 0; |
| 184 | static char termType[32] = "TERM=linux"; | 165 | static char termType[32] = "TERM=linux"; |
| 185 | static char console[32] = _PATH_CONSOLE; | 166 | static char console[32] = _PATH_CONSOLE; |
| 186 | sig_atomic_t got_cont = 0; | 167 | static sig_atomic_t got_cont = 0; |
| 168 | static const int LOG = 0x1; | ||
| 169 | static const int CONSOLE = 0x2; | ||
| 170 | #if defined BB_FEATURE_EXTRA_QUIET | ||
| 171 | static const int MAYBE_CONSOLE = 0x0; | ||
| 172 | #else | ||
| 173 | #define MAYBE_CONSOLE CONSOLE | ||
| 174 | #endif | ||
| 175 | #ifndef RB_HALT_SYSTEM | ||
| 176 | static const int RB_HALT_SYSTEM = 0xcdef0123; | ||
| 177 | static const int RB_ENABLE_CAD = 0x89abcdef; | ||
| 178 | static const int RB_DISABLE_CAD = 0; | ||
| 179 | #define RB_POWER_OFF 0x4321fedc | ||
| 180 | static const int RB_AUTOBOOT = 0x01234567; | ||
| 181 | #endif | ||
| 182 | |||
| 183 | /* Function prototypes */ | ||
| 184 | static void delete_init_action(struct init_action *a); | ||
| 185 | static int waitfor(struct init_action *a); | ||
| 187 | 186 | ||
| 188 | static void delete_initAction(initAction * action); | ||
| 189 | 187 | ||
| 190 | static void loop_forever(void) | 188 | static void loop_forever(void) |
| 191 | { | 189 | { |
| @@ -200,8 +198,7 @@ static inline messageND(int device, char *fmt, ...) { } | |||
| 200 | #else | 198 | #else |
| 201 | #define messageND message | 199 | #define messageND message |
| 202 | #endif | 200 | #endif |
| 203 | static void message(int device, char *fmt, ...) | 201 | static void message(int device, char *fmt, ...) __attribute__ ((format (printf, 2, 3))); |
| 204 | __attribute__ ((format (printf, 2, 3))); | ||
| 205 | static void message(int device, char *fmt, ...) | 202 | static void message(int device, char *fmt, ...) |
| 206 | { | 203 | { |
| 207 | va_list arguments; | 204 | va_list arguments; |
| @@ -216,7 +213,7 @@ static void message(int device, char *fmt, ...) | |||
| 216 | va_start(arguments, fmt); | 213 | va_start(arguments, fmt); |
| 217 | vsnprintf(msg, sizeof(msg), fmt, arguments); | 214 | vsnprintf(msg, sizeof(msg), fmt, arguments); |
| 218 | va_end(arguments); | 215 | va_end(arguments); |
| 219 | syslog_msg(LOG_USER, LOG_USER|LOG_INFO, msg); | 216 | syslog_msg(LOG_USER, LOG_INFO, msg); |
| 220 | } | 217 | } |
| 221 | #else | 218 | #else |
| 222 | static int log_fd = -1; | 219 | static int log_fd = -1; |
| @@ -247,8 +244,7 @@ static void message(int device, char *fmt, ...) | |||
| 247 | /* Always send console messages to /dev/console so people will see them. */ | 244 | /* Always send console messages to /dev/console so people will see them. */ |
| 248 | if ( | 245 | if ( |
| 249 | (fd = | 246 | (fd = |
| 250 | device_open(_PATH_CONSOLE, | 247 | device_open(_PATH_CONSOLE, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) { |
| 251 | O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) { | ||
| 252 | va_start(arguments, fmt); | 248 | va_start(arguments, fmt); |
| 253 | vdprintf(fd, fmt, arguments); | 249 | vdprintf(fd, fmt, arguments); |
| 254 | va_end(arguments); | 250 | va_end(arguments); |
| @@ -383,8 +379,8 @@ static void console_init(void) | |||
| 383 | /* Perhaps we should panic here? */ | 379 | /* Perhaps we should panic here? */ |
| 384 | safe_strncpy(console, "/dev/null", sizeof(console)); | 380 | safe_strncpy(console, "/dev/null", sizeof(console)); |
| 385 | } else { | 381 | } else { |
| 386 | /* check for serial console and disable logging to tty5 & running a | 382 | /* check for serial console and disable logging to tty5 & |
| 387 | * shell to tty2-4 */ | 383 | * running a shell to tty2-4 */ |
| 388 | if (ioctl(0, TIOCGSERIAL, &sr) == 0) { | 384 | if (ioctl(0, TIOCGSERIAL, &sr) == 0) { |
| 389 | log = NULL; | 385 | log = NULL; |
| 390 | secondConsole = NULL; | 386 | secondConsole = NULL; |
| @@ -418,23 +414,41 @@ static void fixup_argv(int argc, char **argv, char *new_argv0) | |||
| 418 | } | 414 | } |
| 419 | } | 415 | } |
| 420 | 416 | ||
| 421 | 417 | /* Make sure there is enough memory to do something useful. * | |
| 422 | static pid_t run(char *command, char *terminal, int get_enter) | 418 | * Calls "swapon -a" if needed so be sure /etc/fstab is present... */ |
| 419 | static void check_memory(void) | ||
| 423 | { | 420 | { |
| 424 | int i, j; | 421 | struct stat statBuf; |
| 425 | int fd; | ||
| 426 | pid_t pid; | ||
| 427 | char *tmpCmd, *s; | ||
| 428 | char *cmd[255], *cmdpath; | ||
| 429 | char buf[255]; | ||
| 430 | struct stat sb; | ||
| 431 | static const char press_enter[] = | ||
| 432 | 422 | ||
| 433 | #ifdef CUSTOMIZED_BANNER | 423 | if (check_free_memory() > 1000) |
| 434 | #include CUSTOMIZED_BANNER | 424 | return; |
| 425 | |||
| 426 | #if !defined(__UCLIBC__) || defined(__UCLIBC_HAS_MMU__) | ||
| 427 | if (stat("/etc/fstab", &statBuf) == 0) { | ||
| 428 | /* swapon -a requires /proc typically */ | ||
| 429 | system("/bin/mount -t proc proc /proc"); | ||
| 430 | /* Try to turn on swap */ | ||
| 431 | system("/sbin/swapon -a"); | ||
| 432 | if (check_free_memory() < 1000) | ||
| 433 | goto goodnight; | ||
| 434 | } else | ||
| 435 | goto goodnight; | ||
| 436 | return; | ||
| 435 | #endif | 437 | #endif |
| 436 | 438 | ||
| 437 | "\nPlease press Enter to activate this console. "; | 439 | goodnight: |
| 440 | message(CONSOLE, | ||
| 441 | "Sorry, your computer does not have enough memory.\n"); | ||
| 442 | loop_forever(); | ||
| 443 | } | ||
| 444 | |||
| 445 | static pid_t run(struct init_action *a) | ||
| 446 | { | ||
| 447 | struct stat sb; | ||
| 448 | int i, j, fd, junk; | ||
| 449 | pid_t pid, pgrp, tmp_pid; | ||
| 450 | char *s, *tmpCmd, *cmd[255], *cmdpath, buf[255]; | ||
| 451 | sigset_t nmask, omask; | ||
| 438 | char *environment[MAXENV+1] = { | 452 | char *environment[MAXENV+1] = { |
| 439 | termType, | 453 | termType, |
| 440 | "HOME=/", | 454 | "HOME=/", |
| @@ -443,6 +457,11 @@ static pid_t run(char *command, char *terminal, int get_enter) | |||
| 443 | "USER=root", | 457 | "USER=root", |
| 444 | NULL | 458 | NULL |
| 445 | }; | 459 | }; |
| 460 | static const char press_enter[] = | ||
| 461 | #ifdef CUSTOMIZED_BANNER | ||
| 462 | #include CUSTOMIZED_BANNER | ||
| 463 | #endif | ||
| 464 | "\nPlease press Enter to activate this console. "; | ||
| 446 | 465 | ||
| 447 | /* inherit environment to the child, merging our values -andy */ | 466 | /* inherit environment to the child, merging our values -andy */ |
| 448 | for (i=0; environ[i]; i++) { | 467 | for (i=0; environ[i]; i++) { |
| @@ -457,57 +476,117 @@ static pid_t run(char *command, char *terminal, int get_enter) | |||
| 457 | } | 476 | } |
| 458 | } | 477 | } |
| 459 | 478 | ||
| 460 | #if !defined(__UCLIBC__) || defined(__UCLIBC_HAS_MMU__) | 479 | /* Block sigchild while forking. */ |
| 480 | sigemptyset(&nmask); | ||
| 481 | sigaddset(&nmask, SIGCHLD); | ||
| 482 | sigprocmask(SIG_BLOCK, &nmask, &omask); | ||
| 483 | |||
| 461 | if ((pid = fork()) == 0) | 484 | if ((pid = fork()) == 0) |
| 462 | #else | ||
| 463 | if ((pid = vfork()) == 0) | ||
| 464 | #endif | ||
| 465 | { | 485 | { |
| 466 | /* Clean up */ | 486 | /* Clean up */ |
| 467 | ioctl(0, TIOCNOTTY, 0); | 487 | ioctl(0, TIOCNOTTY, 0); |
| 468 | close(0); | 488 | close(0); |
| 469 | close(1); | 489 | close(1); |
| 470 | close(2); | 490 | close(2); |
| 491 | sigprocmask(SIG_SETMASK, &omask, NULL); | ||
| 492 | |||
| 493 | /* Create a new session and make ourself the process group leader */ | ||
| 471 | setsid(); | 494 | setsid(); |
| 472 | 495 | ||
| 473 | /* Reset signal handlers set for parent process */ | 496 | /* Reset signal handlers that were set by the parent process */ |
| 474 | signal(SIGUSR1, SIG_DFL); | 497 | signal(SIGUSR1, SIG_DFL); |
| 475 | signal(SIGUSR2, SIG_DFL); | 498 | signal(SIGUSR2, SIG_DFL); |
| 476 | signal(SIGINT, SIG_DFL); | 499 | signal(SIGINT, SIG_DFL); |
| 477 | signal(SIGTERM, SIG_DFL); | 500 | signal(SIGTERM, SIG_DFL); |
| 478 | signal(SIGHUP, SIG_DFL); | 501 | signal(SIGHUP, SIG_DFL); |
| 479 | signal(SIGCONT, SIG_DFL); | 502 | signal(SIGCONT, SIG_DFL); |
| 480 | signal(SIGSTOP, SIG_DFL); | 503 | signal(SIGSTOP, SIG_DFL); |
| 481 | signal(SIGTSTP, SIG_DFL); | 504 | signal(SIGTSTP, SIG_DFL); |
| 482 | 505 | ||
| 483 | if ((fd = device_open(terminal, O_RDWR)) < 0) { | 506 | /* Open the new terminal device */ |
| 484 | if (stat(terminal, &sb) != 0) { | 507 | if ((fd = device_open(a->terminal, O_RDWR|O_NOCTTY)) < 0) { |
| 508 | if (stat(a->terminal, &sb) != 0) { | ||
| 485 | message(LOG | CONSOLE, "device '%s' does not exist.\n", | 509 | message(LOG | CONSOLE, "device '%s' does not exist.\n", |
| 486 | terminal); | 510 | a->terminal); |
| 487 | exit(1); | 511 | _exit(1); |
| 488 | } | 512 | } |
| 489 | message(LOG | CONSOLE, "Bummer, can't open %s\n", terminal); | 513 | message(LOG | CONSOLE, "Bummer, can't open %s\n", a->terminal); |
| 490 | exit(1); | 514 | _exit(1); |
| 491 | } | 515 | } |
| 492 | dup2(fd, 0); | 516 | /* Make sure the terminal will act fairly normal for us */ |
| 493 | dup2(fd, 1); | ||
| 494 | dup2(fd, 2); | ||
| 495 | ioctl(0, TIOCSCTTY, 1); | ||
| 496 | tcsetpgrp(0, getpgrp()); | ||
| 497 | set_term(0); | 517 | set_term(0); |
| 498 | 518 | ||
| 519 | /* If the init Action requires up to wait, then force the | ||
| 520 | * supplied terminal to be the controlling tty. */ | ||
| 521 | if (a->action & (SYSINIT|WAIT|CTRLALTDEL|SHUTDOWN|RESTART)) { | ||
| 522 | |||
| 523 | /* Take over the controlling tty */ | ||
| 524 | ioctl(fd, TIOCSCTTY, 1); | ||
| 525 | /* Setup stdin, stdout, stderr for the new process so | ||
| 526 | * they point to the supplied terminal */ | ||
| 527 | dup(fd); | ||
| 528 | dup(fd); | ||
| 529 | |||
| 530 | /* Now fork off another process to just hang around */ | ||
| 531 | if ((pid = fork()) < 0) { | ||
| 532 | message(LOG | CONSOLE, "Can't fork!\n"); | ||
| 533 | _exit(1); | ||
| 534 | } | ||
| 535 | |||
| 536 | if (pid > 0) { | ||
| 537 | |||
| 538 | /* We are the parent -- wait till the child is done */ | ||
| 539 | signal(SIGINT, SIG_IGN); | ||
| 540 | signal(SIGTSTP, SIG_IGN); | ||
| 541 | signal(SIGQUIT, SIG_IGN); | ||
| 542 | signal(SIGCHLD, SIG_DFL); | ||
| 543 | |||
| 544 | /* Wait for child to exit */ | ||
| 545 | while ((tmp_pid = waitpid(pid, &junk, 0)) != pid) { | ||
| 546 | if (tmp_pid < 0 && errno == ECHILD) | ||
| 547 | break; | ||
| 548 | } | ||
| 549 | |||
| 550 | /* See if stealing the controlling tty back is necessary */ | ||
| 551 | pgrp = tcgetpgrp(tmp_pid); | ||
| 552 | if (pgrp != getpid()) | ||
| 553 | _exit(0); | ||
| 554 | |||
| 555 | /* Use a temporary process to steal the controlling tty. */ | ||
| 556 | if ((pid = fork()) < 0) { | ||
| 557 | message(LOG | CONSOLE, "Can't fork!\n"); | ||
| 558 | _exit(1); | ||
| 559 | } | ||
| 560 | if (pid == 0) { | ||
| 561 | setsid(); | ||
| 562 | ioctl(tmp_pid, TIOCSCTTY, 1); | ||
| 563 | _exit(0); | ||
| 564 | } | ||
| 565 | while((tmp_pid = waitpid(pid, &junk, 0)) != pid) { | ||
| 566 | if (tmp_pid < 0 && errno == ECHILD) | ||
| 567 | break; | ||
| 568 | } | ||
| 569 | _exit(0); | ||
| 570 | } | ||
| 571 | |||
| 572 | /* Now fall though to actually execute things */ | ||
| 573 | } else { | ||
| 574 | dup(fd); | ||
| 575 | dup(fd); | ||
| 576 | } | ||
| 577 | |||
| 499 | /* See if any special /bin/sh requiring characters are present */ | 578 | /* See if any special /bin/sh requiring characters are present */ |
| 500 | if (strpbrk(command, "~`!$^&*()=|\\{}[];\"'<>?") != NULL) { | 579 | if (strpbrk(a->command, "~`!$^&*()=|\\{}[];\"'<>?") != NULL) { |
| 501 | cmd[0] = SHELL; | 580 | cmd[0] = SHELL; |
| 502 | cmd[1] = "-c"; | 581 | cmd[1] = "-c"; |
| 503 | strcpy(buf, "exec "); | 582 | strcpy(buf, "exec "); |
| 504 | safe_strncpy(buf + sizeof("exec "), command, | 583 | safe_strncpy(buf + sizeof("exec "), a->command, |
| 505 | sizeof(buf) - sizeof("exec ")); | 584 | sizeof(buf) - sizeof("exec ")); |
| 506 | cmd[2] = buf; | 585 | cmd[2] = buf; |
| 507 | cmd[3] = NULL; | 586 | cmd[3] = NULL; |
| 508 | } else { | 587 | } else { |
| 509 | /* Convert command (char*) into cmd (char**, one word per string) */ | 588 | /* Convert command (char*) into cmd (char**, one word per string) */ |
| 510 | safe_strncpy(buf, command, sizeof(buf)); | 589 | safe_strncpy(buf, a->command, sizeof(buf)); |
| 511 | s = buf; | 590 | s = buf; |
| 512 | for (tmpCmd = buf, i = 0; | 591 | for (tmpCmd = buf, i = 0; |
| 513 | (tmpCmd = strsep(&s, " \t")) != NULL;) { | 592 | (tmpCmd = strsep(&s, " \t")) != NULL;) { |
| @@ -547,7 +626,7 @@ static pid_t run(char *command, char *terminal, int get_enter) | |||
| 547 | } | 626 | } |
| 548 | } | 627 | } |
| 549 | 628 | ||
| 550 | if (get_enter) { | 629 | if (a->action & ASKFIRST) { |
| 551 | /* | 630 | /* |
| 552 | * Save memory by not exec-ing anything large (like a shell) | 631 | * Save memory by not exec-ing anything large (like a shell) |
| 553 | * before the user wants it. This is critical if swap is not | 632 | * before the user wants it. This is critical if swap is not |
| @@ -556,15 +635,15 @@ static pid_t run(char *command, char *terminal, int get_enter) | |||
| 556 | * be allowed to start a shell or whatever an init script | 635 | * be allowed to start a shell or whatever an init script |
| 557 | * specifies. | 636 | * specifies. |
| 558 | */ | 637 | */ |
| 559 | messageND(LOG, "Waiting for enter to start '%s' (pid %d, console %s)\n", | 638 | messageND(LOG, "Waiting for enter to start '%s' (pid %d, terminal %s)\n", |
| 560 | cmd[0], getpid(), terminal); | 639 | cmdpath, getpid(), a->terminal); |
| 561 | write(fileno(stdout), press_enter, sizeof(press_enter) - 1); | 640 | write(fileno(stdout), press_enter, sizeof(press_enter) - 1); |
| 562 | getc(stdin); | 641 | getc(stdin); |
| 563 | } | 642 | } |
| 564 | 643 | ||
| 565 | /* Log the process name and args */ | 644 | /* Log the process name and args */ |
| 566 | messageND(LOG, "Starting pid %d, console %s: '%s'\n", | 645 | messageND(LOG, "Starting pid %d, console %s: '%s'\n", |
| 567 | getpid(), terminal, command); | 646 | getpid(), a->terminal, cmdpath); |
| 568 | 647 | ||
| 569 | #if defined CONFIG_FEATURE_INIT_COREDUMPS | 648 | #if defined CONFIG_FEATURE_INIT_COREDUMPS |
| 570 | if (stat (CORE_ENABLE_FLAG_FILE, &sb) == 0) { | 649 | if (stat (CORE_ENABLE_FLAG_FILE, &sb) == 0) { |
| @@ -582,16 +661,18 @@ static pid_t run(char *command, char *terminal, int get_enter) | |||
| 582 | /* We're still here? Some error happened. */ | 661 | /* We're still here? Some error happened. */ |
| 583 | message(LOG | CONSOLE, "Bummer, could not run '%s': %s\n", cmdpath, | 662 | message(LOG | CONSOLE, "Bummer, could not run '%s': %s\n", cmdpath, |
| 584 | strerror(errno)); | 663 | strerror(errno)); |
| 585 | exit(-1); | 664 | _exit(-1); |
| 586 | } | 665 | } |
| 666 | sigprocmask(SIG_SETMASK, &omask, NULL); | ||
| 587 | return pid; | 667 | return pid; |
| 588 | } | 668 | } |
| 589 | 669 | ||
| 590 | static int waitfor(char *command, char *terminal, int get_enter) | 670 | static int waitfor(struct init_action *a) |
| 591 | { | 671 | { |
| 672 | int pid; | ||
| 592 | int status, wpid; | 673 | int status, wpid; |
| 593 | int pid = run(command, terminal, get_enter); | ||
| 594 | 674 | ||
| 675 | pid = run(a); | ||
| 595 | while (1) { | 676 | while (1) { |
| 596 | wpid = wait(&status); | 677 | wpid = wait(&status); |
| 597 | if (wpid > 0 && wpid != pid) { | 678 | if (wpid > 0 && wpid != pid) { |
| @@ -603,43 +684,27 @@ static int waitfor(char *command, char *terminal, int get_enter) | |||
| 603 | return wpid; | 684 | return wpid; |
| 604 | } | 685 | } |
| 605 | 686 | ||
| 606 | /* Make sure there is enough memory to do something useful. * | 687 | /* Run all commands of a particular type */ |
| 607 | * Calls "swapon -a" if needed so be sure /etc/fstab is present... */ | 688 | static void run_actions(int action) |
| 608 | static void check_memory(void) | ||
| 609 | { | 689 | { |
| 610 | struct stat statBuf; | 690 | struct init_action *a, *tmp; |
| 611 | 691 | ||
| 612 | if (check_free_memory() > 1000) | 692 | for (a = init_action_list; a; a = tmp) { |
| 613 | return; | 693 | tmp = a->next; |
| 614 | |||
| 615 | #if !defined(__UCLIBC__) || defined(__UCLIBC_HAS_MMU__) | ||
| 616 | if (stat("/etc/fstab", &statBuf) == 0) { | ||
| 617 | /* swapon -a requires /proc typically */ | ||
| 618 | waitfor("/bin/mount -t proc proc /proc", console, FALSE); | ||
| 619 | /* Try to turn on swap */ | ||
| 620 | waitfor("/sbin/swapon -a", console, FALSE); | ||
| 621 | if (check_free_memory() < 1000) | ||
| 622 | goto goodnight; | ||
| 623 | } else | ||
| 624 | goto goodnight; | ||
| 625 | return; | ||
| 626 | #endif | ||
| 627 | |||
| 628 | goodnight: | ||
| 629 | message(CONSOLE, | ||
| 630 | "Sorry, your computer does not have enough memory.\n"); | ||
| 631 | loop_forever(); | ||
| 632 | } | ||
| 633 | |||
| 634 | /* Run all commands to be run right before halt/reboot */ | ||
| 635 | static void run_actions(initActionEnum action) | ||
| 636 | { | ||
| 637 | initAction *a, *tmp; | ||
| 638 | for (a = initActionList; a; a = tmp) { | ||
| 639 | tmp = a->nextPtr; | ||
| 640 | if (a->action == action) { | 694 | if (a->action == action) { |
| 641 | waitfor(a->process, a->console, FALSE); | 695 | if (a->action & (SYSINIT|WAIT|CTRLALTDEL|SHUTDOWN|RESTART)) { |
| 642 | delete_initAction(a); | 696 | waitfor(a); |
| 697 | delete_init_action(a); | ||
| 698 | } else if (a->action & ONCE) { | ||
| 699 | run(a); | ||
| 700 | delete_init_action(a); | ||
| 701 | } else if (a->action & (RESPAWN|ASKFIRST)) { | ||
| 702 | /* Only run stuff with pid==0. If they have | ||
| 703 | * a pid, that means it is still running */ | ||
| 704 | if (a->pid == 0) { | ||
| 705 | a->pid = run(a); | ||
| 706 | } | ||
| 707 | } | ||
| 643 | } | 708 | } |
| 644 | } | 709 | } |
| 645 | } | 710 | } |
| @@ -692,16 +757,16 @@ static void shutdown_system(void) | |||
| 692 | 757 | ||
| 693 | static void exec_signal(int sig) | 758 | static void exec_signal(int sig) |
| 694 | { | 759 | { |
| 695 | initAction *a, *tmp; | 760 | struct init_action *a, *tmp; |
| 696 | for (a = initActionList; a; a = tmp) { | 761 | for (a = init_action_list; a; a = tmp) { |
| 697 | tmp = a->nextPtr; | 762 | tmp = a->next; |
| 698 | if (a->action == RESTART) { | 763 | if (a->action & RESTART) { |
| 699 | shutdown_system(); | 764 | shutdown_system(); |
| 700 | message(CONSOLE|LOG, "Trying to re-exec %s\n", a->process); | 765 | message(CONSOLE|LOG, "Trying to re-exec %s\n", a->command); |
| 701 | execl(a->process, a->process, NULL); | 766 | execl(a->command, a->command, NULL); |
| 702 | 767 | ||
| 703 | message(CONSOLE|LOG, "execl of %s failed: %s\n", | 768 | message(CONSOLE|LOG, "execl of %s failed: %s\n", |
| 704 | a->process, sys_errlist[errno]); | 769 | a->command, sys_errlist[errno]); |
| 705 | sync(); | 770 | sync(); |
| 706 | sleep(2); | 771 | sleep(2); |
| 707 | init_reboot(RB_HALT_SYSTEM); | 772 | init_reboot(RB_HALT_SYSTEM); |
| @@ -755,12 +820,10 @@ static void ctrlaltdel_signal(int sig) | |||
| 755 | run_actions(CTRLALTDEL); | 820 | run_actions(CTRLALTDEL); |
| 756 | } | 821 | } |
| 757 | 822 | ||
| 758 | /* | 823 | /* The SIGSTOP & SIGTSTP handler */ |
| 759 | * The SIGSTOP & SIGTSTP handler | ||
| 760 | */ | ||
| 761 | static void stop_handler(int sig) | 824 | static void stop_handler(int sig) |
| 762 | { | 825 | { |
| 763 | int saved_errno = errno; | 826 | int saved_errno = errno; |
| 764 | 827 | ||
| 765 | got_cont = 0; | 828 | got_cont = 0; |
| 766 | while(!got_cont) pause(); | 829 | while(!got_cont) pause(); |
| @@ -768,9 +831,7 @@ static void stop_handler(int sig) | |||
| 768 | errno = saved_errno; | 831 | errno = saved_errno; |
| 769 | } | 832 | } |
| 770 | 833 | ||
| 771 | /* | 834 | /* The SIGCONT handler */ |
| 772 | * The SIGCONT handler | ||
| 773 | */ | ||
| 774 | static void cont_handler(int sig) | 835 | static void cont_handler(int sig) |
| 775 | { | 836 | { |
| 776 | got_cont = 1; | 837 | got_cont = 1; |
| @@ -778,53 +839,54 @@ static void cont_handler(int sig) | |||
| 778 | 839 | ||
| 779 | #endif /* ! DEBUG_INIT */ | 840 | #endif /* ! DEBUG_INIT */ |
| 780 | 841 | ||
| 781 | static void new_initAction(initActionEnum action, char *process, char *cons) | 842 | static void new_init_action(int action, char *command, char *cons) |
| 782 | { | 843 | { |
| 783 | initAction *newAction; | 844 | struct init_action *new_action, *a; |
| 784 | initAction *a; | ||
| 785 | 845 | ||
| 786 | if (*cons == '\0') | 846 | if (*cons == '\0') |
| 787 | cons = console; | 847 | cons = console; |
| 788 | 848 | ||
| 789 | /* If BusyBox detects that a serial console is in use, | 849 | /* If BusyBox detects that a serial console is in use, then entries |
| 790 | * then entries not refering to the console or null devices will _not_ be run. | 850 | * not refering to the console or null devices will _not_ be run. |
| 791 | * The exception to this rule is the null device. | 851 | * The exception to this rule is the null device. |
| 792 | */ | 852 | */ |
| 793 | if (secondConsole == NULL && strcmp(cons, console) | 853 | if (secondConsole == NULL && strcmp(cons, console) |
| 794 | && strcmp(cons, "/dev/null")) | 854 | && strcmp(cons, "/dev/null")) |
| 795 | return; | 855 | return; |
| 796 | if (strcmp(cons, "/dev/null") == 0 && action == ASKFIRST) | 856 | if (strcmp(cons, "/dev/null") == 0 && (action & ASKFIRST)) |
| 797 | return; | 857 | return; |
| 798 | 858 | ||
| 799 | newAction = calloc((size_t) (1), sizeof(initAction)); | 859 | new_action = calloc((size_t) (1), sizeof(struct init_action)); |
| 800 | if (!newAction) { | 860 | if (!new_action) { |
| 801 | message(LOG | CONSOLE, "Memory allocation failure\n"); | 861 | message(LOG | CONSOLE, "Memory allocation failure\n"); |
| 802 | loop_forever(); | 862 | loop_forever(); |
| 803 | } | 863 | } |
| 804 | for (a = initActionList; a && a->nextPtr; a = a->nextPtr) ; | 864 | |
| 865 | /* Append to the end of the list */ | ||
| 866 | for (a = init_action_list; a && a->next; a = a->next) ; | ||
| 805 | if (a) { | 867 | if (a) { |
| 806 | a->nextPtr = newAction; | 868 | a->next = new_action; |
| 807 | } else { | 869 | } else { |
| 808 | initActionList = newAction; | 870 | init_action_list = new_action; |
| 809 | } | 871 | } |
| 810 | safe_strncpy(newAction->process, process, 255); | 872 | safe_strncpy(new_action->command, command, 255); |
| 811 | newAction->action = action; | 873 | new_action->action = action; |
| 812 | safe_strncpy(newAction->console, cons, 255); | 874 | safe_strncpy(new_action->terminal, cons, 255); |
| 813 | newAction->pid = 0; | 875 | new_action->pid = 0; |
| 814 | // message(LOG|CONSOLE, "process='%s' action='%d' console='%s'\n", | 876 | // message(LOG|CONSOLE, "command='%s' action='%d' terminal='%s'\n", |
| 815 | // newAction->process, newAction->action, newAction->console); | 877 | // new_action->command, new_action->action, new_action->terminal); |
| 816 | } | 878 | } |
| 817 | 879 | ||
| 818 | static void delete_initAction(initAction * action) | 880 | static void delete_init_action(struct init_action * action) |
| 819 | { | 881 | { |
| 820 | initAction *a, *b = NULL; | 882 | struct init_action *a, *b = NULL; |
| 821 | 883 | ||
| 822 | for (a = initActionList; a; b = a, a = a->nextPtr) { | 884 | for (a = init_action_list; a; b = a, a = a->next) { |
| 823 | if (a == action) { | 885 | if (a == action) { |
| 824 | if (b == NULL) { | 886 | if (b == NULL) { |
| 825 | initActionList = a->nextPtr; | 887 | init_action_list = a->next; |
| 826 | } else { | 888 | } else { |
| 827 | b->nextPtr = a->nextPtr; | 889 | b->next = a->next; |
| 828 | } | 890 | } |
| 829 | free(a); | 891 | free(a); |
| 830 | break; | 892 | break; |
| @@ -844,8 +906,8 @@ static void parse_inittab(void) | |||
| 844 | #ifdef CONFIG_FEATURE_USE_INITTAB | 906 | #ifdef CONFIG_FEATURE_USE_INITTAB |
| 845 | FILE *file; | 907 | FILE *file; |
| 846 | char buf[256], lineAsRead[256], tmpConsole[256]; | 908 | char buf[256], lineAsRead[256], tmpConsole[256]; |
| 847 | char *id, *runlev, *action, *process, *eol; | 909 | char *id, *runlev, *action, *command, *eol; |
| 848 | const struct initActionType *a = actions; | 910 | const struct init_action_type *a = actions; |
| 849 | int foundIt; | 911 | int foundIt; |
| 850 | 912 | ||
| 851 | 913 | ||
| @@ -854,28 +916,28 @@ static void parse_inittab(void) | |||
| 854 | /* No inittab file -- set up some default behavior */ | 916 | /* No inittab file -- set up some default behavior */ |
| 855 | #endif | 917 | #endif |
| 856 | /* Reboot on Ctrl-Alt-Del */ | 918 | /* Reboot on Ctrl-Alt-Del */ |
| 857 | new_initAction(CTRLALTDEL, "/sbin/reboot", console); | 919 | new_init_action(CTRLALTDEL, "/sbin/reboot", console); |
| 858 | /* Umount all filesystems on halt/reboot */ | 920 | /* Umount all filesystems on halt/reboot */ |
| 859 | new_initAction(SHUTDOWN, "/bin/umount -a -r", console); | 921 | new_init_action(SHUTDOWN, "/bin/umount -a -r", console); |
| 860 | #if !defined(__UCLIBC__) || defined(__UCLIBC_HAS_MMU__) | 922 | #if !defined(__UCLIBC__) || defined(__UCLIBC_HAS_MMU__) |
| 861 | /* Swapoff on halt/reboot */ | 923 | /* Swapoff on halt/reboot */ |
| 862 | new_initAction(SHUTDOWN, "/sbin/swapoff -a", console); | 924 | new_init_action(SHUTDOWN, "/sbin/swapoff -a", console); |
| 863 | #endif | 925 | #endif |
| 864 | /* Prepare to restart init when a HUP is received */ | 926 | /* Prepare to restart init when a HUP is received */ |
| 865 | new_initAction(RESTART, "/sbin/init", console); | 927 | new_init_action(RESTART, "/sbin/init", console); |
| 866 | /* Askfirst shell on tty1 */ | 928 | /* Askfirst shell on tty1 */ |
| 867 | new_initAction(ASKFIRST, LOGIN_SHELL, console); | 929 | new_init_action(ASKFIRST, LOGIN_SHELL, console); |
| 868 | /* Askfirst shell on tty2 */ | 930 | /* Askfirst shell on tty2 */ |
| 869 | if (secondConsole != NULL) | 931 | if (secondConsole != NULL) |
| 870 | new_initAction(ASKFIRST, LOGIN_SHELL, secondConsole); | 932 | new_init_action(ASKFIRST, LOGIN_SHELL, secondConsole); |
| 871 | /* Askfirst shell on tty3 */ | 933 | /* Askfirst shell on tty3 */ |
| 872 | if (thirdConsole != NULL) | 934 | if (thirdConsole != NULL) |
| 873 | new_initAction(ASKFIRST, LOGIN_SHELL, thirdConsole); | 935 | new_init_action(ASKFIRST, LOGIN_SHELL, thirdConsole); |
| 874 | /* Askfirst shell on tty4 */ | 936 | /* Askfirst shell on tty4 */ |
| 875 | if (fourthConsole != NULL) | 937 | if (fourthConsole != NULL) |
| 876 | new_initAction(ASKFIRST, LOGIN_SHELL, fourthConsole); | 938 | new_init_action(ASKFIRST, LOGIN_SHELL, fourthConsole); |
| 877 | /* sysinit */ | 939 | /* sysinit */ |
| 878 | new_initAction(SYSINIT, INIT_SCRIPT, console); | 940 | new_init_action(SYSINIT, INIT_SCRIPT, console); |
| 879 | 941 | ||
| 880 | return; | 942 | return; |
| 881 | #ifdef CONFIG_FEATURE_USE_INITTAB | 943 | #ifdef CONFIG_FEATURE_USE_INITTAB |
| @@ -918,14 +980,14 @@ static void parse_inittab(void) | |||
| 918 | ++action; | 980 | ++action; |
| 919 | } | 981 | } |
| 920 | 982 | ||
| 921 | /* Separate the action from the process */ | 983 | /* Separate the action from the command */ |
| 922 | process = strchr(action, ':'); | 984 | command = strchr(action, ':'); |
| 923 | if (process == NULL || *(process + 1) == '\0') { | 985 | if (command == NULL || *(command + 1) == '\0') { |
| 924 | message(LOG | CONSOLE, "Bad inittab entry: %s\n", lineAsRead); | 986 | message(LOG | CONSOLE, "Bad inittab entry: %s\n", lineAsRead); |
| 925 | continue; | 987 | continue; |
| 926 | } else { | 988 | } else { |
| 927 | *process = '\0'; | 989 | *command = '\0'; |
| 928 | ++process; | 990 | ++command; |
| 929 | } | 991 | } |
| 930 | 992 | ||
| 931 | /* Ok, now process it */ | 993 | /* Ok, now process it */ |
| @@ -937,12 +999,12 @@ static void parse_inittab(void) | |||
| 937 | strncat(tmpConsole, id, 200); | 999 | strncat(tmpConsole, id, 200); |
| 938 | id = tmpConsole; | 1000 | id = tmpConsole; |
| 939 | } | 1001 | } |
| 940 | new_initAction(a->action, process, id); | 1002 | new_init_action(a->action, command, id); |
| 941 | foundIt = TRUE; | 1003 | foundIt = TRUE; |
| 942 | } | 1004 | } |
| 943 | a++; | 1005 | a++; |
| 944 | } | 1006 | } |
| 945 | if (foundIt) | 1007 | if (foundIt == TRUE) |
| 946 | continue; | 1008 | continue; |
| 947 | else { | 1009 | else { |
| 948 | /* Choke on an unknown action */ | 1010 | /* Choke on an unknown action */ |
| @@ -957,11 +1019,10 @@ static void parse_inittab(void) | |||
| 957 | 1019 | ||
| 958 | extern int init_main(int argc, char **argv) | 1020 | extern int init_main(int argc, char **argv) |
| 959 | { | 1021 | { |
| 960 | initAction *a, *tmp; | 1022 | struct init_action *a; |
| 961 | pid_t wpid; | 1023 | pid_t wpid; |
| 962 | int status; | 1024 | int status; |
| 963 | 1025 | ||
| 964 | |||
| 965 | if (argc > 1 && !strcmp(argv[1], "-q")) { | 1026 | if (argc > 1 && !strcmp(argv[1], "-q")) { |
| 966 | /* don't assume init's pid == 1 */ | 1027 | /* don't assume init's pid == 1 */ |
| 967 | long *pid = find_pid_by_name("init"); | 1028 | long *pid = find_pid_by_name("init"); |
| @@ -986,10 +1047,10 @@ extern int init_main(int argc, char **argv) | |||
| 986 | } | 1047 | } |
| 987 | /* Set up sig handlers -- be sure to | 1048 | /* Set up sig handlers -- be sure to |
| 988 | * clear all of these in run() */ | 1049 | * clear all of these in run() */ |
| 989 | signal(SIGHUP, exec_signal); | 1050 | signal(SIGHUP, exec_signal); |
| 990 | signal(SIGUSR1, halt_signal); | 1051 | signal(SIGUSR1, halt_signal); |
| 991 | signal(SIGUSR2, halt_signal); | 1052 | signal(SIGUSR2, halt_signal); |
| 992 | signal(SIGINT, ctrlaltdel_signal); | 1053 | signal(SIGINT, ctrlaltdel_signal); |
| 993 | signal(SIGTERM, reboot_signal); | 1054 | signal(SIGTERM, reboot_signal); |
| 994 | signal(SIGCONT, cont_handler); | 1055 | signal(SIGCONT, cont_handler); |
| 995 | signal(SIGSTOP, stop_handler); | 1056 | signal(SIGSTOP, stop_handler); |
| @@ -1029,13 +1090,13 @@ extern int init_main(int argc, char **argv) | |||
| 1029 | !strcmp(argv[1], "-s") || !strcmp(argv[1], "1"))) { | 1090 | !strcmp(argv[1], "-s") || !strcmp(argv[1], "1"))) { |
| 1030 | /* Ask first then start a shell on tty2-4 */ | 1091 | /* Ask first then start a shell on tty2-4 */ |
| 1031 | if (secondConsole != NULL) | 1092 | if (secondConsole != NULL) |
| 1032 | new_initAction(ASKFIRST, LOGIN_SHELL, secondConsole); | 1093 | new_init_action(ASKFIRST, LOGIN_SHELL, secondConsole); |
| 1033 | if (thirdConsole != NULL) | 1094 | if (thirdConsole != NULL) |
| 1034 | new_initAction(ASKFIRST, LOGIN_SHELL, thirdConsole); | 1095 | new_init_action(ASKFIRST, LOGIN_SHELL, thirdConsole); |
| 1035 | if (fourthConsole != NULL) | 1096 | if (fourthConsole != NULL) |
| 1036 | new_initAction(ASKFIRST, LOGIN_SHELL, fourthConsole); | 1097 | new_init_action(ASKFIRST, LOGIN_SHELL, fourthConsole); |
| 1037 | /* Start a shell on tty1 */ | 1098 | /* Start a shell on tty1 */ |
| 1038 | new_initAction(RESPAWN, LOGIN_SHELL, console); | 1099 | new_init_action(RESPAWN, LOGIN_SHELL, console); |
| 1039 | } else { | 1100 | } else { |
| 1040 | /* Not in single user mode -- see what inittab says */ | 1101 | /* Not in single user mode -- see what inittab says */ |
| 1041 | 1102 | ||
| @@ -1053,58 +1114,44 @@ extern int init_main(int argc, char **argv) | |||
| 1053 | 1114 | ||
| 1054 | /* First run the sysinit command */ | 1115 | /* First run the sysinit command */ |
| 1055 | run_actions(SYSINIT); | 1116 | run_actions(SYSINIT); |
| 1117 | |||
| 1056 | /* Next run anything that wants to block */ | 1118 | /* Next run anything that wants to block */ |
| 1057 | run_actions(WAIT); | 1119 | run_actions(WAIT); |
| 1120 | |||
| 1058 | /* Next run anything to be run only once */ | 1121 | /* Next run anything to be run only once */ |
| 1059 | for (a = initActionList; a; a = tmp) { | 1122 | run_actions(ONCE); |
| 1060 | tmp = a->nextPtr; | 1123 | |
| 1061 | if (a->action == ONCE) { | ||
| 1062 | run(a->process, a->console, FALSE); | ||
| 1063 | /* Now remove the "once" entry from the list */ | ||
| 1064 | delete_initAction(a); | ||
| 1065 | } | ||
| 1066 | } | ||
| 1067 | /* If there is nothing else to do, stop */ | 1124 | /* If there is nothing else to do, stop */ |
| 1068 | if (initActionList == NULL) { | 1125 | if (init_action_list == NULL) { |
| 1069 | message(LOG | CONSOLE, | 1126 | message(LOG | CONSOLE, "No more tasks for init -- sleeping forever.\n"); |
| 1070 | "No more tasks for init -- sleeping forever.\n"); | ||
| 1071 | loop_forever(); | 1127 | loop_forever(); |
| 1072 | } | 1128 | } |
| 1073 | 1129 | ||
| 1074 | /* Now run the looping stuff for the rest of forever */ | 1130 | /* Now run the looping stuff for the rest of forever */ |
| 1075 | while (1) { | 1131 | while (1) { |
| 1076 | for (a = initActionList; a; a = a->nextPtr) { | 1132 | /* run the respawn stuff */ |
| 1077 | /* Only run stuff with pid==0. If they have | 1133 | run_actions(RESPAWN); |
| 1078 | * a pid, that means they are still running */ | 1134 | |
| 1079 | if (a->pid == 0) { | 1135 | /* run the askfirst stuff */ |
| 1080 | switch (a->action) { | 1136 | run_actions(ASKFIRST); |
| 1081 | case RESPAWN: | 1137 | |
| 1082 | /* run the respawn stuff */ | 1138 | /* Don't consume all CPU time -- sleep a bit */ |
| 1083 | a->pid = run(a->process, a->console, FALSE); | 1139 | sleep(1); |
| 1084 | break; | 1140 | |
| 1085 | case ASKFIRST: | ||
| 1086 | /* run the askfirst stuff */ | ||
| 1087 | a->pid = run(a->process, a->console, TRUE); | ||
| 1088 | break; | ||
| 1089 | /* silence the compiler's incessant whining */ | ||
| 1090 | default: | ||
| 1091 | break; | ||
| 1092 | } | ||
| 1093 | } | ||
| 1094 | } | ||
| 1095 | /* Wait for a child process to exit */ | 1141 | /* Wait for a child process to exit */ |
| 1096 | wpid = wait(&status); | 1142 | wpid = wait(&status); |
| 1097 | if (wpid > 0) { | 1143 | if (wpid > 0) { |
| 1098 | /* Find out who died and clean up their corpse */ | 1144 | /* Find out who died and clean up their corpse */ |
| 1099 | for (a = initActionList; a; a = a->nextPtr) { | 1145 | for (a = init_action_list; a; a = a->next) { |
| 1100 | if (a->pid == wpid) { | 1146 | if (a->pid == wpid) { |
| 1147 | /* Set the pid to 0 so that the process gets | ||
| 1148 | * restarted by run_actions() */ | ||
| 1101 | a->pid = 0; | 1149 | a->pid = 0; |
| 1102 | message(LOG, "Process '%s' (pid %d) exited. Scheduling it for restart.\n", | 1150 | message(LOG, "Process '%s' (pid %d) exited. " |
| 1103 | a->process, wpid); | 1151 | "Scheduling it for restart.\n", a->command, wpid); |
| 1104 | } | 1152 | } |
| 1105 | } | 1153 | } |
| 1106 | } | 1154 | } |
| 1107 | sleep(1); | ||
| 1108 | } | 1155 | } |
| 1109 | } | 1156 | } |
| 1110 | 1157 | ||
