* init - avoid compiler warnings

* init - initialize console by using the macros from ttydefaults.h
  * init - add the possiblity to ignore further interrupts from keyboard
  * init - add the possiblity to set sane terminal line settings
This commit is contained in:
Werner Fink 2010-02-26 13:45:49 +00:00
parent 1107f3ba7d
commit d80bb06fec
3 changed files with 136 additions and 28 deletions

View File

@ -13,6 +13,10 @@
* Retry to write out shutdown messages if interrupted. * Retry to write out shutdown messages if interrupted.
* pidof/killall5 - make omit pid list a dynamic one. * pidof/killall5 - make omit pid list a dynamic one.
* pidof - provide '-n' to skip stat(2) syscall on network based FS. * pidof - provide '-n' to skip stat(2) syscall on network based FS.
* init - avoid compiler warnings
* init - initialize console by using the macros from ttydefaults.h
* init - add the possiblity to ignore further interrupts from keyboard
* init - add the possiblity to set sane terminal line settings
sysvinit (2.88dsf) UNRELEASED; urgency=low sysvinit (2.88dsf) UNRELEASED; urgency=low

View File

@ -66,6 +66,7 @@ char *progname;
extern int ifdown(void); extern int ifdown(void);
extern int hddown(void); extern int hddown(void);
extern int hdflush(void);
extern void write_wtmp(char *user, char *id, int pid, int type, char *line); extern void write_wtmp(char *user, char *id, int pid, int type, char *line);
/* /*

View File

@ -58,12 +58,14 @@
#ifdef __i386__ #ifdef __i386__
# if (__GLIBC__ >= 2) # ifdef __GLIBC__
/* GNU libc 2.x */ /* GNU libc 2.x */
# define STACK_DEBUG 1 # define STACK_DEBUG 1
# if (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0) # if (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
/* Only glibc 2.0 needs this */ /* Only glibc 2.0 needs this */
# include <sigcontext.h> # include <sigcontext.h>
# elif ( __GLIBC__ > 2) && ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 1))
# include <bits/sigcontext.h>
# endif # endif
# endif # endif
#endif #endif
@ -216,6 +218,7 @@ char *extra_env[NR_EXTRA_ENV];
* This only works correctly because the linux select updates * This only works correctly because the linux select updates
* the elapsed time in the struct timeval passed to select! * the elapsed time in the struct timeval passed to select!
*/ */
static
void do_sleep(int sec) void do_sleep(int sec)
{ {
struct timeval tv; struct timeval tv;
@ -231,6 +234,7 @@ void do_sleep(int sec)
/* /*
* Non-failing allocation routines (init cannot fail). * Non-failing allocation routines (init cannot fail).
*/ */
static
void *imalloc(size_t size) void *imalloc(size_t size)
{ {
void *m; void *m;
@ -243,7 +247,7 @@ void *imalloc(size_t size)
return m; return m;
} }
static
char *istrdup(char *s) char *istrdup(char *s)
{ {
char *m; char *m;
@ -260,6 +264,7 @@ char *istrdup(char *s)
* Send the state info of the previous running init to * Send the state info of the previous running init to
* the new one, in a version-independant way. * the new one, in a version-independant way.
*/ */
static
void send_state(int fd) void send_state(int fd)
{ {
FILE *fp; FILE *fp;
@ -452,6 +457,7 @@ static CHILD *get_record(FILE *f)
* Read the complete state info from the state pipe. * Read the complete state info from the state pipe.
* Returns 0 on success * Returns 0 on success
*/ */
static
int receive_state(int fd) int receive_state(int fd)
{ {
FILE *f; FILE *f;
@ -499,6 +505,7 @@ static int setproctitle(char *fmt, ...)
/* /*
* Set console_dev to a working console. * Set console_dev to a working console.
*/ */
static
void console_init(void) void console_init(void)
{ {
int fd; int fd;
@ -536,6 +543,7 @@ void console_init(void)
/* /*
* Open the console with retries. * Open the console with retries.
*/ */
static
int console_open(int mode) int console_open(int mode)
{ {
int f, fd = -1; int f, fd = -1;
@ -567,6 +575,7 @@ int console_open(int mode)
/* /*
* We got a signal (HUP PWR WINCH ALRM INT) * We got a signal (HUP PWR WINCH ALRM INT)
*/ */
static
void signal_handler(int sig) void signal_handler(int sig)
{ {
ADDSET(got_signals, sig); ADDSET(got_signals, sig);
@ -575,7 +584,12 @@ void signal_handler(int sig)
/* /*
* SIGCHLD: one of our children has died. * SIGCHLD: one of our children has died.
*/ */
void chld_handler() static
# ifdef __GNUC__
void chld_handler(int sig __attribute__((unused)))
# else
void chld_handler(int sig)
# endif
{ {
CHILD *ch; CHILD *ch;
int pid, st; int pid, st;
@ -615,7 +629,12 @@ void chld_handler()
* *
* The SIGCONT handler * The SIGCONT handler
*/ */
void cont_handler() static
# ifdef __GNUC__
void cont_handler(int sig __attribute__((unused)))
# else
void cont_handler(int sig)
# endif
{ {
got_cont = 1; got_cont = 1;
} }
@ -623,6 +642,7 @@ void cont_handler()
/* /*
* Fork and dump core in /. * Fork and dump core in /.
*/ */
static
void coredump(void) void coredump(void)
{ {
static int dumped = 0; static int dumped = 0;
@ -656,8 +676,13 @@ void coredump(void)
* If we have the info, print where it occured. * If we have the info, print where it occured.
* Then sleep 30 seconds and try to continue. * Then sleep 30 seconds and try to continue.
*/ */
static
#if defined(STACK_DEBUG) && defined(__linux__) #if defined(STACK_DEBUG) && defined(__linux__)
# ifdef __GNUC__
void segv_handler(int sig __attribute__((unused)), struct sigcontext ctx)
# else
void segv_handler(int sig, struct sigcontext ctx) void segv_handler(int sig, struct sigcontext ctx)
# endif
{ {
char *p = ""; char *p = "";
int saved_errno = errno; int saved_errno = errno;
@ -672,7 +697,11 @@ void segv_handler(int sig, struct sigcontext ctx)
errno = saved_errno; errno = saved_errno;
} }
#else #else
void segv_handler() # ifdef __GNUC__
void segv_handler(int sig __attribute__((unused)))
# else
void segv_handler(int sig)
# endif
{ {
int saved_errno = errno; int saved_errno = errno;
@ -687,7 +716,12 @@ void segv_handler()
/* /*
* The SIGSTOP & SIGTSTP handler * The SIGSTOP & SIGTSTP handler
*/ */
void stop_handler() static
# ifdef __GNUC__
void stop_handler(int sig __attribute__((unused)))
# else
void stop_handler(int sig)
# endif
{ {
int saved_errno = errno; int saved_errno = errno;
@ -700,6 +734,7 @@ void stop_handler()
/* /*
* Set terminal settings to reasonable defaults * Set terminal settings to reasonable defaults
*/ */
static
void console_stty(void) void console_stty(void)
{ {
struct termios tty; struct termios tty;
@ -715,28 +750,43 @@ void console_stty(void)
tty.c_cflag &= CBAUD|CBAUDEX|CSIZE|CSTOPB|PARENB|PARODD; tty.c_cflag &= CBAUD|CBAUDEX|CSIZE|CSTOPB|PARENB|PARODD;
tty.c_cflag |= HUPCL|CLOCAL|CREAD; tty.c_cflag |= HUPCL|CLOCAL|CREAD;
tty.c_cc[VINTR] = 3; /* ctrl('c') */ tty.c_cc[VINTR] = CINTR;
tty.c_cc[VQUIT] = 28; /* ctrl('\\') */ tty.c_cc[VQUIT] = CQUIT;
tty.c_cc[VERASE] = 127; tty.c_cc[VERASE] = CERASE; /* ASCII DEL (0177) */
tty.c_cc[VKILL] = 24; /* ctrl('x') */ tty.c_cc[VKILL] = CKILL;
tty.c_cc[VEOF] = 4; /* ctrl('d') */ tty.c_cc[VEOF] = CEOF;
tty.c_cc[VTIME] = 0; tty.c_cc[VTIME] = 0;
tty.c_cc[VMIN] = 1; tty.c_cc[VMIN] = 1;
tty.c_cc[VSTART] = 17; /* ctrl('q') */ tty.c_cc[VSWTC] = _POSIX_VDISABLE;
tty.c_cc[VSTOP] = 19; /* ctrl('s') */ tty.c_cc[VSTART] = CSTART;
tty.c_cc[VSUSP] = 26; /* ctrl('z') */ 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 * Set pre and post processing
*/ */
tty.c_iflag = IGNPAR|ICRNL|IXON|IXANY tty.c_iflag = IGNPAR|ICRNL|IXON|IXANY;
#ifdef IUTF8 /* Not defined on FreeBSD */ #ifdef IUTF8 /* Not defined on FreeBSD */
| (tty.c_iflag & IUTF8) tty.c_iflag |= IUTF8;
#endif /* IUTF8 */ #endif /* IUTF8 */
;
tty.c_oflag = OPOST|ONLCR; tty.c_oflag = OPOST|ONLCR;
tty.c_lflag = ISIG|ICANON|ECHO|ECHOCTL|ECHOPRT|ECHOKE; tty.c_lflag = ISIG|ICANON|ECHO|ECHOCTL|ECHOPRT|ECHOKE;
#if defined(SANE_TIO) && (SANE_TIO == 1)
/*
* Disable 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);
#endif
/* /*
* Now set the terminal line. * Now set the terminal line.
* We don't care about non-transmitted output data * We don't care about non-transmitted output data
@ -808,6 +858,7 @@ char **init_buildenv(int child)
char i_lvl[] = "RUNLEVEL=x"; char i_lvl[] = "RUNLEVEL=x";
char i_prev[] = "PREVLEVEL=x"; char i_prev[] = "PREVLEVEL=x";
char i_cons[32]; char i_cons[32];
char i_shell[] = "SHELL=" SHELL;
char **e; char **e;
int n, i; int n, i;
@ -827,6 +878,7 @@ char **init_buildenv(int child)
snprintf(i_cons, sizeof(i_cons), "CONSOLE=%s", console_dev); snprintf(i_cons, sizeof(i_cons), "CONSOLE=%s", console_dev);
i_lvl[9] = thislevel; i_lvl[9] = thislevel;
i_prev[10] = prevlevel; i_prev[10] = prevlevel;
e[n++] = istrdup(i_shell);
e[n++] = istrdup(i_lvl); e[n++] = istrdup(i_lvl);
e[n++] = istrdup(i_prev); e[n++] = istrdup(i_prev);
e[n++] = istrdup(i_cons); e[n++] = istrdup(i_cons);
@ -855,6 +907,7 @@ void init_freeenv(char **e)
* This function is too long and indents too deep. * This function is too long and indents too deep.
* *
*/ */
static
int spawn(CHILD *ch, int *res) int spawn(CHILD *ch, int *res)
{ {
char *args[16]; /* Argv array */ char *args[16]; /* Argv array */
@ -1121,6 +1174,7 @@ int spawn(CHILD *ch, int *res)
/* /*
* Start a child running! * Start a child running!
*/ */
static
void startup(CHILD *ch) void startup(CHILD *ch)
{ {
/* /*
@ -1155,6 +1209,7 @@ void startup(CHILD *ch)
/* /*
* Read the inittab file. * Read the inittab file.
*/ */
static
void read_inittab(void) void read_inittab(void)
{ {
FILE *fp; /* The INITTAB file */ FILE *fp; /* The INITTAB file */
@ -1535,6 +1590,7 @@ void read_inittab(void)
* The entries that do not belong here at all are removed * The entries that do not belong here at all are removed
* from the list. * from the list.
*/ */
static
void start_if_needed(void) void start_if_needed(void)
{ {
CHILD *ch; /* Pointer to child */ CHILD *ch; /* Pointer to child */
@ -1580,6 +1636,7 @@ void start_if_needed(void)
/* /*
* Ask the user on the console for a runlevel * Ask the user on the console for a runlevel
*/ */
static
int ask_runlevel(void) int ask_runlevel(void)
{ {
const char prompt[] = "\nEnter runlevel: "; const char prompt[] = "\nEnter runlevel: ";
@ -1608,6 +1665,7 @@ int ask_runlevel(void)
* Search the INITTAB file for the 'initdefault' field, with the default * Search the INITTAB file for the 'initdefault' field, with the default
* runlevel. If this fails, ask the user to supply a runlevel. * runlevel. If this fails, ask the user to supply a runlevel.
*/ */
static
int get_init_default(void) int get_init_default(void)
{ {
CHILD *ch; CHILD *ch;
@ -1656,6 +1714,7 @@ int get_init_default(void)
* the "old" INITLVL and arg == 0, try to read the new * the "old" INITLVL and arg == 0, try to read the new
* runlevel from that file first. * runlevel from that file first.
*/ */
static
int read_level(int arg) int read_level(int arg)
{ {
CHILD *ch; /* Walk through list */ CHILD *ch; /* Walk through list */
@ -1724,7 +1783,14 @@ int read_level(int arg)
initlog(L_VB, "Switching to runlevel: %c", foo); initlog(L_VB, "Switching to runlevel: %c", foo);
} }
if (foo == 'Q') return runlevel; if (foo == 'Q') {
#if defined(SIGINT_ONLYONCE) && (SIGINT_ONLYONCE == 1)
/* Re-enable signal from keyboard */
struct sigaction sa;
SETSIG(sa, SIGINT, signal_handler, 0);
#endif
return runlevel;
}
/* Check if this is a runlevel a, b or c */ /* Check if this is a runlevel a, b or c */
if (strchr("ABC", foo)) { if (strchr("ABC", foo)) {
@ -1763,6 +1829,7 @@ int read_level(int arg)
* longer than 5 minutes, or inittab was read again due * longer than 5 minutes, or inittab was read again due
* to user interaction. * to user interaction.
*/ */
static
void fail_check(void) void fail_check(void)
{ {
CHILD *ch; /* Pointer to child structure */ CHILD *ch; /* Pointer to child structure */
@ -1795,6 +1862,7 @@ void fail_check(void)
} }
/* Set all 'Fail' timers to 0 */ /* Set all 'Fail' timers to 0 */
static
void fail_cancel(void) void fail_cancel(void)
{ {
CHILD *ch; CHILD *ch;
@ -1809,6 +1877,7 @@ void fail_cancel(void)
/* /*
* Start up powerfail entries. * Start up powerfail entries.
*/ */
static
void do_power_fail(int pwrstat) void do_power_fail(int pwrstat)
{ {
CHILD *ch; CHILD *ch;
@ -1842,6 +1911,7 @@ void do_power_fail(int pwrstat)
/* /*
* Check for state-pipe presence * Check for state-pipe presence
*/ */
static
int check_pipe(int fd) int check_pipe(int fd)
{ {
struct timeval t; struct timeval t;
@ -1862,6 +1932,7 @@ int check_pipe(int fd)
/* /*
* Make a state-pipe. * Make a state-pipe.
*/ */
static
int make_pipe(int fd) int make_pipe(int fd)
{ {
int fds[2]; int fds[2];
@ -1879,6 +1950,7 @@ int make_pipe(int fd)
/* /*
* Attempt to re-exec. * Attempt to re-exec.
*/ */
static
void re_exec(void) void re_exec(void)
{ {
CHILD *ch; CHILD *ch;
@ -1973,6 +2045,7 @@ void redo_utmp_wtmp(void)
* We got a change runlevel request through the * We got a change runlevel request through the
* init.fifo. Process it. * init.fifo. Process it.
*/ */
static
void fifo_new_level(int level) void fifo_new_level(int level)
{ {
#if CHANGE_WAIT #if CHANGE_WAIT
@ -2002,7 +2075,7 @@ void fifo_new_level(int level)
if (runlevel > '1' && runlevel < '6') redo_utmp_wtmp(); if (runlevel > '1' && runlevel < '6') redo_utmp_wtmp();
read_inittab(); read_inittab();
fail_cancel(); fail_cancel();
setproctitle("init [%c]", runlevel); setproctitle("init [%c]", (int)runlevel);
} }
} }
} }
@ -2013,6 +2086,7 @@ void fifo_new_level(int level)
* encoded as KEY=VAL\0KEY=VAL\0\0. With "=VAL" it means * encoded as KEY=VAL\0KEY=VAL\0\0. With "=VAL" it means
* setenv, without it means unsetenv. * setenv, without it means unsetenv.
*/ */
static
void initcmd_setenv(char *data, int size) void initcmd_setenv(char *data, int size)
{ {
char *env, *p, *e, *eq; char *env, *p, *e, *eq;
@ -2070,6 +2144,7 @@ void initcmd_setenv(char *data, int size)
* the 2.2 kernel credential stuff to see who we're talking to. * the 2.2 kernel credential stuff to see who we're talking to.
* *
*/ */
static
void check_init_fifo(void) void check_init_fifo(void)
{ {
struct init_request request; struct init_request request;
@ -2212,6 +2287,7 @@ void check_init_fifo(void)
* This function is used in the transition * This function is used in the transition
* sysinit (-> single user) boot -> multi-user. * sysinit (-> single user) boot -> multi-user.
*/ */
static
void boot_transitions() void boot_transitions()
{ {
CHILD *ch; CHILD *ch;
@ -2288,7 +2364,7 @@ void boot_transitions()
write_utmp_wtmp("runlevel", "~~", runlevel + 256 * oldlevel, RUN_LVL, "~"); write_utmp_wtmp("runlevel", "~~", runlevel + 256 * oldlevel, RUN_LVL, "~");
thislevel = runlevel; thislevel = runlevel;
prevlevel = oldlevel; prevlevel = oldlevel;
setproctitle("init [%c]", runlevel); setproctitle("init [%c]", (int)runlevel);
} }
} }
} }
@ -2297,6 +2373,7 @@ void boot_transitions()
* Init got hit by a signal. See which signal it is, * Init got hit by a signal. See which signal it is,
* and act accordingly. * and act accordingly.
*/ */
static
void process_signals() void process_signals()
{ {
CHILD *ch; CHILD *ch;
@ -2321,6 +2398,11 @@ void process_signals()
} }
if (ISMEMBER(got_signals, SIGINT)) { if (ISMEMBER(got_signals, SIGINT)) {
#if defined(SIGINT_ONLYONCE) && (SIGINT_ONLYONCE == 1)
/* Ignore any further signal from keyboard */
struct sigaction sa;
SETSIG(sa, SIGINT, SIG_IGN, SA_RESTART);
#endif
INITDBG(L_VB, "got SIGINT"); INITDBG(L_VB, "got SIGINT");
/* Tell ctrlaltdel entry to start up */ /* Tell ctrlaltdel entry to start up */
for(ch = family; ch; ch = ch->next) for(ch = family; ch; ch = ch->next)
@ -2383,7 +2465,7 @@ void process_signals()
runlevel == '1') console_stty(); runlevel == '1') console_stty();
read_inittab(); read_inittab();
fail_cancel(); fail_cancel();
setproctitle("init [%c]", runlevel); setproctitle("init [%c]", (int)runlevel);
DELSET(got_signals, SIGHUP); DELSET(got_signals, SIGHUP);
} }
} }
@ -2402,7 +2484,8 @@ void process_signals()
/* /*
* The main loop * The main loop
*/ */
int init_main() static
void init_main(void)
{ {
CHILD *ch; CHILD *ch;
struct sigaction sa; struct sigaction sa;
@ -2562,12 +2645,14 @@ int init_main()
/* /*
* Tell the user about the syntax we expect. * Tell the user about the syntax we expect.
*/ */
static
void usage(char *s) void usage(char *s)
{ {
fprintf(stderr, "Usage: %s {-e VAR[=VAL] | [-t SECONDS] {0|1|2|3|4|5|6|S|s|Q|q|A|a|B|b|C|c|U|u}}\n", s); fprintf(stderr, "Usage: %s {-e VAR[=VAL] | [-t SECONDS] {0|1|2|3|4|5|6|S|s|Q|q|A|a|B|b|C|c|U|u}}\n", s);
exit(1); exit(1);
} }
static
int telinit(char *progname, int argc, char **argv) int telinit(char *progname, int argc, char **argv)
{ {
#ifdef TELINIT_USES_INITLVL #ifdef TELINIT_USES_INITLVL
@ -2619,12 +2704,28 @@ int telinit(char *progname, int argc, char **argv)
request.sleeptime = sltime; request.sleeptime = sltime;
} }
/* Change to the root directory. */
chdir("/");
/* Open the fifo and write a command. */ /* Open the fifo and write a command. */
/* Make sure we don't hang on opening /dev/initctl */ /* Make sure we don't hang on opening /dev/initctl */
SETSIG(sa, SIGALRM, signal_handler, 0); SETSIG(sa, SIGALRM, signal_handler, 0);
alarm(3); alarm(3);
if ((fd = open(INIT_FIFO, O_WRONLY)) >= 0 && if ((fd = open(INIT_FIFO, O_WRONLY)) >= 0) {
write(fd, &request, sizeof(request)) == sizeof(request)) { 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); close(fd);
alarm(0); alarm(0);
return 0; return 0;
@ -2677,6 +2778,8 @@ int main(int argc, char **argv)
p++; p++;
else else
p = argv[0]; p = argv[0];
/* Common umask */
umask(022); umask(022);
/* Quick check */ /* Quick check */
@ -2710,7 +2813,7 @@ int main(int argc, char **argv)
for (f = 0; f < argc; f++) for (f = 0; f < argc; f++)
maxproclen += strlen(argv[f]) + 1; maxproclen += strlen(argv[f]) + 1;
reload = 1; reload = 1;
setproctitle("init [%c]",runlevel); setproctitle("init [%c]", (int)runlevel);
init_main(); init_main();
} }
@ -2754,7 +2857,7 @@ int main(int argc, char **argv)
argv0 = argv[0]; argv0 = argv[0];
argv[1] = NULL; argv[1] = NULL;
setproctitle("init boot"); setproctitle("init boot");
init_main(dfl_level); init_main();
/*NOTREACHED*/ /*NOTREACHED*/
return 0; return 0;