From 8b27adcf7516fa89ced66c840cfb085f2b6067af Mon Sep 17 00:00:00 2001 From: Michel Stam Date: Mon, 13 Oct 2014 16:14:35 +0200 Subject: Show the shutdown sequence on the active virtual terminal procd by default writes to /dev/console. When rebooting, this means that the terminal on which the reboot sequence was started will not see what is going on. This patch fixes that by reopening stdin, stdout and stderr to the console device specified on the commandline, /dev/tty0 or /dev/console upon reboot. Also, due to (probably) pivot-root, /proc/1/fd shows 1-3 pointing to /console. This patch also fixes that. Signed-off-by: Michel Stam --- state.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/state.c b/state.c index 41e4471..7f0ec50 100644 --- a/state.c +++ b/state.c @@ -12,7 +12,9 @@ * GNU General Public License for more details. */ +#include #include +#include #include #include #include @@ -23,6 +25,7 @@ #include "plug/hotplug.h" #include "watchdog.h" #include "service/service.h" +#include "utils/utils.h" enum { STATE_NONE = 0, @@ -38,6 +41,52 @@ enum { static int state = STATE_NONE; static int reboot_event; +static void set_stdio(const char* tty) +{ + chdir("/dev"); + freopen(tty, "r", stdin); + freopen(tty, "w", stdout); + freopen(tty, "w", stderr); + chdir("/"); + fcntl(STDERR_FILENO, F_SETFL, fcntl(STDERR_FILENO, F_GETFL) | O_NONBLOCK); +} + +static void set_console(void) +{ + const char* tty; + char* split; + char line[ 20 ]; + const char* try[] = { "tty0", "console", NULL }; /* Try the most common outputs */ + int f, i = 0; + + tty = get_cmdline_val("console",line,sizeof(line)); + if (tty != NULL) { + split = strchr(tty, ','); + if ( split != NULL ) + *split = '\0'; + } else { + // Try a default + tty=try[i]; + i++; + } + + chdir("/dev"); + while (tty!=NULL) { + f = open(tty, O_RDONLY); + if (f >= 0) { + close(f); + break; + } + + tty=try[i]; + i++; + } + chdir("/"); + + if (tty != NULL) + set_stdio(tty); +} + static void state_enter(void) { char ubus_cmd[] = "/sbin/ubusd"; @@ -53,6 +102,7 @@ static void state_enter(void) case STATE_UBUS: // try to reopen incase the wdt was not available before coldplug watchdog_init(0); + set_stdio("console"); LOG("- ubus -\n"); procd_connect_ubus(); service_init(); @@ -73,6 +123,8 @@ static void state_enter(void) break; case STATE_SHUTDOWN: + /* Redirect output to the console for the users' benefit */ + set_console(); LOG("- shutdown -\n"); procd_inittab_run("shutdown"); sync(); -- cgit v1.2.3