diff options
author | Michel Stam <m.stam@fugro.nl> | 2014-10-13 16:14:35 +0200 |
---|---|---|
committer | John Crispin <blogic@openwrt.org> | 2014-10-12 13:24:11 +0200 |
commit | 8b27adcf7516fa89ced66c840cfb085f2b6067af (patch) | |
tree | c0e651faa5faa51e989f153361ed280704a36bd9 | |
parent | 79872ea6ca5867631c1ec5405721af12bea818b2 (diff) | |
download | unitd-8b27adcf7516fa89ced66c840cfb085f2b6067af.tar unitd-8b27adcf7516fa89ced66c840cfb085f2b6067af.zip |
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 <m.stam@fugro.nl>
-rw-r--r-- | state.c | 52 |
1 files changed, 52 insertions, 0 deletions
@@ -12,7 +12,9 @@ * GNU General Public License for more details. */ +#include <fcntl.h> #include <sys/reboot.h> +#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> @@ -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(); |