Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 27 Apr 2026 03:21:34 +0000
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: d7338bb4914d - main - bin/sh: make it possible to use as interactive init
Message-ID:  <69eed63e.3af1e.59d3cfe4@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=d7338bb4914d120e5719d3216b23a509c49ed3be

commit d7338bb4914d120e5719d3216b23a509c49ed3be
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2026-04-20 18:03:39 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-04-27 01:45:12 +0000

    bin/sh: make it possible to use as interactive init
    
    If the /sbin/init binary is broken somehow, the way out is to set the
    loader environment variable init_path to something else.  The most
    natural choice would be either /bin/sh or /rescue/sh.  Unfortunately,
    this does not work because the init process starts withoud stdin/out
    descriptors.
    
    Make it nicer to users by teaching /bin/sh startup code to open standard
    descriptors on /dev/console if the shell is run as init.
    
    Reviewed by:    imp, jilles, zlei
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D56536
---
 bin/sh/main.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/bin/sh/main.c b/bin/sh/main.c
index 94e8da6b4921..0ca2d4942426 100644
--- a/bin/sh/main.c
+++ b/bin/sh/main.c
@@ -39,6 +39,9 @@
 #include <fcntl.h>
 #include <locale.h>
 #include <errno.h>
+#include <termios.h>
+#include <paths.h>
+#include <unistd.h>
 
 #include "shell.h"
 #include "main.h"
@@ -124,6 +127,22 @@ main(int argc, char *argv[])
 	trputs("Shell args:  ");  trargs(argv);
 #endif
 	rootpid = getpid();
+	if (rootpid == 1) {
+		/*
+		 * Make sh usable for invocation as interactive init
+		 * substitute with init_path=/bin/sh, by opening
+		 * file descriptors 0, 1, and 2 on /dev/console.
+		 */
+		if (fcntl(STDIN_FILENO, F_GETFL, NULL) == -1 && errno == EBADF) {
+			(void)open(_PATH_CONSOLE, O_RDWR);
+			(void)setsid();
+			(void)tcsetsid(STDIN_FILENO, rootpid);
+		}
+		if (fcntl(STDOUT_FILENO, F_GETFL, NULL) == -1 && errno == EBADF)
+			(void)dup2(STDIN_FILENO, STDOUT_FILENO);
+		if (fcntl(STDERR_FILENO, F_GETFL, NULL) == -1 && errno == EBADF)
+			(void)dup2(STDIN_FILENO, STDERR_FILENO);
+	}
 	rootshell = 1;
 	INTOFF;
 	initvar();


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69eed63e.3af1e.59d3cfe4>