diff options
-rw-r--r-- | fdisks/fdisk-menu.c | 53 | ||||
-rw-r--r-- | fdisks/fdisk.c | 12 | ||||
-rw-r--r-- | fdisks/fdisk.h | 2 |
3 files changed, 47 insertions, 20 deletions
diff --git a/fdisks/fdisk-menu.c b/fdisks/fdisk-menu.c index c7f92b0c0..7bbca6f49 100644 --- a/fdisks/fdisk-menu.c +++ b/fdisks/fdisk-menu.c @@ -31,7 +31,7 @@ struct menu { enum fdisk_labeltype label; /* only for this label */ enum fdisk_labeltype exclude; /* all labels except this */ - int (*callback)(struct fdisk_context *, + int (*callback)(struct fdisk_context **, const struct menu *, const struct menu_entry *); @@ -45,7 +45,7 @@ struct menu_context { #define MENU_CXT_EMPTY { 0, 0 } #define DECLARE_MENU_CB(x) \ - static int x(struct fdisk_context *, \ + static int x(struct fdisk_context **, \ const struct menu *, \ const struct menu_entry *) @@ -199,7 +199,7 @@ struct menu menu_dos = { }; struct menu menu_bsd = { -/* .callback = bsd_menu_cb, */ +/* .callback = bsd_menu_cb,*/ .label = FDISK_DISKLABEL_OSF, .entries = { MENU_SEP(N_("BSD")), @@ -339,12 +339,16 @@ int print_fdisk_menu(struct fdisk_context *cxt) * returns the command key if no callback for the command is * implemented. * + * Note that this function might exchange the context pointer to + * switch to another (nested) context. + * * Returns: <0 on error * 0 on success (the command performed) * >0 if no callback (then returns the key) */ -int process_fdisk_menu(struct fdisk_context *cxt) +int process_fdisk_menu(struct fdisk_context **cxt0) { + struct fdisk_context *cxt = *cxt0; const struct menu_entry *ent; const struct menu *menu; int key, rc; @@ -368,19 +372,23 @@ int process_fdisk_menu(struct fdisk_context *cxt) return -EINVAL; } + rc = 0; DBG(FRONTEND, dbgprint("selected: key=%c, entry='%s'", key, ent->title)); /* hardcoded help */ - if (key == 'm') { + if (key == 'm') print_fdisk_menu(cxt); - return 0; /* menu has implemented callback, use it */ - } else if (menu->callback) - return menu->callback(cxt, menu, ent); + else if (menu->callback) + rc = menu->callback(cxt0, menu, ent); + else { + DBG(FRONTEND, dbgprint("no callback, return key '%c'", key)); + return key; + } - /* no callback, return the key */ - return key; + DBG(FRONTEND, dbgprint("process menu done [rc=%d]", rc)); + return rc; } @@ -388,10 +396,11 @@ int process_fdisk_menu(struct fdisk_context *cxt) * This is fdisk frontend for GPT specific libfdisk functions that * are not expported by generic libfdisk API. */ -static int gpt_menu_cb(struct fdisk_context *cxt, +static int gpt_menu_cb(struct fdisk_context **cxt0, const struct menu *menu __attribute__((__unused__)), const struct menu_entry *ent) { + struct fdisk_context *cxt = *cxt0; size_t n; int rc; @@ -424,12 +433,15 @@ static int gpt_menu_cb(struct fdisk_context *cxt, * This is fdisk frontend for MBR specific libfdisk functions that * are not expported by generic libfdisk API. */ -static int dos_menu_cb(struct fdisk_context *cxt, +static int dos_menu_cb(struct fdisk_context **cxt0, const struct menu *menu __attribute__((__unused__)), const struct menu_entry *ent) { + struct fdisk_context *cxt = *cxt0; int rc = 0; + DBG(FRONTEND, dbgprint("enter DOS menu")); + if (!ent->expert) { switch (ent->key) { case 'a': @@ -448,9 +460,10 @@ static int dos_menu_cb(struct fdisk_context *cxt, return -ENOMEM; if (!fdisk_dev_has_disklabel(bsd)) rc = fdisk_create_disklabel(bsd, "bsd"); - if (!rc) - bsd_command_prompt(bsd); - fdisk_free_context(bsd); + if (rc) + fdisk_free_context(bsd); + else + *cxt0 = cxt = bsd; break; } case 'c': @@ -483,12 +496,15 @@ static int dos_menu_cb(struct fdisk_context *cxt, return rc; } -static int sun_menu_cb(struct fdisk_context *cxt, +static int sun_menu_cb(struct fdisk_context **cxt0, const struct menu *menu __attribute__((__unused__)), const struct menu_entry *ent) { + struct fdisk_context *cxt = *cxt0; int rc = 0; + DBG(FRONTEND, dbgprint("enter SUN menu")); + assert(cxt); assert(ent); assert(fdisk_is_disklabel(cxt, SUN)); @@ -535,13 +551,16 @@ static int sun_menu_cb(struct fdisk_context *cxt, } /* C/H/S commands */ -static int geo_menu_cb(struct fdisk_context *cxt, +static int geo_menu_cb(struct fdisk_context **cxt0, const struct menu *menu __attribute__((__unused__)), const struct menu_entry *ent) { + struct fdisk_context *cxt = *cxt0; int rc = -EINVAL; uintmax_t c = 0, h = 0, s = 0; + DBG(FRONTEND, dbgprint("enter GEO menu")); + assert(cxt); assert(ent); diff --git a/fdisks/fdisk.c b/fdisks/fdisk.c index 0ca888943..f95266bd1 100644 --- a/fdisks/fdisk.c +++ b/fdisks/fdisk.c @@ -381,7 +381,7 @@ expert_command_prompt(struct fdisk_context *cxt) while(1) { assert(cxt->label); - c = process_fdisk_menu(cxt); + c = process_fdisk_menu(&cxt); if (c <= 0) continue; @@ -512,7 +512,7 @@ static void command_prompt(struct fdisk_context *cxt) while (1) { assert(cxt->label); - c = process_fdisk_menu(cxt); + c = process_fdisk_menu(&cxt); if (c <= 0) continue; @@ -588,6 +588,14 @@ static void command_prompt(struct fdisk_context *cxt) case 'x': expert_command_prompt(cxt); break; + case 'r': + if (cxt->parent) { + struct fdisk_context *tmp = cxt->parent; + + fdisk_free_context(cxt); + cxt = tmp; + } + break; default: unknown_command(c); } diff --git a/fdisks/fdisk.h b/fdisks/fdisk.h index 9c40d314b..05721bbd8 100644 --- a/fdisks/fdisk.h +++ b/fdisks/fdisk.h @@ -25,7 +25,7 @@ extern int get_user_reply(struct fdisk_context *cxt, const char *prompt, char *buf, size_t bufsz); extern int print_fdisk_menu(struct fdisk_context *cxt); -extern int process_fdisk_menu(struct fdisk_context *cxt); +extern int process_fdisk_menu(struct fdisk_context **cxt); extern int ask_callback(struct fdisk_context *cxt, struct fdisk_ask *ask, void *data __attribute__((__unused__))); |