Related to bnc#892526 -- let plymouthd become a real daemon that is it should use its own session with the help of the system call setsid(2). Also avoid an EBUSY on ioctl TIOCCONS if a former plymouthd had failed. And a crash or termination may restore not only the current virtual console but also any serial console as well restore the system console. --- plymouth-0.9.0/src/libply-splash-core/ply-device-manager.c | 9 ++ plymouth-0.9.0/src/libply-splash-core/ply-device-manager.h | 1 plymouth-0.9.0/src/libply/ply-terminal-session.c | 7 ++ plymouth-0.9.0/src/libply/ply-utils.c | 2 plymouth-0.9.0/src/main.c | 42 +++++++------ 5 files changed, 43 insertions(+), 18 deletions(-) Index: plymouth-0.9.2+git20160823.e4b7e49/src/libply-splash-core/ply-device-manager.c =================================================================== --- plymouth-0.9.2+git20160823.e4b7e49.orig/src/libply-splash-core/ply-device-manager.c +++ plymouth-0.9.2+git20160823.e4b7e49/src/libply-splash-core/ply-device-manager.c @@ -949,3 +949,12 @@ ply_device_manager_deactivate_keyboards manager->keyboards_activated = false; } + +void +ply_close_all_terminals (ply_device_manager_t *manager) +{ + ply_hashtable_foreach (manager->terminals, + (ply_hashtable_foreach_func_t *) + ply_terminal_close, + manager); +} Index: plymouth-0.9.2+git20160823.e4b7e49/src/libply-splash-core/ply-device-manager.h =================================================================== --- plymouth-0.9.2+git20160823.e4b7e49.orig/src/libply-splash-core/ply-device-manager.h +++ plymouth-0.9.2+git20160823.e4b7e49/src/libply-splash-core/ply-device-manager.h @@ -65,6 +65,7 @@ void ply_device_manager_deactivate_keybo void ply_device_manager_activate_renderers (ply_device_manager_t *manager); void ply_device_manager_deactivate_renderers (ply_device_manager_t *manager); ply_terminal_t *ply_device_manager_get_default_terminal (ply_device_manager_t *manager); +void ply_close_all_terminals (ply_device_manager_t *manager); #endif Index: plymouth-0.9.2+git20160823.e4b7e49/src/libply/ply-utils.c =================================================================== --- plymouth-0.9.2+git20160823.e4b7e49.orig/src/libply/ply-utils.c +++ plymouth-0.9.2+git20160823.e4b7e49/src/libply/ply-utils.c @@ -77,6 +77,7 @@ static int errno_stack[PLY_ERRNO_STACK_SIZE]; static int errno_stack_position = 0; +static bool inChild = false; static int overridden_device_scale = 0; @@ -796,6 +797,7 @@ ply_create_daemon (void) if (!ply_read (receiver_fd, &byte, sizeof(uint8_t))) { int read_error = errno; int status; + inChild = true; if (waitpid (pid, &status, WNOHANG) <= 0) ply_error ("failed to read status from child immediately after starting to daemonize: %s", strerror (read_error)); @@ -836,6 +838,9 @@ ply_detach_daemon (ply_daemon_handle_t * close (sender_fd); free (handle); + if (inChild) + setsid(); + return true; } Index: plymouth-0.9.2+git20160823.e4b7e49/src/libply/ply-terminal-session.c =================================================================== --- plymouth-0.9.2+git20160823.e4b7e49.orig/src/libply/ply-terminal-session.c +++ plymouth-0.9.2+git20160823.e4b7e49/src/libply/ply-terminal-session.c @@ -187,6 +187,12 @@ ply_terminal_session_redirect_console (p assert (terminal_name != NULL); + fd = open ("/dev/console", O_RDWR | O_NOCTTY); + if (fd >= 0) { + ioctl (fd, TIOCCONS); /* Undo any current map if any */ + close (fd); + } + fd = open (terminal_name, O_RDWR | O_NOCTTY); if (fd < 0) Index: plymouth-0.9.2+git20160823.e4b7e49/src/main.c =================================================================== --- plymouth-0.9.2+git20160823.e4b7e49.orig/src/main.c +++ plymouth-0.9.2+git20160823.e4b7e49/src/main.c @@ -1101,6 +1101,7 @@ on_text_display_removed (state_t ply_boot_splash_remove_text_display (state->boot_splash, display); } +static ply_device_manager_t *manager; static void load_devices (state_t *state, ply_device_manager_flags_t flags) @@ -1108,6 +1109,8 @@ load_devices (state_t state->device_manager = ply_device_manager_new (state->default_tty, flags); state->local_console_terminal = ply_device_manager_get_default_terminal (state->device_manager); + manager = state->device_manager; + ply_device_manager_watch_devices (state->device_manager, state->device_timeout, (ply_keyboard_added_handler_t) @@ -1146,6 +1149,7 @@ quit_splash (state_t *state) ply_trace ("Not retaining splash, so deallocating VT"); ply_terminal_deactivate_vt (state->local_console_terminal); ply_terminal_close (state->local_console_terminal); + ply_close_all_terminals (state->device_manager); } } @@ -2091,28 +2095,20 @@ dump_debug_buffer_to_file (void) #include #include static void -on_crash (int signum) +dosigaction (int signum) { - struct termios term_attributes; int fd; - static const char *show_cursor_sequence = "\033[?25h"; - - fd = open ("/dev/tty1", O_RDWR | O_NOCTTY); - if (fd < 0) fd = open ("/dev/hvc0", O_RDWR | O_NOCTTY); - - ioctl (fd, KDSETMODE, KD_TEXT); - - write (fd, show_cursor_sequence, sizeof (show_cursor_sequence) - 1); - - tcgetattr (fd, &term_attributes); - term_attributes.c_iflag |= BRKINT | IGNPAR | ICRNL | IXON; - term_attributes.c_oflag |= OPOST; - term_attributes.c_lflag |= ECHO | ICANON | ISIG | IEXTEN; - - tcsetattr (fd, TCSAFLUSH, &term_attributes); + if (manager) { + ply_device_manager_deactivate_keyboards (manager); + ply_close_all_terminals (manager); + } - close (fd); + fd = open ("/dev/console", O_RDWR | O_NOCTTY); + if (fd >= 0) { + ioctl (fd, TIOCCONS); /* Undo any current map if any */ + close (fd); + } if (debug_buffer != NULL) { dump_debug_buffer_to_file (); @@ -2125,7 +2121,6 @@ on_crash (int signum) pid_file = NULL; } - signal (signum, SIG_DFL); raise (signum); } @@ -2159,6 +2154,7 @@ main (int argc, char *kernel_command_line = NULL; char *tty = NULL; ply_device_manager_flags_t device_manager_flags = PLY_DEVICE_MANAGER_FLAGS_NONE; + struct sigaction sa; state.start_time = ply_get_timestamp (); state.command_parser = ply_command_parser_new ("plymouthd", "Splash server"); @@ -2261,8 +2257,13 @@ main (int argc, if (debug) debug_buffer = ply_buffer_new (); - signal (SIGABRT, on_crash); - signal (SIGSEGV, on_crash); + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESETHAND; + sa.sa_handler = dosigaction; + sigaction (SIGHUP, &sa, NULL); + sigaction (SIGTERM, &sa, NULL); + sigaction (SIGABRT, &sa, NULL); + sigaction (SIGSEGV, &sa, NULL); /* before do anything we need to make sure we have a working * environment.