aboutsummaryrefslogtreecommitdiff
path: root/init/init.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-02-21 00:15:20 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-02-21 00:15:20 +0000
commit7a2ca5e111a21cca703e111ee448317bfaf96ed9 (patch)
treebe7c65eeb924440e094ba4bdc46b60317eefe6f1 /init/init.c
parenta624c11d5e9ac32f6e7b22b406e5a0eec44e2d3b (diff)
downloadbusybox-w32-7a2ca5e111a21cca703e111ee448317bfaf96ed9.tar.gz
busybox-w32-7a2ca5e111a21cca703e111ee448317bfaf96ed9.tar.bz2
busybox-w32-7a2ca5e111a21cca703e111ee448317bfaf96ed9.zip
init: stop doing silly things with the console (-400 bytes)
init_shared.[ch]: unused, thus deleted
Diffstat (limited to 'init/init.c')
-rw-r--r--init/init.c348
1 files changed, 131 insertions, 217 deletions
diff --git a/init/init.c b/init/init.c
index b488f649f..ec18332fb 100644
--- a/init/init.c
+++ b/init/init.c
@@ -16,44 +16,13 @@
16#include <sys/wait.h> 16#include <sys/wait.h>
17#include <sys/reboot.h> 17#include <sys/reboot.h>
18 18
19#include "init_shared.h"
20
21#if ENABLE_SYSLOGD 19#if ENABLE_SYSLOGD
22# include <sys/syslog.h> 20# include <sys/syslog.h>
23#endif 21#endif
24 22
25#define INIT_BUFFS_SIZE 256 23#define INIT_BUFFS_SIZE 256
26 24#define CONSOLE_NAME_SIZE 32
27/* From <linux/vt.h> */ 25#define MAXENV 16 /* Number of env. vars */
28struct vt_stat {
29 unsigned short v_active; /* active vt */
30 unsigned short v_signal; /* signal to send */
31 unsigned short v_state; /* vt bitmask */
32};
33enum { VT_GETSTATE = 0x5603 }; /* get global vt state info */
34
35/* From <linux/serial.h> */
36struct serial_struct {
37 int type;
38 int line;
39 unsigned int port;
40 int irq;
41 int flags;
42 int xmit_fifo_size;
43 int custom_divisor;
44 int baud_base;
45 unsigned short close_delay;
46 char io_type;
47 char reserved_char[1];
48 int hub6;
49 unsigned short closing_wait; /* time to wait before closing */
50 unsigned short closing_wait2; /* no longer used... */
51 unsigned char *iomem_base;
52 unsigned short iomem_reg_shift;
53 unsigned int port_high;
54 unsigned long iomap_base; /* cookie passed into ioremap */
55 int reserved[1];
56};
57 26
58#ifndef _PATH_STDPATH 27#ifndef _PATH_STDPATH
59#define _PATH_STDPATH "/usr/bin:/bin:/usr/sbin:/sbin" 28#define _PATH_STDPATH "/usr/bin:/bin:/usr/sbin:/sbin"
@@ -75,10 +44,6 @@ struct serial_struct {
75#define INIT_SCRIPT "/etc/init.d/rcS" /* Default sysinit script. */ 44#define INIT_SCRIPT "/etc/init.d/rcS" /* Default sysinit script. */
76#endif 45#endif
77 46
78#define MAXENV 16 /* Number of env. vars */
79
80#define CONSOLE_BUFF_SIZE 32
81
82/* Allowed init action types */ 47/* Allowed init action types */
83#define SYSINIT 0x001 48#define SYSINIT 0x001
84#define RESPAWN 0x002 49#define RESPAWN 0x002
@@ -109,16 +74,15 @@ static const struct init_action_type actions[] = {
109 74
110/* Set up a linked list of init_actions, to be read from inittab */ 75/* Set up a linked list of init_actions, to be read from inittab */
111struct init_action { 76struct init_action {
112 pid_t pid;
113 char command[INIT_BUFFS_SIZE];
114 char terminal[CONSOLE_BUFF_SIZE];
115 struct init_action *next; 77 struct init_action *next;
116 int action; 78 int action;
79 pid_t pid;
80 char command[INIT_BUFFS_SIZE];
81 char terminal[CONSOLE_NAME_SIZE];
117}; 82};
118 83
119/* Static variables */ 84/* Static variables */
120static struct init_action *init_action_list = NULL; 85static struct init_action *init_action_list = NULL;
121static char console_name[CONSOLE_BUFF_SIZE] = DEV_CONSOLE;
122 86
123#if !ENABLE_SYSLOGD 87#if !ENABLE_SYSLOGD
124static const char *log_console = VC_5; 88static const char *log_console = VC_5;
@@ -180,68 +144,60 @@ static void message(int device, const char *fmt, ...)
180 __attribute__ ((format(printf, 2, 3))); 144 __attribute__ ((format(printf, 2, 3)));
181static void message(int device, const char *fmt, ...) 145static void message(int device, const char *fmt, ...)
182{ 146{
183 va_list arguments;
184 int l;
185 RESERVE_CONFIG_BUFFER(msg, 1024);
186#if !ENABLE_SYSLOGD 147#if !ENABLE_SYSLOGD
187 static int log_fd = -1; 148 static int log_fd = -1;
188#endif 149#endif
189 150
151 va_list arguments;
152 int l;
153 char msg[128];
154
190 msg[0] = '\r'; 155 msg[0] = '\r';
191 va_start(arguments, fmt); 156 va_start(arguments, fmt);
192 l = vsnprintf(msg + 1, 1024 - 2, fmt, arguments) + 1; 157 vsnprintf(msg + 1, sizeof(msg) - 2, fmt, arguments);
193 va_end(arguments); 158 va_end(arguments);
159 msg[sizeof(msg) - 2] = '\0';
160 l = strlen(msg);
194 161
195#if ENABLE_SYSLOGD 162#if ENABLE_SYSLOGD
196 /* Log the message to syslogd */ 163 /* Log the message to syslogd */
197 if (device & L_LOG) { 164 if (device & L_LOG) {
198 /* don`t out "\r\n" */ 165 /* don't out "\r" */
199 openlog(applet_name, 0, LOG_DAEMON); 166 openlog(applet_name, 0, LOG_DAEMON);
200 syslog(LOG_INFO, "%s", msg + 1); 167 syslog(LOG_INFO, "init: %s", msg + 1);
201 closelog(); 168 closelog();
202 } 169 }
203
204 msg[l++] = '\n'; 170 msg[l++] = '\n';
205 msg[l] = 0; 171 msg[l] = '\0';
206#else 172#else
207
208 msg[l++] = '\n'; 173 msg[l++] = '\n';
209 msg[l] = 0; 174 msg[l] = '\0';
210 /* Take full control of the log tty, and never close it. 175 /* Take full control of the log tty, and never close it.
211 * It's mine, all mine! Muhahahaha! */ 176 * It's mine, all mine! Muhahahaha! */
212 if (log_fd < 0) { 177 if (log_fd < 0) {
213 log_fd = device_open(log_console, O_WRONLY | O_NONBLOCK | O_NOCTTY); 178 if (!log_console) {
214 if (log_fd < 0) { 179 log_fd = 2;
215 log_fd = -2;
216 bb_error_msg("bummer, can't log to %s!", log_console);
217 device = L_CONSOLE;
218 } else { 180 } else {
219 fcntl(log_fd, F_SETFD, FD_CLOEXEC); 181 log_fd = device_open(log_console, O_WRONLY | O_NONBLOCK | O_NOCTTY);
182 if (log_fd < 0) {
183 bb_error_msg("can't log to %s", log_console);
184 device = L_CONSOLE;
185 } else {
186 fcntl(log_fd, F_SETFD, FD_CLOEXEC);
187 }
220 } 188 }
221 } 189 }
222 if (device & L_LOG) { 190 if (device & L_LOG) {
223 full_write(log_fd, msg, l); 191 full_write(log_fd, msg, l);
192 if (log_fd == 2)
193 return; /* don't print dup messages */
224 } 194 }
225#endif 195#endif
226 196
227 if (device & L_CONSOLE) { 197 if (device & L_CONSOLE) {
228 int fd = device_open(DEV_CONSOLE, 198 /* Send console messages to console so people will see them. */
229 O_WRONLY | O_NOCTTY | O_NONBLOCK); 199 full_write(2, msg, l);
230 /* Always send console messages to /dev/console so people will see them. */
231 if (fd >= 0) {
232 full_write(fd, msg, l);
233 close(fd);
234#if ENABLE_DEBUG_INIT
235 /* all descriptors may be closed */
236 } else {
237 bb_error_msg("bummer, can't print: ");
238 va_start(arguments, fmt);
239 vfprintf(stderr, fmt, arguments);
240 va_end(arguments);
241#endif
242 }
243 } 200 }
244 RELEASE_CONFIG_BUFFER(msg);
245} 201}
246 202
247/* Set terminal settings to reasonable defaults */ 203/* Set terminal settings to reasonable defaults */
@@ -268,7 +224,6 @@ static void set_term(void)
268 tty.c_cflag &= CBAUD | CBAUDEX | CSIZE | CSTOPB | PARENB | PARODD; 224 tty.c_cflag &= CBAUD | CBAUDEX | CSIZE | CSTOPB | PARENB | PARODD;
269 tty.c_cflag |= CREAD | HUPCL | CLOCAL; 225 tty.c_cflag |= CREAD | HUPCL | CLOCAL;
270 226
271
272 /* input modes */ 227 /* input modes */
273 tty.c_iflag = ICRNL | IXON | IXOFF; 228 tty.c_iflag = ICRNL | IXON | IXOFF;
274 229
@@ -282,60 +237,59 @@ static void set_term(void)
282 tcsetattr(STDIN_FILENO, TCSANOW, &tty); 237 tcsetattr(STDIN_FILENO, TCSANOW, &tty);
283} 238}
284 239
240/* From <linux/serial.h> */
241struct serial_struct {
242 int type;
243 int line;
244 unsigned int port;
245 int irq;
246 int flags;
247 int xmit_fifo_size;
248 int custom_divisor;
249 int baud_base;
250 unsigned short close_delay;
251 char io_type;
252 char reserved_char[1];
253 int hub6;
254 unsigned short closing_wait; /* time to wait before closing */
255 unsigned short closing_wait2; /* no longer used... */
256 unsigned char *iomem_base;
257 unsigned short iomem_reg_shift;
258 unsigned int port_high;
259 unsigned long iomap_base; /* cookie passed into ioremap */
260 int reserved[1];
261 /* Paranoia (imagine 64bit kernel overwriting 32bit userspace stack) */
262 uint32_t bbox_reserved[16];
263};
285static void console_init(void) 264static void console_init(void)
286{ 265{
287 int fd;
288 int tried = 0;
289 struct vt_stat vt;
290 struct serial_struct sr; 266 struct serial_struct sr;
291 char *s; 267 char *s;
292 268
293 if ((s = getenv("CONSOLE")) != NULL || (s = getenv("console")) != NULL) { 269 s = getenv("CONSOLE");
294 safe_strncpy(console_name, s, sizeof(console_name)); 270 if (!s) s = getenv("console");
295 } else { 271 if (s) {
296 /* 2.2 kernels: identify the real console backend and try to use it */ 272 int fd = open(s, O_RDWR | O_NONBLOCK | O_NOCTTY);
297 if (ioctl(0, TIOCGSERIAL, &sr) == 0) { 273 if (fd >= 0) {
298 /* this is a serial console */ 274 dup2(fd, 0);
299 snprintf(console_name, sizeof(console_name) - 1, SC_FORMAT, sr.line); 275 dup2(fd, 1);
300 } else if (ioctl(0, VT_GETSTATE, &vt) == 0) { 276 dup2(fd, 2);
301 /* this is linux virtual tty */ 277 while (fd > 2) close(fd--);
302 snprintf(console_name, sizeof(console_name) - 1, VC_FORMAT, vt.v_active);
303 } else {
304 strcpy(console_name, DEV_CONSOLE);
305 tried++;
306 } 278 }
279 messageD(L_LOG, "console='%s'", s);
307 } 280 }
308 281
309 while ((fd = open(console_name, O_RDONLY | O_NONBLOCK)) < 0 && tried < 2) { 282 s = getenv("TERM");
310 /* Can't open selected console -- try 283 if (ioctl(0, TIOCGSERIAL, &sr) == 0) {
311 logical system console and VT_MASTER */ 284 /* Force the TERM setting to vt102 for serial console --
312 strcpy(console_name, (tried == 0 ? DEV_CONSOLE : CURRENT_VC)); 285 * if TERM is set to linux (the default) */
313 tried++; 286 if (!s || strcmp(s, "linux") == 0)
314 } 287 putenv((char*)"TERM=vt102");
315 if (fd < 0) {
316 /* Perhaps we should panic here? */
317#if !ENABLE_SYSLOGD
318 log_console =
319#endif
320 strcpy(console_name, bb_dev_null);
321 } else {
322 s = getenv("TERM");
323 /* check for serial console */
324 if (ioctl(fd, TIOCGSERIAL, &sr) == 0) {
325 /* Force the TERM setting to vt102 for serial console --
326 * if TERM is set to linux (the default) */
327 if (s == NULL || strcmp(s, "linux") == 0)
328 putenv((char*)"TERM=vt102");
329#if !ENABLE_SYSLOGD 288#if !ENABLE_SYSLOGD
330 log_console = console_name; 289 log_console = NULL;
331#endif 290#endif
332 } else { 291 } else if (!s)
333 if (s == NULL) 292 putenv((char*)"TERM=linux");
334 putenv((char*)"TERM=linux");
335 }
336 close(fd);
337 }
338 messageD(L_LOG, "console=%s", console_name);
339} 293}
340 294
341static void fixup_argv(int argc, char **argv, const char *new_argv0) 295static void fixup_argv(int argc, char **argv, const char *new_argv0)
@@ -355,24 +309,29 @@ static void fixup_argv(int argc, char **argv, const char *new_argv0)
355} 309}
356 310
357/* Open the new terminal device */ 311/* Open the new terminal device */
358static void open_new_terminal(const char* device, int fail) { 312static void open_stdio_to_tty(const char* tty_name, int fail)
359 struct stat sb; 313{
360 314 /* empty tty_name means "use init's tty", else... */
361 if ((device_open(device, O_RDWR)) < 0) { 315 if (tty_name[0]) {
362 if (stat(device, &sb) != 0) { 316 close(0);
363 message(L_LOG | L_CONSOLE, "device '%s' does not exist", device); 317 if ((device_open(tty_name, O_RDWR)) < 0) {
364 } else { 318 dup2(1, 0); /* restore fd #0 - avoid nasty surprises */
365 message(L_LOG | L_CONSOLE, "Bummer, can't open %s", device); 319 message(L_LOG | L_CONSOLE, "can't open %s: %s",
366 } 320 tty_name, strerror(errno));
367 if (fail) 321 if (fail)
368 _exit(1); 322 _exit(1);
369 /* else */
370#if !ENABLE_DEBUG_INIT 323#if !ENABLE_DEBUG_INIT
371 shutdown_signal(SIGUSR1); 324 shutdown_signal(SIGUSR1);
372#else 325#else
373 _exit(2); 326 _exit(2);
374#endif 327#endif
328 }
375 } 329 }
330 close(1);
331 close(2);
332 set_term();
333 dup(0);
334 dup(0);
376} 335}
377 336
378static pid_t run(const struct init_action *a) 337static pid_t run(const struct init_action *a)
@@ -395,11 +354,7 @@ static pid_t run(const struct init_action *a)
395 sigprocmask(SIG_BLOCK, &nmask, &omask); 354 sigprocmask(SIG_BLOCK, &nmask, &omask);
396 355
397 if ((pid = fork()) == 0) { 356 if ((pid = fork()) == 0) {
398
399 /* Clean up */ 357 /* Clean up */
400 close(0);
401 close(1);
402 close(2);
403 sigprocmask(SIG_SETMASK, &omask, NULL); 358 sigprocmask(SIG_SETMASK, &omask, NULL);
404 359
405 /* Reset signal handlers that were set by the parent process */ 360 /* Reset signal handlers that were set by the parent process */
@@ -418,14 +373,7 @@ static pid_t run(const struct init_action *a)
418 setsid(); 373 setsid();
419 374
420 /* Open the new terminal device */ 375 /* Open the new terminal device */
421 open_new_terminal(a->terminal, 1); 376 open_stdio_to_tty(a->terminal, 1);
422
423 /* Make sure the terminal will act fairly normal for us */
424 set_term();
425 /* Setup stdout, stderr for the new process so
426 * they point to the supplied terminal */
427 dup(0);
428 dup(0);
429 377
430 /* If the init Action requires us to wait, then force the 378 /* If the init Action requires us to wait, then force the
431 * supplied terminal to be the controlling tty. */ 379 * supplied terminal to be the controlling tty. */
@@ -433,7 +381,7 @@ static pid_t run(const struct init_action *a)
433 381
434 /* Now fork off another process to just hang around */ 382 /* Now fork off another process to just hang around */
435 if ((pid = fork()) < 0) { 383 if ((pid = fork()) < 0) {
436 message(L_LOG | L_CONSOLE, "Can't fork!"); 384 message(L_LOG | L_CONSOLE, "can't fork");
437 _exit(1); 385 _exit(1);
438 } 386 }
439 387
@@ -452,7 +400,7 @@ static pid_t run(const struct init_action *a)
452 400
453 /* Use a temporary process to steal the controlling tty. */ 401 /* Use a temporary process to steal the controlling tty. */
454 if ((pid = fork()) < 0) { 402 if ((pid = fork()) < 0) {
455 message(L_LOG | L_CONSOLE, "Can't fork!"); 403 message(L_LOG | L_CONSOLE, "can't fork");
456 _exit(1); 404 _exit(1);
457 } 405 }
458 if (pid == 0) { 406 if (pid == 0) {
@@ -489,14 +437,12 @@ static pid_t run(const struct init_action *a)
489 cmdpath = cmd[0]; 437 cmdpath = cmd[0];
490 438
491 /* 439 /*
492 Interactive shells want to see a dash in argv[0]. This 440 * Interactive shells want to see a dash in argv[0]. This
493 typically is handled by login, argv will be setup this 441 * typically is handled by login, argv will be setup this
494 way if a dash appears at the front of the command path 442 * way if a dash appears at the front of the command path
495 (like "-/bin/sh"). 443 * (like "-/bin/sh").
496 */ 444 */
497
498 if (*cmdpath == '-') { 445 if (*cmdpath == '-') {
499
500 /* skip over the dash */ 446 /* skip over the dash */
501 ++cmdpath; 447 ++cmdpath;
502 448
@@ -515,8 +461,8 @@ static pid_t run(const struct init_action *a)
515 /* Establish this process as session leader and 461 /* Establish this process as session leader and
516 * (attempt) to make the tty (if any) a controlling tty. 462 * (attempt) to make the tty (if any) a controlling tty.
517 */ 463 */
518 (void) setsid(); 464 setsid();
519 (void) ioctl(0, TIOCSCTTY, 0/*don't steal it*/); 465 ioctl(0, TIOCSCTTY, 0 /*don't steal it*/);
520#endif 466#endif
521 } 467 }
522 468
@@ -532,7 +478,7 @@ static pid_t run(const struct init_action *a)
532 * specifies. 478 * specifies.
533 */ 479 */
534 messageD(L_LOG, "Waiting for enter to start '%s'" 480 messageD(L_LOG, "Waiting for enter to start '%s'"
535 "(pid %d, terminal %s)\n", 481 "(pid %d, tty '%s')\n",
536 cmdpath, getpid(), a->terminal); 482 cmdpath, getpid(), a->terminal);
537 full_write(1, press_enter, sizeof(press_enter) - 1); 483 full_write(1, press_enter, sizeof(press_enter) - 1);
538 while (read(0, &c, 1) == 1 && c != '\n') 484 while (read(0, &c, 1) == 1 && c != '\n')
@@ -541,7 +487,7 @@ static pid_t run(const struct init_action *a)
541#endif 487#endif
542 488
543 /* Log the process name and args */ 489 /* Log the process name and args */
544 message(L_LOG, "Starting pid %d, console %s: '%s'", 490 message(L_LOG, "starting pid %d, tty '%s': '%s'",
545 getpid(), a->terminal, cmdpath); 491 getpid(), a->terminal, cmdpath);
546 492
547#if ENABLE_FEATURE_INIT_COREDUMPS 493#if ENABLE_FEATURE_INIT_COREDUMPS
@@ -562,7 +508,8 @@ static pid_t run(const struct init_action *a)
562 BB_EXECVP(cmdpath, cmd); 508 BB_EXECVP(cmdpath, cmd);
563 509
564 /* We're still here? Some error happened. */ 510 /* We're still here? Some error happened. */
565 message(L_LOG | L_CONSOLE, "Bummer, cannot run '%s': %m", cmdpath); 511 message(L_LOG | L_CONSOLE, "Cannot run '%s': %s",
512 cmdpath, strerror(errno));
566 _exit(-1); 513 _exit(-1);
567 } 514 }
568 sigprocmask(SIG_SETMASK, &omask, NULL); 515 sigprocmask(SIG_SETMASK, &omask, NULL);
@@ -597,7 +544,8 @@ static void run_actions(int action)
597 for (a = init_action_list; a; a = tmp) { 544 for (a = init_action_list; a; a = tmp) {
598 tmp = a->next; 545 tmp = a->next;
599 if (a->action == action) { 546 if (a->action == action) {
600 if (access(a->terminal, R_OK | W_OK)) { 547 /* a->terminal of "" means "init's console" */
548 if (a->terminal[0] && access(a->terminal, R_OK | W_OK)) {
601 delete_init_action(a); 549 delete_init_action(a);
602 } else if (a->action & (SYSINIT | WAIT | CTRLALTDEL | SHUTDOWN | RESTART)) { 550 } else if (a->action & (SYSINIT | WAIT | CTRLALTDEL | SHUTDOWN | RESTART)) {
603 waitfor(a, 0); 551 waitfor(a, 0);
@@ -654,23 +602,21 @@ static void shutdown_system(void)
654 sigaddset(&block_signals, SIGTSTP); 602 sigaddset(&block_signals, SIGTSTP);
655 sigprocmask(SIG_BLOCK, &block_signals, NULL); 603 sigprocmask(SIG_BLOCK, &block_signals, NULL);
656 604
605 message(L_CONSOLE | L_LOG, "The system is going down NOW!");
606
657 /* Allow Ctrl-Alt-Del to reboot system. */ 607 /* Allow Ctrl-Alt-Del to reboot system. */
658 init_reboot(RB_ENABLE_CAD); 608 init_reboot(RB_ENABLE_CAD);
659 609
660 message(L_CONSOLE | L_LOG, "The system is going down NOW !!");
661 sync();
662
663 /* Send signals to every process _except_ pid 1 */ 610 /* Send signals to every process _except_ pid 1 */
664 message(L_CONSOLE | L_LOG, init_sending_format, "TERM"); 611 message(L_CONSOLE | L_LOG, "Sending SIG%s to all processes", "TERM");
665 kill(-1, SIGTERM); 612 kill(-1, SIGTERM);
666 sleep(1);
667 sync(); 613 sync();
668
669 message(L_CONSOLE | L_LOG, init_sending_format, "KILL");
670 kill(-1, SIGKILL);
671 sleep(1); 614 sleep(1);
672 615
616 message(L_CONSOLE | L_LOG, "Sending SIG%s to all processes", "KILL");
617 kill(-1, SIGKILL);
673 sync(); 618 sync();
619 sleep(1);
674} 620}
675 621
676static void exec_signal(int sig ATTRIBUTE_UNUSED) 622static void exec_signal(int sig ATTRIBUTE_UNUSED)
@@ -697,26 +643,14 @@ static void exec_signal(int sig ATTRIBUTE_UNUSED)
697 sigaddset(&unblock_signals, SIGTSTP); 643 sigaddset(&unblock_signals, SIGTSTP);
698 sigprocmask(SIG_UNBLOCK, &unblock_signals, NULL); 644 sigprocmask(SIG_UNBLOCK, &unblock_signals, NULL);
699 645
700 /* Close whatever files are open. */
701 close(0);
702 close(1);
703 close(2);
704
705 /* Open the new terminal device */ 646 /* Open the new terminal device */
706 open_new_terminal(a->terminal, 0); 647 open_stdio_to_tty(a->terminal, 0);
707
708 /* Make sure the terminal will act fairly normal for us */
709 set_term();
710 /* Setup stdout, stderr on the supplied terminal */
711 dup(0);
712 dup(0);
713 648
714 messageD(L_CONSOLE | L_LOG, "Trying to re-exec %s", a->command); 649 messageD(L_CONSOLE | L_LOG, "Trying to re-exec %s", a->command);
715 BB_EXECLP(a->command, a->command, NULL); 650 BB_EXECLP(a->command, a->command, NULL);
716 651
717 message(L_CONSOLE | L_LOG, "exec of '%s' failed: %m", 652 message(L_CONSOLE | L_LOG, "Cannot run '%s': %s",
718 a->command); 653 a->command, strerror(errno));
719 sync();
720 sleep(2); 654 sleep(2);
721 init_reboot(RB_HALT_SYSTEM); 655 init_reboot(RB_HALT_SYSTEM);
722 loop_forever(); 656 loop_forever();
@@ -741,11 +675,8 @@ static void shutdown_signal(int sig)
741 rb = RB_POWER_OFF; 675 rb = RB_POWER_OFF;
742 } 676 }
743 message(L_CONSOLE | L_LOG, "Requesting system %s", m); 677 message(L_CONSOLE | L_LOG, "Requesting system %s", m);
744 sync();
745
746 /* allow time for last message to reach serial console */ 678 /* allow time for last message to reach serial console */
747 sleep(2); 679 sleep(2);
748
749 init_reboot(rb); 680 init_reboot(rb);
750 loop_forever(); 681 loop_forever();
751} 682}
@@ -779,14 +710,9 @@ static void new_init_action(int action, const char *command, const char *cons)
779{ 710{
780 struct init_action *new_action, *a, *last; 711 struct init_action *new_action, *a, *last;
781 712
782 if (*cons == '\0')
783 cons = console_name;
784
785 if (strcmp(cons, bb_dev_null) == 0 && (action & ASKFIRST)) 713 if (strcmp(cons, bb_dev_null) == 0 && (action & ASKFIRST))
786 return; 714 return;
787 715
788 new_action = xzalloc(sizeof(struct init_action));
789
790 /* Append to the end of the list */ 716 /* Append to the end of the list */
791 for (a = last = init_action_list; a; a = a->next) { 717 for (a = last = init_action_list; a; a = a->next) {
792 /* don't enter action if it's already in the list, 718 /* don't enter action if it's already in the list,
@@ -795,11 +721,12 @@ static void new_init_action(int action, const char *command, const char *cons)
795 && (strcmp(a->terminal, cons) == 0) 721 && (strcmp(a->terminal, cons) == 0)
796 ) { 722 ) {
797 a->action = action; 723 a->action = action;
798 free(new_action);
799 return; 724 return;
800 } 725 }
801 last = a; 726 last = a;
802 } 727 }
728
729 new_action = xzalloc(sizeof(struct init_action));
803 if (last) { 730 if (last) {
804 last->next = new_action; 731 last->next = new_action;
805 } else { 732 } else {
@@ -808,7 +735,7 @@ static void new_init_action(int action, const char *command, const char *cons)
808 strcpy(new_action->command, command); 735 strcpy(new_action->command, command);
809 new_action->action = action; 736 new_action->action = action;
810 strcpy(new_action->terminal, cons); 737 strcpy(new_action->terminal, cons);
811 messageD(L_LOG | L_CONSOLE, "command='%s' action='%d' terminal='%s'\n", 738 messageD(L_LOG | L_CONSOLE, "command='%s' action=%d tty='%s'\n",
812 new_action->command, new_action->action, new_action->terminal); 739 new_action->command, new_action->action, new_action->terminal);
813} 740}
814 741
@@ -841,11 +768,10 @@ static void parse_inittab(void)
841#if ENABLE_FEATURE_USE_INITTAB 768#if ENABLE_FEATURE_USE_INITTAB
842 FILE *file; 769 FILE *file;
843 char buf[INIT_BUFFS_SIZE], lineAsRead[INIT_BUFFS_SIZE]; 770 char buf[INIT_BUFFS_SIZE], lineAsRead[INIT_BUFFS_SIZE];
844 char tmpConsole[CONSOLE_BUFF_SIZE]; 771 char tmpConsole[CONSOLE_NAME_SIZE];
845 char *id, *runlev, *action, *command, *eol; 772 char *id, *runlev, *action, *command, *eol;
846 const struct init_action_type *a = actions; 773 const struct init_action_type *a = actions;
847 774
848
849 file = fopen(INITTAB, "r"); 775 file = fopen(INITTAB, "r");
850 if (file == NULL) { 776 if (file == NULL) {
851 /* No inittab file -- set up some default behavior */ 777 /* No inittab file -- set up some default behavior */
@@ -925,7 +851,7 @@ static void parse_inittab(void)
925 id += 5; 851 id += 5;
926 strcpy(tmpConsole, "/dev/"); 852 strcpy(tmpConsole, "/dev/");
927 safe_strncpy(tmpConsole + 5, id, 853 safe_strncpy(tmpConsole + 5, id,
928 CONSOLE_BUFF_SIZE - 5); 854 sizeof(tmpConsole) - 5);
929 id = tmpConsole; 855 id = tmpConsole;
930 } 856 }
931 new_init_action(a->action, command, id); 857 new_init_action(a->action, command, id);
@@ -938,7 +864,6 @@ static void parse_inittab(void)
938 } 864 }
939 } 865 }
940 fclose(file); 866 fclose(file);
941 return;
942#endif /* FEATURE_USE_INITTAB */ 867#endif /* FEATURE_USE_INITTAB */
943} 868}
944 869
@@ -947,7 +872,7 @@ static void reload_signal(int sig ATTRIBUTE_UNUSED)
947{ 872{
948 struct init_action *a, *tmp; 873 struct init_action *a, *tmp;
949 874
950 message(L_LOG, "Reloading /etc/inittab"); 875 message(L_LOG, "reloading /etc/inittab");
951 876
952 /* disable old entrys */ 877 /* disable old entrys */
953 for (a = init_action_list; a; a = a->next ) { 878 for (a = init_action_list; a; a = a->next ) {
@@ -965,7 +890,6 @@ static void reload_signal(int sig ATTRIBUTE_UNUSED)
965 } 890 }
966 } 891 }
967 run_actions(RESPAWN); 892 run_actions(RESPAWN);
968 return;
969} 893}
970#endif /* FEATURE_USE_INITTAB */ 894#endif /* FEATURE_USE_INITTAB */
971 895
@@ -978,13 +902,13 @@ int init_main(int argc, char **argv)
978 die_sleep = 30 * 24*60*60; /* if xmalloc will ever die... */ 902 die_sleep = 30 * 24*60*60; /* if xmalloc will ever die... */
979 903
980 if (argc > 1 && !strcmp(argv[1], "-q")) { 904 if (argc > 1 && !strcmp(argv[1], "-q")) {
981 return kill(1,SIGHUP); 905 return kill(1, SIGHUP);
982 } 906 }
983#if !ENABLE_DEBUG_INIT 907#if !ENABLE_DEBUG_INIT
984 /* Expect to be invoked as init with PID=1 or be invoked as linuxrc */ 908 /* Expect to be invoked as init with PID=1 or be invoked as linuxrc */
985 if (getpid() != 1 && 909 if (getpid() != 1
986 (!ENABLE_FEATURE_INITRD || !strstr(applet_name, "linuxrc"))) 910 && (!ENABLE_FEATURE_INITRD || !strstr(applet_name, "linuxrc"))
987 { 911 ) {
988 bb_show_usage(); 912 bb_show_usage();
989 } 913 }
990 /* Set up sig handlers -- be sure to 914 /* Set up sig handlers -- be sure to
@@ -1006,17 +930,7 @@ int init_main(int argc, char **argv)
1006 930
1007 /* Figure out where the default console should be */ 931 /* Figure out where the default console should be */
1008 console_init(); 932 console_init();
1009 933 set_term();
1010 /* Close whatever files are open, and reset the console. */
1011 close(0);
1012 close(1);
1013 close(2);
1014
1015 if (device_open(console_name, O_RDWR | O_NOCTTY) == 0) {
1016 set_term();
1017 close(0);
1018 }
1019
1020 chdir("/"); 934 chdir("/");
1021 setsid(); 935 setsid();
1022 { 936 {
@@ -1029,7 +943,7 @@ int init_main(int argc, char **argv)
1029 if (argc > 1) setenv("RUNLEVEL", argv[1], 1); 943 if (argc > 1) setenv("RUNLEVEL", argv[1], 1);
1030 944
1031 /* Hello world */ 945 /* Hello world */
1032 message(MAYBE_CONSOLE | L_LOG, "init started: %s", bb_msg_full_version); 946 message(MAYBE_CONSOLE | L_LOG, "init started: %s", bb_msg_full_version);
1033 947
1034 /* Make sure there is enough memory to do something useful. */ 948 /* Make sure there is enough memory to do something useful. */
1035 if (ENABLE_SWAPONOFF) { 949 if (ENABLE_SWAPONOFF) {
@@ -1038,7 +952,7 @@ int init_main(int argc, char **argv)
1038 if (!sysinfo(&info) && 952 if (!sysinfo(&info) &&
1039 (info.mem_unit ? : 1) * (long long)info.totalram < 1024*1024) 953 (info.mem_unit ? : 1) * (long long)info.totalram < 1024*1024)
1040 { 954 {
1041 message(L_CONSOLE, "Low memory: forcing swapon."); 955 message(L_CONSOLE, "Low memory, forcing swapon");
1042 /* swapon -a requires /proc typically */ 956 /* swapon -a requires /proc typically */
1043 new_init_action(SYSINIT, "mount -t proc proc /proc", ""); 957 new_init_action(SYSINIT, "mount -t proc proc /proc", "");
1044 /* Try to turn on swap */ 958 /* Try to turn on swap */
@@ -1073,7 +987,7 @@ int init_main(int argc, char **argv)
1073 } else if (enforce > 0) { 987 } else if (enforce > 0) {
1074 /* SELinux in enforcing mode but load_policy failed */ 988 /* SELinux in enforcing mode but load_policy failed */
1075 /* At this point, we probably can't open /dev/console, so log() won't work */ 989 /* At this point, we probably can't open /dev/console, so log() won't work */
1076 message(CONSOLE,"Unable to load SELinux Policy. Machine is in enforcing mode. Halting now."); 990 message(CONSOLE, "Cannot load SELinux Policy. Machine is in enforcing mode. Halting now.");
1077 exit(1); 991 exit(1);
1078 } 992 }
1079 } 993 }
@@ -1121,7 +1035,7 @@ int init_main(int argc, char **argv)
1121 /* Set the pid to 0 so that the process gets 1035 /* Set the pid to 0 so that the process gets
1122 * restarted by run_actions() */ 1036 * restarted by run_actions() */
1123 a->pid = 0; 1037 a->pid = 0;
1124 message(L_LOG, "Process '%s' (pid %d) exited. " 1038 message(L_LOG, "process '%s' (pid %d) exited. "
1125 "Scheduling it for restart.", 1039 "Scheduling it for restart.",
1126 a->command, wpid); 1040 a->command, wpid);
1127 } 1041 }