]> git.ozlabs.org Git - petitboot/blobdiff - ui/ncurses/nc-cui.c
ui/ncurses: Make server connect message more clear
[petitboot] / ui / ncurses / nc-cui.c
index a2de48e75f3e71c8bf94571896ce4d6d327196b9..a4711a943330687c6093dbbc4f3e504a7bf31a02 100644 (file)
@@ -45,6 +45,8 @@
 
 extern const struct help_text main_menu_help_text;
 
+static bool cui_detached = false;
+
 static struct pmenu *main_menu_init(struct cui *cui);
 
 static void cui_start(void)
@@ -83,6 +85,7 @@ static void cui_start(void)
        define_key("OF", KEY_END);
        define_key("\x1b\x5b\x41", KEY_UP);
        define_key("\x1b\x5b\x42", KEY_DOWN);
+       define_key("\x1b\x5b\x33\x7e", KEY_DC);
 
        while (getch() != ERR)          /* flush stdin */
                (void)0;
@@ -90,6 +93,9 @@ static void cui_start(void)
 
 static void cui_atexit(void)
 {
+       if (cui_detached)
+               return;
+
        clear();
        refresh();
        endwin();
@@ -423,11 +429,16 @@ static int cui_process_key(void *arg)
                if (c == ERR)
                        break;
 
-               if (!cui->has_input && cui->client) {
-                       pb_log("UI input received (key = %d), aborting "
-                                       "default boot\n", c);
-                       discover_client_cancel_default(cui->client);
+               if (!cui->has_input) {
                        cui->has_input = true;
+                       if (cui->client) {
+                               pb_log("UI input received (key = %d), aborting "
+                                       "default boot\n", c);
+                               discover_client_cancel_default(cui->client);
+                       } else {
+                               pb_log("UI input received (key = %d), aborting "
+                                       "once server connects\n", c);
+                       }
                }
 
                if (process_global_keys(cui, c))
@@ -896,6 +907,31 @@ static struct discover_client_ops cui_client_ops = {
        .update_config = cui_update_config,
 };
 
+/* cui_server_wait_on_exit - On exit spin until the server is available.
+ *
+ * If the program exits before connecting to the server autoboot won't be
+ * cancelled even though there has been keyboard activity. This function is
+ * called by a child process which will spin until the server is connected and
+ * told to cancel autoboot.
+ *
+ * Processes exiting from this function will not carry out the cui_atexit()
+ * steps.
+ */
+static void cui_server_wait_on_exit(struct cui *cui)
+{
+       cui_detached = true;
+
+       while (!cui->client) {
+               cui->client = discover_client_init(cui->waitset,
+                               &cui_client_ops, cui);
+               if (!cui->client)
+                       sleep(1);
+       }
+
+       talloc_steal(cui, cui->client);
+       discover_client_cancel_default(cui->client);
+}
+
 /* cui_server_wait - Connect to the discover server.
  * @arg: Pointer to the cui instance.
  *
@@ -923,10 +959,17 @@ static int cui_server_wait(void *arg)
        if (!cui->client) {
                waiter_register_timeout(cui->waitset, 1000, cui_server_wait,
                                        cui);
-               nc_scr_status_printf(cui->current, "Info: Waiting for server");
+               nc_scr_status_printf(cui->current,
+                                    "Info: Waiting for device discovery");
        } else {
-               nc_scr_status_printf(cui->current, "Info: Connected to server!");
+               nc_scr_status_printf(cui->current,
+                                    "Info: Connected to pb-discover!");
                talloc_steal(cui, cui->client);
+
+               if (cui->has_input) {
+                       pb_log("Aborting default boot on pb-discover connect\n");
+                       discover_client_cancel_default(cui->client);
+               }
        }
 
        return 0;
@@ -1045,6 +1088,8 @@ fail_alloc:
 
 int cui_run(struct cui *cui)
 {
+       pid_t pid;
+
        assert(main);
 
        cui->current = &cui->main->scr;
@@ -1071,5 +1116,16 @@ int cui_run(struct cui *cui)
 
        cui_atexit();
 
+       if (!cui->client) {
+               /* Fork a child to tell the server to cancel autoboot */
+               pid = fork();
+               if (!pid) {
+                       cui_server_wait_on_exit(cui);
+                       exit(EXIT_SUCCESS);
+               }
+               if (pid < 0)
+                       pb_log("Failed to fork child on exit: %m\n");
+       }
+
        return cui->abort ? 0 : -1;
 }