summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Mendoza-Jonas <sam@mendozajonas.com>2016-11-23 11:48:07 +1100
committerSamuel Mendoza-Jonas <sam@mendozajonas.com>2016-11-24 13:30:11 +1100
commit69078e89091998d40ffac03b0d57511d3531b2f2 (patch)
tree1ebaf4d0ba8ebd27db3f8caedcf55af062a58ac0
parenta23c3271090ddb9004678b8ede3b2ba8f83d7acf (diff)
downloadpetitboot-69078e89091998d40ffac03b0d57511d3531b2f2.zip
petitboot-69078e89091998d40ffac03b0d57511d3531b2f2.tar.gz
ui/ncurses: Spin child to ensure autoboot cancelled on exit
If the client is not connected to the server instance when exiting, fork and have the child process spin until the server is available and can be told to cancel autoboot. This prevents the scenario of a user exiting the UI and having the server continue to autoboot while they are using the command line. Signed-off-by: Samuel Mendoza-Jonas <sam@mendozajonas.com> (cherry picked from commit 1dd51e986202e5e111c1042f148867bd08c2bedc)
-rw-r--r--ui/ncurses/nc-cui.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/ui/ncurses/nc-cui.c b/ui/ncurses/nc-cui.c
index 0c355cc..f386c82 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)
@@ -91,6 +93,9 @@ static void cui_start(void)
static void cui_atexit(void)
{
+ if (cui_detached)
+ return;
+
clear();
refresh();
endwin();
@@ -902,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.
*
@@ -1056,6 +1086,8 @@ fail_alloc:
int cui_run(struct cui *cui)
{
+ pid_t pid;
+
assert(main);
cui->current = &cui->main->scr;
@@ -1082,5 +1114,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;
}
OpenPOWER on IntegriCloud