diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-02-21 00:15:20 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-02-21 00:15:20 +0000 |
commit | 7a2ca5e111a21cca703e111ee448317bfaf96ed9 (patch) | |
tree | be7c65eeb924440e094ba4bdc46b60317eefe6f1 /init/init.c | |
parent | a624c11d5e9ac32f6e7b22b406e5a0eec44e2d3b (diff) | |
download | busybox-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.c | 348 |
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 */ |
28 | struct 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 | }; | ||
33 | enum { VT_GETSTATE = 0x5603 }; /* get global vt state info */ | ||
34 | |||
35 | /* From <linux/serial.h> */ | ||
36 | struct 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 */ |
111 | struct init_action { | 76 | struct 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 */ |
120 | static struct init_action *init_action_list = NULL; | 85 | static struct init_action *init_action_list = NULL; |
121 | static char console_name[CONSOLE_BUFF_SIZE] = DEV_CONSOLE; | ||
122 | 86 | ||
123 | #if !ENABLE_SYSLOGD | 87 | #if !ENABLE_SYSLOGD |
124 | static const char *log_console = VC_5; | 88 | static 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))); |
181 | static void message(int device, const char *fmt, ...) | 145 | static 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> */ | ||
241 | struct 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 | }; | ||
285 | static void console_init(void) | 264 | static 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 | ||
341 | static void fixup_argv(int argc, char **argv, const char *new_argv0) | 295 | static 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 */ |
358 | static void open_new_terminal(const char* device, int fail) { | 312 | static 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 | ||
378 | static pid_t run(const struct init_action *a) | 337 | static 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 | ||
676 | static void exec_signal(int sig ATTRIBUTE_UNUSED) | 622 | static 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 | } |