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
This commit is contained in:
@@ -39,6 +39,9 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <paths.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "shell.h"
|
#include "shell.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
@@ -124,6 +127,22 @@ main(int argc, char *argv[])
|
|||||||
trputs("Shell args: "); trargs(argv);
|
trputs("Shell args: "); trargs(argv);
|
||||||
#endif
|
#endif
|
||||||
rootpid = getpid();
|
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;
|
rootshell = 1;
|
||||||
INTOFF;
|
INTOFF;
|
||||||
initvar();
|
initvar();
|
||||||
|
|||||||
Reference in New Issue
Block a user