diff options
author | Michael I. Bushnell <mib@gnu.org> | 1996-06-19 18:55:30 +0000 |
---|---|---|
committer | Michael I. Bushnell <mib@gnu.org> | 1996-06-19 18:55:30 +0000 |
commit | bd81af8f477cebe3a4586a08add55080e0b8cb99 (patch) | |
tree | ec05cfeefe4f2621222b2c02e31eb35b4c76dce0 | |
parent | 6ba1ea0bae21ae1d634041d08407a68fbd5c503d (diff) |
(run_for_real): Return zero if we fail.
(startup_terminal): Deal properly if one of the run_for_real's fails.
(launch_single_user): If the shell can't be started, crash the system.
(process_rc_script): Return non-zero if run_for_real fails.
(process_signal) [SIGCHLD]: If process_rc_script fails, go back to
single-user.
(S_startup_essential_task): Likewise.
-rw-r--r-- | init/init.c | 49 |
1 files changed, 38 insertions, 11 deletions
diff --git a/init/init.c b/init/init.c index 8fa4d7f7..5c0e5b81 100644 --- a/init/init.c +++ b/init/init.c @@ -382,7 +382,8 @@ run (char *server, mach_port_t *ports, task_t *task) /* Run FILENAME as root with ARGS as its argv (length ARGLEN). Return the task that we started. If CTTY is set, then make that the controlling terminal of the new process and put it in its own login - collection. If SETSID is set, put it in a new session. */ + collection. If SETSID is set, put it in a new session. Return + 0 if the task was not created successfully. */ pid_t run_for_real (char *filename, char *args, int arglen, mach_port_t ctty, int setsid) @@ -410,7 +411,7 @@ run_for_real (char *filename, char *args, int arglen, mach_port_t ctty, if (!file) { error (0, errno, "%s", filename); - return MACH_PORT_NULL; + return 0; } #endif @@ -457,7 +458,7 @@ run_for_real (char *filename, char *args, int arglen, mach_port_t ctty, if (err) { error (0, err, "Cannot execute %s", filename); - return MACH_PORT_NULL; + return 0; } return pid; } @@ -562,18 +563,30 @@ free_ttys (void) void startup_terminal (struct terminal *t) { + pid_t pid; assert (t->on); assert (t->getty_argz); if (t->window_argz) { - run_for_real (t->window_argz, t->window_argz, - t->window_argz_len, MACH_PORT_NULL, 1); + pid = run_for_real (t->window_argz, t->window_argz, + t->window_argz_len, MACH_PORT_NULL, 1); + if (!pid) + goto error; + sleep (WINDOW_DELAY); } - t->pid = run_for_real (t->getty_argz, t->getty_argz, - t->getty_argz_len, MACH_PORT_NULL, 0); + pid = run_for_real (t->getty_argz, t->getty_argz, + t->getty_argz_len, MACH_PORT_NULL, 0); + if (pid == 0) + { + error: + t->pid = 0; + t->on = 0; + } + else + t->pid = pid; } /* For each line in /etc/ttys, start up the specified program */ @@ -1077,12 +1090,14 @@ launch_single_user () /* The shell needs a real controlling terminal, so set that up here. */ shell_pid = run_for_real (shell, shell, strlen (shell) + 1, term, 1); mach_port_deallocate (mach_task_self (), term); + if (shell_pid == 0) + crash_system (); printf (" shell.\n"); fflush (stdout); } -/* Run /etc/rc as a shell script. */ -void +/* Run /etc/rc as a shell script. Return non-zero if we fail. */ +int process_rc_script () { char *rcargs; @@ -1106,6 +1121,7 @@ process_rc_script () rc_pid = run_for_real (rcargs, rcargs, rcargslen, term, 1); mach_port_deallocate (mach_task_self (), term); + return ! rc_pid; } /* Start up multi-user state. */ @@ -1215,6 +1231,8 @@ kill_multi_user () void process_signal (int signo) { + int fail; + switch (signo) { case SIGTERM: @@ -1260,7 +1278,12 @@ process_signal (int signo) else { do_fastboot = 1; - process_rc_script (); + fail = process_rc_script (); + if (fail) + { + do_fastboot = 0; + launch_single_user (); + } } } else if (pid == rc_pid && system_state == RUNCOM) @@ -1421,7 +1444,11 @@ S_startup_essential_task (mach_port_t server, if (bootstrap_args & RB_SINGLE) launch_single_user (); else - process_rc_script (); + { + fail = process_rc_script (); + if (fail) + launch_single_user (); + } return MIG_NO_REPLY; } } |