* Version: @(#)init.c 2.86 30-Jul-2004 miquels@cistron.nl
*/
#define VERSION "2.88"
-#define DATE "31-Jul-2004"
+#define DATE "26-Mar-2010"
/*
* This file is part of the sysvinit suite,
* Copyright (C) 1991-2004 Miquel van Smoorenburg.
#include <sys/time.h>
#ifdef WITH_SELINUX
-#include <selinux/selinux.h>
-#include <sys/mount.h>
+# include <selinux/selinux.h>
+# include <sys/mount.h>
+# ifndef MNT_DETACH /* present in glibc 2.10, missing in 2.7 */
+# define MNT_DETACH 2
+# endif
#endif
-
#ifdef __i386__
# ifdef __GLIBC__
/* GNU libc 2.x */
*/
for(f = 0; f < 5; f++) {
if ((fd = open(console_dev, m)) >= 0) break;
- usleep(100);
+ usleep(10000);
}
if (fd < 0) return fd;
return;
}
+#ifdef __FreeBSD_kernel__
+ /*
+ * The kernel of FreeBSD expects userland to set TERM. Usually, we want
+ * "cons25". Later, gettys might disagree on this (i.e. we're not using
+ * syscons) but some boot scripts, like /etc/init.d/xserver-xorg, still
+ * need a non-dumb terminal.
+ */
+ putenv ("TERM=cons25");
+#endif
+
(void) tcgetattr(fd, &tty);
tty.c_cflag &= CBAUD|CBAUDEX|CSIZE|CSTOPB|PARENB|PARODD;
for (n = 0; environ[n]; n++)
;
- n += NR_EXTRA_ENV + 8;
+ n += NR_EXTRA_ENV;
+ if (child)
+ n += 8;
e = calloc(n, sizeof(char *));
for (n = 0; environ[n]; n++)
e[n] = istrdup(environ[n]);
- for (i = 0; i < NR_EXTRA_ENV; i++)
+ for (i = 0; i < NR_EXTRA_ENV; i++) {
if (extra_env[i])
e[n++] = istrdup(extra_env[i]);
+ }
if (child) {
snprintf(i_cons, sizeof(i_cons), "CONSOLE=%s", console_dev);
*
*/
static
-int spawn(CHILD *ch, int *res)
+pid_t spawn(CHILD *ch, int *res)
{
char *args[16]; /* Argv array */
char buf[136]; /* Line buffer */
- int f, st, rc; /* Scratch variables */
+ int f, st; /* Scratch variables */
char *ptr; /* Ditto */
time_t t; /* System time */
int oldAlarm; /* Previous alarm value */
sigprocmask(SIG_SETMASK, &omask, NULL);
- /*
- * Update utmp/wtmp file prior to starting
- * any child. This MUST be done right here in
- * the child process in order to prevent a race
- * condition that occurs when the child
- * process' time slice executes before the
- * parent (can and does happen in a uniprocessor
- * environment). If the child is a getty and
- * the race condition happens, then init's utmp
- * update will happen AFTER the getty runs
- * and expects utmp to be updated already!
- *
- * Do NOT log if process field starts with '+'
- * FIXME: that's for compatibility with *very*
- * old getties - probably it can be taken out.
- */
- if (ch->action == RESPAWN && ch->process[0] != '+')
- write_utmp_wtmp("", ch->id, getpid(), INIT_PROCESS, "");
-
/*
* In sysinit, boot, bootwait or single user mode:
* for any wait-type subprocess we _force_ the console
exit(1);
}
if (pid > 0) {
+ pid_t rc;
/*
* Ignore keyboard signals etc.
* Then wait for child to exit.
dup(f);
}
+ /*
+ * Update utmp/wtmp file prior to starting
+ * any child. This MUST be done right here in
+ * the child process in order to prevent a race
+ * condition that occurs when the child
+ * process' time slice executes before the
+ * parent (can and does happen in a uniprocessor
+ * environment). If the child is a getty and
+ * the race condition happens, then init's utmp
+ * update will happen AFTER the getty runs
+ * and expects utmp to be updated already!
+ *
+ * Do NOT log if process field starts with '+'
+ * FIXME: that's for compatibility with *very*
+ * old getties - probably it can be taken out.
+ */
+ if (ch->process[0] != '+')
+ write_utmp_wtmp("", ch->id, getpid(), INIT_PROCESS, "");
+
/* Reset all the signals, set up environment */
for(f = 1; f < NSIG; f++) SETSIG(sa, f, SIG_DFL, SA_RESTART);
environ = init_buildenv(1);
execvp(args[1], args + 1);
}
initlog(L_VB, "cannot execute \"%s\"", args[1]);
+
+ if (ch->process[0] != '+')
+ write_utmp_wtmp("", ch->id, getpid(), DEAD_PROCESS, NULL);
exit(1);
}
*res = pid;
pwrstat = c;
close(fd);
unlink(PWRSTAT);
- }
+ } else if ((fd = open(PWRSTAT_OLD, O_RDONLY)) >= 0) {
+ /* Path changed 2010-03-20. Look for the old path for a while. */
+ initlog(L_VB, "warning: found obsolete path %s, use %s instead",
+ PWRSTAT_OLD, PWRSTAT);
+ c = 0;
+ read(fd, &c, 1);
+ pwrstat = c;
+ close(fd);
+ unlink(PWRSTAT_OLD);
+ }
do_power_fail(pwrstat);
DELSET(got_signals, SIGPWR);
}
CHILD *ch;
struct sigaction sa;
sigset_t sgt;
- pid_t rc;
int f, st;
if (!reload) {
* See if we have to start an emergency shell.
*/
if (emerg_shell) {
+ pid_t rc;
SETSIG(sa, SIGCHLD, SIG_DFL, SA_RESTART);
if (spawn(&ch_emerg, &f) > 0) {
while((rc = wait(&st)) != f)