summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichel Stam <m.stam@fugro.nl>2014-10-13 16:14:35 +0200
committerJohn Crispin <blogic@openwrt.org>2014-10-12 13:24:11 +0200
commit8b27adcf7516fa89ced66c840cfb085f2b6067af (patch)
treec0e651faa5faa51e989f153361ed280704a36bd9
parent79872ea6ca5867631c1ec5405721af12bea818b2 (diff)
downloadunitd-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.c52
1 files changed, 52 insertions, 0 deletions
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 <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();