fix single user mode
This commit is contained in:
parent
c7000aeaab
commit
1bc96141e6
@ -113,7 +113,7 @@ veinfo vewarn vebegin veend vewend veindent veoutdent: do_e.o rc-misc.o
|
|||||||
fstabinfo: fstabinfo.o _usage.o rc-misc.o
|
fstabinfo: fstabinfo.o _usage.o rc-misc.o
|
||||||
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
||||||
|
|
||||||
openrc-init: openrc-init.o rc-wtmp.o
|
openrc-init: openrc-init.o rc-plugin.o rc-wtmp.o
|
||||||
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
||||||
|
|
||||||
is_newer_than: is_newer_than.o rc-misc.o
|
is_newer_than: is_newer_than.o rc-misc.o
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <pwd.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -37,6 +38,7 @@
|
|||||||
|
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
#include "rc.h"
|
#include "rc.h"
|
||||||
|
#include "rc-plugin.h"
|
||||||
#include "rc-wtmp.h"
|
#include "rc-wtmp.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
@ -118,6 +120,65 @@ static void handle_shutdown(const char *runlevel, int cmd)
|
|||||||
reboot(cmd);
|
reboot(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void run_program(const char *prog)
|
||||||
|
{
|
||||||
|
sigset_t full;
|
||||||
|
sigset_t old;
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
|
/* We need to block signals until we have forked */
|
||||||
|
sigfillset(&full);
|
||||||
|
sigprocmask(SIG_SETMASK, &full, &old);
|
||||||
|
pid = fork();
|
||||||
|
if (pid == -1) {
|
||||||
|
perror("init");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (pid == 0) {
|
||||||
|
/* Unmask signals */
|
||||||
|
sigprocmask(SIG_SETMASK, &old, NULL);
|
||||||
|
execl(prog, prog, (char *)NULL);
|
||||||
|
perror("init");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
/* Unmask signals and wait for child */
|
||||||
|
sigprocmask(SIG_SETMASK, &old, NULL);
|
||||||
|
if (rc_waitpid(pid) == -1)
|
||||||
|
perror("init");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void open_shell(void)
|
||||||
|
{
|
||||||
|
const char *shell;
|
||||||
|
struct passwd *pw;
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
const char *sys = rc_sys();
|
||||||
|
|
||||||
|
/* VSERVER systems cannot really drop to shells */
|
||||||
|
if (sys && strcmp(sys, RC_SYS_VSERVER) == 0)
|
||||||
|
{
|
||||||
|
execlp("halt", "halt", "-f", (char *) NULL);
|
||||||
|
perror("init");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
shell = rc_conf_value("rc_shell");
|
||||||
|
/* No shell set, so obey env, then passwd, then default to /bin/sh */
|
||||||
|
if (!shell) {
|
||||||
|
shell = getenv("SHELL");
|
||||||
|
if (!shell) {
|
||||||
|
pw = getpwuid(getuid());
|
||||||
|
if (pw)
|
||||||
|
shell = pw->pw_shell;
|
||||||
|
if (!shell)
|
||||||
|
shell = "/bin/sh";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
run_program(shell);
|
||||||
|
}
|
||||||
|
|
||||||
static void handle_single(void)
|
static void handle_single(void)
|
||||||
{
|
{
|
||||||
do_openrc("single");
|
do_openrc("single");
|
||||||
@ -248,8 +309,11 @@ int main(int argc, char **argv)
|
|||||||
handle_shutdown("reboot", RB_AUTOBOOT);
|
handle_shutdown("reboot", RB_AUTOBOOT);
|
||||||
else if (strcmp(buf, "reexec") == 0)
|
else if (strcmp(buf, "reexec") == 0)
|
||||||
handle_reexec(argv[0]);
|
handle_reexec(argv[0]);
|
||||||
else if (strcmp(buf, "single") == 0)
|
else if (strcmp(buf, "single") == 0) {
|
||||||
handle_single();
|
handle_single();
|
||||||
|
open_shell();
|
||||||
|
init(default_runlevel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user