Run daemons in their own session.
This commit is contained in:
parent
035cd9b1a2
commit
e88c1ca56c
1 changed files with 14 additions and 31 deletions
45
init/init.c
45
init/init.c
|
@ -313,6 +313,7 @@ struct communication
|
||||||
|
|
||||||
static pid_t main_pid;
|
static pid_t main_pid;
|
||||||
static pid_t forward_signal_pid = -1;
|
static pid_t forward_signal_pid = -1;
|
||||||
|
static int tty_fd;
|
||||||
|
|
||||||
static volatile sig_atomic_t caught_exit_signal = -1;
|
static volatile sig_atomic_t caught_exit_signal = -1;
|
||||||
static sigset_t handled_signals;
|
static sigset_t handled_signals;
|
||||||
|
@ -2545,31 +2546,24 @@ static void daemon_start(struct daemon* daemon)
|
||||||
fatal("fork: %m");
|
fatal("fork: %m");
|
||||||
if ( daemon->need_tty )
|
if ( daemon->need_tty )
|
||||||
{
|
{
|
||||||
if ( tcgetattr(0, &daemon->oldtio) )
|
if ( tcgetattr(tty_fd, &daemon->oldtio) )
|
||||||
fatal("tcgetattr: %m");
|
fatal("tcgetattr: %m");
|
||||||
}
|
}
|
||||||
if ( daemon->pid == 0 )
|
if ( daemon->pid == 0 )
|
||||||
{
|
{
|
||||||
uninstall_signal_handler();
|
uninstall_signal_handler();
|
||||||
close(errfds[0]);
|
close(errfds[0]);
|
||||||
|
if ( setsid() < 0 )
|
||||||
|
exit_errfd(errfds[1], "setsid");
|
||||||
if ( chdir(cd) < 0 )
|
if ( chdir(cd) < 0 )
|
||||||
exit_errfd(errfds[1], "chdir");
|
exit_errfd(errfds[1], "chdir");
|
||||||
if ( daemon->need_tty )
|
if ( daemon->need_tty )
|
||||||
{
|
{
|
||||||
pid_t pid = getpid();
|
if ( ioctl(tty_fd, TIOCSCTTY, 1) < 0 )
|
||||||
// TODO: Support for setsid(2).
|
exit_errfd(errfds[1], "TIOCSCTTY");
|
||||||
if ( setpgid(0, 0) < 0 )
|
|
||||||
exit_errfd(errfds[1], "setpgid");
|
|
||||||
sigset_t oldset, sigttou;
|
|
||||||
sigemptyset(&sigttou);
|
|
||||||
sigaddset(&sigttou, SIGTTOU);
|
|
||||||
sigprocmask(SIG_BLOCK, &sigttou, &oldset);
|
|
||||||
if ( tcsetpgrp(0, pid) < 0 )
|
|
||||||
exit_errfd(errfds[1], "tcsetpgrp");
|
|
||||||
daemon->oldtio.c_cflag |= CREAD;
|
daemon->oldtio.c_cflag |= CREAD;
|
||||||
if ( tcsetattr(0, TCSANOW, &daemon->oldtio) < 0 )
|
if ( tcsetattr(tty_fd, TCSANOW, &daemon->oldtio) < 0 )
|
||||||
exit_errfd(errfds[1], "tcsetattr");
|
exit_errfd(errfds[1], "tcsetattr");
|
||||||
sigprocmask(SIG_SETMASK, &oldset, NULL);
|
|
||||||
dup3(errfds[1], 3, O_CLOEXEC);
|
dup3(errfds[1], 3, O_CLOEXEC);
|
||||||
closefrom(4);
|
closefrom(4);
|
||||||
}
|
}
|
||||||
|
@ -2723,10 +2717,10 @@ static void daemon_on_exit(struct daemon* daemon, int exit_code)
|
||||||
sigemptyset(&sigttou);
|
sigemptyset(&sigttou);
|
||||||
sigaddset(&sigttou, SIGTTOU);
|
sigaddset(&sigttou, SIGTTOU);
|
||||||
sigprocmask(SIG_BLOCK, &sigttou, &oldset);
|
sigprocmask(SIG_BLOCK, &sigttou, &oldset);
|
||||||
if ( tcsetattr(0, TCSAFLUSH, &daemon->oldtio) )
|
if ( tcsetattr(tty_fd, TCSAFLUSH, &daemon->oldtio) )
|
||||||
fatal("tcsetattr: %m");
|
fatal("tcsetattr: %m");
|
||||||
if ( tcsetpgrp(0, getpgid(0)) < 0 )
|
if ( ioctl(tty_fd, TIOCSCTTY, 1) < 0 )
|
||||||
fatal("tcsetpgrp: %m");
|
fatal("TIOCSCTTY: %m");
|
||||||
sigprocmask(SIG_SETMASK, &oldset, NULL);
|
sigprocmask(SIG_SETMASK, &oldset, NULL);
|
||||||
}
|
}
|
||||||
daemon_on_finished(daemon);
|
daemon_on_finished(daemon);
|
||||||
|
@ -3728,12 +3722,8 @@ static void set_hostname(void)
|
||||||
|
|
||||||
static void set_kblayout(void)
|
static void set_kblayout(void)
|
||||||
{
|
{
|
||||||
int tty_fd = open("/dev/tty", O_RDWR);
|
|
||||||
if ( !tty_fd )
|
|
||||||
return warning("unable to set keyboard layout: /dev/tty: %m");
|
|
||||||
bool unsupported = tcgetblob(tty_fd, "kblayout", NULL, 0) < 0 &&
|
bool unsupported = tcgetblob(tty_fd, "kblayout", NULL, 0) < 0 &&
|
||||||
(errno == ENOTTY || errno == ENOENT);
|
(errno == ENOTTY || errno == ENOENT);
|
||||||
close(tty_fd);
|
|
||||||
if ( unsupported )
|
if ( unsupported )
|
||||||
return;
|
return;
|
||||||
FILE* fp = fopen("/etc/kblayout", "r");
|
FILE* fp = fopen("/etc/kblayout", "r");
|
||||||
|
@ -3766,9 +3756,6 @@ static void set_kblayout(void)
|
||||||
|
|
||||||
static void set_videomode(void)
|
static void set_videomode(void)
|
||||||
{
|
{
|
||||||
int tty_fd = open("/dev/tty", O_RDWR);
|
|
||||||
if ( !tty_fd )
|
|
||||||
return warning("unable to set video mode: /dev/tty: %m");
|
|
||||||
struct tiocgdisplay display;
|
struct tiocgdisplay display;
|
||||||
struct tiocgdisplays gdisplays;
|
struct tiocgdisplays gdisplays;
|
||||||
memset(&gdisplays, 0, sizeof(gdisplays));
|
memset(&gdisplays, 0, sizeof(gdisplays));
|
||||||
|
@ -3776,7 +3763,6 @@ static void set_videomode(void)
|
||||||
gdisplays.displays = &display;
|
gdisplays.displays = &display;
|
||||||
bool unsupported = ioctl(tty_fd, TIOCGDISPLAYS, &gdisplays) < 0 ||
|
bool unsupported = ioctl(tty_fd, TIOCGDISPLAYS, &gdisplays) < 0 ||
|
||||||
gdisplays.count == 0;
|
gdisplays.count == 0;
|
||||||
close(tty_fd);
|
|
||||||
if ( unsupported )
|
if ( unsupported )
|
||||||
return;
|
return;
|
||||||
FILE* fp = fopen("/etc/videomode", "r");
|
FILE* fp = fopen("/etc/videomode", "r");
|
||||||
|
@ -4303,13 +4289,14 @@ int main(int argc, char* argv[])
|
||||||
if ( getinit(0) != getpid() )
|
if ( getinit(0) != getpid() )
|
||||||
fatal("System is already managed by an init process");
|
fatal("System is already managed by an init process");
|
||||||
|
|
||||||
if ( !isatty(0) || !isatty(1) || !isatty(2) )
|
|
||||||
fatal("stdin, stdout, and stderr must be the terminal");
|
|
||||||
|
|
||||||
// Register handler that shuts down the system when init exits.
|
// Register handler that shuts down the system when init exits.
|
||||||
if ( atexit(niht) != 0 )
|
if ( atexit(niht) != 0 )
|
||||||
fatal("atexit: %m");
|
fatal("atexit: %m");
|
||||||
|
|
||||||
|
// Remember the controlling terminal to give it away and reclaim it.
|
||||||
|
if ( (tty_fd = open("/dev/tty", O_RDWR | O_CLOEXEC)) < 0 )
|
||||||
|
fatal("/dev/tty: %m");
|
||||||
|
|
||||||
// Handle signals but block them until the safe points where we handle them.
|
// Handle signals but block them until the safe points where we handle them.
|
||||||
// All child processes have to uninstall the signal handler and unblock the
|
// All child processes have to uninstall the signal handler and unblock the
|
||||||
// signals or they keep blocking the signals.
|
// signals or they keep blocking the signals.
|
||||||
|
@ -4461,9 +4448,6 @@ int main(int argc, char* argv[])
|
||||||
chain_location_dev_made = true;
|
chain_location_dev_made = true;
|
||||||
close(new_dev_fd);
|
close(new_dev_fd);
|
||||||
close(old_dev_fd);
|
close(old_dev_fd);
|
||||||
int tty_fd = open("/dev/tty", O_RDWR | O_CLOEXEC);
|
|
||||||
if ( tty_fd < 0 )
|
|
||||||
fatal("/dev/tty: %m");
|
|
||||||
// TODO: Forward the early init log to the chain init.
|
// TODO: Forward the early init log to the chain init.
|
||||||
// Run the chain booted operating system.
|
// Run the chain booted operating system.
|
||||||
pid_t child_pid = fork();
|
pid_t child_pid = fork();
|
||||||
|
@ -4512,7 +4496,6 @@ int main(int argc, char* argv[])
|
||||||
forward_signal_pid = -1; // Racy with waitpid.
|
forward_signal_pid = -1; // Racy with waitpid.
|
||||||
if ( ioctl(tty_fd, TIOCSCTTY, 1) < 0 )
|
if ( ioctl(tty_fd, TIOCSCTTY, 1) < 0 )
|
||||||
fatal("ioctl: TIOCSCTTY: %m");
|
fatal("ioctl: TIOCSCTTY: %m");
|
||||||
close(tty_fd);
|
|
||||||
if ( WIFEXITED(status) )
|
if ( WIFEXITED(status) )
|
||||||
return WEXITSTATUS(status);
|
return WEXITSTATUS(status);
|
||||||
else if ( WIFSIGNALED(status) )
|
else if ( WIFSIGNALED(status) )
|
||||||
|
|
Loading…
Reference in a new issue