summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Mendoza-Jonas <sam@mendozajonas.com>2018-02-16 13:55:26 +1100
committerSamuel Mendoza-Jonas <sam@mendozajonas.com>2018-02-27 11:43:36 +1100
commitd63bacef37d61b46e8db10914d4a7a677ba0775a (patch)
tree23b6c6c44b3cd6b99aec64dd5351fffad634be5f
parentdc85de97c79c2172a87fc95cca16e6c6055dc1f4 (diff)
downloadtalos-petitboot-d63bacef37d61b46e8db10914d4a7a677ba0775a.zip
talos-petitboot-d63bacef37d61b46e8db10914d4a7a677ba0775a.tar.gz
ui/ncurses: Fix boot editor segfault on update
The boot option editor screen segfaults on a system info update since it loses track of which fields actually exist. The boot editor screen's setup and drawing logic is a bit different from other screens, so to fix this bug and preserve the maintainer's sanity, bring the screen setup and redraw into line with other screens. This includes a full teardown of the widgets on update, so save the content of any textboxes on update so the user's changes are not lost. Signed-off-by: Samuel Mendoza-Jonas <sam@mendozajonas.com>
-rw-r--r--ui/ncurses/nc-boot-editor.c108
1 files changed, 71 insertions, 37 deletions
diff --git a/ui/ncurses/nc-boot-editor.c b/ui/ncurses/nc-boot-editor.c
index 5b098a4..f302c52 100644
--- a/ui/ncurses/nc-boot-editor.c
+++ b/ui/ncurses/nc-boot-editor.c
@@ -488,18 +488,11 @@ static void boot_editor_find_device(struct boot_editor *boot_editor,
static void boot_editor_setup_widgets(struct boot_editor *boot_editor,
const struct system_info *sysinfo)
{
- struct nc_widgetset *set;
+ struct nc_widgetset *set = boot_editor->widgetset;
int field_size;
field_size = COLS - 1 - boot_editor->field_x;
- boot_editor->widgetset = set = widgetset_create(boot_editor,
- boot_editor->scr.main_ncw,
- boot_editor->pad);
-
- widgetset_set_widget_focus(boot_editor->widgetset,
- boot_editor_widget_focus, boot_editor);
-
boot_editor->widgets.device_l = widget_new_label(set, 0, 0,
_("Device:"));
boot_editor->widgets.device_f = widget_new_select(set, 0, 0,
@@ -549,33 +542,82 @@ static void boot_editor_setup_widgets(struct boot_editor *boot_editor,
_("Cancel"), cancel_click, boot_editor);
}
-void boot_editor_update(struct boot_editor *boot_editor,
+static void boot_editor_draw(struct boot_editor *boot_editor,
const struct system_info *sysinfo)
{
+ bool repost = false;
int height;
+ height = pad_height(sysinfo ? sysinfo->n_blockdevs : 0);
+
+ if (!boot_editor->pad || getmaxy(boot_editor->pad) < height) {
+ if (boot_editor->pad)
+ delwin(boot_editor->pad);
+ boot_editor->pad = newpad(height, COLS);
+ }
+
+ if (boot_editor->widgetset) {
+ widgetset_unpost(boot_editor->widgetset);
+ talloc_free(boot_editor->widgetset);
+ repost = true;
+ }
+
+ boot_editor->widgetset = widgetset_create(boot_editor,
+ boot_editor->scr.main_ncw,
+ boot_editor->pad);
+ widgetset_set_widget_focus(boot_editor->widgetset,
+ boot_editor_widget_focus, boot_editor);
+
+ boot_editor_setup_widgets(boot_editor, sysinfo);
+ boot_editor_layout_widgets(boot_editor);
+
+ if (repost)
+ widgetset_post(boot_editor->widgetset);
+}
+
+void boot_editor_update(struct boot_editor *boot_editor,
+ const struct system_info *sysinfo)
+{
+ const char *str;
+
if (boot_editor->cui->current != boot_editor_scr(boot_editor)) {
boot_editor->need_update = true;
return;
}
- widgetset_unpost(boot_editor->widgetset);
+ str = widget_textbox_get_value(boot_editor->widgets.image_f);
+ if (str) {
+ talloc_free(boot_editor->image);
+ boot_editor->image = talloc_strdup(boot_editor, str);
+ }
- height = pad_height(sysinfo ? sysinfo->n_blockdevs : 0);
- if (getmaxy(boot_editor->pad) < height) {
- delwin(boot_editor->pad);
- boot_editor->pad = newpad(height, COLS);
- widgetset_set_windows(boot_editor->widgetset,
- boot_editor->scr.main_ncw,
- boot_editor->pad);
+ str = widget_textbox_get_value(boot_editor->widgets.initrd_f);
+ if (str) {
+ talloc_free(boot_editor->initrd);
+ boot_editor->initrd = talloc_strdup(boot_editor, str);
}
- boot_editor_populate_device_select(boot_editor, sysinfo);
+ str = widget_textbox_get_value(boot_editor->widgets.dtb_f);
+ if (str) {
+ talloc_free(boot_editor->dtb);
+ boot_editor->dtb = talloc_strdup(boot_editor, str);
+ }
- boot_editor_layout_widgets(boot_editor);
+ str = widget_textbox_get_value(boot_editor->widgets.args_f);
+ if (str) {
+ talloc_free(boot_editor->args);
+ boot_editor->args = talloc_strdup(boot_editor, str);
+ }
- widgetset_post(boot_editor->widgetset);
+ if (boot_editor->use_signature_files) {
+ str = widget_textbox_get_value(boot_editor->widgets.args_sig_file_f);
+ if (str) {
+ talloc_free(boot_editor->args_sig_file);
+ boot_editor->args_sig_file = talloc_strdup(boot_editor, str);
+ }
+ }
+ boot_editor_draw(boot_editor, sysinfo);
pad_refresh(boot_editor);
}
@@ -634,28 +676,20 @@ struct boot_editor *boot_editor_init(struct cui *cui,
if (item) {
struct pb_boot_data *bd = cod_from_item(item)->bd;
- boot_editor->image = bd->image;
- boot_editor->initrd = bd->initrd;
- boot_editor->dtb = bd->dtb;
- boot_editor->args = bd->args;
+ boot_editor->image = talloc_strdup(boot_editor, bd->image);
+ boot_editor->initrd = talloc_strdup(boot_editor, bd->initrd);
+ boot_editor->dtb = talloc_strdup(boot_editor, bd->dtb);
+ boot_editor->args = talloc_strdup(boot_editor, bd->args);
if (boot_editor->use_signature_files)
- boot_editor->args_sig_file = bd->args_sig_file;
+ boot_editor->args_sig_file = talloc_strdup(boot_editor,
+ bd->args_sig_file);
else
- boot_editor->args_sig_file = talloc_strdup(bd, "");
+ boot_editor->args_sig_file = talloc_strdup(boot_editor,
+ "");
boot_editor_find_device(boot_editor, bd, sysinfo);
- } else {
- boot_editor->image = boot_editor->initrd =
- boot_editor->dtb = boot_editor->args =
- boot_editor->args_sig_file = "";
}
- boot_editor->pad = newpad(
- pad_height(sysinfo ? sysinfo->n_blockdevs : 0),
- COLS);
-
- boot_editor_setup_widgets(boot_editor, sysinfo);
-
- boot_editor_layout_widgets(boot_editor);
+ boot_editor_draw(boot_editor, sysinfo);
wrefresh(boot_editor->scr.main_ncw);
return boot_editor;
OpenPOWER on IntegriCloud