+2006-12-12 Marco Gerards <marco@gnu.org>
+
+ * include/grub/err.h (grub_err_t): Add `GRUB_ERR_MENU'.
+
+ * kern/env.c (grub_env_unset): Don't free the member `value' when
+ the type is GRUB_ENV_VAR_DATA, in this case it's a user defined
+ pointer.
+
+ * normal/main.c (current_menu): Removed.
+ (free_menu): Unset the `menu' environment variable.
+ (grub_normal_menu_addentry): Make use of the environment variable
+ `menu', instead of using the global `current_menu'. Allocate
+ memory for the sourcecode of this entry.
+ (read_config_file): New argument `nested', changed all callers.
+ Only in the case of a new context, initialize a new menu. Set the
+ `menu' environment variable.
+ (grub_normal_execute): Don't set and unset the environment
+ variable `menu' here anymore. Only free the menu when leaving the
+ context.
+
+ * util/i386/pc/biosdisk.c (linux_find_partition): Fixed a memory
+ leak.
+
2006-12-11 Marco Gerards <marco@gnu.org>
* normal/menu_entry.c (run): Fix off by one bug so the last line
static grub_fs_module_list_t fs_module_list = 0;
-/* The menu to which the new entries are added by the parser. */
-static grub_menu_t current_menu = 0;
-
#define GRUB_DEFAULT_HISTORY_SIZE 50
/* Read a line from the file FILE. */
free_menu (grub_menu_t menu)
{
grub_menu_entry_t entry = menu->entry_list;
-
+
while (entry)
{
grub_menu_entry_t next_entry = entry->next;
}
grub_free (menu);
+ grub_env_unset_data_slot ("menu");
}
grub_err_t
const char *sourcecode)
{
const char *menutitle;
- grub_menu_entry_t *last = ¤t_menu->entry_list;
+ const char *menusourcecode;
+ grub_menu_t menu;
+ grub_menu_entry_t *last;
+
+ menu = grub_env_get_data_slot("menu");
+ if (! menu)
+ return grub_error (GRUB_ERR_MENU, "no menu context");
+
+ last = &menu->entry_list;
+
+ menusourcecode = grub_strdup (sourcecode);
+ if (! menusourcecode)
+ return grub_errno;
menutitle = grub_strdup (title);
if (! menutitle)
- return grub_errno;
+ {
+ grub_free ((void *) menusourcecode);
+ return grub_errno;
+ }
/* Add the menu entry at the end of the list. */
while (*last)
if (! *last)
{
grub_free ((void *) menutitle);
- grub_free ((void *) sourcecode);
+ grub_free ((void *) menusourcecode);
return grub_errno;
}
(*last)->commands = script;
(*last)->title = menutitle;
(*last)->next = 0;
- (*last)->sourcecode = sourcecode;
+ (*last)->sourcecode = menusourcecode;
- current_menu->size++;
+ menu->size++;
return GRUB_ERR_NONE;
}
static grub_menu_t
-read_config_file (const char *config)
+read_config_file (const char *config, int nested)
{
grub_file_t file;
auto grub_err_t getline (char **line);
grub_menu_t newmenu;
- newmenu = grub_malloc (sizeof (*newmenu));
- if (! newmenu)
- return 0;
- newmenu->size = 0;
- newmenu->entry_list = 0;
- current_menu = newmenu;
+ if (nested)
+ {
+ newmenu = grub_malloc (sizeof (*newmenu));
+ if (! newmenu)
+ return 0;
+ newmenu->size = 0;
+ newmenu->entry_list = 0;
+ }
/* Try to open the config file. */
file = grub_file_open (config);
if (! file)
return 0;
+ if (nested)
+ grub_env_set_data_slot ("menu", newmenu);
+ else
+ newmenu = grub_env_get_data_slot ("menu");
+
while (1)
{
struct grub_script *parsed_script;
(void) grub_getkey ();
}
- /* If the menu is empty, just drop it. */
- if (current_menu->size == 0)
- {
- grub_free (current_menu);
- return 0;
- }
-
return newmenu;
}
if (config)
{
- menu = read_config_file (config);
+ menu = read_config_file (config, nested);
/* Ignore any error. */
grub_errno = GRUB_ERR_NONE;
if (menu)
{
- grub_env_set_data_slot ("menu", menu);
grub_menu_run (menu, nested);
- grub_env_unset_data_slot ("menu");
- free_menu (menu);
+ if (nested)
+ free_menu (menu);
}
else
grub_cmdline_run (nested);