Changeset View
Changeset View
Standalone View
Standalone View
sbin/init/init.c
Show First 20 Lines • Show All 103 Lines • ▼ Show 20 Lines | |||||
static void stall(const char *, ...) __printflike(1, 2); | static void stall(const char *, ...) __printflike(1, 2); | ||||
static void warning(const char *, ...) __printflike(1, 2); | static void warning(const char *, ...) __printflike(1, 2); | ||||
static void emergency(const char *, ...) __printflike(1, 2); | static void emergency(const char *, ...) __printflike(1, 2); | ||||
static void disaster(int); | static void disaster(int); | ||||
static void revoke_ttys(void); | static void revoke_ttys(void); | ||||
static int runshutdown(void); | static int runshutdown(void); | ||||
static char *strk(char *); | static char *strk(char *); | ||||
static void runfinal(void); | |||||
/* | /* | ||||
* We really need a recursive typedef... | * We really need a recursive typedef... | ||||
* The following at least guarantees that the return type of (*state_t)() | * The following at least guarantees that the return type of (*state_t)() | ||||
* is sufficiently wide to hold a function pointer. | * is sufficiently wide to hold a function pointer. | ||||
*/ | */ | ||||
typedef long (*state_func_t)(void); | typedef long (*state_func_t)(void); | ||||
typedef state_func_t (*state_t)(void); | typedef state_func_t (*state_t)(void); | ||||
▲ Show 20 Lines • Show All 751 Lines • ▼ Show 20 Lines | |||||
#endif | #endif | ||||
#ifdef DEBUGSHELL | #ifdef DEBUGSHELL | ||||
char altshell[128]; | char altshell[128]; | ||||
#endif | #endif | ||||
if (Reboot) { | if (Reboot) { | ||||
/* Instead of going single user, let's reboot the machine */ | /* Instead of going single user, let's reboot the machine */ | ||||
sync(); | sync(); | ||||
/* Run scripts after all processes have been terminated. */ | |||||
runfinal(); | |||||
if (reboot(howto) == -1) { | if (reboot(howto) == -1) { | ||||
emergency("reboot(%#x) failed, %m", howto); | emergency("reboot(%#x) failed, %m", howto); | ||||
_exit(1); /* panic and reboot */ | _exit(1); /* panic and reboot */ | ||||
} | } | ||||
warning("reboot(%#x) returned", howto); | warning("reboot(%#x) returned", howto); | ||||
_exit(0); /* panic as well */ | _exit(0); /* panic as well */ | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,147 Lines • ▼ Show 20 Lines | if ((lc = login_getclassbyname(cname, NULL)) != NULL) { | ||||
setusercontext(lc, (struct passwd*)NULL, 0, | setusercontext(lc, (struct passwd*)NULL, 0, | ||||
LOGIN_SETENV | | LOGIN_SETENV | | ||||
LOGIN_SETPRIORITY | LOGIN_SETRESOURCES | | LOGIN_SETPRIORITY | LOGIN_SETRESOURCES | | ||||
LOGIN_SETLOGINCLASS | LOGIN_SETCPUMASK); | LOGIN_SETLOGINCLASS | LOGIN_SETCPUMASK); | ||||
login_close(lc); | login_close(lc); | ||||
} | } | ||||
} | } | ||||
#endif | #endif | ||||
/* | |||||
* Run /etc/rc.final to execute scripts after all user processes have been | |||||
* terminated. | |||||
*/ | |||||
static void | |||||
runfinal(void) | |||||
{ | |||||
struct stat sb; | |||||
pid_t other_pid, pid; | |||||
sigset_t mask; | |||||
/* Avoid any surprises. */ | |||||
alarm(0); | |||||
/* rc.final is optional. */ | |||||
if (stat(_PATH_RUNFINAL, &sb) == -1 && errno == ENOENT) | |||||
kib: I suggest to also check that +x bit it enabled | |||||
Done Inline ActionsTossed in a warning() if it exists as non-executable kevans: Tossed in a warning() if it exists as non-executable | |||||
return; | |||||
if (access(_PATH_RUNFINAL, X_OK) != 0) { | |||||
warning("%s exists, but not executable", _PATH_RUNFINAL); | |||||
return; | |||||
} | |||||
pid = fork(); | |||||
if (pid == 0) { | |||||
/* | |||||
* Reopen stdin/stdout/stderr so that scripts can write to | |||||
* console. | |||||
*/ | |||||
close(0); | |||||
open(_PATH_DEVNULL, O_RDONLY); | |||||
close(1); | |||||
close(2); | |||||
Done Inline Actionss/ 0/NULL/ ? And perhaps without the cast? kib: s/ 0/NULL/ ? And perhaps without the cast? | |||||
open_console(); | |||||
dup2(1, 2); | |||||
sigemptyset(&mask); | |||||
Done Inline Actionsmay be, say which file you execed so user understand why execl failed. kib: may be, say which file you execed so user understand why execl failed. | |||||
sigprocmask(SIG_SETMASK, &mask, NULL); | |||||
signal(SIGCHLD, SIG_DFL); | |||||
execl(_PATH_RUNFINAL, _PATH_RUNFINAL, NULL); | |||||
perror("execl(" _PATH_RUNFINAL ") failed"); | |||||
exit(1); | |||||
Done Inline ActionsAgain, NULL instead of (int *)0? kib: Again, NULL instead of (int *)0? | |||||
} | |||||
/* Wait for rc.final script to exit */ | |||||
while ((other_pid = waitpid(-1, NULL, 0)) != pid && other_pid > 0) { | |||||
continue; | |||||
} | |||||
} |
I suggest to also check that +x bit it enabled