Run daemons in their own session.

This commit is contained in:
Jonas 'Sortie' Termansen 2024-06-16 19:42:13 +00:00
parent 6e51c1ae51
commit e90e2077e7
1 changed files with 14 additions and 31 deletions

View File

@ -313,6 +313,7 @@ struct communication
static pid_t main_pid;
static pid_t forward_signal_pid = -1;
static int tty_fd;
static volatile sig_atomic_t caught_exit_signal = -1;
static sigset_t handled_signals;
@ -2545,31 +2546,24 @@ static void daemon_start(struct daemon* daemon)
fatal("fork: %m");
if ( daemon->need_tty )
{
if ( tcgetattr(0, &daemon->oldtio) )
if ( tcgetattr(tty_fd, &daemon->oldtio) )
fatal("tcgetattr: %m");
}
if ( daemon->pid == 0 )
{
uninstall_signal_handler();
close(errfds[0]);
if ( setsid() < 0 )
exit_errfd(errfds[1], "setsid");
if ( chdir(cd) < 0 )
exit_errfd(errfds[1], "chdir");
if ( daemon->need_tty )
{
pid_t pid = getpid();
// TODO: Support for setsid(2).
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");
if ( ioctl(tty_fd, TIOCSCTTY, 1) < 0 )
exit_errfd(errfds[1], "TIOCSCTTY");
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");
sigprocmask(SIG_SETMASK, &oldset, NULL);
dup3(errfds[1], 3, O_CLOEXEC);
closefrom(4);
}
@ -2723,10 +2717,10 @@ static void daemon_on_exit(struct daemon* daemon, int exit_code)
sigemptyset(&sigttou);
sigaddset(&sigttou, SIGTTOU);
sigprocmask(SIG_BLOCK, &sigttou, &oldset);
if ( tcsetattr(0, TCSAFLUSH, &daemon->oldtio) )
if ( tcsetattr(tty_fd, TCSAFLUSH, &daemon->oldtio) )
fatal("tcsetattr: %m");
if ( tcsetpgrp(0, getpgid(0)) < 0 )
fatal("tcsetpgrp: %m");
if ( ioctl(tty_fd, TIOCSCTTY, 1) < 0 )
fatal("TIOCSCTTY: %m");
sigprocmask(SIG_SETMASK, &oldset, NULL);
}
daemon_on_finished(daemon);
@ -3728,12 +3722,8 @@ static void set_hostname(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 &&
(errno == ENOTTY || errno == ENOENT);
close(tty_fd);
if ( unsupported )
return;
FILE* fp = fopen("/etc/kblayout", "r");
@ -3766,9 +3756,6 @@ static void set_kblayout(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 tiocgdisplays gdisplays;
memset(&gdisplays, 0, sizeof(gdisplays));
@ -3776,7 +3763,6 @@ static void set_videomode(void)
gdisplays.displays = &display;
bool unsupported = ioctl(tty_fd, TIOCGDISPLAYS, &gdisplays) < 0 ||
gdisplays.count == 0;
close(tty_fd);
if ( unsupported )
return;
FILE* fp = fopen("/etc/videomode", "r");
@ -4303,13 +4289,14 @@ int main(int argc, char* argv[])
if ( getinit(0) != getpid() )
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.
if ( atexit(niht) != 0 )
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.
// All child processes have to uninstall the signal handler and unblock the
// signals or they keep blocking the signals.
@ -4461,9 +4448,6 @@ int main(int argc, char* argv[])
chain_location_dev_made = true;
close(new_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.
// Run the chain booted operating system.
pid_t child_pid = fork();
@ -4512,7 +4496,6 @@ int main(int argc, char* argv[])
forward_signal_pid = -1; // Racy with waitpid.
if ( ioctl(tty_fd, TIOCSCTTY, 1) < 0 )
fatal("ioctl: TIOCSCTTY: %m");
close(tty_fd);
if ( WIFEXITED(status) )
return WEXITSTATUS(status);
else if ( WIFSIGNALED(status) )