This is a multi-part message in MIME format. --------------040505020001050308040003 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
Hello, all. Rescue mode doesn't need contexts so I propose to move context handling to normal.mod rather than have it in kernel. Saves 314 bytes. Available in experimental --=20 Regards Vladimir '=CF=86-coder/phcoder' Serbinenko --------------040505020001050308040003 Content-Type: text/x-diff; name="newenv.diff" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline; filename="newenv.diff" =3D=3D=3D added file 'ChangeLog.newenv' --- ChangeLog.newenv 1970-01-01 00:00:00 +0000 +++ ChangeLog.newenv 2009-12-20 13:20:06 +0000 @@ -0,0 +1,55 @@ +2009-12-20 Vladimir Serbinenko <phco...@gmail.com> + + Move context handling out of the kernel. + + * conf/any-emu.rmk (grub_emu_SOURCES): Add normal/context.c. + * conf/common.rmk (normal_mod_SOURCES): Add normal/context.c. + * conf/i386-coreboot.rmk (kernel_img_HEADERS): Add env_private.h. + * conf/i386-efi.rmk: Likewise. + * conf/i386-ieee1275.rmk: Likewise. + * conf/i386-pc.rmk: Likewise. + * conf/powerpc-ieee1275.rmk: Likewise. + * conf/sparc64-ieee1275.rmk: Likewise. + * conf/x86_64-efi.rmk: Likewise. + * include/grub/env.h: Include grub/menu.h. + (grub_env_var_type): Removed. + (grub_env_var): Replaced field 'type' with 'global'. + (grub_env_find): New prototype. + (grub_env_context_open): Remove EXPORT_FUNC. + (grub_env_context_close): Likewise. + (grub_env_export): Likewise. + (grub_env_set_data_slot): Removed. + (grub_env_get_data_slot): Likewise. + (grub_env_unset_data_slot): Likewise. + (grub_env_unset_menu): New prototype. + (grub_env_set_menu): Likewise. + (grub_env_get_menu): Likewise. + * include/grub/env_private.h: New file. + * include/grub/normal.h (grub_context_init): New prototype. + (grub_context_fini): Likewise. + * kern/corecmd.c (grub_core_cmd_export): Moved from here ... + * normal/context.c (grub_cmd_export): ... to here. + * kern/env.c: Include env_private.h. + (HASHSZ): Moved to include/grub/env_private.h. + (grub_env_context): Likewise. + (grub_env_sorted_var): Likewise. + (current_context): Renamed from this ... + (grub_current_context): ...to this. 'static' removed. All users updated= =2E + (grub_env_find): Removed 'static'. + (grub_env_context_open): Moved to normal/context.c. + (grub_env_context_close): Likewise. + (grub_env_export): Likewise. + (mangle_data_slot_name): Removed. + (grub_env_set_data_slot): Likewise. + (grub_env_get_data_slot): Likewise. + (grub_env_unset_data_slot): Likewise. + * kern/main.c (grub_set_root_dev): Don't export root. + It will be done later. + (grub_main): Don't export prefix. + It will be done later. + * normal/context.c: New file. + * normal/main.c (free_menu): Use grub_env_unset_menu. + (grub_normal_add_menu_entry): Use grub_env_get_menu. + (read_config_file): Use grub_env_get_menu and grub_env_set_menu. + (GRUB_MOD_INIT(normal)): Call grub_context_init. + (GRUB_MOD_FINI(normal)): Call grub_context_fini. =3D=3D=3D modified file 'conf/any-emu.rmk' --- conf/any-emu.rmk 2009-11-30 15:39:59 +0000 +++ conf/any-emu.rmk 2009-12-20 01:26:58 +0000 @@ -27,7 +27,7 @@ normal/handler.c normal/auth.c normal/autofs.c \ normal/completion.c normal/main.c normal/color.c \ normal/menu.c normal/menu_entry.c normal/menu_viewer.c \ - normal/menu_text.c \ + normal/menu_text.c normal/context.c \ script/main.c script/execute.c script/function.c \ script/lexer.c script/script.c grub_script.tab.c \ partmap/amiga.c partmap/apple.c partmap/msdos.c partmap/sun.c \ =3D=3D=3D modified file 'conf/common.rmk' --- conf/common.rmk 2009-12-18 02:57:32 +0000 +++ conf/common.rmk 2009-12-20 01:26:58 +0000 @@ -543,7 +543,7 @@ normal/auth.c normal/autofs.c normal/handler.c \ normal/color.c normal/completion.c normal/datetime.c normal/menu.c \ normal/menu_entry.c normal/menu_text.c normal/menu_viewer.c \ - normal/misc.c + normal/misc.c normal/context.c normal_mod_CFLAGS =3D $(COMMON_CFLAGS) normal_mod_LDFLAGS =3D $(COMMON_LDFLAGS) =20 =3D=3D=3D modified file 'conf/i386-coreboot.rmk' --- conf/i386-coreboot.rmk 2009-12-03 23:07:29 +0000 +++ conf/i386-coreboot.rmk 2009-12-20 01:26:58 +0000 @@ -35,7 +35,8 @@ env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \= machine/boot.h machine/console.h machine/init.h \ - machine/memory.h machine/loader.h list.h handler.h command.h i18n.h + machine/memory.h machine/loader.h list.h handler.h command.h i18n.h \ + env_private.h kernel_img_CFLAGS =3D $(COMMON_CFLAGS) kernel_img_ASFLAGS =3D $(COMMON_ASFLAGS) kernel_img_LDFLAGS =3D $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(GRUB_KERNEL_= MACHINE_LINK_ADDR),-Bstatic =3D=3D=3D modified file 'conf/i386-efi.rmk' --- conf/i386-efi.rmk 2009-12-18 02:57:32 +0000 +++ conf/i386-efi.rmk 2009-12-20 01:26:58 +0000 @@ -51,7 +51,8 @@ kernel_img_HEADERS =3D boot.h cache.h device.h disk.h dl.h elf.h elfload= =2Eh \ env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \= - efi/efi.h efi/time.h efi/disk.h i386/pit.h list.h handler.h command.h i= 18n.h + efi/efi.h efi/time.h efi/disk.h i386/pit.h list.h handler.h command.h \= + i18n.h env_private.h kernel_img_CFLAGS =3D $(COMMON_CFLAGS) kernel_img_ASFLAGS =3D $(COMMON_ASFLAGS) kernel_img_LDFLAGS =3D $(COMMON_LDFLAGS) =3D=3D=3D modified file 'conf/i386-ieee1275.rmk' --- conf/i386-ieee1275.rmk 2009-11-26 00:45:53 +0000 +++ conf/i386-ieee1275.rmk 2009-12-20 01:26:58 +0000 @@ -33,7 +33,7 @@ env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \= ieee1275/ieee1275.h machine/kernel.h machine/loader.h machine/memory.h = \ - list.h handler.h command.h i18n.h + list.h handler.h command.h i18n.h env_private.h kernel_img_CFLAGS =3D $(COMMON_CFLAGS) kernel_img_ASFLAGS =3D $(COMMON_ASFLAGS) kernel_img_LDFLAGS =3D $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstat= ic =3D=3D=3D modified file 'conf/i386-pc.rmk' --- conf/i386-pc.rmk 2009-12-18 02:57:32 +0000 +++ conf/i386-pc.rmk 2009-12-20 01:26:58 +0000 @@ -64,7 +64,8 @@ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \= machine/biosdisk.h machine/boot.h machine/console.h machine/init.h \ machine/memory.h machine/loader.h machine/vga.h machine/vbe.h \ - machine/kernel.h machine/pxe.h i386/pit.h list.h handler.h command.h i1= 8n.h + machine/kernel.h machine/pxe.h i386/pit.h list.h handler.h command.h \ + i18n.h env_private.h kernel_img_CFLAGS =3D $(COMMON_CFLAGS) $(TARGET_IMG_CFLAGS) kernel_img_ASFLAGS =3D $(COMMON_ASFLAGS) kernel_img_LDFLAGS =3D $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KER= NEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS) =3D=3D=3D modified file 'conf/powerpc-ieee1275.rmk' --- conf/powerpc-ieee1275.rmk 2009-11-26 00:45:53 +0000 +++ conf/powerpc-ieee1275.rmk 2009-12-20 01:26:58 +0000 @@ -17,7 +17,7 @@ env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h reader.h \ symbol.h term.h time.h types.h powerpc/libgcc.h loader.h partition.h \ msdos_partition.h ieee1275/ieee1275.h machine/kernel.h handler.h list.h= \ - command.h i18n.h + command.h i18n.h env_private.h =20 symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gen= symlist.sh /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) =3D=3D=3D modified file 'conf/sparc64-ieee1275.rmk' --- conf/sparc64-ieee1275.rmk 2009-12-03 11:18:56 +0000 +++ conf/sparc64-ieee1275.rmk 2009-12-20 01:26:58 +0000 @@ -31,7 +31,7 @@ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \= list.h handler.h command.h i18n.h \ sparc64/libgcc.h ieee1275/ieee1275.h machine/kernel.h \ - sparc64/ieee1275/ieee1275.h + sparc64/ieee1275/ieee1275.h env_private.h kernel_img_SOURCES =3D kern/sparc64/ieee1275/crt0.S kern/ieee1275/cmain.= c \ kern/ieee1275/ieee1275.c kern/main.c kern/device.c \ kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \ =3D=3D=3D modified file 'conf/x86_64-efi.rmk' --- conf/x86_64-efi.rmk 2009-12-18 02:57:32 +0000 +++ conf/x86_64-efi.rmk 2009-12-20 01:26:58 +0000 @@ -51,7 +51,7 @@ env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \= efi/efi.h efi/time.h efi/disk.h machine/loader.h i386/pit.h list.h \ - handler.h command.h i18n.h + handler.h command.h i18n.h env_private.h kernel_img_CFLAGS =3D $(COMMON_CFLAGS) kernel_img_ASFLAGS =3D $(COMMON_ASFLAGS) kernel_img_LDFLAGS =3D $(COMMON_LDFLAGS) =3D=3D=3D modified file 'include/grub/env.h' --- include/grub/env.h 2009-03-22 10:45:06 +0000 +++ include/grub/env.h 2009-12-20 01:46:19 +0000 @@ -22,6 +22,7 @@ #include <grub/symbol.h> #include <grub/err.h> #include <grub/types.h> +#include <grub/menu.h> =20 struct grub_env_var; =20 @@ -30,18 +31,6 @@ typedef char *(*grub_env_write_hook_t) (struct grub_env_var *var, const char *val); =20 -enum grub_env_var_type - { - /* The default variable type which is local in current context. */ - GRUB_ENV_VAR_LOCAL, - - /* The exported type, which is passed to new contexts. */ - GRUB_ENV_VAR_GLOBAL, - - /* The data slot type, which is used to store arbitrary data. */ - GRUB_ENV_VAR_DATA - }; - struct grub_env_var { char *name; @@ -50,23 +39,24 @@ grub_env_write_hook_t write_hook; struct grub_env_var *next; struct grub_env_var **prevp; - enum grub_env_var_type type; + int global; }; =20 grub_err_t EXPORT_FUNC(grub_env_set) (const char *name, const char *val)= ; char *EXPORT_FUNC(grub_env_get) (const char *name); void EXPORT_FUNC(grub_env_unset) (const char *name); void EXPORT_FUNC(grub_env_iterate) (int (*func) (struct grub_env_var *va= r)); +struct grub_env_var *EXPORT_FUNC(grub_env_find) (const char *name); grub_err_t EXPORT_FUNC(grub_register_variable_hook) (const char *name, grub_env_read_hook_t read_hook, grub_env_write_hook_t write_hook); -grub_err_t EXPORT_FUNC(grub_env_context_open) (int export); -grub_err_t EXPORT_FUNC(grub_env_context_close) (void); -grub_err_t EXPORT_FUNC(grub_env_export) (const char *name); - -grub_err_t EXPORT_FUNC(grub_env_set_data_slot) (const char *name, - const void *ptr); -void *EXPORT_FUNC(grub_env_get_data_slot) (const char *name); -void EXPORT_FUNC(grub_env_unset_data_slot) (const char *name); + +grub_err_t grub_env_context_open (int export); +grub_err_t grub_env_context_close (void); +grub_err_t grub_env_export (const char *name); + +void grub_env_unset_menu (void); +grub_menu_t grub_env_get_menu (void); +void grub_env_set_menu (grub_menu_t nmenu); =20 #endif /* ! GRUB_ENV_HEADER */ =3D=3D=3D added file 'include/grub/env_private.h' --- include/grub/env_private.h 1970-01-01 00:00:00 +0000 +++ include/grub/env_private.h 2009-12-20 01:21:05 +0000 @@ -0,0 +1,46 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2005,2006,2007,2009 Free Software Foundation, In= c. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by= + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef GRUB_ENV_PRIVATE_HEADER +#define GRUB_ENV_PRIVATE_HEADER 1 + +#include <grub/env.h> + +/* The size of the hash table. */ +#define HASHSZ 13 + +/* A hashtable for quick lookup of variables. */ +struct grub_env_context +{ + /* A hash table for variables. */ + struct grub_env_var *vars[HASHSZ]; + + /* One level deeper on the stack. */ + struct grub_env_context *prev; +}; + +/* This is used for sorting only. */ +struct grub_env_sorted_var +{ + struct grub_env_var *var; + struct grub_env_sorted_var *next; +}; + +extern struct grub_env_context *EXPORT_VAR(grub_current_context); + +#endif /* ! GRUB_ENV_PRIVATE_HEADER */ =3D=3D=3D modified file 'include/grub/normal.h' --- include/grub/normal.h 2009-12-19 23:00:30 +0000 +++ include/grub/normal.h 2009-12-20 13:20:15 +0000 @@ -90,6 +90,8 @@ /* Defined in `autofs.c'. */ void read_fs_list (void); =20 +void grub_context_init (void); +void grub_context_fini (void); =20 #ifdef GRUB_UTIL void grub_normal_init (void); =3D=3D=3D modified file 'kern/corecmd.c' --- kern/corecmd.c 2009-06-10 21:04:23 +0000 +++ kern/corecmd.c 2009-12-20 01:26:58 +0000 @@ -73,18 +73,6 @@ return 0; } =20 -static grub_err_t -grub_core_cmd_export (struct grub_command *cmd __attribute__ ((unused)),= - int argc, char **args) -{ - if (argc < 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "no environment variable specified"); - - grub_env_export (args[0]); - return 0; -} - /* insmod MODULE */ static grub_err_t grub_core_cmd_insmod (struct grub_command *cmd __attribute__ ((unused)),= @@ -193,8 +181,6 @@ "set [ENVVAR=3DVALUE]", "set an environment variable"); grub_register_command ("unset", grub_core_cmd_unset, "unset ENVVAR", "remove an environment variable"); - grub_register_command ("export", grub_core_cmd_export, - "export ENVVAR", "Export a variable."); grub_register_command ("ls", grub_core_cmd_ls, "ls [ARG]", "list devices or files"); grub_register_command ("insmod", grub_core_cmd_insmod, =3D=3D=3D modified file 'kern/env.c' --- kern/env.c 2009-07-16 22:14:09 +0000 +++ kern/env.c 2009-12-20 01:54:58 +0000 @@ -18,34 +18,15 @@ */ =20 #include <grub/env.h> +#include <grub/env_private.h> #include <grub/misc.h> #include <grub/mm.h> =20 -/* The size of the hash table. */ -#define HASHSZ 13 - -/* A hashtable for quick lookup of variables. */ -struct grub_env_context -{ - /* A hash table for variables. */ - struct grub_env_var *vars[HASHSZ]; - - /* One level deeper on the stack. */ - struct grub_env_context *prev; -}; - -/* This is used for sorting only. */ -struct grub_env_sorted_var -{ - struct grub_env_var *var; - struct grub_env_sorted_var *next; -}; - /* The initial context. */ static struct grub_env_context initial_context; =20 /* The current context. */ -static struct grub_env_context *current_context =3D &initial_context; +struct grub_env_context *grub_current_context =3D &initial_context; =20 /* Return the hash representation of the string S. */ static unsigned int @@ -60,87 +41,20 @@ return i % HASHSZ; } =20 -static struct grub_env_var * +struct grub_env_var * grub_env_find (const char *name) { struct grub_env_var *var; int idx =3D grub_env_hashval (name); =20 /* Look for the variable in the current context. */ - for (var =3D current_context->vars[idx]; var; var =3D var->next) + for (var =3D grub_current_context->vars[idx]; var; var =3D var->next) if (grub_strcmp (var->name, name) =3D=3D 0) return var; =20 return 0; } =20 -grub_err_t -grub_env_context_open (int export) -{ - struct grub_env_context *context; - int i; - - context =3D grub_zalloc (sizeof (*context)); - if (! context) - return grub_errno; - - context->prev =3D current_context; - current_context =3D context; - - /* Copy exported variables. */ - for (i =3D 0; i < HASHSZ; i++) - { - struct grub_env_var *var; - - for (var =3D context->prev->vars[i]; var; var =3D var->next) - { - if (export && var->type =3D=3D GRUB_ENV_VAR_GLOBAL) - { - if (grub_env_set (var->name, var->value) !=3D GRUB_ERR_NONE) - { - grub_env_context_close (); - return grub_errno; - } - grub_register_variable_hook (var->name, var->read_hook, var->writ= e_hook); - } - } - } - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_env_context_close (void) -{ - struct grub_env_context *context; - int i; - - if (! current_context->prev) - grub_fatal ("cannot close the initial context"); - - /* Free the variables associated with this context. */ - for (i =3D 0; i < HASHSZ; i++) - { - struct grub_env_var *p, *q; - - for (p =3D current_context->vars[i]; p; p =3D q) - { - q =3D p->next; - grub_free (p->name); - if (p->type !=3D GRUB_ENV_VAR_DATA) - grub_free (p->value); - grub_free (p); - } - } - - /* Restore the previous context. */ - context =3D current_context->prev; - grub_free (current_context); - current_context =3D context; - - return GRUB_ERR_NONE; -} - static void grub_env_insert (struct grub_env_context *context, struct grub_env_var *var) @@ -165,18 +79,6 @@ } =20 grub_err_t -grub_env_export (const char *name) -{ - struct grub_env_var *var; - - var =3D grub_env_find (name); - if (var) - var->type =3D GRUB_ENV_VAR_GLOBAL; - - return GRUB_ERR_NONE; -} - -grub_err_t grub_env_set (const char *name, const char *val) { struct grub_env_var *var; @@ -207,9 +109,8 @@ if (! var) return grub_errno; =20 - /* This is not necessary, because GRUB_ENV_VAR_LOCAL =3D=3D 0. But lea= ve - this for readability. */ - var->type =3D GRUB_ENV_VAR_LOCAL; + /* This is not necessary. But leave this for readability. */ + var->global =3D 0; =20 var->name =3D grub_strdup (name); if (! var->name) @@ -219,7 +120,7 @@ if (! var->value) goto fail; =20 - grub_env_insert (current_context, var); + grub_env_insert (grub_current_context, var); =20 return GRUB_ERR_NONE; =20 @@ -263,8 +164,7 @@ grub_env_remove (var); =20 grub_free (var->name); - if (var->type !=3D GRUB_ENV_VAR_DATA) - grub_free (var->value); + grub_free (var->value); grub_free (var); } =20 @@ -280,14 +180,10 @@ { struct grub_env_var *var; =20 - for (var =3D current_context->vars[i]; var; var =3D var->next) + for (var =3D grub_current_context->vars[i]; var; var =3D var->next= ) { struct grub_env_sorted_var *p, **q; =20 - /* Ignore data slots. */ - if (var->type =3D=3D GRUB_ENV_VAR_DATA) - continue; - sorted_var =3D grub_malloc (sizeof (*sorted_var)); if (! sorted_var) goto fail; @@ -343,84 +239,3 @@ =20 return GRUB_ERR_NONE; } - -static char * -mangle_data_slot_name (const char *name) -{ - char *mangled_name; - - mangled_name =3D grub_malloc (grub_strlen (name) + 2); - if (! mangled_name) - return 0; - - grub_sprintf (mangled_name, "\e%s", name); - return mangled_name; -} - -grub_err_t -grub_env_set_data_slot (const char *name, const void *ptr) -{ - char *mangled_name; - struct grub_env_var *var; - - mangled_name =3D mangle_data_slot_name (name); - if (! mangled_name) - goto fail; - - /* If the variable does already exist, just update the variable. */ - var =3D grub_env_find (mangled_name); - if (var) - { - var->value =3D (char *) ptr; - return GRUB_ERR_NONE; - } - - /* The variable does not exist, so create a new one. */ - var =3D grub_zalloc (sizeof (*var)); - if (! var) - goto fail; - - var->type =3D GRUB_ENV_VAR_DATA; - var->name =3D mangled_name; - var->value =3D (char *) ptr; - - grub_env_insert (current_context, var); - - return GRUB_ERR_NONE; - - fail: - - grub_free (mangled_name); - return grub_errno; -} - -void * -grub_env_get_data_slot (const char *name) -{ - char *mangled_name; - void *ptr =3D 0; - - mangled_name =3D mangle_data_slot_name (name); - if (! mangled_name) - goto fail; - - ptr =3D grub_env_get (mangled_name); - grub_free (mangled_name); - - fail: - - return ptr; -} - -void -grub_env_unset_data_slot (const char *name) -{ - char *mangled_name; - - mangled_name =3D mangle_data_slot_name (name); - if (! mangled_name) - return; - - grub_env_unset (mangled_name); - grub_free (mangled_name); -} =3D=3D=3D modified file 'kern/main.c' --- kern/main.c 2009-06-10 21:04:23 +0000 +++ kern/main.c 2009-12-20 01:26:58 +0000 @@ -114,7 +114,6 @@ const char *prefix; =20 grub_register_variable_hook ("root", 0, grub_env_write_root); - grub_env_export ("root"); =20 prefix =3D grub_env_get ("prefix"); =20 @@ -164,7 +163,6 @@ /* It is better to set the root device as soon as possible, for convenience. */ grub_machine_set_prefix (); - grub_env_export ("prefix"); grub_set_root_dev (); =20 grub_register_core_commands (); =3D=3D=3D added file 'normal/context.c' --- normal/context.c 1970-01-01 00:00:00 +0000 +++ normal/context.c 2009-12-20 01:46:46 +0000 @@ -0,0 +1,172 @@ +/* env.c - Environment variables */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2005,2006,2007,2008,2009 Free Software Foundatio= n, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by= + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <grub/env.h> +#include <grub/env_private.h> +#include <grub/misc.h> +#include <grub/mm.h> +#include <grub/command.h> + +struct menu_pointer +{ + grub_menu_t menu; + struct menu_pointer *prev; +}; + +struct menu_pointer initial_menu; +struct menu_pointer *current_menu =3D &initial_menu; + +void +grub_env_unset_menu (void) +{ + current_menu->menu =3D NULL; +} + +grub_menu_t +grub_env_get_menu (void) +{ + return current_menu->menu; +} + +void +grub_env_set_menu (grub_menu_t nmenu) +{ + current_menu->menu =3D nmenu; +} + +grub_err_t +grub_env_context_open (int export) +{ + struct grub_env_context *context; + int i; + struct menu_pointer *menu; + + context =3D grub_zalloc (sizeof (*context)); + if (! context) + return grub_errno; + menu =3D grub_zalloc (sizeof (*menu)); + if (! menu) + return grub_errno; + + context->prev =3D grub_current_context; + grub_current_context =3D context; + + menu->prev =3D current_menu; + current_menu =3D menu; + + /* Copy exported variables. */ + for (i =3D 0; i < HASHSZ; i++) + { + struct grub_env_var *var; + + for (var =3D context->prev->vars[i]; var; var =3D var->next) + { + if (export && var->global) + { + if (grub_env_set (var->name, var->value) !=3D GRUB_ERR_NONE) + { + grub_env_context_close (); + return grub_errno; + } + grub_register_variable_hook (var->name, var->read_hook, var->writ= e_hook); + } + } + } + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_env_context_close (void) +{ + struct grub_env_context *context; + int i; + struct menu_pointer *menu; + + if (! grub_current_context->prev) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "cannot close the initial context"); + + /* Free the variables associated with this context. */ + for (i =3D 0; i < HASHSZ; i++) + { + struct grub_env_var *p, *q; + + for (p =3D grub_current_context->vars[i]; p; p =3D q) + { + q =3D p->next; + grub_free (p->name); + grub_free (p->value); + grub_free (p); + } + } + + /* Restore the previous context. */ + context =3D grub_current_context->prev; + grub_free (grub_current_context); + grub_current_context =3D context; + + menu =3D current_menu->prev; + grub_free (current_menu); + current_menu =3D menu; + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_env_export (const char *name) +{ + struct grub_env_var *var; + + var =3D grub_env_find (name); + if (var) + var->global =3D 1; + + return GRUB_ERR_NONE; +} + +static grub_command_t export_cmd; + +static grub_err_t +grub_cmd_export (struct grub_command *cmd __attribute__ ((unused)), + int argc, char **args) +{ + if (argc < 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "no environment variable specified"); + + grub_env_export (args[0]); + return 0; +} + +void +grub_context_init (void) +{ + grub_env_export ("root"); + grub_env_export ("prefix"); + + export_cmd =3D grub_register_command ("export", grub_cmd_export, + "export ENVVAR", "Export a variable."); +} + +void +grub_context_fini (void) +{ + grub_unregister_command (export_cmd); +} =3D=3D=3D modified file 'normal/main.c' --- normal/main.c 2009-12-19 23:00:30 +0000 +++ normal/main.c 2009-12-20 13:20:15 +0000 @@ -133,7 +133,7 @@ } =20 grub_free (menu); - grub_env_unset_data_slot ("menu"); + grub_env_unset_menu (); } =20 static void @@ -174,7 +174,7 @@ return grub_errno; classes_tail =3D classes_head; =20 - menu =3D grub_env_get_data_slot ("menu"); + menu =3D grub_env_get_menu (); if (! menu) return grub_error (GRUB_ERR_MENU, "no menu context"); =20 @@ -357,14 +357,14 @@ =20 grub_menu_t newmenu; =20 - newmenu =3D grub_env_get_data_slot ("menu"); + newmenu =3D grub_env_get_menu (); if (! newmenu) { newmenu =3D grub_zalloc (sizeof (*newmenu)); if (! newmenu) return 0; =20 - grub_env_set_data_slot ("menu", newmenu); + grub_env_set_menu (newmenu); } =20 /* Try to open the config file. */ @@ -575,6 +575,8 @@ =20 GRUB_MOD_INIT(normal) { + grub_context_init (); + /* Normal mode shouldn't be unloaded. */ if (mod) grub_dl_ref (mod); @@ -602,6 +604,8 @@ =20 GRUB_MOD_FINI(normal) { + grub_context_fini (); + grub_set_history (0); grub_reader_unregister (&grub_normal_reader); grub_register_variable_hook ("pager", 0, 0); --------------040505020001050308040003--
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel