Changeset 1765 in MondoRescue for branches/2.2.5/mindi-busybox/init


Ignore:
Timestamp:
Nov 4, 2007, 3:16:40 AM (16 years ago)
Author:
Bruno Cornec
Message:

Update to busybox 1.7.2

Location:
branches/2.2.5/mindi-busybox/init
Files:
1 added
4 deleted
4 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.5/mindi-busybox/init/Config.in

    r821 r1765  
    66menu "Init Utilities"
    77
    8 config CONFIG_INIT
     8config INIT
    99    bool "init"
    1010    default n
     11    select FEATURE_SYSLOG
    1112    help
    1213      init is the first program run when the system boots.
    1314
    14 config CONFIG_DEBUG_INIT
     15config DEBUG_INIT
    1516    bool "debugging aid"
    1617    default n
    17     depends on CONFIG_INIT
     18    depends on INIT
    1819    help
    1920      Turn this on to disable all the dangerous
    2021      rebooting stuff when debugging.
    2122
    22 config CONFIG_FEATURE_USE_INITTAB
     23config FEATURE_USE_INITTAB
    2324    bool "Support reading an inittab file"
    2425    default y
    25     depends on CONFIG_INIT
     26    depends on INIT
    2627    help
    2728      Allow init to read an inittab file when the system boot.
    2829
    29 config CONFIG_FEATURE_INIT_SCTTY
     30config FEATURE_INIT_SCTTY
    3031    bool "Support running commands with a controlling-tty"
    3132    default n
    32     depends on CONFIG_INIT
     33    depends on INIT
    3334    help
    3435      If this option is enabled a command starting with hyphen (-)
     
    3839      the console is only accessed during development or for maintenance.
    3940
    40 config CONFIG_FEATURE_EXTRA_QUIET
     41config FEATURE_INIT_SYSLOG
     42    bool "Enable init to write to syslog"
     43    default n
     44    depends on INIT
     45
     46config FEATURE_EXTRA_QUIET
    4147    bool "Be _extra_ quiet on boot"
    4248    default y
    43     depends on CONFIG_INIT
     49    depends on INIT
    4450    help
    4551      Prevent init from logging some messages to the console during boot.
    4652
    47 config CONFIG_FEATURE_INIT_COREDUMPS
     53config FEATURE_INIT_COREDUMPS
    4854    bool "Support dumping core for child processes (debugging only)"
    4955    default n
    50     depends on CONFIG_INIT
     56    depends on INIT
    5157    help
    5258      If this option is enabled and the file /.init_enable_core
     
    5763
    5864
    59 config CONFIG_FEATURE_INITRD
     65config FEATURE_INITRD
    6066    bool "Support running init from within an initrd (not initramfs)"
    6167    default y
    62     depends on CONFIG_INIT
     68    depends on INIT
    6369    help
    6470      Legacy support for running init under the old-style initrd.  Allows
     
    6874      requires no special support.
    6975
    70 config CONFIG_HALT
     76config HALT
    7177    bool "poweroff, halt, and reboot"
    7278    default y
     
    7480      Stop all processes and either halt, reboot, or power off the system.
    7581
    76 config CONFIG_MESG
     82config MESG
    7783    bool "mesg"
    7884    default y
  • branches/2.2.5/mindi-busybox/init/halt.c

    r821 r1765  
    55 * Copyright 2006 by Rob Landley <rob@landley.net>
    66 *
    7  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
     7 * Licensed under GPL version 2, see file LICENSE in this tarball for details.
    88 */
    99
    10 #include "busybox.h"
    11 #include <signal.h>
     10#include "libbb.h"
    1211#include <sys/reboot.h>
    13 #include <unistd.h>
    1412
    15 int halt_main(int argc, char *argv[])
     13int halt_main(int argc, char **argv);
     14int halt_main(int argc, char **argv)
    1615{
    1716    static const int magic[] = {
     
    2827RB_AUTOBOOT
    2928    };
    30     static const int signals[] = {SIGUSR1, SIGUSR2, SIGTERM};
     29    static const int signals[] = { SIGUSR1, SIGUSR2, SIGTERM };
    3130
    32     char *delay = "hpr";
     31    char *delay;
    3332    int which, flags, rc = 1;
    3433
    3534    /* Figure out which applet we're running */
    36     for(which=0;delay[which]!=*bb_applet_name;which++);
     35    for (which = 0; "hpr"[which] != *applet_name; which++);
    3736
    3837    /* Parse and handle arguments */
    39     flags = bb_getopt_ulflags(argc, argv, "d:nf", &delay);
    40     if (flags&1) sleep(atoi(delay));
    41     if (!(flags&2)) sync();
     38    flags = getopt32(argv, "d:nf", &delay);
     39    if (flags & 1) sleep(xatou(delay));
     40    if (!(flags & 2)) sync();
    4241
    4342    /* Perform action. */
    4443    if (ENABLE_INIT && !(flags & 4)) {
    4544        if (ENABLE_FEATURE_INITRD) {
    46             long *pidlist=find_pid_by_name("linuxrc");
    47             if (*pidlist>0) rc = kill(*pidlist,signals[which]);
    48             if (ENABLE_FEATURE_CLEAN_UP) free(pidlist);
     45            pid_t *pidlist = find_pid_by_name("linuxrc");
     46            if (pidlist[0] > 0)
     47                rc = kill(pidlist[0], signals[which]);
     48            if (ENABLE_FEATURE_CLEAN_UP)
     49                free(pidlist);
    4950        }
    50         if (rc) rc = kill(1,signals[which]);
    51     } else rc = reboot(magic[which]);
     51        if (rc)
     52            rc = kill(1, signals[which]);
     53    } else
     54        rc = reboot(magic[which]);
    5255
    53     if (rc) bb_error_msg("No.");
     56    if (rc)
     57        bb_error_msg("no");
    5458    return rc;
    5559}
  • branches/2.2.5/mindi-busybox/init/init.c

    r821 r1765  
    1010 */
    1111
    12 #include "busybox.h"
    13 #include <stdio.h>
    14 #include <stdlib.h>
    15 #include <errno.h>
     12#include "libbb.h"
    1613#include <paths.h>
    17 #include <signal.h>
    18 #include <stdarg.h>
    19 #include <string.h>
    20 #include <termios.h>
    21 #include <unistd.h>
    22 #include <limits.h>
    23 #include <fcntl.h>
    24 #include <sys/ioctl.h>
    25 #include <sys/types.h>
    26 #include <sys/wait.h>
     14//#include <signal.h>
     15//#include <sys/ioctl.h>
     16//#include <sys/wait.h>
    2717#include <sys/reboot.h>
    2818
    29 #include "init_shared.h"
    30 
    31 
    32 #ifdef CONFIG_SYSLOGD
     19#if ENABLE_FEATURE_INIT_SYSLOG
    3320# include <sys/syslog.h>
    3421#endif
    3522
    36 
    37 #ifdef CONFIG_SELINUX
    38 # include <selinux/selinux.h>
    39 #endif /* CONFIG_SELINUX */
    40 
    41 
    4223#define INIT_BUFFS_SIZE 256
    43 
    44 /* From <linux/vt.h> */
    45 struct vt_stat {
    46     unsigned short v_active;    /* active vt */
    47     unsigned short v_signal;    /* signal to send */
    48     unsigned short v_state; /* vt bitmask */
     24#define CONSOLE_NAME_SIZE 32
     25#define MAXENV  16      /* Number of env. vars */
     26
     27#if ENABLE_FEATURE_INIT_COREDUMPS
     28/*
     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....
     33 */
     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. */
     54struct init_action_type {
     55    const char *name;
     56    int action;
    4957};
    50 enum { VT_GETSTATE = 0x5603 };  /* get global vt state info */
     58
     59static 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 */
     72struct init_action {
     73    struct init_action *next;
     74    int action;
     75    pid_t pid;
     76    char command[INIT_BUFFS_SIZE];
     77    char terminal[CONSOLE_NAME_SIZE];
     78};
     79
     80/* Static variables */
     81static struct init_action *init_action_list = NULL;
     82
     83#if !ENABLE_FEATURE_INIT_SYSLOG
     84static const char *log_console = VC_5;
     85#endif
     86#if !ENABLE_DEBUG_INIT
     87static sig_atomic_t got_cont = 0;
     88#endif
     89
     90enum {
     91    L_LOG = 0x1,
     92    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
     107};
     108
     109static 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 */
     118static void delete_init_action(struct init_action *a);
     119static int waitfor(const struct init_action *a, pid_t pid);
     120#if !ENABLE_DEBUG_INIT
     121static void shutdown_signal(int sig);
     122#endif
     123
     124#if !ENABLE_DEBUG_INIT
     125static void loop_forever(void)
     126{
     127    while (1)
     128        sleep(1);
     129}
     130#endif
     131
     132/* 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
     139static void message(int device, const char *fmt, ...)
     140    __attribute__ ((format(printf, 2, 3)));
     141static void message(int device, const char *fmt, ...)
     142{
     143#if !ENABLE_FEATURE_INIT_SYSLOG
     144    static int log_fd = -1;
     145#endif
     146
     147    va_list arguments;
     148    int l;
     149    char msg[128];
     150
     151    msg[0] = '\r';
     152    va_start(arguments, fmt);
     153    vsnprintf(msg + 1, sizeof(msg) - 2, fmt, arguments);
     154    va_end(arguments);
     155    msg[sizeof(msg) - 2] = '\0';
     156    l = strlen(msg);
     157
     158#if ENABLE_FEATURE_INIT_SYSLOG
     159    /* Log the message to syslogd */
     160    if (device & L_LOG) {
     161        /* don't out "\r" */
     162        openlog(applet_name, 0, LOG_DAEMON);
     163        syslog(LOG_INFO, "init: %s", msg + 1);
     164        closelog();
     165    }
     166    msg[l++] = '\n';
     167    msg[l] = '\0';
     168#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;
     181            } else {
     182                fcntl(log_fd, F_SETFD, FD_CLOEXEC);
     183            }
     184        }
     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) {
     194        /* 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 */
     200static void set_sane_term(void)
     201{
     202    struct termios tty;
     203
     204    tcgetattr(STDIN_FILENO, &tty);
     205
     206    /* set control chars */
     207    tty.c_cc[VINTR] = 3;    /* C-c */
     208    tty.c_cc[VQUIT] = 28;   /* C-\ */
     209    tty.c_cc[VERASE] = 127; /* C-? */
     210    tty.c_cc[VKILL] = 21;   /* C-u */
     211    tty.c_cc[VEOF] = 4; /* C-d */
     212    tty.c_cc[VSTART] = 17;  /* C-q */
     213    tty.c_cc[VSTOP] = 19;   /* C-s */
     214    tty.c_cc[VSUSP] = 26;   /* C-z */
     215
     216    /* use line dicipline 0 */
     217    tty.c_line = 0;
     218
     219    /* Make it be sane */
     220    tty.c_cflag &= CBAUD | CBAUDEX | CSIZE | CSTOPB | PARENB | PARODD;
     221    tty.c_cflag |= CREAD | HUPCL | CLOCAL;
     222
     223    /* input modes */
     224    tty.c_iflag = ICRNL | IXON | IXOFF;
     225
     226    /* output modes */
     227    tty.c_oflag = OPOST | ONLCR;
     228
     229    /* local modes */
     230    tty.c_lflag =
     231        ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN;
     232
     233    tcsetattr(STDIN_FILENO, TCSANOW, &tty);
     234}
    51235
    52236/* From <linux/serial.h> */
     
    71255    unsigned long   iomap_base; /* cookie passed into ioremap */
    72256    int reserved[1];
     257    /* Paranoia (imagine 64bit kernel overwriting 32bit userspace stack) */
     258    uint32_t bbox_reserved[16];
    73259};
    74 
    75 
    76 #ifndef _PATH_STDPATH
    77 #define _PATH_STDPATH   "/usr/bin:/bin:/usr/sbin:/sbin"
    78 #endif
    79 
    80 #if defined CONFIG_FEATURE_INIT_COREDUMPS
    81 /*
    82  * When a file named CORE_ENABLE_FLAG_FILE exists, setrlimit is called
    83  * before processes are spawned to set core file size as unlimited.
    84  * This is for debugging only.  Don't use this is production, unless
    85  * you want core dumps lying about....
    86  */
    87 #define CORE_ENABLE_FLAG_FILE "/.init_enable_core"
    88 #include <sys/resource.h>
    89 #endif
    90 
    91 #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
    92 
    93 #define INITTAB      "/etc/inittab" /* inittab file location */
    94 #ifndef INIT_SCRIPT
    95 #define INIT_SCRIPT  "/etc/init.d/rcS"  /* Default sysinit script. */
    96 #endif
    97 
    98 #define MAXENV  16      /* Number of env. vars */
    99 
    100 #define CONSOLE_BUFF_SIZE 32
    101 
    102 /* Allowed init action types */
    103 #define SYSINIT     0x001
    104 #define RESPAWN     0x002
    105 #define ASKFIRST    0x004
    106 #define WAIT        0x008
    107 #define ONCE        0x010
    108 #define CTRLALTDEL  0x020
    109 #define SHUTDOWN    0x040
    110 #define RESTART     0x080
    111 
    112 /* A mapping between "inittab" action name strings and action type codes. */
    113 struct init_action_type {
    114     const char *name;
    115     int action;
    116 };
    117 
    118 static const struct init_action_type actions[] = {
    119     {"sysinit", SYSINIT},
    120     {"respawn", RESPAWN},
    121     {"askfirst", ASKFIRST},
    122     {"wait", WAIT},
    123     {"once", ONCE},
    124     {"ctrlaltdel", CTRLALTDEL},
    125     {"shutdown", SHUTDOWN},
    126     {"restart", RESTART},
    127     {0, 0}
    128 };
    129 
    130 /* Set up a linked list of init_actions, to be read from inittab */
    131 struct init_action {
    132     pid_t pid;
    133     char command[INIT_BUFFS_SIZE];
    134     char terminal[CONSOLE_BUFF_SIZE];
    135     struct init_action *next;
    136     int action;
    137 };
    138 
    139 /* Static variables */
    140 static struct init_action *init_action_list = NULL;
    141 static char console[CONSOLE_BUFF_SIZE] = CONSOLE_DEV;
    142 
    143 #ifndef CONFIG_SYSLOGD
    144 static char *log_console = VC_5;
    145 #endif
    146 #if !ENABLE_DEBUG_INIT
    147 static sig_atomic_t got_cont = 0;
    148 #endif
    149 
    150 enum {
    151     LOG = 0x1,
    152     CONSOLE = 0x2,
    153 
    154 #if defined CONFIG_FEATURE_EXTRA_QUIET
    155     MAYBE_CONSOLE = 0x0,
    156 #else
    157     MAYBE_CONSOLE = CONSOLE,
    158 #endif
    159 
    160 #ifndef RB_HALT_SYSTEM
    161     RB_HALT_SYSTEM = 0xcdef0123, /* FIXME: this overflows enum */
    162     RB_ENABLE_CAD = 0x89abcdef,
    163     RB_DISABLE_CAD = 0,
    164     RB_POWER_OFF = 0x4321fedc,
    165     RB_AUTOBOOT = 0x01234567,
    166 #endif
    167 };
    168 
    169 static const char * const environment[] = {
    170     "HOME=/",
    171     "PATH=" _PATH_STDPATH,
    172     "SHELL=/bin/sh",
    173     "USER=root",
    174     NULL
    175 };
    176 
    177 /* Function prototypes */
    178 static void delete_init_action(struct init_action *a);
    179 static int waitfor(const struct init_action *a, pid_t pid);
    180 #if !ENABLE_DEBUG_INIT
    181 static void shutdown_signal(int sig);
    182 #endif
    183 
    184 static void loop_forever(void)
    185 {
    186     while (1)
    187         sleep(1);
    188 }
    189 
    190 /* Print a message to the specified device.
    191  * Device may be bitwise-or'd from LOG | CONSOLE */
    192 #if ENABLE_DEBUG_INIT
    193 #define messageD message
    194 #else
    195 static inline void messageD(int ATTRIBUTE_UNUSED device,
    196                 const char ATTRIBUTE_UNUSED *fmt, ...)
    197 {
    198 }
    199 #endif
    200 static void message(int device, const char *fmt, ...)
    201     __attribute__ ((format(printf, 2, 3)));
    202 static void message(int device, const char *fmt, ...)
    203 {
    204     va_list arguments;
    205     int l;
    206     RESERVE_CONFIG_BUFFER(msg, 1024);
    207 #ifndef CONFIG_SYSLOGD
    208     static int log_fd = -1;
    209 #endif
    210 
    211     msg[0] = '\r';
    212         va_start(arguments, fmt);
    213     l = vsnprintf(msg + 1, 1024 - 2, fmt, arguments) + 1;
    214         va_end(arguments);
    215 
    216 #ifdef CONFIG_SYSLOGD
    217     /* Log the message to syslogd */
    218     if (device & LOG) {
    219         /* don`t out "\r\n" */
    220         openlog(bb_applet_name, 0, LOG_DAEMON);
    221         syslog(LOG_INFO, "%s", msg + 1);
    222         closelog();
    223     }
    224 
    225     msg[l++] = '\n';
    226     msg[l] = 0;
    227 #else
    228 
    229     msg[l++] = '\n';
    230     msg[l] = 0;
    231     /* Take full control of the log tty, and never close it.
    232      * It's mine, all mine!  Muhahahaha! */
    233     if (log_fd < 0) {
    234         if ((log_fd = device_open(log_console, O_RDWR | O_NONBLOCK | O_NOCTTY)) < 0) {
    235             log_fd = -2;
    236             bb_error_msg("Bummer, can't write to log on %s!", log_console);
    237             device = CONSOLE;
    238         } else {
    239             fcntl(log_fd, F_SETFD, FD_CLOEXEC);
    240         }
    241     }
    242     if ((device & LOG) && (log_fd >= 0)) {
    243         bb_full_write(log_fd, msg, l);
    244     }
    245 #endif
    246 
    247     if (device & CONSOLE) {
    248         int fd = device_open(CONSOLE_DEV,
    249                     O_WRONLY | O_NOCTTY | O_NONBLOCK);
    250         /* Always send console messages to /dev/console so people will see them. */
    251         if (fd >= 0) {
    252             bb_full_write(fd, msg, l);
    253             close(fd);
    254 #if ENABLE_DEBUG_INIT
    255         /* all descriptors may be closed */
    256         } else {
    257             bb_error_msg("Bummer, can't print: ");
    258             va_start(arguments, fmt);
    259             vfprintf(stderr, fmt, arguments);
    260             va_end(arguments);
    261 #endif
    262         }
    263     }
    264     RELEASE_CONFIG_BUFFER(msg);
    265 }
    266 
    267 /* Set terminal settings to reasonable defaults */
    268 static void set_term(void)
    269 {
    270     struct termios tty;
    271 
    272     tcgetattr(STDIN_FILENO, &tty);
    273 
    274     /* set control chars */
    275     tty.c_cc[VINTR] = 3;    /* C-c */
    276     tty.c_cc[VQUIT] = 28;   /* C-\ */
    277     tty.c_cc[VERASE] = 127; /* C-? */
    278     tty.c_cc[VKILL] = 21;   /* C-u */
    279     tty.c_cc[VEOF] = 4; /* C-d */
    280     tty.c_cc[VSTART] = 17;  /* C-q */
    281     tty.c_cc[VSTOP] = 19;   /* C-s */
    282     tty.c_cc[VSUSP] = 26;   /* C-z */
    283 
    284     /* use line dicipline 0 */
    285     tty.c_line = 0;
    286 
    287     /* Make it be sane */
    288     tty.c_cflag &= CBAUD | CBAUDEX | CSIZE | CSTOPB | PARENB | PARODD;
    289     tty.c_cflag |= CREAD | HUPCL | CLOCAL;
    290 
    291 
    292     /* input modes */
    293     tty.c_iflag = ICRNL | IXON | IXOFF;
    294 
    295     /* output modes */
    296     tty.c_oflag = OPOST | ONLCR;
    297 
    298     /* local modes */
    299     tty.c_lflag =
    300         ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN;
    301 
    302     tcsetattr(STDIN_FILENO, TCSANOW, &tty);
    303 }
    304 
    305260static void console_init(void)
    306261{
    307     int fd;
    308     int tried = 0;
    309     struct vt_stat vt;
    310262    struct serial_struct sr;
    311263    char *s;
    312264
    313     if ((s = getenv("CONSOLE")) != NULL || (s = getenv("console")) != NULL) {
    314         safe_strncpy(console, s, sizeof(console));
    315 #if 0 /* #cpu(sparc) */
    316     /* sparc kernel supports console=tty[ab] parameter which is also
    317      * passed to init, so catch it here */
    318         /* remap tty[ab] to /dev/ttyS[01] */
    319         if (strcmp(s, "ttya") == 0)
    320             safe_strncpy(console, SC_0, sizeof(console));
    321         else if (strcmp(s, "ttyb") == 0)
    322             safe_strncpy(console, SC_1, sizeof(console));
    323 #endif
     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);
    324276    } else {
    325         /* 2.2 kernels: identify the real console backend and try to use it */
    326         if (ioctl(0, TIOCGSERIAL, &sr) == 0) {
    327             /* this is a serial console */
    328             snprintf(console, sizeof(console) - 1, SC_FORMAT, sr.line);
    329         } else if (ioctl(0, VT_GETSTATE, &vt) == 0) {
    330             /* this is linux virtual tty */
    331             snprintf(console, sizeof(console) - 1, VC_FORMAT, vt.v_active);
     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
     294static 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 */
     305static void open_stdio_to_tty(const char* tty_name, int fail)
     306{
     307    /* empty tty_name means "use init's tty", else... */
     308    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",
     312                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
    332320        } else {
    333             safe_strncpy(console, CONSOLE_DEV, sizeof(console));
    334             tried++;
    335         }
    336     }
    337 
    338     while ((fd = open(console, O_RDONLY | O_NONBLOCK)) < 0 && tried < 2) {
    339         /* Can't open selected console -- try
    340             logical system console and VT_MASTER */
    341         safe_strncpy(console, (tried == 0 ? CONSOLE_DEV : CURRENT_VC),
    342                             sizeof(console));
    343         tried++;
    344     }
    345     if (fd < 0) {
    346         /* Perhaps we should panic here? */
    347 #ifndef CONFIG_SYSLOGD
    348         log_console =
    349 #endif
    350         safe_strncpy(console, bb_dev_null, sizeof(console));
    351     } else {
    352         s = getenv("TERM");
    353         /* check for serial console */
    354         if (ioctl(fd, TIOCGSERIAL, &sr) == 0) {
    355             /* Force the TERM setting to vt102 for serial console --
    356              * if TERM is set to linux (the default) */
    357             if (s == NULL || strcmp(s, "linux") == 0)
    358                 putenv("TERM=vt102");
    359 #ifndef CONFIG_SYSLOGD
    360             log_console = console;
    361 #endif
    362         } else {
    363             if (s == NULL)
    364                 putenv("TERM=linux");
    365         }
    366         close(fd);
    367     }
    368     messageD(LOG, "console=%s", console);
    369 }
    370 
    371 static void fixup_argv(int argc, char **argv, char *new_argv0)
    372 {
    373     int len;
    374 
    375     /* Fix up argv[0] to be certain we claim to be init */
    376     len = strlen(argv[0]);
    377     memset(argv[0], 0, len);
    378     safe_strncpy(argv[0], new_argv0, len + 1);
    379 
    380     /* Wipe argv[1]-argv[N] so they don't clutter the ps listing */
    381     len = 1;
    382     while (argc > len) {
    383         memset(argv[len], 0, strlen(argv[len]));
    384         len++;
    385     }
    386 }
    387 
    388 /* Open the new terminal device */
    389 static void open_new_terminal(const char * const device, const int fail) {
    390     struct stat sb;
    391 
    392     if ((device_open(device, O_RDWR)) < 0) {
    393         if (stat(device, &sb) != 0) {
    394             message(LOG | CONSOLE, "device '%s' does not exist.", device);
    395         } else {
    396             message(LOG | CONSOLE, "Bummer, can't open %s", device);
    397         }
    398         if (fail)
    399             _exit(1);
    400         /* else */
    401 #if !ENABLE_DEBUG_INIT
    402         shutdown_signal(SIGUSR1);
    403 #else
    404         _exit(2);
    405 #endif
    406     }
     321            dup2(fd, 0);
     322            dup2(fd, 1);
     323            dup2(fd, 2);
     324            if (fd > 2) close(fd);
     325        }
     326    }
     327    set_sane_term();
    407328}
    408329
     
    411332    int i;
    412333    pid_t pid;
    413     char *s, *tmpCmd, *cmd[INIT_BUFFS_SIZE], *cmdpath;
     334    char *s, *tmpCmd, *cmdpath;
     335    char *cmd[INIT_BUFFS_SIZE];
    414336    char buf[INIT_BUFFS_SIZE + 6];  /* INIT_BUFFS_SIZE+strlen("exec ")+1 */
    415337    sigset_t nmask, omask;
    416     static const char press_enter[] =
    417 #ifdef CUSTOMIZED_BANNER
    418 #include CUSTOMIZED_BANNER
    419 #endif
    420         "\nPlease press Enter to activate this console. ";
    421338
    422339    /* Block sigchild while forking.  */
     
    424341    sigaddset(&nmask, SIGCHLD);
    425342    sigprocmask(SIG_BLOCK, &nmask, &omask);
    426 
    427     if ((pid = fork()) == 0) {
    428 
    429         /* Clean up */
    430         close(0);
    431         close(1);
    432         close(2);
    433         sigprocmask(SIG_SETMASK, &omask, NULL);
    434 
    435         /* Reset signal handlers that were set by the parent process */
    436         signal(SIGUSR1, SIG_DFL);
    437         signal(SIGUSR2, SIG_DFL);
    438         signal(SIGINT, SIG_DFL);
    439         signal(SIGTERM, SIG_DFL);
    440         signal(SIGHUP, SIG_DFL);
    441         signal(SIGQUIT, SIG_DFL);
    442         signal(SIGCONT, SIG_DFL);
    443         signal(SIGSTOP, SIG_DFL);
    444         signal(SIGTSTP, SIG_DFL);
    445 
    446         /* Create a new session and make ourself the process
    447          * group leader */
    448         setsid();
    449 
    450         /* Open the new terminal device */
    451         open_new_terminal(a->terminal, 1);
    452 
    453         /* Make sure the terminal will act fairly normal for us */
    454         set_term();
    455         /* Setup stdout, stderr for the new process so
    456          * they point to the supplied terminal */
    457         dup(0);
    458         dup(0);
    459 
    460         /* If the init Action requires us to wait, then force the
    461          * supplied terminal to be the controlling tty. */
    462         if (a->action & (SYSINIT | WAIT | CTRLALTDEL | SHUTDOWN | RESTART)) {
    463 
    464             /* Now fork off another process to just hang around */
     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. */
    465391            if ((pid = fork()) < 0) {
    466                 message(LOG | CONSOLE, "Can't fork!");
     392                message(L_LOG | L_CONSOLE, "Can't fork");
    467393                _exit(1);
    468394            }
    469 
    470             if (pid > 0) {
    471 
    472                 /* We are the parent -- wait till the child is done */
    473                 signal(SIGINT, SIG_IGN);
    474                 signal(SIGTSTP, SIG_IGN);
    475                 signal(SIGQUIT, SIG_IGN);
    476                 signal(SIGCHLD, SIG_DFL);
    477 
    478                 waitfor(NULL, pid);
    479                 /* See if stealing the controlling tty back is necessary */
    480                 if (tcgetpgrp(0) != getpid())
    481                     _exit(0);
    482 
    483                 /* Use a temporary process to steal the controlling tty. */
    484                 if ((pid = fork()) < 0) {
    485                     message(LOG | CONSOLE, "Can't fork!");
    486                     _exit(1);
    487                 }
    488                 if (pid == 0) {
    489                     setsid();
    490                     ioctl(0, TIOCSCTTY, 1);
    491                     _exit(0);
    492                 }
    493                 waitfor(NULL, pid);
     395            if (pid == 0) {
     396                setsid();
     397                ioctl(0, TIOCSCTTY, 1);
    494398                _exit(0);
    495399            }
    496 
    497             /* Now fall though to actually execute things */
    498         }
    499 
    500         /* See if any special /bin/sh requiring characters are present */
    501         if (strpbrk(a->command, "~`!$^&*()=|\\{}[];\"'<>?") != NULL) {
    502             cmd[0] = (char *)DEFAULT_SHELL;
    503             cmd[1] = "-c";
    504             cmd[2] = strcat(strcpy(buf, "exec "), a->command);
    505             cmd[3] = NULL;
     400            waitfor(NULL, pid);
     401            _exit(0);
     402        }
     403
     404        /* Now fall though to actually execute things */
     405    }
     406
     407    /* See if any special /bin/sh requiring characters are present */
     408    if (strpbrk(a->command, "~`!$^&*()=|\\{}[];\"'<>?") != NULL) {
     409        cmd[0] = (char*)DEFAULT_SHELL;
     410        cmd[1] = (char*)"-c";
     411        cmd[2] = strcat(strcpy(buf, "exec "), a->command);
     412        cmd[3] = NULL;
     413    } else {
     414        /* 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;
     420                i++;
     421            }
     422        }
     423        cmd[i] = NULL;
     424    }
     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;
    506445        } else {
    507             /* Convert command (char*) into cmd (char**, one word per string) */
    508             strcpy(buf, a->command);
    509             s = buf;
    510             for (tmpCmd = buf, i = 0; (tmpCmd = strsep(&s, " \t")) != NULL;) {
    511                 if (*tmpCmd != '\0') {
    512                     cmd[i] = tmpCmd;
    513                     i++;
    514                 }
    515             }
    516             cmd[i] = NULL;
    517         }
    518 
    519         cmdpath = cmd[0];
    520 
     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) {
     460        static const char press_enter[] ALIGN1 =
     461#ifdef CUSTOMIZED_BANNER
     462#include CUSTOMIZED_BANNER
     463#endif
     464            "\nPlease press Enter to activate this console. ";
     465        char c;
    521466        /*
    522            Interactive shells want to see a dash in argv[0].  This
    523            typically is handled by login, argv will be setup this
    524            way if a dash appears at the front of the command path
    525            (like "-/bin/sh").
     467         * Save memory by not exec-ing anything large (like a shell)
     468         * before the user wants it. This is critical if swap is not
     469         * enabled and the system has low memory. Generally this will
     470         * be run on the second virtual console, and the first will
     471         * be allowed to start a shell or whatever an init script
     472         * specifies.
    526473         */
    527 
    528         if (*cmdpath == '-') {
    529 
    530             /* skip over the dash */
    531             ++cmdpath;
    532 
    533             /* find the last component in the command pathname */
    534             s = bb_get_last_path_component(cmdpath);
    535 
    536             /* make a new argv[0] */
    537             if ((cmd[0] = malloc(strlen(s) + 2)) == NULL) {
    538                 message(LOG | CONSOLE, bb_msg_memory_exhausted);
    539                 cmd[0] = cmdpath;
    540             } else {
    541                 cmd[0][0] = '-';
    542                 strcpy(cmd[0] + 1, s);
    543             }
    544 #ifdef CONFIG_FEATURE_INIT_SCTTY
    545             /* Establish this process as session leader and
    546              * (attempt) to make the tty (if any) a controlling tty.
    547              */
    548             (void) setsid();
    549             (void) ioctl(0, TIOCSCTTY, 0/*don't steal it*/);
    550 #endif
    551         }
    552 
    553 #if !defined(__UCLIBC__) || defined(__ARCH_HAS_MMU__)
    554         if (a->action & ASKFIRST) {
    555             char c;
    556             /*
    557              * Save memory by not exec-ing anything large (like a shell)
    558              * before the user wants it. This is critical if swap is not
    559              * enabled and the system has low memory. Generally this will
    560              * be run on the second virtual console, and the first will
    561              * be allowed to start a shell or whatever an init script
    562              * specifies.
    563              */
    564             messageD(LOG, "Waiting for enter to start '%s'"
    565                         "(pid %d, terminal %s)\n",
    566                       cmdpath, getpid(), a->terminal);
    567             bb_full_write(1, press_enter, sizeof(press_enter) - 1);
    568             while(read(0, &c, 1) == 1 && c != '\n')
    569                 ;
    570         }
    571 #endif
    572 
    573         /* Log the process name and args */
    574         message(LOG, "Starting pid %d, console %s: '%s'",
    575                   getpid(), a->terminal, cmdpath);
    576 
    577 #if defined CONFIG_FEATURE_INIT_COREDUMPS
    578         {
    579             struct stat sb;
    580             if (stat(CORE_ENABLE_FLAG_FILE, &sb) == 0) {
    581                 struct rlimit limit;
    582 
    583                 limit.rlim_cur = RLIM_INFINITY;
    584                 limit.rlim_max = RLIM_INFINITY;
    585                 setrlimit(RLIMIT_CORE, &limit);
    586             }
    587         }
    588 #endif
    589 
    590         /* Now run it.  The new program will take over this PID,
    591          * so nothing further in init.c should be run. */
    592         execv(cmdpath, cmd);
    593 
    594         /* We're still here?  Some error happened. */
    595         message(LOG | CONSOLE, "Bummer, could not run '%s': %m", cmdpath);
    596         _exit(-1);
    597     }
    598     sigprocmask(SIG_SETMASK, &omask, NULL);
    599     return pid;
     474        messageD(L_LOG, "waiting for enter to start '%s'"
     475                    "(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) {
     490            struct rlimit limit;
     491
     492            limit.rlim_cur = RLIM_INFINITY;
     493            limit.rlim_max = RLIM_INFINITY;
     494            setrlimit(RLIMIT_CORE, &limit);
     495        }
     496    }
     497#endif
     498    /* Now run it.  The new program will take over this PID,
     499     * so nothing further in init.c should be run. */
     500    BB_EXECVP(cmdpath, cmd);
     501
     502    /* We're still here?  Some error happened. */
     503    message(L_LOG | L_CONSOLE, "Cannot run '%s': %s",
     504            cmdpath, strerror(errno));
     505    _exit(-1);
    600506}
    601507
     
    607513    runpid = (NULL == a)? pid : run(a);
    608514    while (1) {
    609         wpid = waitpid(runpid,&status,0);
     515        wpid = waitpid(runpid, &status, 0);
    610516        if (wpid == runpid)
    611517            break;
     
    628534        tmp = a->next;
    629535        if (a->action == action) {
    630             if (access(a->terminal, R_OK | W_OK)) {
     536            /* a->terminal of "" means "init's console" */
     537            if (a->terminal[0] && access(a->terminal, R_OK | W_OK)) {
    631538                delete_init_action(a);
    632539            } else if (a->action & (SYSINIT | WAIT | CTRLALTDEL | SHUTDOWN | RESTART)) {
     
    654561     * linux/kernel/sys.c, which can cause the machine to panic when
    655562     * the init process is killed.... */
    656     if ((pid = fork()) == 0) {
     563    pid = vfork();
     564    if (pid == 0) { /* child */
    657565        reboot(magic);
    658566        _exit(0);
    659567    }
    660     waitpid (pid, NULL, 0);
     568    waitpid(pid, NULL, 0);
    661569}
    662570
     
    684592    sigprocmask(SIG_BLOCK, &block_signals, NULL);
    685593
     594    message(L_CONSOLE | L_LOG, "The system is going down NOW!");
     595
    686596    /* Allow Ctrl-Alt-Del to reboot system. */
    687597    init_reboot(RB_ENABLE_CAD);
    688598
    689     message(CONSOLE | LOG, "The system is going down NOW !!");
     599    /* Send signals to every process _except_ pid 1 */
     600    message(L_CONSOLE | L_LOG, "Sending SIG%s to all processes", "TERM");
     601    kill(-1, SIGTERM);
    690602    sync();
    691 
    692     /* Send signals to every process _except_ pid 1 */
    693     message(CONSOLE | LOG, init_sending_format, "TERM");
    694     kill(-1, SIGTERM);
    695603    sleep(1);
     604
     605    message(L_CONSOLE | L_LOG, "Sending SIG%s to all processes", "KILL");
     606    kill(-1, SIGKILL);
    696607    sync();
    697 
    698     message(CONSOLE | LOG, init_sending_format, "KILL");
    699     kill(-1, SIGKILL);
    700608    sleep(1);
    701 
    702     sync();
    703609}
    704610
     
    727633            sigprocmask(SIG_UNBLOCK, &unblock_signals, NULL);
    728634
    729             /* Close whatever files are open. */
    730             close(0);
    731             close(1);
    732             close(2);
    733 
    734635            /* Open the new terminal device */
    735             open_new_terminal(a->terminal, 0);
    736 
    737             /* Make sure the terminal will act fairly normal for us */
    738             set_term();
    739             /* Setup stdout, stderr on the supplied terminal */
    740             dup(0);
    741             dup(0);
    742 
    743             messageD(CONSOLE | LOG, "Trying to re-exec %s", a->command);
    744             execl(a->command, a->command, NULL);
    745 
    746             message(CONSOLE | LOG, "exec of '%s' failed: %m",
    747                     a->command);
    748             sync();
     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));
    749643            sleep(2);
    750644            init_reboot(RB_HALT_SYSTEM);
     
    756650static void shutdown_signal(int sig)
    757651{
    758     char *m;
     652    const char *m;
    759653    int rb;
    760654
    761655    shutdown_system();
    762656
     657    m = "halt";
     658    rb = RB_HALT_SYSTEM;
    763659    if (sig == SIGTERM) {
    764660        m = "reboot";
     
    767663        m = "poweroff";
    768664        rb = RB_POWER_OFF;
    769     } else {
    770         m = "halt";
    771         rb = RB_HALT_SYSTEM;
    772     }
    773     message(CONSOLE | LOG, "Requesting system %s.", m);
    774     sync();
    775 
     665    }
     666    message(L_CONSOLE | L_LOG, "Requesting system %s", m);
    776667    /* allow time for last message to reach serial console */
    777668    sleep(2);
    778 
    779669    init_reboot(rb);
    780 
    781670    loop_forever();
    782671}
     
    805694}
    806695
    807 #endif                          /* ! ENABLE_DEBUG_INIT */
     696#endif  /* !ENABLE_DEBUG_INIT */
    808697
    809698static void new_init_action(int action, const char *command, const char *cons)
    810699{
    811700    struct init_action *new_action, *a, *last;
    812 
    813     if (*cons == '\0')
    814         cons = console;
    815701
    816702    if (strcmp(cons, bb_dev_null) == 0 && (action & ASKFIRST))
    817703        return;
    818 
    819     new_action = calloc((size_t) (1), sizeof(struct init_action));
    820     if (!new_action) {
    821         message(LOG | CONSOLE, "Memory allocation failure");
    822         loop_forever();
    823     }
    824704
    825705    /* Append to the end of the list */
     
    827707        /* don't enter action if it's already in the list,
    828708         * but do overwrite existing actions */
    829         if ((strcmp(a->command, command) == 0) &&
    830             (strcmp(a->terminal, cons) ==0)) {
     709        if ((strcmp(a->command, command) == 0)
     710         && (strcmp(a->terminal, cons) == 0)
     711        ) {
    831712            a->action = action;
    832             free(new_action);
    833713            return;
    834714        }
    835715        last = a;
    836716    }
     717
     718    new_action = xzalloc(sizeof(struct init_action));
    837719    if (last) {
    838720        last->next = new_action;
     
    843725    new_action->action = action;
    844726    strcpy(new_action->terminal, cons);
    845 #if 0   /* calloc zeroed always */
    846     new_action->pid = 0;
    847 #endif
    848     messageD(LOG|CONSOLE, "command='%s' action='%d' terminal='%s'\n",
     727    messageD(L_LOG | L_CONSOLE, "command='%s' action=%d tty='%s'\n",
    849728        new_action->command, new_action->action, new_action->terminal);
    850729}
     
    876755static void parse_inittab(void)
    877756{
    878 #ifdef CONFIG_FEATURE_USE_INITTAB
     757#if ENABLE_FEATURE_USE_INITTAB
    879758    FILE *file;
    880759    char buf[INIT_BUFFS_SIZE], lineAsRead[INIT_BUFFS_SIZE];
    881     char tmpConsole[CONSOLE_BUFF_SIZE];
     760    char tmpConsole[CONSOLE_NAME_SIZE];
    882761    char *id, *runlev, *action, *command, *eol;
    883762    const struct init_action_type *a = actions;
    884 
    885763
    886764    file = fopen(INITTAB, "r");
     
    889767#endif
    890768        /* Reboot on Ctrl-Alt-Del */
    891         new_init_action(CTRLALTDEL, "/sbin/reboot", "");
     769        new_init_action(CTRLALTDEL, "reboot", "");
    892770        /* Umount all filesystems on halt/reboot */
    893         new_init_action(SHUTDOWN, "/bin/umount -a -r", "");
     771        new_init_action(SHUTDOWN, "umount -a -r", "");
    894772        /* Swapoff on halt/reboot */
    895         if(ENABLE_SWAPONOFF) new_init_action(SHUTDOWN, "/sbin/swapoff -a", "");
     773        if (ENABLE_SWAPONOFF) new_init_action(SHUTDOWN, "swapoff -a", "");
    896774        /* Prepare to restart init when a HUP is received */
    897         new_init_action(RESTART, "/sbin/init", "");
     775        new_init_action(RESTART, "init", "");
    898776        /* Askfirst shell on tty1-4 */
    899777        new_init_action(ASKFIRST, bb_default_login_shell, "");
     
    905783
    906784        return;
    907 #ifdef CONFIG_FEATURE_USE_INITTAB
     785#if ENABLE_FEATURE_USE_INITTAB
    908786    }
    909787
     
    917795
    918796        /* Trim the trailing \n */
     797        //XXX: chomp() ?
    919798        eol = strrchr(id, '\n');
    920799        if (eol != NULL)
     
    927806        runlev = strchr(id, ':');
    928807        if (runlev == NULL || *(runlev + 1) == '\0') {
    929             message(LOG | CONSOLE, "Bad inittab entry: %s", lineAsRead);
     808            message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead);
    930809            continue;
    931810        } else {
     
    937816        action = strchr(runlev, ':');
    938817        if (action == NULL || *(action + 1) == '\0') {
    939             message(LOG | CONSOLE, "Bad inittab entry: %s", lineAsRead);
     818            message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead);
    940819            continue;
    941820        } else {
     
    947826        command = strchr(action, ':');
    948827        if (command == NULL || *(command + 1) == '\0') {
    949             message(LOG | CONSOLE, "Bad inittab entry: %s", lineAsRead);
     828            message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead);
    950829            continue;
    951830        } else {
     
    958837            if (strcmp(a->name, action) == 0) {
    959838                if (*id != '\0') {
    960                     if(strncmp(id, "/dev/", 5) == 0)
     839                    if (strncmp(id, "/dev/", 5) == 0)
    961840                        id += 5;
    962841                    strcpy(tmpConsole, "/dev/");
    963842                    safe_strncpy(tmpConsole + 5, id,
    964                         CONSOLE_BUFF_SIZE - 5);
     843                        sizeof(tmpConsole) - 5);
    965844                    id = tmpConsole;
    966845                }
     
    971850        if (a->name == 0) {
    972851            /* Choke on an unknown action */
    973             message(LOG | CONSOLE, "Bad inittab entry: %s", lineAsRead);
     852            message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead);
    974853        }
    975854    }
    976855    fclose(file);
    977     return;
    978 #endif                          /* CONFIG_FEATURE_USE_INITTAB */
    979 }
    980 
    981 #ifdef CONFIG_FEATURE_USE_INITTAB
     856#endif /* FEATURE_USE_INITTAB */
     857}
     858
     859#if ENABLE_FEATURE_USE_INITTAB
    982860static void reload_signal(int sig ATTRIBUTE_UNUSED)
    983861{
    984862    struct init_action *a, *tmp;
    985863
    986     message(LOG, "Reloading /etc/inittab");
     864    message(L_LOG, "reloading /etc/inittab");
    987865
    988866    /* disable old entrys */
     
    996874    for (a = init_action_list; a; a = tmp) {
    997875        tmp = a->next;
    998         if (a->action & (ONCE | SYSINIT | WAIT ) &&
    999                 a->pid == 0 ) {
     876        if ((a->action & (ONCE | SYSINIT | WAIT)) && a->pid == 0) {
    1000877            delete_init_action(a);
    1001878        }
    1002879    }
    1003880    run_actions(RESPAWN);
    1004     return;
    1005 }
    1006 #endif                          /* CONFIG_FEATURE_USE_INITTAB */
    1007 
     881}
     882#endif  /* FEATURE_USE_INITTAB */
     883
     884int init_main(int argc, char **argv);
    1008885int init_main(int argc, char **argv)
    1009886{
     
    1011888    pid_t wpid;
    1012889
     890    die_sleep = 30 * 24*60*60; /* if xmalloc will ever die... */
     891
    1013892    if (argc > 1 && !strcmp(argv[1], "-q")) {
    1014         return kill(1,SIGHUP);
     893        return kill(1, SIGHUP);
    1015894    }
    1016895#if !ENABLE_DEBUG_INIT
    1017896    /* Expect to be invoked as init with PID=1 or be invoked as linuxrc */
    1018     if (getpid() != 1 &&
    1019         (!ENABLE_FEATURE_INITRD || !strstr(bb_applet_name, "linuxrc")))
    1020     {
     897    if (getpid() != 1
     898     && (!ENABLE_FEATURE_INITRD || !strstr(applet_name, "linuxrc"))
     899    ) {
    1021900        bb_show_usage();
    1022901    }
     
    1038917#endif
    1039918
     919
    1040920    /* Figure out where the default console should be */
    1041921    console_init();
    1042 
    1043     /* Close whatever files are open, and reset the console. */
    1044     close(0);
    1045     close(1);
    1046     close(2);
    1047 
    1048     if (device_open(console, O_RDWR | O_NOCTTY) == 0) {
    1049         set_term();
    1050         close(0);
    1051     }
    1052 
     922    set_sane_term();
    1053923    chdir("/");
    1054924    setsid();
    1055925    {
    1056         const char * const *e;
     926        const char *const *e;
    1057927        /* Make sure environs is set to something sane */
    1058         for(e = environment; *e; e++)
     928        for (e = environment; *e; e++)
    1059929            putenv((char *) *e);
    1060930    }
     931
     932    if (argc > 1) setenv("RUNLEVEL", argv[1], 1);
     933
    1061934    /* Hello world */
    1062     message(MAYBE_CONSOLE | LOG, "init started:  %s", bb_msg_full_version);
     935    message(MAYBE_CONSOLE | L_LOG, "init started: %s", bb_banner);
    1063936
    1064937    /* Make sure there is enough memory to do something useful. */
     
    1067940
    1068941        if (!sysinfo(&info) &&
    1069             (info.mem_unit ? : 1) * (long long)info.totalram < MEGABYTE)
     942            (info.mem_unit ? : 1) * (long long)info.totalram < 1024*1024)
    1070943        {
    1071             message(CONSOLE,"Low memory: forcing swapon.");
     944            message(L_CONSOLE, "Low memory, forcing swapon");
    1072945            /* swapon -a requires /proc typically */
    1073             new_init_action(SYSINIT, "/bin/mount -t proc proc /proc", "");
     946            new_init_action(SYSINIT, "mount -t proc proc /proc", "");
    1074947            /* Try to turn on swap */
    1075             new_init_action(SYSINIT, "/sbin/swapon -a", "");
     948            new_init_action(SYSINIT, "swapon -a", "");
    1076949            run_actions(SYSINIT);   /* wait and removing */
    1077950        }
     
    1079952
    1080953    /* Check if we are supposed to be in single user mode */
    1081     if (argc > 1 && (!strcmp(argv[1], "single") ||
    1082                      !strcmp(argv[1], "-s") || !strcmp(argv[1], "1"))) {
     954    if (argc > 1
     955     && (!strcmp(argv[1], "single") || !strcmp(argv[1], "-s") || LONE_CHAR(argv[1], '1'))
     956    ) {
    1083957        /* Start a shell on console */
    1084958        new_init_action(RESPAWN, bb_default_login_shell, "");
     
    1093967    }
    1094968
    1095 #ifdef CONFIG_SELINUX
     969#if ENABLE_SELINUX
    1096970    if (getenv("SELINUX_INIT") == NULL) {
    1097971        int enforce = 0;
    1098972
    1099         putenv("SELINUX_INIT=YES");
     973        putenv((char*)"SELINUX_INIT=YES");
    1100974        if (selinux_init_load_policy(&enforce) == 0) {
    1101             execv(argv[0], argv);
     975            BB_EXECVP(argv[0], argv);
    1102976        } else if (enforce > 0) {
    1103977            /* SELinux in enforcing mode but load_policy failed */
    1104978            /* At this point, we probably can't open /dev/console, so log() won't work */
    1105             message(CONSOLE,"Unable to load SELinux Policy. Machine is in enforcing mode. Halting now.");
     979            message(L_CONSOLE, "Cannot load SELinux Policy. "
     980                "Machine is in enforcing mode. Halting now.");
    1106981            exit(1);
    1107982        }
     
    1110985
    1111986    /* Make the command line just say "init"  -- thats all, nothing else */
    1112     fixup_argv(argc, argv, "init");
     987    fixup_argv(argv);
    1113988
    1114989    /* Now run everything that needs to be run */
     
    1123998    run_actions(ONCE);
    1124999
    1125 #ifdef CONFIG_FEATURE_USE_INITTAB
     1000#if ENABLE_FEATURE_USE_INITTAB
    11261001    /* Redefine SIGHUP to reread /etc/inittab */
    11271002    signal(SIGHUP, reload_signal);
    11281003#else
    11291004    signal(SIGHUP, SIG_IGN);
    1130 #endif /* CONFIG_FEATURE_USE_INITTAB */
    1131 
     1005#endif /* FEATURE_USE_INITTAB */
    11321006
    11331007    /* Now run the looping stuff for the rest of forever */
     
    11511025                     * restarted by run_actions() */
    11521026                    a->pid = 0;
    1153                     message(LOG, "Process '%s' (pid %d) exited. "
     1027                    message(L_LOG, "process '%s' (pid %d) exited. "
    11541028                            "Scheduling it for restart.",
    11551029                            a->command, wpid);
     
    11571031            }
    11581032            /* see if anyone else is waiting to be reaped */
    1159             wpid = waitpid (-1, NULL, WNOHANG);
    1160         }
    1161     }
    1162 }
     1033            wpid = waitpid(-1, NULL, WNOHANG);
     1034        }
     1035    }
     1036}
  • branches/2.2.5/mindi-busybox/init/mesg.c

    r821 r1765  
    88 */
    99
    10 #include "busybox.h"
    11 #include <unistd.h>
    12 #include <stdlib.h>
     10#include "libbb.h"
    1311
    1412#ifdef USE_TTY_GROUP
     
    1816#endif
    1917
    20 int mesg_main(int argc, char *argv[])
     18int mesg_main(int argc, char **argv);
     19int mesg_main(int argc, char **argv)
    2120{
    2221    struct stat sb;
    23     char *tty;
     22    const char *tty;
    2423    char c = 0;
    2524
    26     if ((--argc == 0)
    27         || ((argc == 1) && (((c = **++argv) == 'y') || (c == 'n')))) {
    28         if ((tty = ttyname(STDERR_FILENO)) == NULL) {
     25    if (--argc == 0
     26     || (argc == 1 && ((c = **++argv) == 'y' || c == 'n'))
     27    ) {
     28        tty = ttyname(STDERR_FILENO);
     29        if (tty == NULL) {
    2930            tty = "ttyname";
    3031        } else if (stat(tty, &sb) == 0) {
     32            mode_t m;
    3133            if (argc == 0) {
    32                 puts(((sb.st_mode & (S_IWGRP | S_IWOTH)) ==
    33                       0) ? "is n" : "is y");
     34                puts((sb.st_mode & (S_IWGRP|S_IWOTH)) ? "is y" : "is n");
    3435                return EXIT_SUCCESS;
    3536            }
    36             if (chmod
    37                 (tty,
    38                  (c ==
    39                   'y') ? sb.st_mode | (S_IWGRP_OR_S_IWOTH) : sb.
    40                  st_mode & ~(S_IWGRP | S_IWOTH)) == 0) {
     37            m = (c == 'y') ? sb.st_mode | S_IWGRP_OR_S_IWOTH
     38                           : sb.st_mode & ~(S_IWGRP|S_IWOTH);
     39            if (chmod(tty, m) == 0) {
    4140                return EXIT_SUCCESS;
    4241            }
Note: See TracChangeset for help on using the changeset viewer.