X-Git-Url: http://git.ozlabs.org/?a=blobdiff_plain;ds=sidebyside;f=ui%2Fncurses%2Fnc-cui.c;h=a4711a943330687c6093dbbc4f3e504a7bf31a02;hb=f5c10524f88751be5ec2766185875b4359fcbb70;hp=a2de48e75f3e71c8bf94571896ce4d6d327196b9;hpb=bbaa3ac16e14b1f386d70d14f16d0164d163017e;p=petitboot diff --git a/ui/ncurses/nc-cui.c b/ui/ncurses/nc-cui.c index a2de48e..a4711a9 100644 --- a/ui/ncurses/nc-cui.c +++ b/ui/ncurses/nc-cui.c @@ -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; }