From a47fec81b2a9eae2712da86c75db27cf76fae4b4 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Wed, 10 Jul 2013 14:17:58 +0200 Subject: fdisk: allow to exchange context pointer in menu callbacks ... to make it possible to switch to nested contexts (nested partition tables). Signed-off-by: Karel Zak --- fdisks/fdisk-menu.c | 53 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 17 deletions(-) (limited to 'fdisks/fdisk-menu.c') 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); -- cgit v1.2.3-55-g7522