Index: head/sbin/init/init.c =================================================================== --- head/sbin/init/init.c +++ head/sbin/init/init.c @@ -146,6 +146,7 @@ static state_t requested_transition; static state_t current_state = death_single; +static void execute_script(char *argv[]); static void open_console(void); static const char *get_shell(void); static void write_stderr(const char *message); @@ -1046,6 +1047,46 @@ return (state_func_t) read_ttys; } +static void +execute_script(char *argv[]) +{ + struct sigaction sa; + const char *shell, *script; + int error; + + bzero(&sa, sizeof(sa)); + sigemptyset(&sa.sa_mask); + sa.sa_handler = SIG_IGN; + sigaction(SIGTSTP, &sa, NULL); + sigaction(SIGHUP, &sa, NULL); + + open_console(); + + sigprocmask(SIG_SETMASK, &sa.sa_mask, NULL); +#ifdef LOGIN_CAP + setprocresources(RESOURCE_RC); +#endif + + /* + * Try to directly execute the script first. If it + * fails, try the old method of passing the script path + * to sh(1). Don't complain if it fails because of + * the missing execute bit. + */ + script = argv[1]; + error = access(script, X_OK); + if (error == 0) { + execv(script, argv + 1); + warning("can't exec %s: %m", script); + } else if (errno != EACCES) { + warning("can't access %s: %m", script); + } + + shell = get_shell(); + execv(shell, argv); + stall("can't exec %s for %s: %m", shell, script); +} + /* * Run a shell script. * Returns 0 on success, otherwise the next transition to enter: @@ -1057,22 +1098,14 @@ run_script(const char *script) { pid_t pid, wpid; - int error, status; + int status; char *argv[4]; const char *shell; - struct sigaction sa; shell = get_shell(); if ((pid = fork()) == 0) { - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sa.sa_handler = SIG_IGN; - sigaction(SIGTSTP, &sa, (struct sigaction *)0); - sigaction(SIGHUP, &sa, (struct sigaction *)0); - open_console(); - char _sh[] = "sh"; char _autoboot[] = "autoboot"; @@ -1081,28 +1114,8 @@ argv[2] = runcom_mode == AUTOBOOT ? _autoboot : 0; argv[3] = 0; - sigprocmask(SIG_SETMASK, &sa.sa_mask, (sigset_t *) 0); - -#ifdef LOGIN_CAP - setprocresources(RESOURCE_RC); -#endif - - /* - * Try to directly execute the script first. If it - * fails, try the old method of passing the script path - * to sh(1). Don't complain if it fails because of - * the missing execute bit. - */ - error = access(script, X_OK); - if (error == 0) { - execv(script, argv + 1); - warning("can't exec %s: %m", script); - } else if (errno != EACCES) { - warning("can't access %s: %m", script); - } - - execv(shell, argv); - stall("can't exec %s for %s: %m", shell, script); + execute_script(argv); + sleep(STALL_TIMEOUT); _exit(1); /* force single user mode */ } @@ -1869,12 +1882,10 @@ runshutdown(void) { pid_t pid, wpid; - int error, status; + int status; int shutdowntimeout; size_t len; char *argv[4]; - const char *shell; - struct sigaction sa; struct stat sb; /* @@ -1886,17 +1897,7 @@ if (stat(_PATH_RUNDOWN, &sb) == -1 && errno == ENOENT) return 0; - shell = get_shell(); - if ((pid = fork()) == 0) { - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sa.sa_handler = SIG_IGN; - sigaction(SIGTSTP, &sa, (struct sigaction *)0); - sigaction(SIGHUP, &sa, (struct sigaction *)0); - - open_console(); - char _sh[] = "sh"; char _reboot[] = "reboot"; char _single[] = "single"; @@ -1906,34 +1907,13 @@ argv[1] = _path_rundown; argv[2] = Reboot ? _reboot : _single; argv[3] = 0; - - sigprocmask(SIG_SETMASK, &sa.sa_mask, (sigset_t *) 0); - -#ifdef LOGIN_CAP - setprocresources(RESOURCE_RC); -#endif - - /* - * Try to directly execute the script first. If it - * fails, try the old method of passing the script path - * to sh(1). Don't complain if it fails because of - * the missing execute bit. - */ - error = access(_path_rundown, X_OK); - if (error == 0) { - execv(_path_rundown, argv + 1); - warning("can't exec %s: %m", _path_rundown); - } else if (errno != EACCES) { - warning("can't access %s: %m", _path_rundown); - } - - execv(shell, argv); - warning("can't exec %s for %s: %m", shell, _PATH_RUNDOWN); + + execute_script(argv); _exit(1); /* force single user mode */ } if (pid == -1) { - emergency("can't fork for %s on %s: %m", shell, _PATH_RUNDOWN); + emergency("can't fork for %s: %m", _PATH_RUNDOWN); while (waitpid(-1, (int *) 0, WNOHANG) > 0) continue; sleep(STALL_TIMEOUT); @@ -1956,20 +1936,20 @@ if (clang == 1) { /* we were waiting for the sub-shell */ kill(wpid, SIGTERM); - warning("timeout expired for %s on %s: %m; going to " - "single user mode", shell, _PATH_RUNDOWN); + warning("timeout expired for %s: %m; going to " + "single user mode", _PATH_RUNDOWN); return -1; } if (wpid == -1) { if (errno == EINTR) continue; - warning("wait for %s on %s failed: %m; going to " - "single user mode", shell, _PATH_RUNDOWN); + warning("wait for %s failed: %m; going to " + "single user mode", _PATH_RUNDOWN); return -1; } if (wpid == pid && WIFSTOPPED(status)) { - warning("init: %s on %s stopped, restarting\n", - shell, _PATH_RUNDOWN); + warning("init: %s stopped, restarting\n", + _PATH_RUNDOWN); kill(pid, SIGCONT); wpid = -1; } @@ -1992,8 +1972,8 @@ } if (!WIFEXITED(status)) { - warning("%s on %s terminated abnormally, going to " - "single user mode", shell, _PATH_RUNDOWN); + warning("%s terminated abnormally, going to " + "single user mode", _PATH_RUNDOWN); return -2; }