]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
2006-12-12 Marco Gerards <marco@gnu.org>
authormarco_g <marco_g@localhost>
Tue, 12 Dec 2006 00:13:55 +0000 (00:13 +0000)
committermarco_g <marco_g@localhost>
Tue, 12 Dec 2006 00:13:55 +0000 (00:13 +0000)
* 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.

ChangeLog
include/grub/err.h
kern/env.c
normal/main.c
util/i386/pc/biosdisk.c

index e74884d84f31d310872ce96e2ec887fd07b94a53..4a137d1aeb7250b7a488804a0acd62bf62d1fd2f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+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
index d4013be6c64fc56cfb4b69f3711dcb4fc0d75e66..2a59309c024a123bdef45846abb1de730a600923 100644 (file)
@@ -52,6 +52,7 @@ typedef enum
     GRUB_ERR_NOT_IMPLEMENTED_YET,
     GRUB_ERR_SYMLINK_LOOP,
     GRUB_ERR_BAD_GZIP_DATA,
+    GRUB_ERR_MENU
   }
 grub_err_t;
 
index b534e05f2f9a0850b7b22b538a9db08effb276ad..0e841ef5aa8ba155ee5a8576526f8203d35a9b48 100644 (file)
@@ -261,7 +261,8 @@ grub_env_unset (const char *name)
   grub_env_remove (var);
 
   grub_free (var->name);
-  grub_free (var->value);
+  if (var->type != GRUB_ENV_VAR_DATA)
+    grub_free (var->value);
   grub_free (var);
 }
 
index 92979139d23ab346163f08ae619323ead11ca626..33e1fcfe9280ad36c0920ad2a4843aeaa23f91c6 100644 (file)
@@ -34,9 +34,6 @@ grub_jmp_buf grub_exit_env;
 
 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.  */
@@ -136,7 +133,7 @@ static void
 free_menu (grub_menu_t menu)
 {
   grub_menu_entry_t entry = menu->entry_list;
-  
+
   while (entry)
     {
       grub_menu_entry_t next_entry = entry->next;
@@ -148,6 +145,7 @@ free_menu (grub_menu_t menu)
     }
 
   grub_free (menu);
+  grub_env_unset_data_slot ("menu");
 }
 
 grub_err_t
@@ -155,11 +153,26 @@ grub_normal_menu_addentry (const char *title, struct grub_script *script,
                           const char *sourcecode)
 {
   const char *menutitle;
-  grub_menu_entry_t *last = &current_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)
@@ -169,22 +182,22 @@ grub_normal_menu_addentry (const char *title, struct grub_script *script,
   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);
@@ -204,18 +217,25 @@ read_config_file (const char *config)
 
   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;
@@ -257,13 +277,6 @@ read_config_file (const char *config)
       (void) grub_getkey ();
     }
 
-  /* If the menu is empty, just drop it.  */
-  if (current_menu->size == 0)
-    {
-      grub_free (current_menu);
-      return 0;
-    }
-
   return newmenu;
 }
 
@@ -459,7 +472,7 @@ grub_normal_execute (const char *config, int nested)
   
   if (config)
     {
-      menu = read_config_file (config);
+      menu = read_config_file (config, nested);
 
       /* Ignore any error.  */
       grub_errno = GRUB_ERR_NONE;
@@ -467,10 +480,9 @@ grub_normal_execute (const char *config, int nested)
 
   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);
index 4d8131c8e0b703c90dcf5e7003beacad6be1eecf..65afa9e3dc0a2a26c763dff937fc9a6a11fc5ed2 100644 (file)
@@ -235,7 +235,10 @@ linux_find_partition (char *dev, unsigned long sector)
     {
       p = strchr (real_dev + 9, 'd');
       if (! p)
-       return 0;
+       {
+         free (real_dev);
+         return 0;
+       }
 
       p++;
       while (*p && isdigit (*p))