From: Ray Strode Date: Sun, 1 Dec 2013 01:57:52 +0000 (-0500) Subject: main: maintain better accounting of terminals X-Git-Tag: 0.9.0~65^2~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a20a99790ca0ac7df57c8e93d56706210ab12c8b;p=thirdparty%2Fplymouth.git main: maintain better accounting of terminals Currently terminals are created in the main file and passed down to other layers, with no direct reference maintained in the main file. There are points when we need to get references to all those terminals again, and we have to fish them out from other layers. This commit makes it all more explicit, maintaining the terminals in a hash table in the main state object. --- diff --git a/src/main.c b/src/main.c index 6ef7bff2..715e5bdc 100644 --- a/src/main.c +++ b/src/main.c @@ -84,6 +84,7 @@ typedef struct { ply_event_loop_t *loop; ply_boot_server_t *boot_server; + ply_hashtable_t *terminals; ply_list_t *pixel_displays; ply_list_t *text_displays; ply_keyboard_t *keyboard; @@ -153,6 +154,58 @@ static void tell_systemd_to_stop_printing_details (state_t *state); #endif static const char * get_cache_file_for_mode (ply_mode_t mode); +static void +free_terminal (char *device, + ply_terminal_t *terminal, + state_t *state) +{ + ply_hashtable_remove (state->terminals, device); + + ply_terminal_close (terminal); + ply_terminal_free (terminal); +} + +static void +free_terminals (state_t *state) +{ + ply_hashtable_foreach (state->terminals, + (ply_hashtable_foreach_func_t *) + free_terminal, + state); +} + +static ply_terminal_t * +get_terminal (state_t *state, + const char *device_name) +{ + char *full_name; + ply_terminal_t *terminal; + + if (strncmp (device_name, "/dev/", strlen ("/dev/")) == 0) + full_name = strdup (device_name); + else + asprintf (&full_name, "/dev/%s", device_name); + + if (strcmp (full_name, "/dev/tty0") == 0 || + strcmp (full_name, "/dev/tty") == 0) + { + free (full_name); + full_name = strdup (state->default_tty); + } + + terminal = ply_hashtable_lookup (state->terminals, full_name); + + if (terminal == NULL) + { + terminal = ply_terminal_new (full_name); + + ply_hashtable_insert (state->terminals, (void *) ply_terminal_get_name (terminal), terminal); + } + free (full_name); + + return terminal; +} + static void on_session_output (state_t *state, const char *output, @@ -915,62 +968,9 @@ on_show_splash (state_t *state) show_messages (state); } -static ply_list_t * -get_tracked_terminals (state_t *state) -{ - ply_list_t *terminals; - ply_list_node_t *node; - - terminals = ply_list_new (); - - node = ply_list_get_first_node (state->text_displays); - while (node != NULL) - { - ply_list_node_t *next_node; - ply_text_display_t *display; - ply_terminal_t *terminal; - - next_node = ply_list_get_next_node (state->text_displays, node); - display = ply_list_node_get_data (node); - terminal = ply_text_display_get_terminal (display); - - ply_list_append_data (terminals, terminal); - - node = next_node; - } - - return terminals; -} - -static void -free_terminals (state_t *state, - ply_list_t *terminals) -{ - ply_list_node_t *node; - node = ply_list_get_first_node (terminals); - while (node != NULL) - { - ply_list_node_t *next_node; - ply_terminal_t *terminal; - - next_node = ply_list_get_next_node (state->text_displays, node); - terminal = ply_list_node_get_data (node); - - ply_terminal_close (terminal); - ply_terminal_free (terminal); - ply_list_remove_node (terminals, node); - - node = next_node; - } - - ply_list_free (terminals); -} - static void quit_splash (state_t *state) { - ply_list_t *terminals; - ply_trace ("quiting splash"); if (state->boot_splash != NULL) { @@ -979,8 +979,6 @@ quit_splash (state_t *state) state->boot_splash = NULL; } - terminals = get_tracked_terminals (state); - ply_trace ("removing displays and keyboard"); remove_displays_and_keyboard (state); @@ -1000,7 +998,8 @@ quit_splash (state_t *state) } state->local_console_terminal = NULL; } - free_terminals (state, terminals); + + free_terminals (state); detach_from_running_session (state); } @@ -1575,7 +1574,7 @@ add_default_displays_and_keyboard (state_t *state) ply_trace ("adding default displays and keyboard"); - state->local_console_terminal = ply_terminal_new (state->default_tty); + state->local_console_terminal = get_terminal (state, state->default_tty); renderer = ply_renderer_new (PLY_RENDERER_TYPE_AUTO, NULL, state->local_console_terminal); @@ -1957,24 +1956,19 @@ check_logging (state_t *state) } static void -add_display_and_keyboard_for_console (const char *console, - const char *null, - state_t *state) +add_display_and_keyboard_for_console (const char *name, + ply_terminal_t *terminal, + state_t *state) { - ply_terminal_t *terminal; - - terminal = ply_terminal_new (console); - - if (strcmp (console, state->default_tty) == 0) + if (strcmp (name, state->default_tty) == 0) state->local_console_terminal = terminal; - ply_trace ("adding display and keyboard for console %s", console); + ply_trace ("adding display and keyboard for console %s", name); add_display_and_keyboard_for_terminal (state, terminal); } static int add_consoles_from_file (state_t *state, - ply_hashtable_t *consoles, const char *path) { int fd; @@ -2010,7 +2004,8 @@ add_consoles_from_file (state_t *state, { char *console; size_t console_length; - char *console_device; + const char *console_device; + ply_terminal_t *terminal; /* Advance past any leading whitespace */ remaining_file_contents += strspn (remaining_file_contents, " \n\t\v"); @@ -2035,12 +2030,12 @@ add_consoles_from_file (state_t *state, if (strcmp (console, "tty0") != 0) state->should_force_details = true; - asprintf (&console_device, "/dev/%s", console); + terminal = get_terminal (state, console); + console_device = ply_terminal_get_name (terminal); free (console); ply_trace ("console %s found!", console_device); - ply_hashtable_insert (consoles, console_device, console_device); num_consoles++; /* Move past the parsed console string, and the whitespace we @@ -2055,8 +2050,7 @@ add_consoles_from_file (state_t *state, } static int -add_consoles_from_kernel_command_line (state_t *state, - ply_hashtable_t *consoles) +add_consoles_from_kernel_command_line (state_t *state) { const char *console_string; const char *remaining_command_line; @@ -2072,7 +2066,8 @@ add_consoles_from_kernel_command_line (state_t *state, { char *end; size_t console_length; - char *console_device; + const char *console_device; + ply_terminal_t *terminal; remaining_command_line = console_string; @@ -2087,20 +2082,10 @@ add_consoles_from_kernel_command_line (state_t *state, console_length = strlen (console); - if (strncmp (console, "/dev/", strlen ("/dev/")) == 0) - { - console_device = console; - console = NULL; - } - else - { - asprintf (&console_device, "/dev/%s", console); - free (console); - console = NULL; - } + terminal = get_terminal (state, console); + console_device = ply_terminal_get_name (terminal); ply_trace ("console %s found!", console_device); - ply_hashtable_insert (consoles, console_device, console_device); num_consoles++; remaining_command_line += console_length; } @@ -2111,49 +2096,30 @@ add_consoles_from_kernel_command_line (state_t *state, static void check_for_consoles (state_t *state) { - char *console; - ply_hashtable_t *consoles; int num_consoles; bool ignore_serial_consoles; ply_trace ("checking for consoles%s", state->is_shown? " and adding displays": ""); - consoles = ply_hashtable_new (ply_hashtable_string_hash, - ply_hashtable_string_compare); ignore_serial_consoles = command_line_has_argument (state->kernel_command_line, "plymouth.ignore-serial-consoles"); num_consoles = 0; if (!ignore_serial_consoles) { - num_consoles = add_consoles_from_file (state, consoles, "/sys/class/tty/console/active"); + num_consoles = add_consoles_from_file (state, "/sys/class/tty/console/active"); if (num_consoles == 0) { ply_trace ("falling back to kernel command line"); - num_consoles = add_consoles_from_kernel_command_line (state, consoles); + num_consoles = add_consoles_from_kernel_command_line (state); } } else { ply_trace ("ignoring all consoles but default console because of plymouth.ignore-serial-consoles"); - } - - console = ply_hashtable_remove (consoles, (void *) "/dev/tty0"); - if (console != NULL) - { - free (console); - console = strdup (state->default_tty); - ply_hashtable_insert (consoles, console, console); - } - - console = ply_hashtable_remove (consoles, (void *) "/dev/tty"); - if (console != NULL) - { - free (console); - console = strdup (state->default_tty); - ply_hashtable_insert (consoles, console, console); + get_terminal (state, state->default_tty); } if (state->is_shown) @@ -2161,20 +2127,15 @@ check_for_consoles (state_t *state) /* Do a full graphical splash if there's no weird serial console * stuff going on, otherwise just prepare text splashes */ - if ((num_consoles == 0) || - ((num_consoles == 1) && - (ply_hashtable_lookup (consoles, (void *) state->default_tty) != NULL))) + if (num_consoles <= 1) add_default_displays_and_keyboard (state); else - ply_hashtable_foreach (consoles, + ply_hashtable_foreach (state->terminals, (ply_hashtable_foreach_func_t *) add_display_and_keyboard_for_console, state); } - ply_hashtable_foreach (consoles, (ply_hashtable_foreach_func_t *) free, NULL); - ply_hashtable_free (consoles); - ply_trace ("After processing serial consoles there are now %d text displays", ply_list_get_length (state->text_displays)); } @@ -2260,6 +2221,7 @@ initialize_environment (state_t *state) state->keystroke_triggers = ply_list_new (); state->entry_triggers = ply_list_new (); state->entry_buffer = ply_buffer_new(); + state->terminals = ply_hashtable_new (ply_hashtable_string_hash, ply_hashtable_string_compare); state->pixel_displays = ply_list_new (); state->text_displays = ply_list_new (); state->messages = ply_list_new ();