sysvinit/sysvinit-2.86.dif

927 lines
23 KiB
Plaintext
Raw Normal View History

--- .pkgextract
+++ .pkgextract 2006-08-18 14:45:28.000000000 +0200
@@ -0,0 +1,12 @@
+patch -p0 -b -s --suffix=.nfs4pidof < ../sysvinit-2.86-nfs4pidof.patch
+patch -p0 -b -s --suffix=.sulogin < ../sysvinit-2.86-sulogin.patch
+patch -p0 -b -s --suffix=.ststdmn < ../sysvinit-2.82-startstop.patch
+patch -p0 -b -s --suffix=.suse < ../sysvinit-2.85-suse.patch
+patch -p0 -b -s --suffix=.paths < ../sysvinit-2.85-paths.patch
+patch -p0 -b -s --suffix=.utmp < ../sysvinit-2.86-utmp.patch
+patch -p0 -b -s --suffix=.race < ../sysvinit-2.86-race.patch
+patch -p0 -b -s --suffix=.lib64 < ../sysvinit-2.86-lib64.patch
+patch -p0 -b -s --suffix=.mltline < ../sysvinit-2.82-multiline.patch
+patch -p0 -b -s --suffix=.usage < ../sysvinit-2.86-usage-message.patch
+patch -p0 -b -s --suffix=.fulltime < ../sysvinit-2.86-full-time.patch
+patch -p0 -b -s --suffix=.hddown < ../sysvinit-2.86-hddown.patch
--- src/Makefile
+++ src/Makefile 2006-08-18 14:45:28.000000000 +0200
@@ -8,17 +8,20 @@
# Version: @(#)Makefile 2.85-13 23-Mar-2004 miquels@cistron.nl
#
+DISTRO = SuSE
+
CC = gcc
-CFLAGS = -Wall -O2 -fomit-frame-pointer -D_GNU_SOURCE
-LDFLAGS = -s
-STATIC =
+CFLAGS = -Wall $(RPM_OPT_FLAGS) -D_GNU_SOURCE -pipe
+LDFLAGS = -Wl,-warn-common
+STATIC = -static
+IFLAGS = -D__NO_STRING_INLINES -D__OPTIMIZE_SIZE__
# For some known distributions we do not build all programs, otherwise we do.
BIN =
SBIN = init halt shutdown runlevel killall5
-USRBIN = last mesg
+USRBIN = last
-MAN1 = last.1 lastb.1 mesg.1
+MAN1 = last.1 lastb.1
MAN5 = initscript.5 inittab.5
MAN8 = halt.8 init.8 killall5.8 pidof.8 poweroff.8 reboot.8 runlevel.8
MAN8 += shutdown.8 telinit.8
@@ -26,27 +29,36 @@ MAN8 += shutdown.8 telinit.8
ifeq ($(DISTRO),)
BIN += mountpoint
SBIN += sulogin bootlogd
-USRBIN += utmpdump wall
-MAN1 += mountpoint.1 wall.1
+USRBIN += utmpdump wall mesg
+MAN1 += mountpoint.1 wall.1 mesg.1
MAN8 += sulogin.8 bootlogd.8
endif
ifeq ($(DISTRO),Debian)
BIN += mountpoint
SBIN += sulogin bootlogd
-MAN1 += mountpoint.1
+USRBIN += mesg
+MAN1 += mountpoint.1 mesg.1
MAN8 += sulogin.8 bootlogd.8
endif
ifeq ($(DISTRO),Owl)
-USRBIN += wall
-MAN1 += wall.1
+USRBIN += wall mesg
+MAN1 += wall.1 mesg.1
+endif
+
+ifeq ($(DISTRO),SuSE)
+BIN += mountpoint
+SBIN += sulogin
+USRBIN += utmpdump
+MAN1 += mountpoint.1
+MAN8 += sulogin.8
endif
BIN_OWNER = root
BIN_GROUP = root
BIN_COMBO = $(BIN_OWNER):$(BIN_GROUP)
-INSTALL = install -o $(BIN_OWNER) -g $(BIN_GROUP)
+INSTALL = install
MANDIR = /usr/share/man
# Additional libs for GNU libc.
@@ -78,7 +90,7 @@ runlevel: runlevel.o
$(CC) $(LDFLAGS) -o $@ runlevel.o
sulogin: sulogin.o
- $(CC) $(LDFLAGS) $(STATIC) -o $@ sulogin.o $(LCRYPT)
+ $(CC) $(LDFLAGS) -o $@ sulogin.o $(LCRYPT)
wall: dowall.o wall.o
$(CC) $(LDFLAGS) -o $@ dowall.o wall.o
@@ -90,13 +102,13 @@ bootlogd: bootlogd.o
$(CC) $(LDFLAGS) -o $@ bootlogd.o -lutil
init.o: init.c init.h set.h reboot.h initreq.h
- $(CC) -c $(CFLAGS) init.c
+ $(CC) -c $(CFLAGS) $(IFLAGS) init.c
utmp.o: utmp.c init.h
$(CC) -c $(CFLAGS) utmp.c
init_utmp.o: utmp.c init.h
- $(CC) -c $(CFLAGS) -DINIT_MAIN utmp.c -o init_utmp.o
+ $(CC) -c $(CFLAGS) -DINIT_MAIN $(IFLAGS) utmp.c -o init_utmp.o
cleanobjs:
rm -f *.o *.bak
@@ -119,10 +131,10 @@ install:
for i in $(USRBIN); do \
$(INSTALL) -m 755 $$i $(ROOT)/usr/bin/; \
done
- # $(INSTALL) -m 755 etc/initscript.sample $(ROOT)/etc/
- ln -sf halt $(ROOT)/sbin/reboot
- ln -sf halt $(ROOT)/sbin/poweroff
- ln -sf init $(ROOT)/sbin/telinit
+ ln -sf halt $(ROOT)/sbin/reboot
+ ln -sf halt $(ROOT)/sbin/poweroff
+ ln -sf init $(ROOT)/sbin/telinit
+ ln -sf killall5 $(ROOT)/sbin/pidof
ln -sf ../sbin/killall5 $(ROOT)/bin/pidof
if [ ! -f $(ROOT)/usr/bin/lastb ]; then \
ln -sf last $(ROOT)/usr/bin/lastb; \
--- src/bootlogd.c
+++ src/bootlogd.c 2006-08-18 14:45:28.000000000 +0200
@@ -210,7 +210,7 @@ int isconsole(char *s, char *res, int rl
int consolename(char *res, int rlen)
{
#ifdef TIOCGDEV
- unsigned int kdev;
+ kdev_t kdev;
#endif
struct stat st, st2;
char buf[256];
@@ -506,7 +506,7 @@ int main(int argc, char **argv)
}
(void)ioctl(0, TIOCCONS, NULL);
-#if 1
+#if 0
/* Work around bug in 2.1/2.2 kernels. Fixed in 2.2.13 and 2.3.18 */
if ((n = open("/dev/tty0", O_RDWR)) >= 0) {
(void)ioctl(n, TIOCCONS, NULL);
--- src/dowall.c
+++ src/dowall.c 2006-08-18 14:45:28.000000000 +0200
@@ -65,7 +65,7 @@ static void getuidtty(char **userp, char
uid_t uid;
char *tty;
static char uidbuf[32];
- static char ttynm[32];
+ static char ttynm[UT_LINESIZE + 4];
static int init = 0;
if (!init) {
@@ -79,9 +79,13 @@ static void getuidtty(char **userp, char
}
if ((tty = ttyname(0)) != NULL) {
- if (strncmp(tty, "/dev/", 5) == 0)
- tty += 5;
- sprintf(ttynm, "(%.28s) ", tty);
+ if (strncmp(tty, _PATH_DEV, strlen(_PATH_DEV)) == 0) {
+ tty += strlen(_PATH_DEV);
+ if (tty[0] == '/')
+ tty ++;
+ }
+ snprintf(ttynm, sizeof(ttynm), "(%.*s) ",
+ UT_LINESIZE, tty);
} else
ttynm[0] = 0;
init++;
@@ -129,7 +133,7 @@ void wall(char *text, int fromshutdown,
struct sigaction sa;
struct utmp *utmp;
time_t t;
- char term[UT_LINESIZE+6];
+ char term[UT_LINESIZE + strlen(_PATH_DEV) + 1];
char line[81];
char *date, *p;
char *user, *tty;
@@ -178,11 +182,11 @@ void wall(char *text, int fromshutdown,
while ((utmp = getutent()) != NULL) {
if(utmp->ut_type != USER_PROCESS ||
utmp->ut_user[0] == 0) continue;
- if (strncmp(utmp->ut_line, "/dev/", 5) == 0) {
+ if (strncmp(utmp->ut_line, _PATH_DEV, strlen(_PATH_DEV)) == 0) {
term[0] = 0;
- strncat(term, utmp->ut_line, UT_LINESIZE);
+ strncat(term, utmp->ut_line, sizeof(term)-1);
} else
- snprintf(term, sizeof(term), "/dev/%.*s",
+ snprintf(term, sizeof(term), _PATH_DEV "%.*s",
UT_LINESIZE, utmp->ut_line);
if (strstr(term, "/../")) continue;
--- src/init.c
+++ src/init.c 2006-08-18 14:45:28.000000000 +0200
@@ -52,12 +52,12 @@
#include <sys/time.h>
#ifdef __i386__
-# if (__GLIBC__ >= 2)
- /* GNU libc 2.x */
+# if defined (__GLIBC__)
# define STACK_DEBUG 1
# if (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
- /* Only glibc 2.0 needs this */
# include <sigcontext.h>
+# elif ( __GLIBC__ > 2) && ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 1))
+# include <bits/sigcontext.h>
# endif
# endif
#endif
@@ -68,6 +68,12 @@
#include "reboot.h"
#include "set.h"
+#ifdef __GNUC__
+ __attribute__ ((format (printf, 2, 3)))
+#endif
+static void initlog(int loglevel, char *fmt, ...);
+static void print(char *fmt);
+
#ifndef SIGPWR
# define SIGPWR SIGUSR2
#endif
@@ -82,11 +88,15 @@
/* Set a signal handler. */
#define SETSIG(sa, sig, fun, flags) \
do { \
+ memset(&sa, 0, sizeof(sa)); \
sa.sa_handler = fun; \
sa.sa_flags = flags; \
sigemptyset(&sa.sa_mask); \
sigaction(sig, &sa, NULL); \
} while(0)
+#ifndef mem_barrier
+# define mem_barrier() __asm__ __volatile__("": : :"memory")
+#endif
/* Version information */
char *Version = "@(#) init " VERSION " " DATE " miquels@cistron.nl";
@@ -208,6 +218,7 @@ char *extra_env[NR_EXTRA_ENV];
* This only works correctly because the linux select updates
* the elapsed time in the struct timeval passed to select!
*/
+static
void do_sleep(int sec)
{
struct timeval tv;
@@ -216,13 +227,14 @@ void do_sleep(int sec)
tv.tv_usec = 0;
while(select(0, NULL, NULL, NULL, &tv) < 0 && errno == EINTR)
- ;
+ mem_barrier();
}
/*
* Non-failing allocation routines (init cannot fail).
*/
+static
void *imalloc(size_t size)
{
void *m;
@@ -235,7 +247,7 @@ void *imalloc(size_t size)
return m;
}
-
+static
char *istrdup(char *s)
{
char *m;
@@ -252,6 +264,7 @@ char *istrdup(char *s)
* Send the state info of the previous running init to
* the new one, in a version-independant way.
*/
+static
void send_state(int fd)
{
FILE *fp;
@@ -316,7 +329,7 @@ static int get_void(FILE *f)
int c;
while ((c = getc(f)) != EOF && c != '\n')
- ;
+ mem_barrier();
return (c != EOF);
}
@@ -333,7 +346,7 @@ static int get_cmd(FILE *f)
return C_EOF;
for(i = 0; cmds[i].cmd && strcmp(cmds[i].name, cmd) != 0; i++)
- ;
+ mem_barrier();
return cmds[i].cmd;
}
@@ -438,6 +451,7 @@ static CHILD *get_record(FILE *f)
* Read the complete state info from the state pipe.
* Returns 0 on success
*/
+static
int receive_state(int fd)
{
FILE *f;
@@ -451,7 +465,7 @@ int receive_state(int fd)
get_string(old_version, sizeof(old_version), f);
oops_error = 0;
for (pp = &family; (*pp = get_record(f)) != NULL; pp = &((*pp)->next))
- ;
+ mem_barrier();
fclose(f);
return oops_error;
}
@@ -485,6 +499,7 @@ static int setproctitle(char *fmt, ...)
/*
* Set console_dev to a working console.
*/
+static
void console_init(void)
{
int fd;
@@ -524,6 +539,7 @@ void console_init(void)
/*
* Open the console with retries.
*/
+static
int console_open(int mode)
{
int f, fd = -1;
@@ -553,6 +569,7 @@ int console_open(int mode)
/*
* We got a signal (HUP PWR WINCH ALRM INT)
*/
+static
void signal_handler(int sig)
{
ADDSET(got_signals, sig);
@@ -561,6 +578,7 @@ void signal_handler(int sig)
/*
* SIGCHLD: one of our children has died.
*/
+static
void chld_handler()
{
CHILD *ch;
@@ -600,7 +618,8 @@ void chld_handler()
*
* The SIGCONT handler
*/
-void cont_handler()
+static
+void cont_handler(int sig)
{
got_cont = 1;
}
@@ -608,6 +627,7 @@ void cont_handler()
/*
* Fork and dump core in /.
*/
+static
void coredump(void)
{
static int dumped = 0;
@@ -641,6 +661,7 @@ void coredump(void)
* If we have the info, print where it occured.
* Then sleep 30 seconds and try to continue.
*/
+static
#if defined(STACK_DEBUG) && defined(__linux__)
void segv_handler(int sig, struct sigcontext ctx)
{
@@ -657,7 +678,7 @@ void segv_handler(int sig, struct sigcon
errno = saved_errno;
}
#else
-void segv_handler()
+void segv_handler(int sig)
{
int saved_errno = errno;
@@ -672,7 +693,8 @@ void segv_handler()
/*
* The SIGSTOP & SIGTSTP handler
*/
-void stop_handler()
+static
+void stop_handler(int sig)
{
int saved_errno = errno;
@@ -685,6 +707,7 @@ void stop_handler()
/*
* Set terminal settings to reasonable defaults
*/
+static
void console_stty(void)
{
struct termios tty;
@@ -700,16 +723,23 @@ void console_stty(void)
tty.c_cflag &= CBAUD|CBAUDEX|CSIZE|CSTOPB|PARENB|PARODD;
tty.c_cflag |= HUPCL|CLOCAL|CREAD;
- tty.c_cc[VINTR] = 3; /* ctrl('c') */
- tty.c_cc[VQUIT] = 28; /* ctrl('\\') */
- tty.c_cc[VERASE] = 127;
- tty.c_cc[VKILL] = 24; /* ctrl('x') */
- tty.c_cc[VEOF] = 4; /* ctrl('d') */
- tty.c_cc[VTIME] = 0;
- tty.c_cc[VMIN] = 1;
- tty.c_cc[VSTART] = 17; /* ctrl('q') */
- tty.c_cc[VSTOP] = 19; /* ctrl('s') */
- tty.c_cc[VSUSP] = 26; /* ctrl('z') */
+ tty.c_cc[VTIME] = 0;
+ tty.c_cc[VMIN] = 1;
+ tty.c_cc[VINTR] = CINTR;
+ tty.c_cc[VQUIT] = CQUIT;
+ tty.c_cc[VERASE] = CERASE; /* ASCII DEL (0177) */
+ tty.c_cc[VKILL] = CKILL;
+ tty.c_cc[VEOF] = CEOF;
+ tty.c_cc[VSWTC] = _POSIX_VDISABLE;
+ tty.c_cc[VSTART] = CSTART;
+ tty.c_cc[VSTOP] = CSTOP;
+ tty.c_cc[VSUSP] = CSUSP;
+ tty.c_cc[VEOL] = _POSIX_VDISABLE;
+ tty.c_cc[VREPRINT] = CREPRINT;
+ tty.c_cc[VDISCARD] = CDISCARD;
+ tty.c_cc[VWERASE] = CWERASE;
+ tty.c_cc[VLNEXT] = CLNEXT;
+ tty.c_cc[VEOL2] = _POSIX_VDISABLE;
/*
* Set pre and post processing
@@ -719,6 +749,14 @@ void console_stty(void)
tty.c_lflag = ISIG|ICANON|ECHO|ECHOCTL|ECHOPRT|ECHOKE;
/*
+ * Setting for SuSE: No flow control (-ixon), ignore break (ignbrk),
+ * and make nl/cr more usable (sane).
+ */
+ tty.c_iflag |= IGNBRK;
+ tty.c_iflag &= ~(BRKINT|INLCR|IGNCR|IXON);
+ tty.c_oflag &= ~(OCRNL|ONLRET);
+
+ /*
* Now set the terminal line.
* We don't care about non-transmitted output data
* and non-read input data.
@@ -731,6 +769,7 @@ void console_stty(void)
/*
* Print to the system console
*/
+static
void print(char *s)
{
int fd;
@@ -747,6 +786,7 @@ void print(char *s)
#ifdef __GNUC__
__attribute__ ((format (printf, 2, 3)))
#endif
+static
void initlog(int loglevel, char *s, ...)
{
va_list va_alist;
@@ -789,6 +829,7 @@ char **init_buildenv(int child)
char i_lvl[] = "RUNLEVEL=x";
char i_prev[] = "PREVLEVEL=x";
char i_cons[32];
+ char i_shell[] = "SHELL=" SHELL;
char **e;
int n, i;
@@ -808,6 +849,7 @@ char **init_buildenv(int child)
snprintf(i_cons, sizeof(i_cons), "CONSOLE=%s", console_dev);
i_lvl[9] = thislevel;
i_prev[10] = prevlevel;
+ e[n++] = istrdup(i_shell);
e[n++] = istrdup(i_lvl);
e[n++] = istrdup(i_prev);
e[n++] = istrdup(i_cons);
@@ -836,6 +878,7 @@ void init_freeenv(char **e)
* This function is too long and indents too deep.
*
*/
+static
int spawn(CHILD *ch, int *res)
{
char *args[16]; /* Argv array */
@@ -978,7 +1021,7 @@ int spawn(CHILD *ch, int *res)
}
SETSIG(sa, SIGCHLD, SIG_DFL, SA_RESTART);
if ((pid = fork()) < 0) {
- initlog(L_VB, "cannot fork");
+ initlog(L_VB, "cannot fork: %s", strerror(errno));
exit(1);
}
if (pid > 0) {
@@ -1007,7 +1050,7 @@ int spawn(CHILD *ch, int *res)
* this with a temporary process.
*/
if ((pid = fork()) < 0) {
- initlog(L_VB, "cannot fork");
+ initlog(L_VB, "cannot fork: %s", strerror(errno));
exit(1);
}
if (pid == 0) {
@@ -1073,6 +1116,7 @@ int spawn(CHILD *ch, int *res)
/*
* Start a child running!
*/
+static
void startup(CHILD *ch)
{
/*
@@ -1115,6 +1159,7 @@ void startup(CHILD *ch)
/*
* Read the inittab file.
*/
+static
void read_inittab(void)
{
FILE *fp; /* The INITTAB file */
@@ -1172,7 +1217,7 @@ void read_inittab(void)
* Skip comments and empty lines
*/
for(p = buf; *p == ' ' || *p == '\t'; p++)
- ;
+ mem_barrier();
if (*p == '#' || *p == '\n') continue;
/*
@@ -1495,6 +1540,7 @@ void read_inittab(void)
* The entries that do not belong here at all are removed
* from the list.
*/
+static
void start_if_needed(void)
{
CHILD *ch; /* Pointer to child */
@@ -1540,6 +1586,7 @@ void start_if_needed(void)
/*
* Ask the user on the console for a runlevel
*/
+static
int ask_runlevel(void)
{
const char prompt[] = "\nEnter runlevel: ";
@@ -1568,6 +1615,7 @@ int ask_runlevel(void)
* Search the INITTAB file for the 'initdefault' field, with the default
* runlevel. If this fails, ask the user to supply a runlevel.
*/
+static
int get_init_default(void)
{
CHILD *ch;
@@ -1616,6 +1664,7 @@ int get_init_default(void)
* the "old" INITLVL and arg == 0, try to read the new
* runlevel from that file first.
*/
+static
int read_level(int arg)
{
CHILD *ch; /* Walk through list */
@@ -1684,7 +1733,16 @@ int read_level(int arg)
initlog(L_VB, "Switching to runlevel: %c", foo);
}
- if (foo == 'Q') return runlevel;
+ if (foo == 'Q') {
+ struct sigaction sa;
+
+ /*
+ * Re-enable SIGINT's, which may disabled by
+ * an former Ctrl-Alt-Del action in process_signals().
+ */
+ SETSIG(sa, SIGINT, signal_handler, 0);
+ return(runlevel);
+ }
/* Check if this is a runlevel a, b or c */
if (strchr("ABC", foo)) {
@@ -1723,6 +1781,7 @@ int read_level(int arg)
* longer than 5 minutes, or inittab was read again due
* to user interaction.
*/
+static
void fail_check(void)
{
CHILD *ch; /* Pointer to child structure */
@@ -1755,6 +1814,7 @@ void fail_check(void)
}
/* Set all 'Fail' timers to 0 */
+static
void fail_cancel(void)
{
CHILD *ch;
@@ -1769,6 +1829,7 @@ void fail_cancel(void)
/*
* Start up powerfail entries.
*/
+static
void do_power_fail(int pwrstat)
{
CHILD *ch;
@@ -1802,6 +1863,7 @@ void do_power_fail(int pwrstat)
/*
* Check for state-pipe presence
*/
+static
int check_pipe(int fd)
{
struct timeval t;
@@ -1822,6 +1884,7 @@ int check_pipe(int fd)
/*
* Make a state-pipe.
*/
+static
int make_pipe(int fd)
{
int fds[2];
@@ -1839,6 +1902,7 @@ int make_pipe(int fd)
/*
* Attempt to re-exec.
*/
+static
void re_exec(void)
{
CHILD *ch;
@@ -1896,7 +1960,7 @@ void re_exec(void)
* The existing init process execs a new init binary.
*/
env = init_buildenv(0);
- execl(myname, myname, "--init", NULL, env);
+ execle(myname, myname, "--init", NULL, env);
/*
* We shouldn't be here, something failed.
@@ -1914,6 +1978,7 @@ void re_exec(void)
* We got a change runlevel request through the
* init.fifo. Process it.
*/
+static
void fifo_new_level(int level)
{
#if CHANGE_WAIT
@@ -1942,7 +2007,7 @@ void fifo_new_level(int level)
runlevel == '1') console_stty();
read_inittab();
fail_cancel();
- setproctitle("init [%c]", runlevel);
+ setproctitle("init [%c]", (int)runlevel);
}
}
}
@@ -2010,6 +2075,7 @@ void initcmd_setenv(char *data, int size
* the 2.2 kernel credential stuff to see who we're talking to.
*
*/
+static
void check_init_fifo(void)
{
struct init_request request;
@@ -2075,7 +2141,7 @@ void check_init_fifo(void)
tv.tv_usec = 0;
n = select(pipe_fd + 1, &fds, NULL, NULL, &tv);
if (n <= 0) {
- if (n == 0 || errno == EINTR) return;
+ if (n == 0 || errno == EINTR || errno == EAGAIN) return;
continue;
}
@@ -2092,7 +2158,7 @@ void check_init_fifo(void)
return;
}
if (n <= 0) {
- if (errno == EINTR) return;
+ if (errno == EINTR || errno == EAGAIN) return;
initlog(L_VB, "error reading initrequest");
continue;
}
@@ -2164,6 +2230,7 @@ void check_init_fifo(void)
* This function is used in the transition
* sysinit (-> single user) boot -> multi-user.
*/
+static
void boot_transitions()
{
CHILD *ch;
@@ -2240,7 +2307,7 @@ void boot_transitions()
write_utmp_wtmp("runlevel", "~~", runlevel + 256 * oldlevel, RUN_LVL, "~");
thislevel = runlevel;
prevlevel = oldlevel;
- setproctitle("init [%c]", runlevel);
+ setproctitle("init [%c]", (int)runlevel);
}
}
}
@@ -2249,6 +2316,7 @@ void boot_transitions()
* Init got hit by a signal. See which signal it is,
* and act accordingly.
*/
+static
void process_signals()
{
CHILD *ch;
@@ -2273,7 +2341,12 @@ void process_signals()
}
if (ISMEMBER(got_signals, SIGINT)) {
+ struct sigaction sa;
INITDBG(L_VB, "got SIGINT");
+
+ /* we don't want any more SIGINT's */
+ SETSIG(sa, SIGINT, SIG_IGN, SA_RESTART);
+
/* Tell ctrlaltdel entry to start up */
for(ch = family; ch; ch = ch->next)
if (ch->action == CTRLALTDEL)
@@ -2335,7 +2408,7 @@ void process_signals()
runlevel == '1') console_stty();
read_inittab();
fail_cancel();
- setproctitle("init [%c]", runlevel);
+ setproctitle("init [%c]", (int)runlevel);
DELSET(got_signals, SIGHUP);
}
}
@@ -2354,7 +2427,8 @@ void process_signals()
/*
* The main loop
*/
-int init_main()
+static
+void init_main(void)
{
CHILD *ch;
struct sigaction sa;
@@ -2507,6 +2581,7 @@ int init_main()
/*
* Tell the user about the syntax we expect.
*/
+static
void usage(char *s)
{
fprintf(stderr, "Usage: %s 0123456SsQqAaBbCcUu\n", s);
@@ -2564,12 +2639,38 @@ int telinit(char *progname, int argc, ch
request.sleeptime = sltime;
}
+ /* Catch some common signals. */
+ signal(SIGQUIT, SIG_IGN);
+ signal(SIGCHLD, SIG_IGN);
+ signal(SIGHUP, SIG_IGN);
+ signal(SIGTSTP, SIG_IGN);
+ signal(SIGTTIN, SIG_IGN);
+ signal(SIGTTOU, SIG_IGN);
+ signal(SIGINT, SIG_IGN);
+
+ /* Go to the root directory. */
+ chdir("/");
+
/* Open the fifo and write a command. */
+
/* Make sure we don't hang on opening /dev/initctl */
SETSIG(sa, SIGALRM, signal_handler, 0);
alarm(3);
- if ((fd = open(INIT_FIFO, O_WRONLY)) >= 0 &&
- write(fd, &request, sizeof(request)) == sizeof(request)) {
+ if ((fd = open(INIT_FIFO, O_WRONLY)) >= 0) {
+ ssize_t p = 0;
+ size_t s = sizeof(request);
+ void *ptr = &request;
+
+ while (s > 0) {
+ p = write(fd, ptr, s);
+ if (p < 0) {
+ if (errno == EINTR || errno == EAGAIN)
+ continue;
+ break;
+ }
+ ptr += p;
+ s -= p;
+ }
close(fd);
alarm(0);
return 0;
@@ -2619,6 +2720,8 @@ int main(int argc, char **argv)
p++;
else
p = argv[0];
+
+ /* Common umask */
umask(022);
/* Quick check */
@@ -2651,7 +2754,7 @@ int main(int argc, char **argv)
for (f = 0; f < argc; f++)
maxproclen += strlen(argv[f]) + 1;
reload = 1;
- setproctitle("init [%c]",runlevel);
+ setproctitle("init [%c]", (int)runlevel);
init_main();
}
@@ -2680,7 +2783,7 @@ int main(int argc, char **argv)
argv0 = argv[0];
argv[1] = NULL;
setproctitle("init boot");
- init_main(dfl_level);
+ init_main();
/*NOTREACHED*/
return 0;
--- src/init.h
+++ src/init.h 2006-08-18 14:45:28.000000000 +0200
@@ -30,12 +30,6 @@
/* Prototypes. */
void write_utmp_wtmp(char *user, char *id, int pid, int type, char *line);
void write_wtmp(char *user, char *id, int pid, int type, char *line);
-#ifdef __GNUC__
-__attribute__ ((format (printf, 2, 3)))
-#endif
-void initlog(int loglevel, char *fmt, ...);
-void set_term(int how);
-void print(char *fmt);
#if DEBUG
# define INITDBG(level, fmt, args...) initlog(level, fmt, ##args)
--- src/shutdown.c
+++ src/shutdown.c 2006-08-18 14:45:28.000000000 +0200
@@ -60,6 +60,7 @@ char *clean_env[] = {
"HOME=/",
"PATH=/bin:/usr/bin:/sbin:/usr/sbin",
"TERM=dumb",
+ "SHELL=/bin/sh",
NULL,
};
@@ -159,11 +160,24 @@ int init_setenv(char *name, char *value)
sigaction(SIGALRM, &sa, NULL);
got_alrm = 0;
alarm(3);
- if ((fd = open(INIT_FIFO, O_WRONLY)) >= 0 &&
- write(fd, &request, sizeof(request)) == sizeof(request)) {
- close(fd);
- alarm(0);
- return 0;
+ if ((fd = open(INIT_FIFO, O_WRONLY)) >= 0) {
+ ssize_t p = 0;
+ size_t s = sizeof(request);
+ void *ptr = &request;
+
+ while (s > 0) {
+ p = write(fd, ptr, s);
+ if (p < 0) {
+ if (errno == EINTR || errno == EAGAIN)
+ continue;
+ break;
+ }
+ ptr += p;
+ s -= p;
+ }
+ close(fd);
+ alarm(0);
+ return 0;
}
fprintf(stderr, "shutdown: ");
--- src/utmp.c
+++ src/utmp.c 2006-08-18 14:45:28.000000000 +0200
@@ -47,6 +47,9 @@ char *line) /* Which line is this */
int fd;
struct utmp utmp;
struct utsname uname_buf;
+#if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32
+ struct timeval tv;
+#endif
/*
* Can't do much if WTMP_FILE is not present or not writable.
@@ -99,7 +102,13 @@ char *line) /* Which line is this */
*/
memset(&utmp, 0, sizeof(utmp));
#if defined(__GLIBC__)
+# if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32
+ gettimeofday(&tv, NULL);
+ utmp.ut_tv.tv_sec = (int32_t)tv.tv_sec;
+ utmp.ut_tv.tv_usec = (int32_t)tv.tv_usec;
+# else
gettimeofday(&utmp.ut_tv, NULL);
+# endif
#else
time(&utmp.ut_time);
#endif
@@ -136,6 +145,9 @@ char *oldline) /* Line of old utmp ent
struct utmp utmp;
struct utmp tmp;
struct utmp *utmptr;
+#if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32
+ struct timeval tv;
+#endif
/*
* Can't do much if UTMP_FILE is not present or not writable.
@@ -184,7 +196,13 @@ char *oldline) /* Line of old utmp ent
utmp.ut_pid = pid;
strncpy(utmp.ut_id, id, sizeof(utmp.ut_id));
#if defined(__GLIBC__)
+# if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32
+ gettimeofday(&tv, NULL);
+ utmp.ut_tv.tv_sec = (int32_t)tv.tv_sec;
+ utmp.ut_tv.tv_usec = (int32_t)tv.tv_usec;
+# else
gettimeofday(&utmp.ut_tv, NULL);
+# endif
#else
time(&utmp.ut_time);
#endif