summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeah Neukirchen <leah@vuxu.org>2022-01-07 19:34:42 +0100
committerLeah Neukirchen <leah@vuxu.org>2022-01-07 19:34:42 +0100
commit2f7a6bdb8a581fe9a8ba81c9309d7aced7957092 (patch)
treeeeda9e3d66d80c4e4a769f7bdf0078047c61f61d
parent263d901fcf674bc7c36ffe5927aece974a8dd33b (diff)
downloadrvnit-2f7a6bdb8a581fe9a8ba81c9309d7aced7957092.tar.gz
rvnit-2f7a6bdb8a581fe9a8ba81c9309d7aced7957092.tar.xz
rvnit-2f7a6bdb8a581fe9a8ba81c9309d7aced7957092.zip
when pid 1, make oneshot startup services control the tty
-rw-r--r--rvnit.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/rvnit.c b/rvnit.c
index 0f3be57..4f6acab 100644
--- a/rvnit.c
+++ b/rvnit.c
@@ -1,6 +1,7 @@
 /* accept4 */
 #define _GNU_SOURCE
 
+#include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/un.h>
@@ -57,6 +58,7 @@ int selflogfd[2];
 int newlogfd[2];
 int globallogfd[2];
 
+int pid1;
 int use_global_log;
 
 sig_atomic_t want_shutdown;
@@ -69,7 +71,8 @@ on_sigint(int sig)
 {
 	(void)sig;
 	want_shutdown = 1;
-	want_reboot = 1;
+	if (pid1)
+		want_reboot = 1;
 }
 
 void
@@ -153,6 +156,8 @@ restart(int i)
 		}
 		sleep(delay);
 		setsid();
+		if (services[i].name[2] == 'S' && pid1)
+			ioctl(0, TIOCSCTTY, 1);
 		execl(services[i].name,
 		    services[i].name,
 		    (char *)0);
@@ -602,6 +607,20 @@ next:		;
 	closedir(dir);
 }
 
+void
+own_console()
+{
+	int ttyfd = open("/dev/console", O_RDWR);
+	if (ttyfd < 0)
+		return;
+	dup2(ttyfd, 0);
+	dup2(ttyfd, 1);
+	dup2(ttyfd, 2);
+	if (ttyfd > 2)
+		close(ttyfd);
+	ioctl(0, TIOCSCTTY, 1);
+}
+
 int
 main(int argc, char *argv[])
 {
@@ -615,6 +634,10 @@ main(int argc, char *argv[])
 		return 111;
 	}
 
+	pid1 = (getpid() == 1);
+	if (pid1)
+		own_console();
+
 	pipe(selflogfd);
 	fcntl(selflogfd[0], F_SETFL, O_NONBLOCK);
 	fcntl(selflogfd[1], F_SETFL, O_NONBLOCK);
@@ -710,7 +733,6 @@ main(int argc, char *argv[])
 				goto cont1;
 
 			if (services[i].name[2] == 'S') {
-
 				if (services[i].status != 0) {
 					LOG("oneshot %s failed, running error services for level=%d", services[i].name, level);
 
@@ -736,6 +758,9 @@ main(int argc, char *argv[])
 cont1:
 			pthread_mutex_unlock(&services_lock);
 		}
+
+		if (pid1)
+			ioctl(0, TIOCSCTTY, 1); // steal back console
 	}
 
 	sigset_t emptyset;
@@ -830,6 +855,9 @@ cont2:
 		pthread_mutex_unlock(&services_lock);
 	}
 
+	if (pid1)
+		own_console();
+
 	LOG("shutting down");
 
 	if (want_reboot) {