Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/init/init.c


Ignore:
Timestamp:
Feb 25, 2011, 9:26:54 PM (13 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.18.3 to avoid problems with the tar command which is now failing on recent versions with busybox 1.7.3
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.9/mindi-busybox/init/init.c

    r1765 r2725  
    77 * Adjusted by so many folks, it's impossible to keep track.
    88 *
    9  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
     9 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    1010 */
    1111
     12//applet:IF_INIT(APPLET(init, _BB_DIR_SBIN, _BB_SUID_DROP))
     13//applet:IF_FEATURE_INITRD(APPLET_ODDNAME(linuxrc, init, _BB_DIR_ROOT, _BB_SUID_DROP, linuxrc))
     14
     15//kbuild:lib-$(CONFIG_INIT) += init.o
     16
     17//config:config INIT
     18//config:   bool "init"
     19//config:   default y
     20//config:   select FEATURE_SYSLOG
     21//config:   help
     22//config:     init is the first program run when the system boots.
     23//config:
     24//config:config FEATURE_USE_INITTAB
     25//config:   bool "Support reading an inittab file"
     26//config:   default y
     27//config:   depends on INIT
     28//config:   help
     29//config:     Allow init to read an inittab file when the system boot.
     30//config:
     31//config:config FEATURE_KILL_REMOVED
     32//config:   bool "Support killing processes that have been removed from inittab"
     33//config:   default n
     34//config:   depends on FEATURE_USE_INITTAB
     35//config:   help
     36//config:     When respawn entries are removed from inittab and a SIGHUP is
     37//config:     sent to init, this option will make init kill the processes
     38//config:     that have been removed.
     39//config:
     40//config:config FEATURE_KILL_DELAY
     41//config:   int "How long to wait between TERM and KILL (0 - send TERM only)" if FEATURE_KILL_REMOVED
     42//config:   range 0 1024
     43//config:   default 0
     44//config:   depends on FEATURE_KILL_REMOVED
     45//config:   help
     46//config:     With nonzero setting, init sends TERM, forks, child waits N
     47//config:     seconds, sends KILL and exits. Setting it too high is unwise
     48//config:     (child will hang around for too long and could actually kill
     49//config:     the wrong process!)
     50//config:
     51//config:config FEATURE_INIT_SCTTY
     52//config:   bool "Run commands with leading dash with controlling tty"
     53//config:   default y
     54//config:   depends on INIT
     55//config:   help
     56//config:     If this option is enabled, init will try to give a controlling
     57//config:     tty to any command which has leading hyphen (often it's "-/bin/sh").
     58//config:     More precisely, init will do "ioctl(STDIN_FILENO, TIOCSCTTY, 0)".
     59//config:     If device attached to STDIN_FILENO can be a ctty but is not yet
     60//config:     a ctty for other session, it will become this process' ctty.
     61//config:     This is not the traditional init behavour, but is often what you want
     62//config:     in an embedded system where the console is only accessed during
     63//config:     development or for maintenance.
     64//config:     NB: using cttyhack applet may work better.
     65//config:
     66//config:config FEATURE_INIT_SYSLOG
     67//config:   bool "Enable init to write to syslog"
     68//config:   default y
     69//config:   depends on INIT
     70//config:
     71//config:config FEATURE_EXTRA_QUIET
     72//config:   bool "Be _extra_ quiet on boot"
     73//config:   default y
     74//config:   depends on INIT
     75//config:   help
     76//config:     Prevent init from logging some messages to the console during boot.
     77//config:
     78//config:config FEATURE_INIT_COREDUMPS
     79//config:   bool "Support dumping core for child processes (debugging only)"
     80//config:   default y
     81//config:   depends on INIT
     82//config:   help
     83//config:     If this option is enabled and the file /.init_enable_core
     84//config:     exists, then init will call setrlimit() to allow unlimited
     85//config:     core file sizes. If this option is disabled, processes
     86//config:     will not generate any core files.
     87//config:
     88//config:config FEATURE_INITRD
     89//config:   bool "Support running init from within an initrd (not initramfs)"
     90//config:   default y
     91//config:   depends on INIT
     92//config:   help
     93//config:     Legacy support for running init under the old-style initrd. Allows
     94//config:     the name linuxrc to act as init, and it doesn't assume init is PID 1.
     95//config:
     96//config:     This does not apply to initramfs, which runs /init as PID 1 and
     97//config:     requires no special support.
     98//config:
     99//config:config INIT_TERMINAL_TYPE
     100//config:   string "Initial terminal type"
     101//config:   default "linux"
     102//config:   depends on INIT
     103//config:   help
     104//config:     This is the initial value set by init for the TERM environment
     105//config:     variable. This variable is used by programs which make use of
     106//config:     extended terminal capabilities.
     107//config:
     108//config:     Note that on Linux, init attempts to detect serial terminal and
     109//config:     sets TERM to "vt102" if one is found.
     110
    12111#include "libbb.h"
     112#include <syslog.h>
    13113#include <paths.h>
    14 //#include <signal.h>
    15 //#include <sys/ioctl.h>
    16 //#include <sys/wait.h>
    17 #include <sys/reboot.h>
    18 
    19 #if ENABLE_FEATURE_INIT_SYSLOG
    20 # include <sys/syslog.h>
    21 #endif
    22 
    23 #define INIT_BUFFS_SIZE 256
     114#include <sys/resource.h>
     115#ifdef __linux__
     116#include <linux/vt.h>
     117#endif
     118#if ENABLE_FEATURE_UTMP
     119# include <utmp.h> /* DEAD_PROCESS */
     120#endif
     121#include "reboot.h" /* reboot() constants */
     122
     123/* Used only for sanitizing purposes in set_sane_term() below. On systems where
     124 * the baud rate is stored in a separate field, we can safely disable them. */
     125#ifndef CBAUD
     126# define CBAUD 0
     127# define CBAUDEX 0
     128#endif
     129
     130/* Was a CONFIG_xxx option. A lot of people were building
     131 * not fully functional init by switching it on! */
     132#define DEBUG_INIT 0
     133
     134#define COMMAND_SIZE      256
    24135#define CONSOLE_NAME_SIZE 32
    25 #define MAXENV  16      /* Number of env. vars */
    26 
    27 #if ENABLE_FEATURE_INIT_COREDUMPS
     136
     137/* Default sysinit script. */
     138#ifndef INIT_SCRIPT
     139#define INIT_SCRIPT  "/etc/init.d/rcS"
     140#endif
     141
     142/* Each type of actions can appear many times. They will be
     143 * handled in order. RESTART is an exception, only 1st is used.
     144 */
     145/* Start these actions first and wait for completion */
     146#define SYSINIT     0x01
     147/* Start these after SYSINIT and wait for completion */
     148#define WAIT        0x02
     149/* Start these after WAIT and *dont* wait for completion */
     150#define ONCE        0x04
    28151/*
    29  * When a file named CORE_ENABLE_FLAG_FILE exists, setrlimit is called
    30  * before processes are spawned to set core file size as unlimited.
    31  * This is for debugging only.  Don't use this is production, unless
    32  * you want core dumps lying about....
     152 * NB: while SYSINIT/WAIT/ONCE are being processed,
     153 * SIGHUP ("reread /etc/inittab") will be processed only after
     154 * each group of actions. If new inittab adds, say, a SYSINIT action,
     155 * it will not be run, since init is already "past SYSINIT stage".
    33156 */
    34 #define CORE_ENABLE_FLAG_FILE "/.init_enable_core"
    35 #include <sys/resource.h>
    36 #endif
    37 
    38 #define INITTAB      "/etc/inittab" /* inittab file location */
    39 #ifndef INIT_SCRIPT
    40 #define INIT_SCRIPT  "/etc/init.d/rcS"  /* Default sysinit script. */
    41 #endif
    42 
    43 /* Allowed init action types */
    44 #define SYSINIT     0x001
    45 #define RESPAWN     0x002
    46 #define ASKFIRST    0x004
    47 #define WAIT        0x008
    48 #define ONCE        0x010
    49 #define CTRLALTDEL  0x020
    50 #define SHUTDOWN    0x040
    51 #define RESTART     0x080
    52 
    53 /* A mapping between "inittab" action name strings and action type codes. */
    54 struct init_action_type {
    55     const char *name;
    56     int action;
    57 };
    58 
    59 static const struct init_action_type actions[] = {
    60     {"sysinit", SYSINIT},
    61     {"respawn", RESPAWN},
    62     {"askfirst", ASKFIRST},
    63     {"wait", WAIT},
    64     {"once", ONCE},
    65     {"ctrlaltdel", CTRLALTDEL},
    66     {"shutdown", SHUTDOWN},
    67     {"restart", RESTART},
    68     {0, 0}
    69 };
    70 
    71 /* Set up a linked list of init_actions, to be read from inittab */
     157/* Start these after ONCE are started, restart on exit */
     158#define RESPAWN     0x08
     159/* Like RESPAWN, but wait for <Enter> to be pressed on tty */
     160#define ASKFIRST    0x10
     161/*
     162 * Start these on SIGINT, and wait for completion.
     163 * Then go back to respawning RESPAWN and ASKFIRST actions.
     164 * NB: kernel sends SIGINT to us if Ctrl-Alt-Del was pressed.
     165 */
     166#define CTRLALTDEL  0x20
     167/*
     168 * Start these before killing all processes in preparation for
     169 * running RESTART actions or doing low-level halt/reboot/poweroff
     170 * (initiated by SIGUSR1/SIGTERM/SIGUSR2).
     171 * Wait for completion before proceeding.
     172 */
     173#define SHUTDOWN    0x40
     174/*
     175 * exec() on SIGQUIT. SHUTDOWN actions are started and waited for,
     176 * then all processes are killed, then init exec's 1st RESTART action,
     177 * replacing itself by it. If no RESTART action specified,
     178 * SIGQUIT has no effect.
     179 */
     180#define RESTART     0x80
     181
     182
     183/* A linked list of init_actions, to be read from inittab */
    72184struct init_action {
    73185    struct init_action *next;
    74     int action;
    75186    pid_t pid;
    76     char command[INIT_BUFFS_SIZE];
     187    uint8_t action_type;
    77188    char terminal[CONSOLE_NAME_SIZE];
     189    char command[COMMAND_SIZE];
    78190};
    79191
    80 /* Static variables */
    81192static struct init_action *init_action_list = NULL;
    82193
    83 #if !ENABLE_FEATURE_INIT_SYSLOG
    84194static const char *log_console = VC_5;
    85 #endif
    86 #if !ENABLE_DEBUG_INIT
    87 static sig_atomic_t got_cont = 0;
    88 #endif
    89195
    90196enum {
    91197    L_LOG = 0x1,
    92198    L_CONSOLE = 0x2,
    93 
    94 #if ENABLE_FEATURE_EXTRA_QUIET
    95     MAYBE_CONSOLE = 0x0,
    96 #else
    97     MAYBE_CONSOLE = L_CONSOLE,
    98 #endif
    99 
    100 #ifndef RB_HALT_SYSTEM
    101     RB_HALT_SYSTEM = 0xcdef0123, /* FIXME: this overflows enum */
    102     RB_ENABLE_CAD = 0x89abcdef,
    103     RB_DISABLE_CAD = 0,
    104     RB_POWER_OFF = 0x4321fedc,
    105     RB_AUTOBOOT = 0x01234567,
    106 #endif
    107199};
    108200
    109 static const char *const environment[] = {
    110     "HOME=/",
    111     bb_PATH_root_path,
    112     "SHELL=/bin/sh",
    113     "USER=root",
    114     NULL
    115 };
    116 
    117 /* Function prototypes */
    118 static void delete_init_action(struct init_action *a);
    119 static int waitfor(const struct init_action *a, pid_t pid);
    120 #if !ENABLE_DEBUG_INIT
    121 static void shutdown_signal(int sig);
    122 #endif
    123 
    124 #if !ENABLE_DEBUG_INIT
    125 static void loop_forever(void)
    126 {
    127     while (1)
    128         sleep(1);
    129 }
    130 #endif
    131 
    132201/* Print a message to the specified device.
    133  * Device may be bitwise-or'd from L_LOG | L_CONSOLE */
    134 #if ENABLE_DEBUG_INIT
    135 #define messageD message
    136 #else
    137 #define messageD(...)  do {} while (0)
    138 #endif
    139 static void message(int device, const char *fmt, ...)
     202 * "where" may be bitwise-or'd from L_LOG | L_CONSOLE
     203 * NB: careful, we can be called after vfork!
     204 */
     205#define dbg_message(...) do { if (DEBUG_INIT) message(__VA_ARGS__); } while (0)
     206static void message(int where, const char *fmt, ...)
    140207    __attribute__ ((format(printf, 2, 3)));
    141 static void message(int device, const char *fmt, ...)
    142 {
    143 #if !ENABLE_FEATURE_INIT_SYSLOG
    144     static int log_fd = -1;
    145 #endif
    146 
     208static void message(int where, const char *fmt, ...)
     209{
    147210    va_list arguments;
    148     int l;
     211    unsigned l;
    149212    char msg[128];
    150213
    151214    msg[0] = '\r';
    152215    va_start(arguments, fmt);
    153     vsnprintf(msg + 1, sizeof(msg) - 2, fmt, arguments);
     216    l = 1 + vsnprintf(msg + 1, sizeof(msg) - 2, fmt, arguments);
     217    if (l > sizeof(msg) - 1)
     218        l = sizeof(msg) - 1;
    154219    va_end(arguments);
    155     msg[sizeof(msg) - 2] = '\0';
    156     l = strlen(msg);
    157220
    158221#if ENABLE_FEATURE_INIT_SYSLOG
    159     /* Log the message to syslogd */
    160     if (device & L_LOG) {
    161         /* don't out "\r" */
     222    msg[l] = '\0';
     223    if (where & L_LOG) {
     224        /* Log the message to syslogd */
    162225        openlog(applet_name, 0, LOG_DAEMON);
    163         syslog(LOG_INFO, "init: %s", msg + 1);
     226        /* don't print "\r" */
     227        syslog(LOG_INFO, "%s", msg + 1);
    164228        closelog();
    165229    }
     
    167231    msg[l] = '\0';
    168232#else
    169     msg[l++] = '\n';
    170     msg[l] = '\0';
    171     /* Take full control of the log tty, and never close it.
    172      * It's mine, all mine!  Muhahahaha! */
    173     if (log_fd < 0) {
    174         if (!log_console) {
    175             log_fd = 2;
    176         } else {
    177             log_fd = device_open(log_console, O_WRONLY | O_NONBLOCK | O_NOCTTY);
    178             if (log_fd < 0) {
    179                 bb_error_msg("can't log to %s", log_console);
    180                 device = L_CONSOLE;
     233    {
     234        static int log_fd = -1;
     235
     236        msg[l++] = '\n';
     237        msg[l] = '\0';
     238        /* Take full control of the log tty, and never close it.
     239         * It's mine, all mine!  Muhahahaha! */
     240        if (log_fd < 0) {
     241            if (!log_console) {
     242                log_fd = STDERR_FILENO;
    181243            } else {
    182                 fcntl(log_fd, F_SETFD, FD_CLOEXEC);
     244                log_fd = device_open(log_console, O_WRONLY | O_NONBLOCK | O_NOCTTY);
     245                if (log_fd < 0) {
     246                    bb_error_msg("can't log to %s", log_console);
     247                    where = L_CONSOLE;
     248                } else {
     249                    close_on_exec_on(log_fd);
     250                }
    183251            }
    184252        }
    185     }
    186     if (device & L_LOG) {
    187         full_write(log_fd, msg, l);
    188         if (log_fd == 2)
    189             return; /* don't print dup messages */
    190     }
    191 #endif
    192 
    193     if (device & L_CONSOLE) {
     253        if (where & L_LOG) {
     254            full_write(log_fd, msg, l);
     255            if (log_fd == STDERR_FILENO)
     256                return; /* don't print dup messages */
     257        }
     258    }
     259#endif
     260
     261    if (where & L_CONSOLE) {
    194262        /* Send console messages to console so people will see them. */
    195         full_write(2, msg, l);
    196     }
    197 }
    198 
    199 /* Set terminal settings to reasonable defaults */
     263        full_write(STDERR_FILENO, msg, l);
     264    }
     265}
     266
     267static void console_init(void)
     268{
     269#ifdef VT_OPENQRY
     270    int vtno;
     271#endif
     272    char *s;
     273
     274    s = getenv("CONSOLE");
     275    if (!s)
     276        s = getenv("console");
     277    if (s) {
     278        int fd = open(s, O_RDWR | O_NONBLOCK | O_NOCTTY);
     279        if (fd >= 0) {
     280            dup2(fd, STDIN_FILENO);
     281            dup2(fd, STDOUT_FILENO);
     282            xmove_fd(fd, STDERR_FILENO);
     283        }
     284        dbg_message(L_LOG, "console='%s'", s);
     285    } else {
     286        /* Make sure fd 0,1,2 are not closed
     287         * (so that they won't be used by future opens) */
     288        bb_sanitize_stdio();
     289// Users report problems
     290//      /* Make sure init can't be blocked by writing to stderr */
     291//      fcntl(STDERR_FILENO, F_SETFL, fcntl(STDERR_FILENO, F_GETFL) | O_NONBLOCK);
     292    }
     293
     294    s = getenv("TERM");
     295#ifdef VT_OPENQRY
     296    if (ioctl(STDIN_FILENO, VT_OPENQRY, &vtno) != 0) {
     297        /* Not a linux terminal, probably serial console.
     298         * Force the TERM setting to vt102
     299         * if TERM is set to linux (the default) */
     300        if (!s || strcmp(s, "linux") == 0)
     301            putenv((char*)"TERM=vt102");
     302        if (!ENABLE_FEATURE_INIT_SYSLOG)
     303            log_console = NULL;
     304    } else
     305#endif
     306    if (!s)
     307        putenv((char*)"TERM=" CONFIG_INIT_TERMINAL_TYPE);
     308}
     309
     310/* Set terminal settings to reasonable defaults.
     311 * NB: careful, we can be called after vfork! */
    200312static void set_sane_term(void)
    201313{
     
    214326    tty.c_cc[VSUSP] = 26;   /* C-z */
    215327
    216     /* use line dicipline 0 */
     328#ifdef __linux__
     329    /* use line discipline 0 */
    217330    tty.c_line = 0;
     331#endif
    218332
    219333    /* Make it be sane */
    220     tty.c_cflag &= CBAUD | CBAUDEX | CSIZE | CSTOPB | PARENB | PARODD;
     334#ifndef CRTSCTS
     335# define CRTSCTS 0
     336#endif
     337    /* added CRTSCTS to fix Debian bug 528560 */
     338    tty.c_cflag &= CBAUD | CBAUDEX | CSIZE | CSTOPB | PARENB | PARODD | CRTSCTS;
    221339    tty.c_cflag |= CREAD | HUPCL | CLOCAL;
    222340
     
    228346
    229347    /* local modes */
    230     tty.c_lflag =
    231         ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN;
    232 
    233     tcsetattr(STDIN_FILENO, TCSANOW, &tty);
    234 }
    235 
    236 /* From <linux/serial.h> */
    237 struct serial_struct {
    238     int type;
    239     int line;
    240     unsigned int    port;
    241     int irq;
    242     int flags;
    243     int xmit_fifo_size;
    244     int custom_divisor;
    245     int baud_base;
    246     unsigned short  close_delay;
    247     char    io_type;
    248     char    reserved_char[1];
    249     int hub6;
    250     unsigned short  closing_wait; /* time to wait before closing */
    251     unsigned short  closing_wait2; /* no longer used... */
    252     unsigned char   *iomem_base;
    253     unsigned short  iomem_reg_shift;
    254     unsigned int    port_high;
    255     unsigned long   iomap_base; /* cookie passed into ioremap */
    256     int reserved[1];
    257     /* Paranoia (imagine 64bit kernel overwriting 32bit userspace stack) */
    258     uint32_t bbox_reserved[16];
    259 };
    260 static void console_init(void)
    261 {
    262     struct serial_struct sr;
    263     char *s;
    264 
    265     s = getenv("CONSOLE");
    266     if (!s) s = getenv("console");
    267     if (s) {
    268         int fd = open(s, O_RDWR | O_NONBLOCK | O_NOCTTY);
    269         if (fd >= 0) {
    270             dup2(fd, 0);
    271             dup2(fd, 1);
    272             dup2(fd, 2);
    273             while (fd > 2) close(fd--);
    274         }
    275         messageD(L_LOG, "console='%s'", s);
    276     } else {
    277         /* Make sure fd 0,1,2 are not closed */
    278         bb_sanitize_stdio();
    279     }
    280 
    281     s = getenv("TERM");
    282     if (ioctl(0, TIOCGSERIAL, &sr) == 0) {
    283         /* Force the TERM setting to vt102 for serial console --
    284          * if TERM is set to linux (the default) */
    285         if (!s || strcmp(s, "linux") == 0)
    286             putenv((char*)"TERM=vt102");
    287 #if !ENABLE_FEATURE_INIT_SYSLOG
    288         log_console = NULL;
    289 #endif
    290     } else if (!s)
    291         putenv((char*)"TERM=linux");
    292 }
    293 
    294 static void fixup_argv(char **argv)
    295 {
    296     /* Fix up argv[0] to be certain we claim to be init */
    297     strncpy(argv[0], "init", strlen(argv[0]));
    298 
    299     /* Wipe argv[1]-argv[N] so they don't clutter the ps listing */
    300     while (*++argv)
    301         memset(*argv, 0, strlen(*argv));
    302 }
    303 
    304 /* Open the new terminal device */
    305 static void open_stdio_to_tty(const char* tty_name, int fail)
     348    tty.c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN;
     349
     350    tcsetattr_stdin_TCSANOW(&tty);
     351}
     352
     353/* Open the new terminal device.
     354 * NB: careful, we can be called after vfork! */
     355static int open_stdio_to_tty(const char* tty_name)
    306356{
    307357    /* empty tty_name means "use init's tty", else... */
    308358    if (tty_name[0]) {
    309         int fd = device_open(tty_name, O_RDWR);
    310         if (fd < 0) {
    311             message(L_LOG | L_CONSOLE, "Can't open %s: %s",
     359        int fd;
     360
     361        close(STDIN_FILENO);
     362        /* fd can be only < 0 or 0: */
     363        fd = device_open(tty_name, O_RDWR);
     364        if (fd) {
     365            message(L_LOG | L_CONSOLE, "can't open %s: %s",
    312366                tty_name, strerror(errno));
    313             if (fail)
    314                 _exit(1);
    315 #if !ENABLE_DEBUG_INIT
    316             shutdown_signal(SIGUSR1);
    317 #else
    318             _exit(2);
    319 #endif
    320         } else {
    321             dup2(fd, 0);
    322             dup2(fd, 1);
    323             dup2(fd, 2);
    324             if (fd > 2) close(fd);
    325         }
     367            return 0; /* failure */
     368        }
     369        dup2(STDIN_FILENO, STDOUT_FILENO);
     370        dup2(STDIN_FILENO, STDERR_FILENO);
    326371    }
    327372    set_sane_term();
    328 }
    329 
    330 static pid_t run(const struct init_action *a)
    331 {
    332     int i;
    333     pid_t pid;
    334     char *s, *tmpCmd, *cmdpath;
    335     char *cmd[INIT_BUFFS_SIZE];
    336     char buf[INIT_BUFFS_SIZE + 6];  /* INIT_BUFFS_SIZE+strlen("exec ")+1 */
    337     sigset_t nmask, omask;
    338 
    339     /* Block sigchild while forking.  */
    340     sigemptyset(&nmask);
    341     sigaddset(&nmask, SIGCHLD);
    342     sigprocmask(SIG_BLOCK, &nmask, &omask);
    343     pid = fork();
    344     sigprocmask(SIG_SETMASK, &omask, NULL);
    345 
    346     if (pid)
    347         return pid;
    348 
    349     /* Reset signal handlers that were set by the parent process */
    350     signal(SIGUSR1, SIG_DFL);
    351     signal(SIGUSR2, SIG_DFL);
    352     signal(SIGINT, SIG_DFL);
    353     signal(SIGTERM, SIG_DFL);
    354     signal(SIGHUP, SIG_DFL);
    355     signal(SIGQUIT, SIG_DFL);
    356     signal(SIGCONT, SIG_DFL);
    357     signal(SIGSTOP, SIG_DFL);
    358     signal(SIGTSTP, SIG_DFL);
    359 
    360     /* Create a new session and make ourself the process
    361      * group leader */
    362     setsid();
    363 
    364     /* Open the new terminal device */
    365     open_stdio_to_tty(a->terminal, 1);
    366 
    367     /* If the init Action requires us to wait, then force the
    368      * supplied terminal to be the controlling tty. */
    369     if (a->action & (SYSINIT | WAIT | CTRLALTDEL | SHUTDOWN | RESTART)) {
    370 
    371         /* Now fork off another process to just hang around */
    372         if ((pid = fork()) < 0) {
    373             message(L_LOG | L_CONSOLE, "Can't fork");
    374             _exit(1);
    375         }
    376 
    377         if (pid > 0) {
    378 
    379             /* We are the parent -- wait till the child is done */
    380             signal(SIGINT, SIG_IGN);
    381             signal(SIGTSTP, SIG_IGN);
    382             signal(SIGQUIT, SIG_IGN);
    383             signal(SIGCHLD, SIG_DFL);
    384 
    385             waitfor(NULL, pid);
    386             /* See if stealing the controlling tty back is necessary */
    387             if (tcgetpgrp(0) != getpid())
    388                 _exit(0);
    389 
    390             /* Use a temporary process to steal the controlling tty. */
    391             if ((pid = fork()) < 0) {
    392                 message(L_LOG | L_CONSOLE, "Can't fork");
    393                 _exit(1);
    394             }
    395             if (pid == 0) {
    396                 setsid();
    397                 ioctl(0, TIOCSCTTY, 1);
    398                 _exit(0);
    399             }
    400             waitfor(NULL, pid);
    401             _exit(0);
    402         }
    403 
    404         /* Now fall though to actually execute things */
    405     }
     373    return 1; /* success */
     374}
     375
     376static void reset_sighandlers_and_unblock_sigs(void)
     377{
     378    bb_signals(0
     379        + (1 << SIGUSR1)
     380        + (1 << SIGUSR2)
     381        + (1 << SIGTERM)
     382        + (1 << SIGQUIT)
     383        + (1 << SIGINT)
     384        + (1 << SIGHUP)
     385        + (1 << SIGTSTP)
     386        + (1 << SIGSTOP)
     387        , SIG_DFL);
     388    sigprocmask_allsigs(SIG_UNBLOCK);
     389}
     390
     391/* Wrapper around exec:
     392 * Takes string (max COMMAND_SIZE chars).
     393 * If chars like '>' detected, execs '[-]/bin/sh -c "exec ......."'.
     394 * Otherwise splits words on whitespace, deals with leading dash,
     395 * and uses plain exec().
     396 * NB: careful, we can be called after vfork!
     397 */
     398static void init_exec(const char *command)
     399{
     400    char *cmd[COMMAND_SIZE / 2];
     401    char buf[COMMAND_SIZE + 6];  /* COMMAND_SIZE+strlen("exec ")+1 */
     402    int dash = (command[0] == '-' /* maybe? && command[1] == '/' */);
    406403
    407404    /* See if any special /bin/sh requiring characters are present */
    408     if (strpbrk(a->command, "~`!$^&*()=|\\{}[];\"'<>?") != NULL) {
    409         cmd[0] = (char*)DEFAULT_SHELL;
     405    if (strpbrk(command, "~`!$^&*()=|\\{}[];\"'<>?") != NULL) {
     406        strcpy(buf, "exec ");
     407        strcpy(buf + 5, command + dash); /* excluding "-" */
     408        /* NB: LIBBB_DEFAULT_LOGIN_SHELL define has leading dash */
     409        cmd[0] = (char*)(LIBBB_DEFAULT_LOGIN_SHELL + !dash);
    410410        cmd[1] = (char*)"-c";
    411         cmd[2] = strcat(strcpy(buf, "exec "), a->command);
     411        cmd[2] = buf;
    412412        cmd[3] = NULL;
    413413    } else {
    414414        /* Convert command (char*) into cmd (char**, one word per string) */
    415         strcpy(buf, a->command);
    416         s = buf;
    417         for (tmpCmd = buf, i = 0; (tmpCmd = strsep(&s, " \t")) != NULL;) {
    418             if (*tmpCmd != '\0') {
    419                 cmd[i] = tmpCmd;
     415        char *word, *next;
     416        int i = 0;
     417        next = strcpy(buf, command); /* including "-" */
     418        while ((word = strsep(&next, " \t")) != NULL) {
     419            if (*word != '\0') { /* not two spaces/tabs together? */
     420                cmd[i] = word;
    420421                i++;
    421422            }
     
    423424        cmd[i] = NULL;
    424425    }
    425 
    426     cmdpath = cmd[0];
    427 
    428     /*
    429      * Interactive shells want to see a dash in argv[0].  This
    430      * typically is handled by login, argv will be setup this
    431      * way if a dash appears at the front of the command path
    432      * (like "-/bin/sh").
    433      */
    434     if (*cmdpath == '-') {
    435         /* skip over the dash */
    436         ++cmdpath;
    437 
    438         /* find the last component in the command pathname */
    439         s = bb_get_last_path_component(cmdpath);
    440 
    441         /* make a new argv[0] */
    442         if ((cmd[0] = malloc(strlen(s) + 2)) == NULL) {
    443             message(L_LOG | L_CONSOLE, bb_msg_memory_exhausted);
    444             cmd[0] = cmdpath;
    445         } else {
    446             cmd[0][0] = '-';
    447             strcpy(cmd[0] + 1, s);
    448         }
    449 #if ENABLE_FEATURE_INIT_SCTTY
    450         /* Establish this process as session leader and
    451          * (attempt) to make the tty (if any) a controlling tty.
    452          */
    453         setsid();
    454         ioctl(0, TIOCSCTTY, 0 /*don't steal it*/);
    455 #endif
    456     }
    457 
    458 #if !defined(__UCLIBC__) || defined(__ARCH_HAS_MMU__)
    459     if (a->action & ASKFIRST) {
     426    /* If we saw leading "-", it is interactive shell.
     427     * Try harder to give it a controlling tty.
     428     * And skip "-" in actual exec call. */
     429    if (dash) {
     430        /* _Attempt_ to make stdin a controlling tty. */
     431        if (ENABLE_FEATURE_INIT_SCTTY)
     432            ioctl(STDIN_FILENO, TIOCSCTTY, 0 /*only try, don't steal*/);
     433    }
     434    BB_EXECVP(cmd[0] + dash, cmd);
     435    message(L_LOG | L_CONSOLE, "can't run '%s': %s", cmd[0], strerror(errno));
     436    /* returns if execvp fails */
     437}
     438
     439/* Used only by run_actions */
     440static pid_t run(const struct init_action *a)
     441{
     442    pid_t pid;
     443
     444    /* Careful: don't be affected by a signal in vforked child */
     445    sigprocmask_allsigs(SIG_BLOCK);
     446    if (BB_MMU && (a->action_type & ASKFIRST))
     447        pid = fork();
     448    else
     449        pid = vfork();
     450    if (pid < 0)
     451        message(L_LOG | L_CONSOLE, "can't fork");
     452    if (pid) {
     453        sigprocmask_allsigs(SIG_UNBLOCK);
     454        return pid; /* Parent or error */
     455    }
     456
     457    /* Child */
     458
     459    /* Reset signal handlers that were set by the parent process */
     460    reset_sighandlers_and_unblock_sigs();
     461
     462    /* Create a new session and make ourself the process group leader */
     463    setsid();
     464
     465    /* Open the new terminal device */
     466    if (!open_stdio_to_tty(a->terminal))
     467        _exit(EXIT_FAILURE);
     468
     469    /* NB: on NOMMU we can't wait for input in child, so
     470     * "askfirst" will work the same as "respawn". */
     471    if (BB_MMU && (a->action_type & ASKFIRST)) {
    460472        static const char press_enter[] ALIGN1 =
    461473#ifdef CUSTOMIZED_BANNER
     
    472484         * specifies.
    473485         */
    474         messageD(L_LOG, "waiting for enter to start '%s'"
     486        dbg_message(L_LOG, "waiting for enter to start '%s'"
    475487                    "(pid %d, tty '%s')\n",
    476                   cmdpath, getpid(), a->terminal);
    477         full_write(1, press_enter, sizeof(press_enter) - 1);
    478         while (read(0, &c, 1) == 1 && c != '\n')
    479             ;
    480     }
    481 #endif
    482     /* Log the process name and args */
    483     message(L_LOG, "starting pid %d, tty '%s': '%s'",
    484               getpid(), a->terminal, cmdpath);
    485 
    486 #if ENABLE_FEATURE_INIT_COREDUMPS
    487     {
    488         struct stat sb;
    489         if (stat(CORE_ENABLE_FLAG_FILE, &sb) == 0) {
     488                a->command, getpid(), a->terminal);
     489        full_write(STDOUT_FILENO, press_enter, sizeof(press_enter) - 1);
     490        while (safe_read(STDIN_FILENO, &c, 1) == 1 && c != '\n')
     491            continue;
     492    }
     493
     494    /*
     495     * When a file named /.init_enable_core exists, setrlimit is called
     496     * before processes are spawned to set core file size as unlimited.
     497     * This is for debugging only.  Don't use this is production, unless
     498     * you want core dumps lying about....
     499     */
     500    if (ENABLE_FEATURE_INIT_COREDUMPS) {
     501        if (access("/.init_enable_core", F_OK) == 0) {
    490502            struct rlimit limit;
    491 
    492503            limit.rlim_cur = RLIM_INFINITY;
    493504            limit.rlim_max = RLIM_INFINITY;
     
    495506        }
    496507    }
    497 #endif
     508
     509    /* Log the process name and args */
     510    message(L_LOG, "starting pid %d, tty '%s': '%s'",
     511              getpid(), a->terminal, a->command);
     512
    498513    /* Now run it.  The new program will take over this PID,
    499514     * so nothing further in init.c should be run. */
    500     BB_EXECVP(cmdpath, cmd);
    501 
     515    init_exec(a->command);
    502516    /* We're still here?  Some error happened. */
    503     message(L_LOG | L_CONSOLE, "Cannot run '%s': %s",
    504             cmdpath, strerror(errno));
    505517    _exit(-1);
    506518}
    507519
    508 static int waitfor(const struct init_action *a, pid_t pid)
    509 {
    510     int runpid;
    511     int status, wpid;
    512 
    513     runpid = (NULL == a)? pid : run(a);
     520static struct init_action *mark_terminated(pid_t pid)
     521{
     522    struct init_action *a;
     523
     524    if (pid > 0) {
     525        for (a = init_action_list; a; a = a->next) {
     526            if (a->pid == pid) {
     527                a->pid = 0;
     528                return a;
     529            }
     530        }
     531        update_utmp(pid, DEAD_PROCESS, /*tty_name:*/ NULL,
     532                /*username:*/ NULL,
     533                /*hostname:*/ NULL);
     534    }
     535    return NULL;
     536}
     537
     538static void waitfor(pid_t pid)
     539{
     540    /* waitfor(run(x)): protect against failed fork inside run() */
     541    if (pid <= 0)
     542        return;
     543
     544    /* Wait for any child (prevent zombies from exiting orphaned processes)
     545     * but exit the loop only when specified one has exited. */
    514546    while (1) {
    515         wpid = waitpid(runpid, &status, 0);
    516         if (wpid == runpid)
     547        pid_t wpid = wait(NULL);
     548        mark_terminated(wpid);
     549        /* Unsafe. SIGTSTP handler might have wait'ed it already */
     550        /*if (wpid == pid) break;*/
     551        /* More reliable: */
     552        if (kill(pid, 0))
    517553            break;
    518         if (wpid == -1 && errno == ECHILD) {
    519             /* we missed its termination */
     554    }
     555}
     556
     557/* Run all commands of a particular type */
     558static void run_actions(int action_type)
     559{
     560    struct init_action *a;
     561
     562    for (a = init_action_list; a; a = a->next) {
     563        if (!(a->action_type & action_type))
     564            continue;
     565
     566        if (a->action_type & (SYSINIT | WAIT | ONCE | CTRLALTDEL | SHUTDOWN)) {
     567            pid_t pid = run(a);
     568            if (a->action_type & (SYSINIT | WAIT | CTRLALTDEL | SHUTDOWN))
     569                waitfor(pid);
     570        }
     571        if (a->action_type & (RESPAWN | ASKFIRST)) {
     572            /* Only run stuff with pid == 0. If pid != 0,
     573             * it is already running
     574             */
     575            if (a->pid == 0)
     576                a->pid = run(a);
     577        }
     578    }
     579}
     580
     581static void new_init_action(uint8_t action_type, const char *command, const char *cons)
     582{
     583    struct init_action *a, **nextp;
     584
     585    /* Scenario:
     586     * old inittab:
     587     * ::shutdown:umount -a -r
     588     * ::shutdown:swapoff -a
     589     * new inittab:
     590     * ::shutdown:swapoff -a
     591     * ::shutdown:umount -a -r
     592     * On reload, we must ensure entries end up in correct order.
     593     * To achieve that, if we find a matching entry, we move it
     594     * to the end.
     595     */
     596    nextp = &init_action_list;
     597    while ((a = *nextp) != NULL) {
     598        /* Don't enter action if it's already in the list,
     599         * This prevents losing running RESPAWNs.
     600         */
     601        if (strcmp(a->command, command) == 0
     602         && strcmp(a->terminal, cons) == 0
     603        ) {
     604            /* Remove from list */
     605            *nextp = a->next;
     606            /* Find the end of the list */
     607            while (*nextp != NULL)
     608                nextp = &(*nextp)->next;
     609            a->next = NULL;
    520610            break;
    521611        }
    522         /* FIXME other errors should maybe trigger an error, but allow
    523          * the program to continue */
    524     }
    525     return wpid;
    526 }
    527 
    528 /* Run all commands of a particular type */
    529 static void run_actions(int action)
    530 {
    531     struct init_action *a, *tmp;
    532 
    533     for (a = init_action_list; a; a = tmp) {
    534         tmp = a->next;
    535         if (a->action == action) {
    536             /* a->terminal of "" means "init's console" */
    537             if (a->terminal[0] && access(a->terminal, R_OK | W_OK)) {
    538                 delete_init_action(a);
    539             } else if (a->action & (SYSINIT | WAIT | CTRLALTDEL | SHUTDOWN | RESTART)) {
    540                 waitfor(a, 0);
    541                 delete_init_action(a);
    542             } else if (a->action & ONCE) {
    543                 run(a);
    544                 delete_init_action(a);
    545             } else if (a->action & (RESPAWN | ASKFIRST)) {
    546                 /* Only run stuff with pid==0.  If they have
    547                  * a pid, that means it is still running */
    548                 if (a->pid == 0) {
    549                     a->pid = run(a);
    550                 }
    551             }
    552         }
    553     }
    554 }
    555 
    556 #if !ENABLE_DEBUG_INIT
    557 static void init_reboot(unsigned long magic)
     612        nextp = &a->next;
     613    }
     614
     615    if (!a)
     616        a = xzalloc(sizeof(*a));
     617    /* Append to the end of the list */
     618    *nextp = a;
     619    a->action_type = action_type;
     620    safe_strncpy(a->command, command, sizeof(a->command));
     621    safe_strncpy(a->terminal, cons, sizeof(a->terminal));
     622    dbg_message(L_LOG | L_CONSOLE, "command='%s' action=%d tty='%s'\n",
     623        a->command, a->action_type, a->terminal);
     624}
     625
     626/* NOTE that if CONFIG_FEATURE_USE_INITTAB is NOT defined,
     627 * then parse_inittab() simply adds in some default
     628 * actions(i.e., runs INIT_SCRIPT and then starts a pair
     629 * of "askfirst" shells).  If CONFIG_FEATURE_USE_INITTAB
     630 * _is_ defined, but /etc/inittab is missing, this
     631 * results in the same set of default behaviors.
     632 */
     633static void parse_inittab(void)
     634{
     635#if ENABLE_FEATURE_USE_INITTAB
     636    char *token[4];
     637    parser_t *parser = config_open2("/etc/inittab", fopen_for_read);
     638
     639    if (parser == NULL)
     640#endif
     641    {
     642        /* No inittab file - set up some default behavior */
     643        /* Reboot on Ctrl-Alt-Del */
     644        new_init_action(CTRLALTDEL, "reboot", "");
     645        /* Umount all filesystems on halt/reboot */
     646        new_init_action(SHUTDOWN, "umount -a -r", "");
     647        /* Swapoff on halt/reboot */
     648        if (ENABLE_SWAPONOFF)
     649            new_init_action(SHUTDOWN, "swapoff -a", "");
     650        /* Prepare to restart init when a QUIT is received */
     651        new_init_action(RESTART, "init", "");
     652        /* Askfirst shell on tty1-4 */
     653        new_init_action(ASKFIRST, bb_default_login_shell, "");
     654//TODO: VC_1 instead of ""? "" is console -> ctty problems -> angry users
     655        new_init_action(ASKFIRST, bb_default_login_shell, VC_2);
     656        new_init_action(ASKFIRST, bb_default_login_shell, VC_3);
     657        new_init_action(ASKFIRST, bb_default_login_shell, VC_4);
     658        /* sysinit */
     659        new_init_action(SYSINIT, INIT_SCRIPT, "");
     660        return;
     661    }
     662
     663#if ENABLE_FEATURE_USE_INITTAB
     664    /* optional_tty:ignored_runlevel:action:command
     665     * Delims are not to be collapsed and need exactly 4 tokens
     666     */
     667    while (config_read(parser, token, 4, 0, "#:",
     668                PARSE_NORMAL & ~(PARSE_TRIM | PARSE_COLLAPSE))) {
     669        /* order must correspond to SYSINIT..RESTART constants */
     670        static const char actions[] ALIGN1 =
     671            "sysinit\0""wait\0""once\0""respawn\0""askfirst\0"
     672            "ctrlaltdel\0""shutdown\0""restart\0";
     673        int action;
     674        char *tty = token[0];
     675
     676        if (!token[3]) /* less than 4 tokens */
     677            goto bad_entry;
     678        action = index_in_strings(actions, token[2]);
     679        if (action < 0 || !token[3][0]) /* token[3]: command */
     680            goto bad_entry;
     681        /* turn .*TTY -> /dev/TTY */
     682        if (tty[0]) {
     683            tty = concat_path_file("/dev/", skip_dev_pfx(tty));
     684        }
     685        new_init_action(1 << action, token[3], tty);
     686        if (tty[0])
     687            free(tty);
     688        continue;
     689 bad_entry:
     690        message(L_LOG | L_CONSOLE, "Bad inittab entry at line %d",
     691                parser->lineno);
     692    }
     693    config_close(parser);
     694#endif
     695}
     696
     697static void pause_and_low_level_reboot(unsigned magic) NORETURN;
     698static void pause_and_low_level_reboot(unsigned magic)
    558699{
    559700    pid_t pid;
    560     /* We have to fork here, since the kernel calls do_exit(0) in
    561      * linux/kernel/sys.c, which can cause the machine to panic when
    562      * the init process is killed.... */
     701
     702    /* Allow time for last message to reach serial console, etc */
     703    sleep(1);
     704
     705    /* We have to fork here, since the kernel calls do_exit(EXIT_SUCCESS)
     706     * in linux/kernel/sys.c, which can cause the machine to panic when
     707     * the init process exits... */
    563708    pid = vfork();
    564709    if (pid == 0) { /* child */
    565710        reboot(magic);
    566         _exit(0);
    567     }
    568     waitpid(pid, NULL, 0);
    569 }
    570 
    571 static void shutdown_system(void)
    572 {
    573     sigset_t block_signals;
    574 
    575     /* run everything to be run at "shutdown".  This is done _prior_
     711        _exit(EXIT_SUCCESS);
     712    }
     713    while (1)
     714        sleep(1);
     715}
     716
     717static void run_shutdown_and_kill_processes(void)
     718{
     719    /* Run everything to be run at "shutdown".  This is done _prior_
    576720     * to killing everything, in case people wish to use scripts to
    577721     * shut things down gracefully... */
    578722    run_actions(SHUTDOWN);
    579723
    580     /* first disable all our signals */
    581     sigemptyset(&block_signals);
    582     sigaddset(&block_signals, SIGHUP);
    583     sigaddset(&block_signals, SIGQUIT);
    584     sigaddset(&block_signals, SIGCHLD);
    585     sigaddset(&block_signals, SIGUSR1);
    586     sigaddset(&block_signals, SIGUSR2);
    587     sigaddset(&block_signals, SIGINT);
    588     sigaddset(&block_signals, SIGTERM);
    589     sigaddset(&block_signals, SIGCONT);
    590     sigaddset(&block_signals, SIGSTOP);
    591     sigaddset(&block_signals, SIGTSTP);
    592     sigprocmask(SIG_BLOCK, &block_signals, NULL);
    593 
    594724    message(L_CONSOLE | L_LOG, "The system is going down NOW!");
    595725
    596     /* Allow Ctrl-Alt-Del to reboot system. */
    597     init_reboot(RB_ENABLE_CAD);
    598 
    599726    /* Send signals to every process _except_ pid 1 */
    600     message(L_CONSOLE | L_LOG, "Sending SIG%s to all processes", "TERM");
    601727    kill(-1, SIGTERM);
     728    message(L_CONSOLE | L_LOG, "Sent SIG%s to all processes", "TERM");
    602729    sync();
    603730    sleep(1);
    604731
    605     message(L_CONSOLE | L_LOG, "Sending SIG%s to all processes", "KILL");
    606732    kill(-1, SIGKILL);
     733    message(L_CONSOLE, "Sent SIG%s to all processes", "KILL");
    607734    sync();
    608     sleep(1);
    609 }
    610 
    611 static void exec_signal(int sig ATTRIBUTE_UNUSED)
    612 {
    613     struct init_action *a, *tmp;
    614     sigset_t unblock_signals;
    615 
    616     for (a = init_action_list; a; a = tmp) {
    617         tmp = a->next;
    618         if (a->action & RESTART) {
    619             shutdown_system();
    620 
    621             /* unblock all signals, blocked in shutdown_system() */
    622             sigemptyset(&unblock_signals);
    623             sigaddset(&unblock_signals, SIGHUP);
    624             sigaddset(&unblock_signals, SIGQUIT);
    625             sigaddset(&unblock_signals, SIGCHLD);
    626             sigaddset(&unblock_signals, SIGUSR1);
    627             sigaddset(&unblock_signals, SIGUSR2);
    628             sigaddset(&unblock_signals, SIGINT);
    629             sigaddset(&unblock_signals, SIGTERM);
    630             sigaddset(&unblock_signals, SIGCONT);
    631             sigaddset(&unblock_signals, SIGSTOP);
    632             sigaddset(&unblock_signals, SIGTSTP);
    633             sigprocmask(SIG_UNBLOCK, &unblock_signals, NULL);
    634 
    635             /* Open the new terminal device */
    636             open_stdio_to_tty(a->terminal, 0);
    637 
    638             messageD(L_CONSOLE | L_LOG, "Trying to re-exec %s", a->command);
    639             BB_EXECLP(a->command, a->command, NULL);
    640 
    641             message(L_CONSOLE | L_LOG, "Cannot run '%s': %s",
    642                     a->command, strerror(errno));
    643             sleep(2);
    644             init_reboot(RB_HALT_SYSTEM);
    645             loop_forever();
    646         }
    647     }
    648 }
    649 
    650 static void shutdown_signal(int sig)
     735    /*sleep(1); - callers take care about making a pause */
     736}
     737
     738/* Signal handling by init:
     739 *
     740 * For process with PID==1, on entry kernel sets all signals to SIG_DFL
     741 * and unmasks all signals. However, for process with PID==1,
     742 * default action (SIG_DFL) on any signal is to ignore it,
     743 * even for special signals SIGKILL and SIGCONT.
     744 * Also, any signal can be caught or blocked.
     745 * (but SIGSTOP is still handled specially, at least in 2.6.20)
     746 *
     747 * We install two kinds of handlers, "immediate" and "delayed".
     748 *
     749 * Immediate handlers execute at any time, even while, say, sysinit
     750 * is running.
     751 *
     752 * Delayed handlers just set a flag variable. The variable is checked
     753 * in the main loop and acted upon.
     754 *
     755 * halt/poweroff/reboot and restart have immediate handlers.
     756 * They only traverse linked list of struct action's, never modify it,
     757 * this should be safe to do even in signal handler. Also they
     758 * never return.
     759 *
     760 * SIGSTOP and SIGTSTP have immediate handlers. They just wait
     761 * for SIGCONT to happen.
     762 *
     763 * SIGHUP has a delayed handler, because modifying linked list
     764 * of struct action's from a signal handler while it is manipulated
     765 * by the program may be disastrous.
     766 *
     767 * Ctrl-Alt-Del has a delayed handler. Not a must, but allowing
     768 * it to happen even somewhere inside "sysinit" would be a bit awkward.
     769 *
     770 * There is a tiny probability that SIGHUP and Ctrl-Alt-Del will collide
     771 * and only one will be remembered and acted upon.
     772 */
     773
     774/* The SIGUSR[12]/SIGTERM handler */
     775static void halt_reboot_pwoff(int sig) NORETURN;
     776static void halt_reboot_pwoff(int sig)
    651777{
    652778    const char *m;
    653     int rb;
    654 
    655     shutdown_system();
     779    unsigned rb;
     780
     781    /* We may call run() and it unmasks signals,
     782     * including the one masked inside this signal handler.
     783     * Testcase which would start multiple reboot scripts:
     784     *  while true; do reboot; done
     785     * Preventing it:
     786     */
     787    reset_sighandlers_and_unblock_sigs();
     788
     789    run_shutdown_and_kill_processes();
    656790
    657791    m = "halt";
     
    664798        rb = RB_POWER_OFF;
    665799    }
    666     message(L_CONSOLE | L_LOG, "Requesting system %s", m);
    667     /* allow time for last message to reach serial console */
    668     sleep(2);
    669     init_reboot(rb);
    670     loop_forever();
    671 }
    672 
    673 static void ctrlaltdel_signal(int sig ATTRIBUTE_UNUSED)
    674 {
    675     run_actions(CTRLALTDEL);
    676 }
    677 
    678 /* The SIGSTOP & SIGTSTP handler */
    679 static void stop_handler(int sig ATTRIBUTE_UNUSED)
    680 {
    681     int saved_errno = errno;
    682 
    683     got_cont = 0;
    684     while (!got_cont)
    685         pause();
    686     got_cont = 0;
     800    message(L_CONSOLE, "Requesting system %s", m);
     801    pause_and_low_level_reboot(rb);
     802    /* not reached */
     803}
     804
     805/* Handler for QUIT - exec "restart" action,
     806 * else (no such action defined) do nothing */
     807static void restart_handler(int sig UNUSED_PARAM)
     808{
     809    struct init_action *a;
     810
     811    for (a = init_action_list; a; a = a->next) {
     812        if (!(a->action_type & RESTART))
     813            continue;
     814
     815        /* Starting from here, we won't return.
     816         * Thus don't need to worry about preserving errno
     817         * and such.
     818         */
     819
     820        reset_sighandlers_and_unblock_sigs();
     821
     822        run_shutdown_and_kill_processes();
     823
     824#ifdef RB_ENABLE_CAD
     825        /* Allow Ctrl-Alt-Del to reboot the system.
     826         * This is how kernel sets it up for init, we follow suit.
     827         */
     828        reboot(RB_ENABLE_CAD); /* misnomer */
     829#endif
     830
     831        if (open_stdio_to_tty(a->terminal)) {
     832            dbg_message(L_CONSOLE, "Trying to re-exec %s", a->command);
     833            /* Theoretically should be safe.
     834             * But in practice, kernel bugs may leave
     835             * unkillable processes, and wait() may block forever.
     836             * Oh well. Hoping "new" init won't be too surprised
     837             * by having children it didn't create.
     838             */
     839            //while (wait(NULL) > 0)
     840            //  continue;
     841            init_exec(a->command);
     842        }
     843        /* Open or exec failed */
     844        pause_and_low_level_reboot(RB_HALT_SYSTEM);
     845        /* not reached */
     846    }
     847}
     848
     849/* The SIGSTOP/SIGTSTP handler
     850 * NB: inside it, all signals except SIGCONT are masked
     851 * via appropriate setup in sigaction().
     852 */
     853static void stop_handler(int sig UNUSED_PARAM)
     854{
     855    smallint saved_bb_got_signal;
     856    int saved_errno;
     857
     858    saved_bb_got_signal = bb_got_signal;
     859    saved_errno = errno;
     860    signal(SIGCONT, record_signo);
     861
     862    while (1) {
     863        pid_t wpid;
     864
     865        if (bb_got_signal == SIGCONT)
     866            break;
     867        /* NB: this can accidentally wait() for a process
     868         * which we waitfor() elsewhere! waitfor() must have
     869         * code which is resilient against this.
     870         */
     871        wpid = wait_any_nohang(NULL);
     872        mark_terminated(wpid);
     873        sleep(1);
     874    }
     875
     876    signal(SIGCONT, SIG_DFL);
    687877    errno = saved_errno;
    688 }
    689 
    690 /* The SIGCONT handler */
    691 static void cont_handler(int sig ATTRIBUTE_UNUSED)
    692 {
    693     got_cont = 1;
    694 }
    695 
    696 #endif  /* !ENABLE_DEBUG_INIT */
    697 
    698 static void new_init_action(int action, const char *command, const char *cons)
    699 {
    700     struct init_action *new_action, *a, *last;
    701 
    702     if (strcmp(cons, bb_dev_null) == 0 && (action & ASKFIRST))
    703         return;
    704 
    705     /* Append to the end of the list */
    706     for (a = last = init_action_list; a; a = a->next) {
    707         /* don't enter action if it's already in the list,
    708          * but do overwrite existing actions */
    709         if ((strcmp(a->command, command) == 0)
    710          && (strcmp(a->terminal, cons) == 0)
     878    bb_got_signal = saved_bb_got_signal;
     879}
     880
     881#if ENABLE_FEATURE_USE_INITTAB
     882static void reload_inittab(void)
     883{
     884    struct init_action *a, **nextp;
     885
     886    message(L_LOG, "reloading /etc/inittab");
     887
     888    /* Disable old entries */
     889    for (a = init_action_list; a; a = a->next)
     890        a->action_type = 0;
     891
     892    /* Append new entries, or modify existing entries
     893     * (incl. setting a->action_type) if cmd and device name
     894     * match new ones. End result: only entries with
     895     * a->action_type == 0 are stale.
     896     */
     897    parse_inittab();
     898
     899#if ENABLE_FEATURE_KILL_REMOVED
     900    /* Kill stale entries */
     901    /* Be nice and send SIGTERM first */
     902    for (a = init_action_list; a; a = a->next)
     903        if (a->action_type == 0 && a->pid != 0)
     904            kill(a->pid, SIGTERM);
     905    if (CONFIG_FEATURE_KILL_DELAY) {
     906        /* NB: parent will wait in NOMMU case */
     907        if ((BB_MMU ? fork() : vfork()) == 0) { /* child */
     908            sleep(CONFIG_FEATURE_KILL_DELAY);
     909            for (a = init_action_list; a; a = a->next)
     910                if (a->action_type == 0 && a->pid != 0)
     911                    kill(a->pid, SIGKILL);
     912            _exit(EXIT_SUCCESS);
     913        }
     914    }
     915#endif
     916
     917    /* Remove stale entries and SYSINIT entries.
     918     * We never rerun SYSINIT entries anyway,
     919     * removing them too saves a few bytes */
     920    nextp = &init_action_list;
     921    while ((a = *nextp) != NULL) {
     922        if ((a->action_type & ~SYSINIT) == 0) {
     923            *nextp = a->next;
     924            free(a);
     925        } else {
     926            nextp = &a->next;
     927        }
     928    }
     929
     930    /* Not needed: */
     931    /* run_actions(RESPAWN | ASKFIRST); */
     932    /* - we return to main loop, which does this automagically */
     933}
     934#endif
     935
     936static int check_delayed_sigs(void)
     937{
     938    int sigs_seen = 0;
     939
     940    while (1) {
     941        smallint sig = bb_got_signal;
     942
     943        if (!sig)
     944            return sigs_seen;
     945        bb_got_signal = 0;
     946        sigs_seen = 1;
     947#if ENABLE_FEATURE_USE_INITTAB
     948        if (sig == SIGHUP)
     949            reload_inittab();
     950#endif
     951        if (sig == SIGINT)
     952            run_actions(CTRLALTDEL);
     953    }
     954}
     955
     956int init_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     957int init_main(int argc UNUSED_PARAM, char **argv)
     958{
     959    if (argv[1] && strcmp(argv[1], "-q") == 0) {
     960        return kill(1, SIGHUP);
     961    }
     962
     963    if (!DEBUG_INIT) {
     964        /* Expect to be invoked as init with PID=1 or be invoked as linuxrc */
     965        if (getpid() != 1
     966         && (!ENABLE_FEATURE_INITRD || applet_name[0] != 'l') /* not linuxrc? */
    711967        ) {
    712             a->action = action;
    713             return;
    714         }
    715         last = a;
    716     }
    717 
    718     new_action = xzalloc(sizeof(struct init_action));
    719     if (last) {
    720         last->next = new_action;
    721     } else {
    722         init_action_list = new_action;
    723     }
    724     strcpy(new_action->command, command);
    725     new_action->action = action;
    726     strcpy(new_action->terminal, cons);
    727     messageD(L_LOG | L_CONSOLE, "command='%s' action=%d tty='%s'\n",
    728         new_action->command, new_action->action, new_action->terminal);
    729 }
    730 
    731 static void delete_init_action(struct init_action *action)
    732 {
    733     struct init_action *a, *b = NULL;
    734 
    735     for (a = init_action_list; a; b = a, a = a->next) {
    736         if (a == action) {
    737             if (b == NULL) {
    738                 init_action_list = a->next;
    739             } else {
    740                 b->next = a->next;
    741             }
    742             free(a);
    743             break;
    744         }
    745     }
    746 }
    747 
    748 /* NOTE that if CONFIG_FEATURE_USE_INITTAB is NOT defined,
    749  * then parse_inittab() simply adds in some default
    750  * actions(i.e., runs INIT_SCRIPT and then starts a pair
    751  * of "askfirst" shells).  If CONFIG_FEATURE_USE_INITTAB
    752  * _is_ defined, but /etc/inittab is missing, this
    753  * results in the same set of default behaviors.
    754  */
    755 static void parse_inittab(void)
    756 {
    757 #if ENABLE_FEATURE_USE_INITTAB
    758     FILE *file;
    759     char buf[INIT_BUFFS_SIZE], lineAsRead[INIT_BUFFS_SIZE];
    760     char tmpConsole[CONSOLE_NAME_SIZE];
    761     char *id, *runlev, *action, *command, *eol;
    762     const struct init_action_type *a = actions;
    763 
    764     file = fopen(INITTAB, "r");
    765     if (file == NULL) {
    766         /* No inittab file -- set up some default behavior */
    767 #endif
    768         /* Reboot on Ctrl-Alt-Del */
    769         new_init_action(CTRLALTDEL, "reboot", "");
    770         /* Umount all filesystems on halt/reboot */
    771         new_init_action(SHUTDOWN, "umount -a -r", "");
    772         /* Swapoff on halt/reboot */
    773         if (ENABLE_SWAPONOFF) new_init_action(SHUTDOWN, "swapoff -a", "");
    774         /* Prepare to restart init when a HUP is received */
    775         new_init_action(RESTART, "init", "");
    776         /* Askfirst shell on tty1-4 */
    777         new_init_action(ASKFIRST, bb_default_login_shell, "");
    778         new_init_action(ASKFIRST, bb_default_login_shell, VC_2);
    779         new_init_action(ASKFIRST, bb_default_login_shell, VC_3);
    780         new_init_action(ASKFIRST, bb_default_login_shell, VC_4);
    781         /* sysinit */
    782         new_init_action(SYSINIT, INIT_SCRIPT, "");
    783 
    784         return;
    785 #if ENABLE_FEATURE_USE_INITTAB
    786     }
    787 
    788     while (fgets(buf, INIT_BUFFS_SIZE, file) != NULL) {
    789         /* Skip leading spaces */
    790         for (id = buf; *id == ' ' || *id == '\t'; id++);
    791 
    792         /* Skip the line if it's a comment */
    793         if (*id == '#' || *id == '\n')
    794             continue;
    795 
    796         /* Trim the trailing \n */
    797         //XXX: chomp() ?
    798         eol = strrchr(id, '\n');
    799         if (eol != NULL)
    800             *eol = '\0';
    801 
    802         /* Keep a copy around for posterity's sake (and error msgs) */
    803         strcpy(lineAsRead, buf);
    804 
    805         /* Separate the ID field from the runlevels */
    806         runlev = strchr(id, ':');
    807         if (runlev == NULL || *(runlev + 1) == '\0') {
    808             message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead);
    809             continue;
    810         } else {
    811             *runlev = '\0';
    812             ++runlev;
    813         }
    814 
    815         /* Separate the runlevels from the action */
    816         action = strchr(runlev, ':');
    817         if (action == NULL || *(action + 1) == '\0') {
    818             message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead);
    819             continue;
    820         } else {
    821             *action = '\0';
    822             ++action;
    823         }
    824 
    825         /* Separate the action from the command */
    826         command = strchr(action, ':');
    827         if (command == NULL || *(command + 1) == '\0') {
    828             message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead);
    829             continue;
    830         } else {
    831             *command = '\0';
    832             ++command;
    833         }
    834 
    835         /* Ok, now process it */
    836         for (a = actions; a->name != 0; a++) {
    837             if (strcmp(a->name, action) == 0) {
    838                 if (*id != '\0') {
    839                     if (strncmp(id, "/dev/", 5) == 0)
    840                         id += 5;
    841                     strcpy(tmpConsole, "/dev/");
    842                     safe_strncpy(tmpConsole + 5, id,
    843                         sizeof(tmpConsole) - 5);
    844                     id = tmpConsole;
    845                 }
    846                 new_init_action(a->action, command, id);
    847                 break;
    848             }
    849         }
    850         if (a->name == 0) {
    851             /* Choke on an unknown action */
    852             message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead);
    853         }
    854     }
    855     fclose(file);
    856 #endif /* FEATURE_USE_INITTAB */
    857 }
    858 
    859 #if ENABLE_FEATURE_USE_INITTAB
    860 static void reload_signal(int sig ATTRIBUTE_UNUSED)
    861 {
    862     struct init_action *a, *tmp;
    863 
    864     message(L_LOG, "reloading /etc/inittab");
    865 
    866     /* disable old entrys */
    867     for (a = init_action_list; a; a = a->next ) {
    868         a->action = ONCE;
    869     }
    870 
    871     parse_inittab();
    872 
    873     /* remove unused entrys */
    874     for (a = init_action_list; a; a = tmp) {
    875         tmp = a->next;
    876         if ((a->action & (ONCE | SYSINIT | WAIT)) && a->pid == 0) {
    877             delete_init_action(a);
    878         }
    879     }
    880     run_actions(RESPAWN);
    881 }
    882 #endif  /* FEATURE_USE_INITTAB */
    883 
    884 int init_main(int argc, char **argv);
    885 int init_main(int argc, char **argv)
    886 {
    887     struct init_action *a;
    888     pid_t wpid;
    889 
    890     die_sleep = 30 * 24*60*60; /* if xmalloc will ever die... */
    891 
    892     if (argc > 1 && !strcmp(argv[1], "-q")) {
    893         return kill(1, SIGHUP);
    894     }
    895 #if !ENABLE_DEBUG_INIT
    896     /* Expect to be invoked as init with PID=1 or be invoked as linuxrc */
    897     if (getpid() != 1
    898      && (!ENABLE_FEATURE_INITRD || !strstr(applet_name, "linuxrc"))
    899     ) {
    900         bb_show_usage();
    901     }
    902     /* Set up sig handlers  -- be sure to
    903      * clear all of these in run() */
    904     signal(SIGHUP, exec_signal);
    905     signal(SIGQUIT, exec_signal);
    906     signal(SIGUSR1, shutdown_signal);
    907     signal(SIGUSR2, shutdown_signal);
    908     signal(SIGINT, ctrlaltdel_signal);
    909     signal(SIGTERM, shutdown_signal);
    910     signal(SIGCONT, cont_handler);
    911     signal(SIGSTOP, stop_handler);
    912     signal(SIGTSTP, stop_handler);
    913 
    914     /* Turn off rebooting via CTL-ALT-DEL -- we get a
    915      * SIGINT on CAD so we can shut things down gracefully... */
    916     init_reboot(RB_DISABLE_CAD);
    917 #endif
    918 
     968            bb_error_msg_and_die("must be run as PID 1");
     969        }
     970#ifdef RB_DISABLE_CAD
     971        /* Turn off rebooting via CTL-ALT-DEL - we get a
     972         * SIGINT on CAD so we can shut things down gracefully... */
     973        reboot(RB_DISABLE_CAD); /* misnomer */
     974#endif
     975    }
     976
     977    /* If, say, xmalloc would ever die, we don't want to oops kernel
     978     * by exiting.
     979     * NB: we set die_sleep *after* PID 1 check and bb_show_usage.
     980     * Otherwise, for example, "init u" ("please rexec yourself"
     981     * command for sysvinit) will show help text (which isn't too bad),
     982     * *and sleep forever* (which is bad!)
     983     */
     984    die_sleep = 30 * 24*60*60;
    919985
    920986    /* Figure out where the default console should be */
    921987    console_init();
    922988    set_sane_term();
    923     chdir("/");
     989    xchdir("/");
    924990    setsid();
    925     {
    926         const char *const *e;
    927         /* Make sure environs is set to something sane */
    928         for (e = environment; *e; e++)
    929             putenv((char *) *e);
    930     }
    931 
    932     if (argc > 1) setenv("RUNLEVEL", argv[1], 1);
    933 
     991
     992    /* Make sure environs is set to something sane */
     993    putenv((char *) "HOME=/");
     994    putenv((char *) bb_PATH_root_path);
     995    putenv((char *) "SHELL=/bin/sh");
     996    putenv((char *) "USER=root"); /* needed? why? */
     997
     998    if (argv[1])
     999        xsetenv("RUNLEVEL", argv[1]);
     1000
     1001#if !ENABLE_FEATURE_EXTRA_QUIET
    9341002    /* Hello world */
    935     message(MAYBE_CONSOLE | L_LOG, "init started: %s", bb_banner);
    936 
     1003    message(L_CONSOLE | L_LOG, "init started: %s", bb_banner);
     1004#endif
     1005
     1006/* struct sysinfo is linux-specific */
     1007#ifdef __linux__
    9371008    /* Make sure there is enough memory to do something useful. */
    9381009    if (ENABLE_SWAPONOFF) {
    9391010        struct sysinfo info;
    9401011
    941         if (!sysinfo(&info) &&
    942             (info.mem_unit ? : 1) * (long long)info.totalram < 1024*1024)
    943         {
     1012        if (sysinfo(&info) == 0
     1013         && (info.mem_unit ? info.mem_unit : 1) * (long long)info.totalram < 1024*1024
     1014        ) {
    9441015            message(L_CONSOLE, "Low memory, forcing swapon");
    9451016            /* swapon -a requires /proc typically */
     
    9501021        }
    9511022    }
     1023#endif
    9521024
    9531025    /* Check if we are supposed to be in single user mode */
    954     if (argc > 1
    955      && (!strcmp(argv[1], "single") || !strcmp(argv[1], "-s") || LONE_CHAR(argv[1], '1'))
     1026    if (argv[1]
     1027     && (strcmp(argv[1], "single") == 0 || strcmp(argv[1], "-s") == 0 || LONE_CHAR(argv[1], '1'))
    9561028    ) {
     1029        /* ??? shouldn't we set RUNLEVEL="b" here? */
    9571030        /* Start a shell on console */
    9581031        new_init_action(RESPAWN, bb_default_login_shell, "");
    9591032    } else {
    960         /* Not in single user mode -- see what inittab says */
     1033        /* Not in single user mode - see what inittab says */
    9611034
    9621035        /* NOTE that if CONFIG_FEATURE_USE_INITTAB is NOT defined,
    9631036         * then parse_inittab() simply adds in some default
    964          * actions(i.e., runs INIT_SCRIPT and then starts a pair
     1037         * actions(i.e., INIT_SCRIPT and a pair
    9651038         * of "askfirst" shells */
    9661039        parse_inittab();
     
    9761049        } else if (enforce > 0) {
    9771050            /* SELinux in enforcing mode but load_policy failed */
    978             /* At this point, we probably can't open /dev/console, so log() won't work */
    979             message(L_CONSOLE, "Cannot load SELinux Policy. "
     1051            message(L_CONSOLE, "can't load SELinux Policy. "
    9801052                "Machine is in enforcing mode. Halting now.");
    981             exit(1);
    982         }
    983     }
    984 #endif /* CONFIG_SELINUX */
    985 
    986     /* Make the command line just say "init"  -- thats all, nothing else */
    987     fixup_argv(argv);
     1053            return EXIT_FAILURE;
     1054        }
     1055    }
     1056#endif
     1057
     1058    /* Make the command line just say "init"  - thats all, nothing else */
     1059    strncpy(argv[0], "init", strlen(argv[0]));
     1060    /* Wipe argv[1]-argv[N] so they don't clutter the ps listing */
     1061    while (*++argv)
     1062        memset(*argv, 0, strlen(*argv));
     1063
     1064    /* Set up signal handlers */
     1065    if (!DEBUG_INIT) {
     1066        struct sigaction sa;
     1067
     1068        bb_signals(0
     1069            + (1 << SIGUSR1) /* halt */
     1070            + (1 << SIGTERM) /* reboot */
     1071            + (1 << SIGUSR2) /* poweroff */
     1072            , halt_reboot_pwoff);
     1073        signal(SIGQUIT, restart_handler); /* re-exec another init */
     1074
     1075        /* Stop handler must allow only SIGCONT inside itself */
     1076        memset(&sa, 0, sizeof(sa));
     1077        sigfillset(&sa.sa_mask);
     1078        sigdelset(&sa.sa_mask, SIGCONT);
     1079        sa.sa_handler = stop_handler;
     1080        /* NB: sa_flags doesn't have SA_RESTART.
     1081         * It must be able to interrupt wait().
     1082         */
     1083        sigaction_set(SIGTSTP, &sa); /* pause */
     1084        /* Does not work as intended, at least in 2.6.20.
     1085         * SIGSTOP is simply ignored by init:
     1086         */
     1087        sigaction_set(SIGSTOP, &sa); /* pause */
     1088
     1089        /* SIGINT (Ctrl-Alt-Del) must interrupt wait(),
     1090         * setting handler without SA_RESTART flag.
     1091         */
     1092        bb_signals_recursive_norestart((1 << SIGINT), record_signo);
     1093    }
     1094
     1095    /* Set up "reread /etc/inittab" handler.
     1096     * Handler is set up without SA_RESTART, it will interrupt syscalls.
     1097     */
     1098    if (!DEBUG_INIT && ENABLE_FEATURE_USE_INITTAB)
     1099        bb_signals_recursive_norestart((1 << SIGHUP), record_signo);
    9881100
    9891101    /* Now run everything that needs to be run */
    990 
    9911102    /* First run the sysinit command */
    9921103    run_actions(SYSINIT);
    993 
     1104    check_delayed_sigs();
    9941105    /* Next run anything that wants to block */
    9951106    run_actions(WAIT);
    996 
     1107    check_delayed_sigs();
    9971108    /* Next run anything to be run only once */
    9981109    run_actions(ONCE);
    9991110
    1000 #if ENABLE_FEATURE_USE_INITTAB
    1001     /* Redefine SIGHUP to reread /etc/inittab */
    1002     signal(SIGHUP, reload_signal);
    1003 #else
    1004     signal(SIGHUP, SIG_IGN);
    1005 #endif /* FEATURE_USE_INITTAB */
    1006 
    1007     /* Now run the looping stuff for the rest of forever */
     1111    /* Now run the looping stuff for the rest of forever.
     1112     */
    10081113    while (1) {
    1009         /* run the respawn stuff */
    1010         run_actions(RESPAWN);
    1011 
    1012         /* run the askfirst stuff */
    1013         run_actions(ASKFIRST);
    1014 
    1015         /* Don't consume all CPU time -- sleep a bit */
     1114        int maybe_WNOHANG;
     1115
     1116        maybe_WNOHANG = check_delayed_sigs();
     1117
     1118        /* (Re)run the respawn/askfirst stuff */
     1119        run_actions(RESPAWN | ASKFIRST);
     1120        maybe_WNOHANG |= check_delayed_sigs();
     1121
     1122        /* Don't consume all CPU time - sleep a bit */
    10161123        sleep(1);
    1017 
    1018         /* Wait for a child process to exit */
    1019         wpid = wait(NULL);
    1020         while (wpid > 0) {
    1021             /* Find out who died and clean up their corpse */
    1022             for (a = init_action_list; a; a = a->next) {
    1023                 if (a->pid == wpid) {
    1024                     /* Set the pid to 0 so that the process gets
    1025                      * restarted by run_actions() */
    1026                     a->pid = 0;
    1027                     message(L_LOG, "process '%s' (pid %d) exited. "
    1028                             "Scheduling it for restart.",
    1029                             a->command, wpid);
    1030                 }
     1124        maybe_WNOHANG |= check_delayed_sigs();
     1125
     1126        /* Wait for any child process(es) to exit.
     1127         *
     1128         * If check_delayed_sigs above reported that a signal
     1129         * was caught, wait will be nonblocking. This ensures
     1130         * that if SIGHUP has reloaded inittab, respawn and askfirst
     1131         * actions will not be delayed until next child death.
     1132         */
     1133        if (maybe_WNOHANG)
     1134            maybe_WNOHANG = WNOHANG;
     1135        while (1) {
     1136            pid_t wpid;
     1137            struct init_action *a;
     1138
     1139            /* If signals happen _in_ the wait, they interrupt it,
     1140             * bb_signals_recursive_norestart set them up that way
     1141             */
     1142            wpid = waitpid(-1, NULL, maybe_WNOHANG);
     1143            if (wpid <= 0)
     1144                break;
     1145
     1146            a = mark_terminated(wpid);
     1147            if (a) {
     1148                message(L_LOG, "process '%s' (pid %d) exited. "
     1149                        "Scheduling for restart.",
     1150                        a->command, wpid);
    10311151            }
    1032             /* see if anyone else is waiting to be reaped */
    1033             wpid = waitpid(-1, NULL, WNOHANG);
    1034         }
    1035     }
    1036 }
     1152            /* See if anyone else is waiting to be reaped */
     1153            maybe_WNOHANG = WNOHANG;
     1154        }
     1155    } /* while (1) */
     1156}
     1157
     1158//usage:#define linuxrc_trivial_usage NOUSAGE_STR
     1159//usage:#define linuxrc_full_usage ""
     1160
     1161//usage:#define init_trivial_usage
     1162//usage:       ""
     1163//usage:#define init_full_usage "\n\n"
     1164//usage:       "Init is the parent of all processes"
     1165//usage:
     1166//usage:#define init_notes_usage
     1167//usage:    "This version of init is designed to be run only by the kernel.\n"
     1168//usage:    "\n"
     1169//usage:    "BusyBox init doesn't support multiple runlevels. The runlevels field of\n"
     1170//usage:    "the /etc/inittab file is completely ignored by BusyBox init. If you want\n"
     1171//usage:    "runlevels, use sysvinit.\n"
     1172//usage:    "\n"
     1173//usage:    "BusyBox init works just fine without an inittab. If no inittab is found,\n"
     1174//usage:    "it has the following default behavior:\n"
     1175//usage:    "\n"
     1176//usage:    "   ::sysinit:/etc/init.d/rcS\n"
     1177//usage:    "   ::askfirst:/bin/sh\n"
     1178//usage:    "   ::ctrlaltdel:/sbin/reboot\n"
     1179//usage:    "   ::shutdown:/sbin/swapoff -a\n"
     1180//usage:    "   ::shutdown:/bin/umount -a -r\n"
     1181//usage:    "   ::restart:/sbin/init\n"
     1182//usage:    "\n"
     1183//usage:    "if it detects that /dev/console is _not_ a serial console, it will also run:\n"
     1184//usage:    "\n"
     1185//usage:    "   tty2::askfirst:/bin/sh\n"
     1186//usage:    "   tty3::askfirst:/bin/sh\n"
     1187//usage:    "   tty4::askfirst:/bin/sh\n"
     1188//usage:    "\n"
     1189//usage:    "If you choose to use an /etc/inittab file, the inittab entry format is as follows:\n"
     1190//usage:    "\n"
     1191//usage:    "   <id>:<runlevels>:<action>:<process>\n"
     1192//usage:    "\n"
     1193//usage:    "   <id>:\n"
     1194//usage:    "\n"
     1195//usage:    "       WARNING: This field has a non-traditional meaning for BusyBox init!\n"
     1196//usage:    "       The id field is used by BusyBox init to specify the controlling tty for\n"
     1197//usage:    "       the specified process to run on. The contents of this field are\n"
     1198//usage:    "       appended to \"/dev/\" and used as-is. There is no need for this field to\n"
     1199//usage:    "       be unique, although if it isn't you may have strange results. If this\n"
     1200//usage:    "       field is left blank, the controlling tty is set to the console. Also\n"
     1201//usage:    "       note that if BusyBox detects that a serial console is in use, then only\n"
     1202//usage:    "       entries whose controlling tty is either the serial console or /dev/null\n"
     1203//usage:    "       will be run. BusyBox init does nothing with utmp. We don't need no\n"
     1204//usage:    "       stinkin' utmp.\n"
     1205//usage:    "\n"
     1206//usage:    "   <runlevels>:\n"
     1207//usage:    "\n"
     1208//usage:    "       The runlevels field is completely ignored.\n"
     1209//usage:    "\n"
     1210//usage:    "   <action>:\n"
     1211//usage:    "\n"
     1212//usage:    "       Valid actions include: sysinit, respawn, askfirst, wait,\n"
     1213//usage:    "       once, restart, ctrlaltdel, and shutdown.\n"
     1214//usage:    "\n"
     1215//usage:    "       The available actions can be classified into two groups: actions\n"
     1216//usage:    "       that are run only once, and actions that are re-run when the specified\n"
     1217//usage:    "       process exits.\n"
     1218//usage:    "\n"
     1219//usage:    "       Run only-once actions:\n"
     1220//usage:    "\n"
     1221//usage:    "           'sysinit' is the first item run on boot. init waits until all\n"
     1222//usage:    "           sysinit actions are completed before continuing. Following the\n"
     1223//usage:    "           completion of all sysinit actions, all 'wait' actions are run.\n"
     1224//usage:    "           'wait' actions, like 'sysinit' actions, cause init to wait until\n"
     1225//usage:    "           the specified task completes. 'once' actions are asynchronous,\n"
     1226//usage:    "           therefore, init does not wait for them to complete. 'restart' is\n"
     1227//usage:    "           the action taken to restart the init process. By default this should\n"
     1228//usage:    "           simply run /sbin/init, but can be a script which runs pivot_root or it\n"
     1229//usage:    "           can do all sorts of other interesting things. The 'ctrlaltdel' init\n"
     1230//usage:    "           actions are run when the system detects that someone on the system\n"
     1231//usage:    "           console has pressed the CTRL-ALT-DEL key combination. Typically one\n"
     1232//usage:    "           wants to run 'reboot' at this point to cause the system to reboot.\n"
     1233//usage:    "           Finally the 'shutdown' action specifies the actions to taken when\n"
     1234//usage:    "           init is told to reboot. Unmounting filesystems and disabling swap\n"
     1235//usage:    "           is a very good here.\n"
     1236//usage:    "\n"
     1237//usage:    "       Run repeatedly actions:\n"
     1238//usage:    "\n"
     1239//usage:    "           'respawn' actions are run after the 'once' actions. When a process\n"
     1240//usage:    "           started with a 'respawn' action exits, init automatically restarts\n"
     1241//usage:    "           it. Unlike sysvinit, BusyBox init does not stop processes from\n"
     1242//usage:    "           respawning out of control. The 'askfirst' actions acts just like\n"
     1243//usage:    "           respawn, except that before running the specified process it\n"
     1244//usage:    "           displays the line \"Please press Enter to activate this console.\"\n"
     1245//usage:    "           and then waits for the user to press enter before starting the\n"
     1246//usage:    "           specified process.\n"
     1247//usage:    "\n"
     1248//usage:    "       Unrecognized actions (like initdefault) will cause init to emit an\n"
     1249//usage:    "       error message, and then go along with its business. All actions are\n"
     1250//usage:    "       run in the order they appear in /etc/inittab.\n"
     1251//usage:    "\n"
     1252//usage:    "   <process>:\n"
     1253//usage:    "\n"
     1254//usage:    "       Specifies the process to be executed and its command line.\n"
     1255//usage:    "\n"
     1256//usage:    "Example /etc/inittab file:\n"
     1257//usage:    "\n"
     1258//usage:    "   # This is run first except when booting in single-user mode\n"
     1259//usage:    "   #\n"
     1260//usage:    "   ::sysinit:/etc/init.d/rcS\n"
     1261//usage:    "   \n"
     1262//usage:    "   # /bin/sh invocations on selected ttys\n"
     1263//usage:    "   #\n"
     1264//usage:    "   # Start an \"askfirst\" shell on the console (whatever that may be)\n"
     1265//usage:    "   ::askfirst:-/bin/sh\n"
     1266//usage:    "   # Start an \"askfirst\" shell on /dev/tty2-4\n"
     1267//usage:    "   tty2::askfirst:-/bin/sh\n"
     1268//usage:    "   tty3::askfirst:-/bin/sh\n"
     1269//usage:    "   tty4::askfirst:-/bin/sh\n"
     1270//usage:    "   \n"
     1271//usage:    "   # /sbin/getty invocations for selected ttys\n"
     1272//usage:    "   #\n"
     1273//usage:    "   tty4::respawn:/sbin/getty 38400 tty4\n"
     1274//usage:    "   tty5::respawn:/sbin/getty 38400 tty5\n"
     1275//usage:    "   \n"
     1276//usage:    "   \n"
     1277//usage:    "   # Example of how to put a getty on a serial line (for a terminal)\n"
     1278//usage:    "   #\n"
     1279//usage:    "   #::respawn:/sbin/getty -L ttyS0 9600 vt100\n"
     1280//usage:    "   #::respawn:/sbin/getty -L ttyS1 9600 vt100\n"
     1281//usage:    "   #\n"
     1282//usage:    "   # Example how to put a getty on a modem line\n"
     1283//usage:    "   #::respawn:/sbin/getty 57600 ttyS2\n"
     1284//usage:    "   \n"
     1285//usage:    "   # Stuff to do when restarting the init process\n"
     1286//usage:    "   ::restart:/sbin/init\n"
     1287//usage:    "   \n"
     1288//usage:    "   # Stuff to do before rebooting\n"
     1289//usage:    "   ::ctrlaltdel:/sbin/reboot\n"
     1290//usage:    "   ::shutdown:/bin/umount -a -r\n"
     1291//usage:    "   ::shutdown:/sbin/swapoff -a\n"
Note: See TracChangeset for help on using the changeset viewer.