diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-12-10 07:06:04 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-12-10 07:06:04 +0000 |
commit | 2afabe8b830cc8c33f5f1984767af4b8dc54803b (patch) | |
tree | 2647f259f9584d874dca8a784af4dd87df6db57e /init | |
parent | 191836845e4551fe6191dc0d43b45a0232bff8be (diff) | |
download | busybox-w32-2afabe8b830cc8c33f5f1984767af4b8dc54803b.tar.gz busybox-w32-2afabe8b830cc8c33f5f1984767af4b8dc54803b.tar.bz2 busybox-w32-2afabe8b830cc8c33f5f1984767af4b8dc54803b.zip |
init: remove superfluous forks and messing up with argv[0]
cttyhack: add stealing of ctty
Diffstat (limited to 'init')
-rw-r--r-- | init/Config.in | 1 | ||||
-rw-r--r-- | init/init.c | 246 |
2 files changed, 123 insertions, 124 deletions
diff --git a/init/Config.in b/init/Config.in index 3987d8fee..318f523a0 100644 --- a/init/Config.in +++ b/init/Config.in | |||
@@ -37,6 +37,7 @@ config FEATURE_INIT_SCTTY | |||
37 | controlling tty (TIOCSCTTY). This is not the traditional init | 37 | controlling tty (TIOCSCTTY). This is not the traditional init |
38 | behavour, but is often what you want in an embedded system where | 38 | behavour, but is often what you want in an embedded system where |
39 | the console is only accessed during development or for maintenance. | 39 | the console is only accessed during development or for maintenance. |
40 | NB: using cttyhack applet may work better. | ||
40 | 41 | ||
41 | config FEATURE_INIT_SYSLOG | 42 | config FEATURE_INIT_SYSLOG |
42 | bool "Enable init to write to syslog" | 43 | bool "Enable init to write to syslog" |
diff --git a/init/init.c b/init/init.c index fe0ec030a..c0c8b17cb 100644 --- a/init/init.c +++ b/init/init.c | |||
@@ -47,31 +47,22 @@ | |||
47 | #define SHUTDOWN 0x040 | 47 | #define SHUTDOWN 0x040 |
48 | #define RESTART 0x080 | 48 | #define RESTART 0x080 |
49 | 49 | ||
50 | /* A mapping between "inittab" action name strings and action type codes. */ | 50 | #define STR_SYSINIT "\x01" |
51 | struct init_action_type { | 51 | #define STR_RESPAWN "\x02" |
52 | const char *name; | 52 | #define STR_ASKFIRST "\x04" |
53 | int action; | 53 | #define STR_WAIT "\x08" |
54 | }; | 54 | #define STR_ONCE "\x10" |
55 | 55 | #define STR_CTRLALTDEL "\x20" | |
56 | static const struct init_action_type actions[] = { | 56 | #define STR_SHUTDOWN "\x40" |
57 | {"sysinit", SYSINIT}, | 57 | #define STR_RESTART "\x80" |
58 | {"respawn", RESPAWN}, | ||
59 | {"askfirst", ASKFIRST}, | ||
60 | {"wait", WAIT}, | ||
61 | {"once", ONCE}, | ||
62 | {"ctrlaltdel", CTRLALTDEL}, | ||
63 | {"shutdown", SHUTDOWN}, | ||
64 | {"restart", RESTART}, | ||
65 | {0, 0} | ||
66 | }; | ||
67 | 58 | ||
68 | /* Set up a linked list of init_actions, to be read from inittab */ | 59 | /* Set up a linked list of init_actions, to be read from inittab */ |
69 | struct init_action { | 60 | struct init_action { |
70 | struct init_action *next; | 61 | struct init_action *next; |
71 | int action; | ||
72 | pid_t pid; | 62 | pid_t pid; |
73 | char command[INIT_BUFFS_SIZE]; | 63 | uint8_t action; |
74 | char terminal[CONSOLE_NAME_SIZE]; | 64 | char terminal[CONSOLE_NAME_SIZE]; |
65 | char command[INIT_BUFFS_SIZE]; | ||
75 | }; | 66 | }; |
76 | 67 | ||
77 | /* Static variables */ | 68 | /* Static variables */ |
@@ -113,7 +104,7 @@ static const char *const environment[] = { | |||
113 | 104 | ||
114 | /* Function prototypes */ | 105 | /* Function prototypes */ |
115 | static void delete_init_action(struct init_action *a); | 106 | static void delete_init_action(struct init_action *a); |
116 | static int waitfor(const struct init_action *a, pid_t pid); | 107 | static int waitfor(pid_t pid); |
117 | #if !ENABLE_DEBUG_INIT | 108 | #if !ENABLE_DEBUG_INIT |
118 | static void shutdown_signal(int sig); | 109 | static void shutdown_signal(int sig); |
119 | #endif | 110 | #endif |
@@ -193,43 +184,6 @@ static void message(int device, const char *fmt, ...) | |||
193 | } | 184 | } |
194 | } | 185 | } |
195 | 186 | ||
196 | /* Set terminal settings to reasonable defaults */ | ||
197 | static void set_sane_term(void) | ||
198 | { | ||
199 | struct termios tty; | ||
200 | |||
201 | tcgetattr(STDIN_FILENO, &tty); | ||
202 | |||
203 | /* set control chars */ | ||
204 | tty.c_cc[VINTR] = 3; /* C-c */ | ||
205 | tty.c_cc[VQUIT] = 28; /* C-\ */ | ||
206 | tty.c_cc[VERASE] = 127; /* C-? */ | ||
207 | tty.c_cc[VKILL] = 21; /* C-u */ | ||
208 | tty.c_cc[VEOF] = 4; /* C-d */ | ||
209 | tty.c_cc[VSTART] = 17; /* C-q */ | ||
210 | tty.c_cc[VSTOP] = 19; /* C-s */ | ||
211 | tty.c_cc[VSUSP] = 26; /* C-z */ | ||
212 | |||
213 | /* use line dicipline 0 */ | ||
214 | tty.c_line = 0; | ||
215 | |||
216 | /* Make it be sane */ | ||
217 | tty.c_cflag &= CBAUD | CBAUDEX | CSIZE | CSTOPB | PARENB | PARODD; | ||
218 | tty.c_cflag |= CREAD | HUPCL | CLOCAL; | ||
219 | |||
220 | /* input modes */ | ||
221 | tty.c_iflag = ICRNL | IXON | IXOFF; | ||
222 | |||
223 | /* output modes */ | ||
224 | tty.c_oflag = OPOST | ONLCR; | ||
225 | |||
226 | /* local modes */ | ||
227 | tty.c_lflag = | ||
228 | ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN; | ||
229 | |||
230 | tcsetattr(STDIN_FILENO, TCSANOW, &tty); | ||
231 | } | ||
232 | |||
233 | /* From <linux/serial.h> */ | 187 | /* From <linux/serial.h> */ |
234 | struct serial_struct { | 188 | struct serial_struct { |
235 | int type; | 189 | int type; |
@@ -277,7 +231,7 @@ static void console_init(void) | |||
277 | 231 | ||
278 | s = getenv("TERM"); | 232 | s = getenv("TERM"); |
279 | if (ioctl(0, TIOCGSERIAL, &sr) == 0) { | 233 | if (ioctl(0, TIOCGSERIAL, &sr) == 0) { |
280 | /* Force the TERM setting to vt102 for serial console -- | 234 | /* Force the TERM setting to vt102 for serial console |
281 | * if TERM is set to linux (the default) */ | 235 | * if TERM is set to linux (the default) */ |
282 | if (!s || strcmp(s, "linux") == 0) | 236 | if (!s || strcmp(s, "linux") == 0) |
283 | putenv((char*)"TERM=vt102"); | 237 | putenv((char*)"TERM=vt102"); |
@@ -288,14 +242,41 @@ static void console_init(void) | |||
288 | putenv((char*)"TERM=linux"); | 242 | putenv((char*)"TERM=linux"); |
289 | } | 243 | } |
290 | 244 | ||
291 | static void fixup_argv(char **argv) | 245 | /* Set terminal settings to reasonable defaults */ |
246 | static void set_sane_term(void) | ||
292 | { | 247 | { |
293 | /* Fix up argv[0] to be certain we claim to be init */ | 248 | struct termios tty; |
294 | strncpy(argv[0], "init", strlen(argv[0])); | ||
295 | 249 | ||
296 | /* Wipe argv[1]-argv[N] so they don't clutter the ps listing */ | 250 | tcgetattr(STDIN_FILENO, &tty); |
297 | while (*++argv) | 251 | |
298 | memset(*argv, 0, strlen(*argv)); | 252 | /* set control chars */ |
253 | tty.c_cc[VINTR] = 3; /* C-c */ | ||
254 | tty.c_cc[VQUIT] = 28; /* C-\ */ | ||
255 | tty.c_cc[VERASE] = 127; /* C-? */ | ||
256 | tty.c_cc[VKILL] = 21; /* C-u */ | ||
257 | tty.c_cc[VEOF] = 4; /* C-d */ | ||
258 | tty.c_cc[VSTART] = 17; /* C-q */ | ||
259 | tty.c_cc[VSTOP] = 19; /* C-s */ | ||
260 | tty.c_cc[VSUSP] = 26; /* C-z */ | ||
261 | |||
262 | /* use line dicipline 0 */ | ||
263 | tty.c_line = 0; | ||
264 | |||
265 | /* Make it be sane */ | ||
266 | tty.c_cflag &= CBAUD | CBAUDEX | CSIZE | CSTOPB | PARENB | PARODD; | ||
267 | tty.c_cflag |= CREAD | HUPCL | CLOCAL; | ||
268 | |||
269 | /* input modes */ | ||
270 | tty.c_iflag = ICRNL | IXON | IXOFF; | ||
271 | |||
272 | /* output modes */ | ||
273 | tty.c_oflag = OPOST | ONLCR; | ||
274 | |||
275 | /* local modes */ | ||
276 | tty.c_lflag = | ||
277 | ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN; | ||
278 | |||
279 | tcsetattr(STDIN_FILENO, TCSANOW, &tty); | ||
299 | } | 280 | } |
300 | 281 | ||
301 | /* Open the new terminal device */ | 282 | /* Open the new terminal device */ |
@@ -324,6 +305,7 @@ static void open_stdio_to_tty(const char* tty_name, int fail) | |||
324 | set_sane_term(); | 305 | set_sane_term(); |
325 | } | 306 | } |
326 | 307 | ||
308 | /* Used only by run_actions */ | ||
327 | static pid_t run(const struct init_action *a) | 309 | static pid_t run(const struct init_action *a) |
328 | { | 310 | { |
329 | int i; | 311 | int i; |
@@ -333,16 +315,20 @@ static pid_t run(const struct init_action *a) | |||
333 | char buf[INIT_BUFFS_SIZE + 6]; /* INIT_BUFFS_SIZE+strlen("exec ")+1 */ | 315 | char buf[INIT_BUFFS_SIZE + 6]; /* INIT_BUFFS_SIZE+strlen("exec ")+1 */ |
334 | sigset_t nmask, omask; | 316 | sigset_t nmask, omask; |
335 | 317 | ||
336 | /* Block sigchild while forking. */ | 318 | /* Block sigchild while forking (why?) */ |
337 | sigemptyset(&nmask); | 319 | sigemptyset(&nmask); |
338 | sigaddset(&nmask, SIGCHLD); | 320 | sigaddset(&nmask, SIGCHLD); |
339 | sigprocmask(SIG_BLOCK, &nmask, &omask); | 321 | sigprocmask(SIG_BLOCK, &nmask, &omask); |
340 | pid = fork(); | 322 | pid = fork(); |
341 | sigprocmask(SIG_SETMASK, &omask, NULL); | 323 | sigprocmask(SIG_SETMASK, &omask, NULL); |
342 | 324 | ||
325 | if (pid < 0) | ||
326 | message(L_LOG | L_CONSOLE, "Can't fork"); | ||
343 | if (pid) | 327 | if (pid) |
344 | return pid; | 328 | return pid; |
345 | 329 | ||
330 | /* Child */ | ||
331 | |||
346 | /* Reset signal handlers that were set by the parent process */ | 332 | /* Reset signal handlers that were set by the parent process */ |
347 | signal(SIGUSR1, SIG_DFL); | 333 | signal(SIGUSR1, SIG_DFL); |
348 | signal(SIGUSR2, SIG_DFL); | 334 | signal(SIGUSR2, SIG_DFL); |
@@ -359,8 +345,9 @@ static pid_t run(const struct init_action *a) | |||
359 | setsid(); | 345 | setsid(); |
360 | 346 | ||
361 | /* Open the new terminal device */ | 347 | /* Open the new terminal device */ |
362 | open_stdio_to_tty(a->terminal, 1); | 348 | open_stdio_to_tty(a->terminal, 1 /* - exit if open fails*/); |
363 | 349 | ||
350 | #ifdef BUT_RUN_ACTIONS_ALREADY_DOES_WAITING | ||
364 | /* If the init Action requires us to wait, then force the | 351 | /* If the init Action requires us to wait, then force the |
365 | * supplied terminal to be the controlling tty. */ | 352 | * supplied terminal to be the controlling tty. */ |
366 | if (a->action & (SYSINIT | WAIT | CTRLALTDEL | SHUTDOWN | RESTART)) { | 353 | if (a->action & (SYSINIT | WAIT | CTRLALTDEL | SHUTDOWN | RESTART)) { |
@@ -373,13 +360,13 @@ static pid_t run(const struct init_action *a) | |||
373 | } | 360 | } |
374 | 361 | ||
375 | if (pid > 0) { | 362 | if (pid > 0) { |
376 | /* We are the parent -- wait till the child is done */ | 363 | /* Parent - wait till the child is done */ |
377 | signal(SIGINT, SIG_IGN); | 364 | signal(SIGINT, SIG_IGN); |
378 | signal(SIGTSTP, SIG_IGN); | 365 | signal(SIGTSTP, SIG_IGN); |
379 | signal(SIGQUIT, SIG_IGN); | 366 | signal(SIGQUIT, SIG_IGN); |
380 | signal(SIGCHLD, SIG_DFL); | 367 | signal(SIGCHLD, SIG_DFL); |
381 | 368 | ||
382 | waitfor(NULL, pid); | 369 | waitfor(pid); |
383 | /* See if stealing the controlling tty back is necessary */ | 370 | /* See if stealing the controlling tty back is necessary */ |
384 | if (tcgetpgrp(0) != getpid()) | 371 | if (tcgetpgrp(0) != getpid()) |
385 | _exit(0); | 372 | _exit(0); |
@@ -395,12 +382,13 @@ static pid_t run(const struct init_action *a) | |||
395 | ioctl(0, TIOCSCTTY, 1); | 382 | ioctl(0, TIOCSCTTY, 1); |
396 | _exit(0); | 383 | _exit(0); |
397 | } | 384 | } |
398 | waitfor(NULL, pid); | 385 | waitfor(pid); |
399 | _exit(0); | 386 | _exit(0); |
400 | } | 387 | } |
401 | 388 | ||
402 | /* Now fall though to actually execute things */ | 389 | /* Child - fall though to actually execute things */ |
403 | } | 390 | } |
391 | #endif | ||
404 | 392 | ||
405 | /* See if any special /bin/sh requiring characters are present */ | 393 | /* See if any special /bin/sh requiring characters are present */ |
406 | if (strpbrk(a->command, "~`!$^&*()=|\\{}[];\"'<>?") != NULL) { | 394 | if (strpbrk(a->command, "~`!$^&*()=|\\{}[];\"'<>?") != NULL) { |
@@ -433,9 +421,9 @@ static pid_t run(const struct init_action *a) | |||
433 | /* skip over the dash */ | 421 | /* skip over the dash */ |
434 | ++cmdpath; | 422 | ++cmdpath; |
435 | 423 | ||
424 | #ifdef WHY_WE_DO_THIS_SHELL_MUST_HANDLE_THIS_ITSELF | ||
436 | /* find the last component in the command pathname */ | 425 | /* find the last component in the command pathname */ |
437 | s = bb_get_last_path_component_nostrip(cmdpath); | 426 | s = bb_get_last_path_component_nostrip(cmdpath); |
438 | |||
439 | /* make a new argv[0] */ | 427 | /* make a new argv[0] */ |
440 | cmd[0] = malloc(strlen(s) + 2); | 428 | cmd[0] = malloc(strlen(s) + 2); |
441 | if (cmd[0] == NULL) { | 429 | if (cmd[0] == NULL) { |
@@ -445,16 +433,16 @@ static pid_t run(const struct init_action *a) | |||
445 | cmd[0][0] = '-'; | 433 | cmd[0][0] = '-'; |
446 | strcpy(cmd[0] + 1, s); | 434 | strcpy(cmd[0] + 1, s); |
447 | } | 435 | } |
436 | #endif | ||
437 | |||
448 | #if ENABLE_FEATURE_INIT_SCTTY | 438 | #if ENABLE_FEATURE_INIT_SCTTY |
449 | /* Establish this process as session leader and | 439 | /* Establish this process as session leader and |
450 | * (attempt) to make the tty (if any) a controlling tty. | 440 | * _attempt_ to make stdin a controlling tty. |
451 | */ | 441 | */ |
452 | setsid(); | 442 | ioctl(0, TIOCSCTTY, 0 /*only try, don't steal*/); |
453 | ioctl(0, TIOCSCTTY, 0 /*don't steal it*/); | ||
454 | #endif | 443 | #endif |
455 | } | 444 | } |
456 | 445 | ||
457 | #if !defined(__UCLIBC__) || defined(__ARCH_HAS_MMU__) | ||
458 | if (a->action & ASKFIRST) { | 446 | if (a->action & ASKFIRST) { |
459 | static const char press_enter[] ALIGN1 = | 447 | static const char press_enter[] ALIGN1 = |
460 | #ifdef CUSTOMIZED_BANNER | 448 | #ifdef CUSTOMIZED_BANNER |
@@ -474,10 +462,10 @@ static pid_t run(const struct init_action *a) | |||
474 | "(pid %d, tty '%s')\n", | 462 | "(pid %d, tty '%s')\n", |
475 | cmdpath, getpid(), a->terminal); | 463 | cmdpath, getpid(), a->terminal); |
476 | full_write(1, press_enter, sizeof(press_enter) - 1); | 464 | full_write(1, press_enter, sizeof(press_enter) - 1); |
477 | while (read(0, &c, 1) == 1 && c != '\n') | 465 | while (safe_read(0, &c, 1) == 1 && c != '\n') |
478 | ; | 466 | continue; |
479 | } | 467 | } |
480 | #endif | 468 | |
481 | /* Log the process name and args */ | 469 | /* Log the process name and args */ |
482 | message(L_LOG, "starting pid %d, tty '%s': '%s'", | 470 | message(L_LOG, "starting pid %d, tty '%s': '%s'", |
483 | getpid(), a->terminal, cmdpath); | 471 | getpid(), a->terminal, cmdpath); |
@@ -504,22 +492,15 @@ static pid_t run(const struct init_action *a) | |||
504 | _exit(-1); | 492 | _exit(-1); |
505 | } | 493 | } |
506 | 494 | ||
507 | static int waitfor(const struct init_action *a, pid_t pid) | 495 | static int waitfor(pid_t runpid) |
508 | { | 496 | { |
509 | int runpid; | ||
510 | int status, wpid; | 497 | int status, wpid; |
511 | 498 | ||
512 | runpid = (NULL == a)? pid : run(a); | ||
513 | while (1) { | 499 | while (1) { |
514 | wpid = waitpid(runpid, &status, 0); | 500 | wpid = waitpid(runpid, &status, 0); |
515 | if (wpid == runpid) | 501 | if (wpid == -1 && errno == EINTR) |
516 | break; | 502 | continue; |
517 | if (wpid == -1 && errno == ECHILD) { | 503 | break; |
518 | /* we missed its termination */ | ||
519 | break; | ||
520 | } | ||
521 | /* FIXME other errors should maybe trigger an error, but allow | ||
522 | * the program to continue */ | ||
523 | } | 504 | } |
524 | return wpid; | 505 | return wpid; |
525 | } | 506 | } |
@@ -534,9 +515,10 @@ static void run_actions(int action) | |||
534 | if (a->action == action) { | 515 | if (a->action == action) { |
535 | /* a->terminal of "" means "init's console" */ | 516 | /* a->terminal of "" means "init's console" */ |
536 | if (a->terminal[0] && access(a->terminal, R_OK | W_OK)) { | 517 | if (a->terminal[0] && access(a->terminal, R_OK | W_OK)) { |
518 | //message(L_LOG | L_CONSOLE, "Device %s cannot be opened in RW mode", a->terminal /*, strerror(errno)*/); | ||
537 | delete_init_action(a); | 519 | delete_init_action(a); |
538 | } else if (a->action & (SYSINIT | WAIT | CTRLALTDEL | SHUTDOWN | RESTART)) { | 520 | } else if (a->action & (SYSINIT | WAIT | CTRLALTDEL | SHUTDOWN | RESTART)) { |
539 | waitfor(a, 0); | 521 | waitfor(run(a)); |
540 | delete_init_action(a); | 522 | delete_init_action(a); |
541 | } else if (a->action & ONCE) { | 523 | } else if (a->action & ONCE) { |
542 | run(a); | 524 | run(a); |
@@ -607,6 +589,29 @@ static void shutdown_system(void) | |||
607 | sleep(1); | 589 | sleep(1); |
608 | } | 590 | } |
609 | 591 | ||
592 | static void shutdown_signal(int sig) | ||
593 | { | ||
594 | const char *m; | ||
595 | int rb; | ||
596 | |||
597 | shutdown_system(); | ||
598 | |||
599 | m = "halt"; | ||
600 | rb = RB_HALT_SYSTEM; | ||
601 | if (sig == SIGTERM) { | ||
602 | m = "reboot"; | ||
603 | rb = RB_AUTOBOOT; | ||
604 | } else if (sig == SIGUSR2) { | ||
605 | m = "poweroff"; | ||
606 | rb = RB_POWER_OFF; | ||
607 | } | ||
608 | message(L_CONSOLE | L_LOG, "Requesting system %s", m); | ||
609 | /* allow time for last message to reach serial console */ | ||
610 | sleep(2); | ||
611 | init_reboot(rb); | ||
612 | loop_forever(); | ||
613 | } | ||
614 | |||
610 | static void exec_signal(int sig ATTRIBUTE_UNUSED) | 615 | static void exec_signal(int sig ATTRIBUTE_UNUSED) |
611 | { | 616 | { |
612 | struct init_action *a, *tmp; | 617 | struct init_action *a, *tmp; |
@@ -632,7 +637,7 @@ static void exec_signal(int sig ATTRIBUTE_UNUSED) | |||
632 | sigprocmask(SIG_UNBLOCK, &unblock_signals, NULL); | 637 | sigprocmask(SIG_UNBLOCK, &unblock_signals, NULL); |
633 | 638 | ||
634 | /* Open the new terminal device */ | 639 | /* Open the new terminal device */ |
635 | open_stdio_to_tty(a->terminal, 0); | 640 | open_stdio_to_tty(a->terminal, 0 /* - shutdown_signal(SIGUSR1) [halt] if open fails */); |
636 | 641 | ||
637 | messageD(L_CONSOLE | L_LOG, "Trying to re-exec %s", a->command); | 642 | messageD(L_CONSOLE | L_LOG, "Trying to re-exec %s", a->command); |
638 | BB_EXECLP(a->command, a->command, NULL); | 643 | BB_EXECLP(a->command, a->command, NULL); |
@@ -646,29 +651,6 @@ static void exec_signal(int sig ATTRIBUTE_UNUSED) | |||
646 | } | 651 | } |
647 | } | 652 | } |
648 | 653 | ||
649 | static void shutdown_signal(int sig) | ||
650 | { | ||
651 | const char *m; | ||
652 | int rb; | ||
653 | |||
654 | shutdown_system(); | ||
655 | |||
656 | m = "halt"; | ||
657 | rb = RB_HALT_SYSTEM; | ||
658 | if (sig == SIGTERM) { | ||
659 | m = "reboot"; | ||
660 | rb = RB_AUTOBOOT; | ||
661 | } else if (sig == SIGUSR2) { | ||
662 | m = "poweroff"; | ||
663 | rb = RB_POWER_OFF; | ||
664 | } | ||
665 | message(L_CONSOLE | L_LOG, "Requesting system %s", m); | ||
666 | /* allow time for last message to reach serial console */ | ||
667 | sleep(2); | ||
668 | init_reboot(rb); | ||
669 | loop_forever(); | ||
670 | } | ||
671 | |||
672 | static void ctrlaltdel_signal(int sig ATTRIBUTE_UNUSED) | 654 | static void ctrlaltdel_signal(int sig ATTRIBUTE_UNUSED) |
673 | { | 655 | { |
674 | run_actions(CTRLALTDEL); | 656 | run_actions(CTRLALTDEL); |
@@ -682,7 +664,7 @@ static void stop_handler(int sig ATTRIBUTE_UNUSED) | |||
682 | got_cont = 0; | 664 | got_cont = 0; |
683 | while (!got_cont) | 665 | while (!got_cont) |
684 | pause(); | 666 | pause(); |
685 | got_cont = 0; | 667 | |
686 | errno = saved_errno; | 668 | errno = saved_errno; |
687 | } | 669 | } |
688 | 670 | ||
@@ -694,7 +676,7 @@ static void cont_handler(int sig ATTRIBUTE_UNUSED) | |||
694 | 676 | ||
695 | #endif /* !ENABLE_DEBUG_INIT */ | 677 | #endif /* !ENABLE_DEBUG_INIT */ |
696 | 678 | ||
697 | static void new_init_action(int action, const char *command, const char *cons) | 679 | static void new_init_action(uint8_t action, const char *command, const char *cons) |
698 | { | 680 | { |
699 | struct init_action *new_action, *a, *last; | 681 | struct init_action *new_action, *a, *last; |
700 | 682 | ||
@@ -754,11 +736,21 @@ static void delete_init_action(struct init_action *action) | |||
754 | static void parse_inittab(void) | 736 | static void parse_inittab(void) |
755 | { | 737 | { |
756 | #if ENABLE_FEATURE_USE_INITTAB | 738 | #if ENABLE_FEATURE_USE_INITTAB |
739 | static const char actions[] = | ||
740 | STR_SYSINIT "sysinit\0" | ||
741 | STR_RESPAWN "respawn\0" | ||
742 | STR_ASKFIRST "askfirst\0" | ||
743 | STR_WAIT "wait\0" | ||
744 | STR_ONCE "once\0" | ||
745 | STR_CTRLALTDEL "ctrlaltdel\0" | ||
746 | STR_SHUTDOWN "shutdown\0" | ||
747 | STR_RESTART "restart\0" | ||
748 | ; | ||
749 | |||
757 | FILE *file; | 750 | FILE *file; |
758 | char buf[INIT_BUFFS_SIZE], lineAsRead[INIT_BUFFS_SIZE]; | 751 | char buf[INIT_BUFFS_SIZE], lineAsRead[INIT_BUFFS_SIZE]; |
759 | char tmpConsole[CONSOLE_NAME_SIZE]; | 752 | char tmpConsole[CONSOLE_NAME_SIZE]; |
760 | char *id, *runlev, *action, *command, *eol; | 753 | char *id, *runlev, *action, *command, *eol; |
761 | const struct init_action_type *a = actions; | ||
762 | 754 | ||
763 | file = fopen(INITTAB, "r"); | 755 | file = fopen(INITTAB, "r"); |
764 | if (file == NULL) { | 756 | if (file == NULL) { |
@@ -769,7 +761,8 @@ static void parse_inittab(void) | |||
769 | /* Umount all filesystems on halt/reboot */ | 761 | /* Umount all filesystems on halt/reboot */ |
770 | new_init_action(SHUTDOWN, "umount -a -r", ""); | 762 | new_init_action(SHUTDOWN, "umount -a -r", ""); |
771 | /* Swapoff on halt/reboot */ | 763 | /* Swapoff on halt/reboot */ |
772 | if (ENABLE_SWAPONOFF) new_init_action(SHUTDOWN, "swapoff -a", ""); | 764 | if (ENABLE_SWAPONOFF) |
765 | new_init_action(SHUTDOWN, "swapoff -a", ""); | ||
773 | /* Prepare to restart init when a HUP is received */ | 766 | /* Prepare to restart init when a HUP is received */ |
774 | new_init_action(RESTART, "init", ""); | 767 | new_init_action(RESTART, "init", ""); |
775 | /* Askfirst shell on tty1-4 */ | 768 | /* Askfirst shell on tty1-4 */ |
@@ -785,6 +778,8 @@ static void parse_inittab(void) | |||
785 | } | 778 | } |
786 | 779 | ||
787 | while (fgets(buf, INIT_BUFFS_SIZE, file) != NULL) { | 780 | while (fgets(buf, INIT_BUFFS_SIZE, file) != NULL) { |
781 | const char *a; | ||
782 | |||
788 | /* Skip leading spaces */ | 783 | /* Skip leading spaces */ |
789 | for (id = buf; *id == ' ' || *id == '\t'; id++); | 784 | for (id = buf; *id == ' ' || *id == '\t'; id++); |
790 | 785 | ||
@@ -832,8 +827,8 @@ static void parse_inittab(void) | |||
832 | } | 827 | } |
833 | 828 | ||
834 | /* Ok, now process it */ | 829 | /* Ok, now process it */ |
835 | for (a = actions; a->name != 0; a++) { | 830 | for (a = actions; a[0]; a += strlen(a) + 1) { |
836 | if (strcmp(a->name, action) == 0) { | 831 | if (strcmp(a + 1, action) == 0) { |
837 | if (*id != '\0') { | 832 | if (*id != '\0') { |
838 | if (strncmp(id, "/dev/", 5) == 0) | 833 | if (strncmp(id, "/dev/", 5) == 0) |
839 | id += 5; | 834 | id += 5; |
@@ -842,11 +837,11 @@ static void parse_inittab(void) | |||
842 | sizeof(tmpConsole) - 5); | 837 | sizeof(tmpConsole) - 5); |
843 | id = tmpConsole; | 838 | id = tmpConsole; |
844 | } | 839 | } |
845 | new_init_action(a->action, command, id); | 840 | new_init_action((uint8_t)a[0], command, id); |
846 | break; | 841 | break; |
847 | } | 842 | } |
848 | } | 843 | } |
849 | if (a->name == 0) { | 844 | if (!a[0]) { |
850 | /* Choke on an unknown action */ | 845 | /* Choke on an unknown action */ |
851 | message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead); | 846 | message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead); |
852 | } | 847 | } |
@@ -981,8 +976,11 @@ int init_main(int argc, char **argv) | |||
981 | } | 976 | } |
982 | #endif /* CONFIG_SELINUX */ | 977 | #endif /* CONFIG_SELINUX */ |
983 | 978 | ||
984 | /* Make the command line just say "init" -- thats all, nothing else */ | 979 | /* Make the command line just say "init" - thats all, nothing else */ |
985 | fixup_argv(argv); | 980 | strncpy(argv[0], "init", strlen(argv[0])); |
981 | /* Wipe argv[1]-argv[N] so they don't clutter the ps listing */ | ||
982 | while (*++argv) | ||
983 | memset(*argv, 0, strlen(*argv)); | ||
986 | 984 | ||
987 | /* Now run everything that needs to be run */ | 985 | /* Now run everything that needs to be run */ |
988 | 986 | ||