~hamo/ubuntu/precise/grub2/grub2.hi_res

« back to all changes in this revision

Viewing changes to grub-core/normal/menu.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson
  • Date: 2011-01-11 17:11:44 UTC
  • mfrom: (1.17.12 upstream)
  • mto: (17.3.43 sid)
  • mto: This revision was merged to the branch mainline in revision 100.
  • Revision ID: james.westby@ubuntu.com-20110111171144-c4c3hc0jslqa1bxe
Tags: 1.99~20110111-1
* New Bazaar snapshot.
  - Don't check amount of low memory, as reportedly INT 12h can be broken
    and if low memory is too low we wouldn't have gotten into
    grub_machine_init anyway (closes: #588293, LP: #513528).
  - Submenu default support (LP: #691878).
  - Fix optimisation-dependent grub-mklayout crash (closes: #609584).
* branch_butter.patch: Don't free an uninitialised pointer if /proc is
  unmounted (LP: #697493).
* Add a po/LINGUAS file listing the translations we've synced from the TP
  (closes: #609671).

Show diffs side-by-side

added added

removed removed

Lines of Context:
154
154
}
155
155
 
156
156
/* Run a menu entry.  */
157
 
void
158
 
grub_menu_execute_entry(grub_menu_entry_t entry)
 
157
static void
 
158
grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot)
159
159
{
160
160
  grub_err_t err = GRUB_ERR_NONE;
161
161
  int errs_before;
162
162
  grub_menu_t menu;
 
163
  char *optr, *buf, *oldchosen = NULL, *olddefault = NULL;
 
164
  const char *ptr, *chosen, *def;
 
165
  grub_size_t sz = 0;
163
166
 
164
167
  if (entry->restricted)
165
168
    err = grub_auth_check_authentication (entry->users);
173
176
 
174
177
  errs_before = grub_err_printed_errors;
175
178
 
 
179
  chosen = grub_env_get ("chosen");
 
180
  def = grub_env_get ("default");
 
181
 
176
182
  if (entry->submenu)
177
183
    {
178
184
      grub_env_context_open ();
180
186
      if (! menu)
181
187
        return;
182
188
      grub_env_set_menu (menu);
 
189
      if (auto_boot)
 
190
        grub_env_set ("timeout", "0");
183
191
    }
184
192
 
185
 
  grub_env_set ("chosen", entry->title);
 
193
  for (ptr = entry->title; *ptr; ptr++)
 
194
    sz += (*ptr == '>') ? 2 : 1;
 
195
  if (chosen)
 
196
    {
 
197
      oldchosen = grub_strdup (chosen);
 
198
      if (!oldchosen)
 
199
        grub_print_error ();
 
200
    }
 
201
  if (def)
 
202
    {
 
203
      olddefault = grub_strdup (def);
 
204
      if (!olddefault)
 
205
        grub_print_error ();
 
206
    }
 
207
  sz++;
 
208
  if (chosen)
 
209
    sz += grub_strlen (chosen);
 
210
  sz++;
 
211
  buf = grub_malloc (sz);
 
212
  if (!buf)
 
213
    grub_print_error ();
 
214
  else
 
215
    {
 
216
      optr = buf;
 
217
      if (chosen)
 
218
        {
 
219
          optr = grub_stpcpy (optr, chosen);
 
220
          *optr++ = '>';
 
221
        }
 
222
      for (ptr = entry->title; *ptr; ptr++)
 
223
        {
 
224
          if (*ptr == '>')
 
225
            *optr++ = '>';
 
226
          *optr++ = *ptr;
 
227
        }
 
228
      *optr = 0;
 
229
      grub_env_set ("chosen", buf);
 
230
      grub_env_export ("chosen");
 
231
      grub_free (buf);
 
232
    }
 
233
  for (ptr = def; *ptr; ptr++)
 
234
    {
 
235
      if (ptr[0] == '>' && ptr[1] == '>')
 
236
        {
 
237
          ptr++;
 
238
          continue;
 
239
        }
 
240
      if (ptr[0] == '>')
 
241
        break;
 
242
    }
 
243
  if (ptr[0] && ptr[1])
 
244
    grub_env_set ("default", ptr + 1);
 
245
  else
 
246
    grub_env_unset ("default");
186
247
  grub_script_execute_sourcecode (entry->sourcecode, entry->argc, entry->args);
187
248
 
188
249
  if (errs_before != grub_err_printed_errors)
196
257
    {
197
258
      if (menu && menu->size)
198
259
        {
199
 
          grub_show_menu (menu, 1);
 
260
          grub_show_menu (menu, 1, auto_boot);
200
261
          grub_normal_free_menu (menu);
201
262
        }
202
263
      grub_env_context_close ();
203
264
    }
 
265
  if (oldchosen)
 
266
    grub_env_set ("chosen", oldchosen);
 
267
  else
 
268
    grub_env_unset ("chosen");
 
269
  if (olddefault)
 
270
    grub_env_set ("default", olddefault);
 
271
  else
 
272
    grub_env_unset ("default");
 
273
  grub_env_unset ("timeout");
204
274
}
205
275
 
206
276
/* Execute ENTRY from the menu MENU, falling back to entries specified
207
277
   in the environment variable "fallback" if it fails.  CALLBACK is a
208
278
   pointer to a struct of function pointers which are used to allow the
209
279
   caller provide feedback to the user.  */
210
 
void
 
280
static void
211
281
grub_menu_execute_with_fallback (grub_menu_t menu,
212
282
                                 grub_menu_entry_t entry,
 
283
                                 int autobooted,
213
284
                                 grub_menu_execute_callback_t callback,
214
285
                                 void *callback_data)
215
286
{
217
288
 
218
289
  callback->notify_booting (entry, callback_data);
219
290
 
220
 
  grub_menu_execute_entry (entry);
 
291
  grub_menu_execute_entry (entry, 1);
221
292
 
222
293
  /* Deal with fallback entries.  */
223
294
  while ((fallback_entry = get_and_remove_first_entry_number ("fallback"))
228
299
 
229
300
      entry = grub_menu_get_entry (menu, fallback_entry);
230
301
      callback->notify_fallback (entry, callback_data);
231
 
      grub_menu_execute_entry (entry);
 
302
      grub_menu_execute_entry (entry, 1);
232
303
      /* If the function call to execute the entry returns at all, then this is
233
304
         taken to indicate a boot failure.  For menu entries that do something
234
305
         other than actually boot an operating system, this could assume
235
306
         incorrectly that something failed.  */
236
307
    }
237
308
 
238
 
  callback->notify_failure (callback_data);
 
309
  if (!autobooted)
 
310
    callback->notify_failure (callback_data);
239
311
}
240
312
 
241
313
static struct grub_menu_viewer *viewers;
309
381
  viewers = viewer;
310
382
}
311
383
 
 
384
static int
 
385
menuentry_eq (const char *title, const char *spec)
 
386
{
 
387
  const char *ptr1, *ptr2;
 
388
  ptr1 = title;
 
389
  ptr2 = spec;
 
390
  while (1)
 
391
    {
 
392
      if (*ptr2 == '>' && ptr2[1] != '>' && *ptr1 == 0)
 
393
        return 1;
 
394
      if (*ptr2 == '>' && ptr2[1] != '>')
 
395
        return 0;
 
396
      if (*ptr2 == '>')
 
397
        ptr2++;
 
398
      if (*ptr1 != *ptr2)
 
399
        return 0;
 
400
      if (*ptr1 == 0)
 
401
        return 1;
 
402
      ptr1++;
 
403
      ptr2++;
 
404
    }
 
405
}
 
406
 
 
407
 
312
408
/* Get the entry number from the variable NAME.  */
313
409
static int
314
410
get_entry_number (grub_menu_t menu, const char *name)
315
411
{
316
 
  char *val;
 
412
  const char *val;
317
413
  int entry;
318
414
 
319
415
  val = grub_env_get (name);
334
430
 
335
431
      for (i = 0; e; i++)
336
432
        {
337
 
          if (grub_strcmp (e->title, val) == 0)
 
433
          if (menuentry_eq (e->title, val))
338
434
            {
339
435
              entry = i;
340
436
              break;
590
686
};
591
687
 
592
688
static grub_err_t
593
 
show_menu (grub_menu_t menu, int nested)
 
689
show_menu (grub_menu_t menu, int nested, int autobooted)
594
690
{
595
691
  while (1)
596
692
    {
609
705
      grub_cls ();
610
706
 
611
707
      if (auto_boot)
612
 
        grub_menu_execute_with_fallback (menu, e, &execution_callback, 0);
 
708
        grub_menu_execute_with_fallback (menu, e, autobooted,
 
709
                                         &execution_callback, 0);
613
710
      else
614
 
        grub_menu_execute_entry (e);
 
711
        grub_menu_execute_entry (e, 0);
 
712
      if (autobooted)
 
713
        break;
615
714
    }
616
715
 
617
716
  return GRUB_ERR_NONE;
618
717
}
619
718
 
620
719
grub_err_t
621
 
grub_show_menu (grub_menu_t menu, int nested)
 
720
grub_show_menu (grub_menu_t menu, int nested, int autoboot)
622
721
{
623
722
  grub_err_t err1, err2;
624
723
 
625
724
  while (1)
626
725
    {
627
 
      err1 = show_menu (menu, nested);
 
726
      err1 = show_menu (menu, nested, autoboot);
 
727
      autoboot = 0;
628
728
      grub_print_error ();
629
729
 
630
730
      if (grub_normal_exit_level)