1 /* menu.c - General supporting functionality for menus. */
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
20 #include <grub/normal.h>
21 #include <grub/misc.h>
22 #include <grub/loader.h>
24 #include <grub/time.h>
26 #include <grub/menu_viewer.h>
27 #include <grub/command.h>
28 #include <grub/parser.h>
29 #include <grub/auth.h>
30 #include <grub/i18n.h>
31 #include <grub/term.h>
32 #include <grub/script_sh.h>
33 #include <grub/gfxterm.h>
36 #include <grub/extcmd.h>
37 #include <grub/ventoy.h>
38 #include "ventoy/ventoy_def.h"
40 int g_ventoy_menu_refresh
= 0;
41 int g_ventoy_memdisk_mode
= 0;
42 int g_ventoy_iso_raw
= 0;
43 int g_ventoy_grub2_mode
= 0;
44 int g_ventoy_wimboot_mode
= 0;
45 int g_ventoy_iso_uefi_drv
= 0;
46 int g_ventoy_last_entry
= -1;
47 int g_ventoy_suppress_esc
= 0;
48 int g_ventoy_menu_esc
= 0;
49 int g_ventoy_fn_mutex
= 0;
50 int g_ventoy_terminal_output
= 0;
52 /* Time to delay after displaying an error message about a default/fallback
53 entry failing to boot. */
54 #define DEFAULT_ENTRY_ERROR_DELAY_MS 2500
56 grub_err_t (*grub_gfxmenu_try_hook
) (int entry
, grub_menu_t menu
,
61 TIMEOUT_STYLE_COUNTDOWN
,
65 struct timeout_style_name
{
67 enum timeout_style style
;
68 } timeout_style_names
[] = {
69 {"menu", TIMEOUT_STYLE_MENU
},
70 {"countdown", TIMEOUT_STYLE_COUNTDOWN
},
71 {"hidden", TIMEOUT_STYLE_HIDDEN
},
75 /* Wait until the user pushes any key so that the user
76 can see what happened. */
78 grub_wait_after_message (void)
80 grub_uint64_t endtime
;
82 grub_printf_ (N_("Press any key to continue..."));
85 endtime
= grub_get_time_ms () + 10000;
87 while (grub_get_time_ms () < endtime
88 && grub_getkey_noblock () == GRUB_TERM_NO_KEY
);
93 /* Get a menu entry by its index in the entry list. */
95 grub_menu_get_entry (grub_menu_t menu
, int no
)
99 for (e
= menu
->entry_list
; e
&& no
> 0; e
= e
->next
, no
--)
105 /* Get the index of a menu entry associated with a given hotkey, or -1. */
107 get_entry_index_by_hotkey (grub_menu_t menu
, int hotkey
)
109 grub_menu_entry_t entry
;
112 for (i
= 0, entry
= menu
->entry_list
; i
< menu
->size
;
113 i
++, entry
= entry
->next
)
114 if (entry
->hotkey
== hotkey
)
120 /* Return the timeout style. If the variable "timeout_style" is not set or
121 invalid, default to TIMEOUT_STYLE_MENU. */
122 static enum timeout_style
123 get_timeout_style (void)
126 struct timeout_style_name
*style_name
;
128 val
= grub_env_get ("timeout_style");
130 return TIMEOUT_STYLE_MENU
;
132 for (style_name
= timeout_style_names
; style_name
->name
; style_name
++)
133 if (grub_strcmp (style_name
->name
, val
) == 0)
134 return style_name
->style
;
136 return TIMEOUT_STYLE_MENU
;
139 /* Return the current timeout. If the variable "timeout" is not set or
140 invalid, return -1. */
142 grub_menu_get_timeout (void)
147 val
= grub_env_get ("timeout");
153 timeout
= (int) grub_strtoul (val
, 0, 0);
155 /* If the value is invalid, unset the variable. */
156 if (grub_errno
!= GRUB_ERR_NONE
)
158 grub_env_unset ("timeout");
159 grub_errno
= GRUB_ERR_NONE
;
168 /* Set current timeout in the variable "timeout". */
170 grub_menu_set_timeout (int timeout
)
172 /* Ignore TIMEOUT if it is zero, because it will be unset really soon. */
177 grub_snprintf (buf
, sizeof (buf
), "%d", timeout
);
178 grub_env_set ("timeout", buf
);
182 /* Get the first entry number from the value of the environment variable NAME,
183 which is a space-separated list of non-negative integers. The entry number
184 which is returned is stripped from the value of NAME. If no entry number
185 can be found, -1 is returned. */
187 get_and_remove_first_entry_number (const char *name
)
193 val
= grub_env_get (name
);
199 entry
= (int) grub_strtoul (val
, &tail
, 0);
201 if (grub_errno
== GRUB_ERR_NONE
)
203 /* Skip whitespace to find the next digit. */
204 while (*tail
&& grub_isspace (*tail
))
206 grub_env_set (name
, tail
);
210 grub_env_unset (name
);
211 grub_errno
= GRUB_ERR_NONE
;
220 /* Run a menu entry. */
222 grub_menu_execute_entry(grub_menu_entry_t entry
, int auto_boot
)
224 grub_err_t err
= GRUB_ERR_NONE
;
226 grub_menu_t menu
= NULL
;
227 char *optr
, *buf
, *oldchosen
= NULL
, *olddefault
= NULL
;
228 const char *ptr
, *chosen
, *def
;
231 if (entry
->restricted
)
232 err
= grub_auth_check_authentication (entry
->users
);
237 grub_errno
= GRUB_ERR_NONE
;
241 errs_before
= grub_err_printed_errors
;
243 chosen
= grub_env_get ("chosen");
244 def
= grub_env_get ("default");
248 grub_env_context_open ();
249 menu
= grub_zalloc (sizeof (*menu
));
252 grub_env_set_menu (menu
);
254 grub_env_set ("timeout", "0");
257 for (ptr
= entry
->id
; *ptr
; ptr
++)
258 sz
+= (*ptr
== '>') ? 2 : 1;
261 oldchosen
= grub_strdup (chosen
);
267 olddefault
= grub_strdup (def
);
273 sz
+= grub_strlen (chosen
);
275 buf
= grub_malloc (sz
);
283 optr
= grub_stpcpy (optr
, chosen
);
286 for (ptr
= entry
->id
; *ptr
; ptr
++)
293 grub_env_set ("chosen", buf
);
294 grub_env_export ("chosen");
298 for (ptr
= def
; ptr
&& *ptr
; ptr
++)
300 if (ptr
[0] == '>' && ptr
[1] == '>')
309 if (ptr
&& ptr
[0] && ptr
[1])
310 grub_env_set ("default", ptr
+ 1);
312 grub_env_unset ("default");
314 grub_script_execute_new_scope (entry
->sourcecode
, entry
->argc
, entry
->args
);
316 if (errs_before
!= grub_err_printed_errors
)
317 grub_wait_after_message ();
319 errs_before
= grub_err_printed_errors
;
321 if (grub_errno
== GRUB_ERR_NONE
&& grub_loader_is_loaded ())
322 /* Implicit execution of boot, only if something is loaded. */
323 grub_command_execute ("boot", 0, 0);
325 if (errs_before
!= grub_err_printed_errors
)
326 grub_wait_after_message ();
330 if (menu
&& menu
->size
)
332 grub_show_menu (menu
, 1, auto_boot
);
333 grub_normal_free_menu (menu
);
335 grub_env_context_close ();
338 grub_env_set ("chosen", oldchosen
);
340 grub_env_unset ("chosen");
342 grub_env_set ("default", olddefault
);
344 grub_env_unset ("default");
345 grub_env_unset ("timeout");
348 /* Execute ENTRY from the menu MENU, falling back to entries specified
349 in the environment variable "fallback" if it fails. CALLBACK is a
350 pointer to a struct of function pointers which are used to allow the
351 caller provide feedback to the user. */
353 grub_menu_execute_with_fallback (grub_menu_t menu
,
354 grub_menu_entry_t entry
,
356 grub_menu_execute_callback_t callback
,
361 callback
->notify_booting (entry
, callback_data
);
363 grub_menu_execute_entry (entry
, 1);
365 /* Deal with fallback entries. */
366 while ((fallback_entry
= get_and_remove_first_entry_number ("fallback"))
370 grub_errno
= GRUB_ERR_NONE
;
372 entry
= grub_menu_get_entry (menu
, fallback_entry
);
373 callback
->notify_fallback (entry
, callback_data
);
374 grub_menu_execute_entry (entry
, 1);
375 /* If the function call to execute the entry returns at all, then this is
376 taken to indicate a boot failure. For menu entries that do something
377 other than actually boot an operating system, this could assume
378 incorrectly that something failed. */
382 callback
->notify_failure (callback_data
);
385 static struct grub_menu_viewer
*viewers
;
387 int g_menu_update_mode
= 0;
388 int g_ventoy_tip_label_enable
= 0;
389 const char * g_ventoy_tip_msg1
= NULL
;
390 const char * g_ventoy_tip_msg2
= NULL
;
393 menu_set_chosen_entry (grub_menu_t menu
, int entry
)
395 struct grub_menu_viewer
*cur
;
397 grub_menu_entry_t e
= grub_menu_get_entry (menu
, entry
);
399 g_ventoy_tip_msg1
= g_ventoy_tip_msg2
= NULL
;
400 if (e
&& e
->id
&& grub_strncmp(e
->id
, "VID_", 4) == 0) {
401 img
= (img_info
*)(void *)grub_strtoul(e
->id
+ 4, NULL
, 16);
404 g_ventoy_tip_msg1
= img
->tip1
;
405 g_ventoy_tip_msg2
= img
->tip2
;
409 for (cur
= viewers
; cur
; cur
= cur
->next
)
410 cur
->set_chosen_entry (entry
, cur
->data
);
414 menu_print_timeout (int timeout
)
416 struct grub_menu_viewer
*cur
;
417 for (cur
= viewers
; cur
; cur
= cur
->next
)
418 cur
->print_timeout (timeout
, cur
->data
);
424 struct grub_menu_viewer
*cur
, *next
;
425 for (cur
= viewers
; cur
; cur
= next
)
428 cur
->fini (cur
->data
);
435 menu_init (int entry
, grub_menu_t menu
, int nested
)
437 struct grub_term_output
*term
;
440 FOR_ACTIVE_TERM_OUTPUTS(term
)
441 if (term
->fullscreen
)
443 if (grub_env_get ("theme"))
445 if (!grub_gfxmenu_try_hook
)
447 grub_dl_load ("gfxmenu");
450 if (grub_gfxmenu_try_hook
)
453 err
= grub_gfxmenu_try_hook (entry
, menu
, nested
);
461 grub_error (GRUB_ERR_BAD_MODULE
,
462 N_("module `%s' isn't loaded"),
465 grub_wait_after_message ();
467 grub_errno
= GRUB_ERR_NONE
;
472 FOR_ACTIVE_TERM_OUTPUTS(term
)
476 if (grub_strcmp (term
->name
, "gfxterm") == 0 && gfxmenu
)
479 err
= grub_menu_try_text (term
, entry
, menu
, nested
);
483 grub_errno
= GRUB_ERR_NONE
;
490 struct grub_menu_viewer
*cur
;
491 for (cur
= viewers
; cur
; cur
= cur
->next
)
492 cur
->clear_timeout (cur
->data
);
496 grub_menu_register_viewer (struct grub_menu_viewer
*viewer
)
498 viewer
->next
= viewers
;
503 menuentry_eq (const char *id
, const char *spec
)
505 const char *ptr1
, *ptr2
;
510 if (*ptr2
== '>' && ptr2
[1] != '>' && *ptr1
== 0)
512 if (*ptr2
== '>' && ptr2
[1] != '>')
526 /* Get the entry number from the variable NAME. */
528 get_entry_number (grub_menu_t menu
, const char *name
)
533 val
= grub_env_get (name
);
539 entry
= (int) grub_strtoul (val
, 0, 0);
541 if (grub_errno
== GRUB_ERR_BAD_NUMBER
)
543 /* See if the variable matches the title of a menu entry. */
544 grub_menu_entry_t e
= menu
->entry_list
;
547 grub_errno
= GRUB_ERR_NONE
;
551 if (menuentry_eq (e
->title
, val
)
552 || menuentry_eq (e
->id
, val
))
564 if (grub_errno
!= GRUB_ERR_NONE
)
566 grub_errno
= GRUB_ERR_NONE
;
575 /* Check whether a second has elapsed since the last tick. If so, adjust
576 the timer and return 1; otherwise, return 0. */
578 has_second_elapsed (grub_uint64_t
*saved_time
)
580 grub_uint64_t current_time
;
582 current_time
= grub_get_time_ms ();
583 if (current_time
- *saved_time
>= 1000)
585 *saved_time
= current_time
;
593 print_countdown (struct grub_term_coordinate
*pos
, int n
)
595 grub_term_restore_pos (pos
);
596 /* NOTE: Do not remove the trailing space characters.
597 They are required to clear the line. */
598 grub_printf ("%d ", n
);
602 #define GRUB_MENU_PAGE_SIZE 10
604 /* Show the menu and handle menu entry selection. Returns the menu entry
605 index that should be executed or -1 if no entry should be executed (e.g.,
606 Esc pressed to exit a sub-menu or switching menu viewers).
607 If the return value is not -1, then *AUTO_BOOT is nonzero iff the menu
608 entry to be executed is a result of an automatic default selection because
611 run_menu (grub_menu_t menu
, int nested
, int *auto_boot
)
614 grub_uint64_t saved_time
;
615 int default_entry
,current_entry
;
617 enum timeout_style timeout_style
;
619 default_entry
= get_entry_number (menu
, "default");
621 if (g_ventoy_suppress_esc
)
623 else if (g_ventoy_last_entry
>= 0 && g_ventoy_last_entry
< menu
->size
) {
624 default_entry
= g_ventoy_last_entry
;
626 /* If DEFAULT_ENTRY is not within the menu entries, fall back to
628 else if (default_entry
< 0 || default_entry
>= menu
->size
)
631 timeout
= grub_menu_get_timeout ();
633 /* If there is no timeout, the "countdown" and "hidden" styles result in
634 the system doing nothing and providing no or very little indication
635 why. Technically this is what the user asked for, but it's not very
636 useful and likely to be a source of confusion, so we disallow this. */
637 grub_env_unset ("timeout_style");
639 timeout_style
= get_timeout_style ();
641 if (timeout_style
== TIMEOUT_STYLE_COUNTDOWN
642 || timeout_style
== TIMEOUT_STYLE_HIDDEN
)
644 static struct grub_term_coordinate
*pos
;
647 if (timeout_style
== TIMEOUT_STYLE_COUNTDOWN
&& timeout
)
649 pos
= grub_term_save_pos ();
650 print_countdown (pos
, timeout
);
653 /* Enter interruptible sleep until Escape or a menu hotkey is pressed,
654 or the timeout expires. */
655 saved_time
= grub_get_time_ms ();
660 key
= grub_getkey_noblock ();
661 if (key
!= GRUB_TERM_NO_KEY
)
663 entry
= get_entry_index_by_hotkey (menu
, key
);
667 if (key
== GRUB_TERM_ESC
)
673 if (timeout
> 0 && has_second_elapsed (&saved_time
))
676 if (timeout_style
== TIMEOUT_STYLE_COUNTDOWN
)
677 print_countdown (pos
, timeout
);
681 /* We will fall through to auto-booting the default entry. */
685 grub_env_unset ("timeout");
686 grub_env_unset ("timeout_style");
694 /* If timeout is 0, drawing is pointless (and ugly). */
698 return default_entry
;
701 current_entry
= default_entry
;
704 menu_init (current_entry
, menu
, nested
);
706 /* Initialize the time. */
707 saved_time
= grub_get_time_ms ();
709 timeout
= grub_menu_get_timeout ();
712 menu_print_timeout (timeout
);
719 timeout
= grub_menu_get_timeout ();
721 if (grub_normal_exit_level
)
724 if (timeout
> 0 && has_second_elapsed (&saved_time
))
727 grub_menu_set_timeout (timeout
);
728 menu_print_timeout (timeout
);
733 grub_env_unset ("timeout");
736 return default_entry
;
739 c
= grub_getkey_noblock ();
741 /* Negative values are returned on error. */
742 if ((c
!= GRUB_TERM_NO_KEY
) && (c
> 0))
746 grub_env_unset ("timeout");
747 grub_env_unset ("fallback");
753 case GRUB_TERM_KEY_HOME
:
754 case GRUB_TERM_CTRL
| 'a':
756 menu_set_chosen_entry (menu
, current_entry
);
759 case GRUB_TERM_KEY_END
:
760 case GRUB_TERM_CTRL
| 'e':
761 current_entry
= menu
->size
- 1;
762 menu_set_chosen_entry (menu
, current_entry
);
765 case GRUB_TERM_KEY_UP
:
766 case GRUB_TERM_CTRL
| 'p':
768 if (current_entry
> 0)
770 menu_set_chosen_entry (menu
, current_entry
);
773 case GRUB_TERM_CTRL
| 'n':
774 case GRUB_TERM_KEY_DOWN
:
776 if (current_entry
< menu
->size
- 1)
778 menu_set_chosen_entry (menu
, current_entry
);
781 case GRUB_TERM_CTRL
| 'g':
782 case GRUB_TERM_KEY_PPAGE
:
783 if (current_entry
< GRUB_MENU_PAGE_SIZE
)
786 current_entry
-= GRUB_MENU_PAGE_SIZE
;
787 menu_set_chosen_entry (menu
, current_entry
);
790 case GRUB_TERM_CTRL
| 'c':
791 case GRUB_TERM_KEY_NPAGE
:
792 if (current_entry
+ GRUB_MENU_PAGE_SIZE
< menu
->size
)
793 current_entry
+= GRUB_MENU_PAGE_SIZE
;
795 current_entry
= menu
->size
- 1;
796 menu_set_chosen_entry (menu
, current_entry
);
801 // case GRUB_TERM_KEY_RIGHT:
802 case GRUB_TERM_CTRL
| 'f':
805 return current_entry
;
808 if (nested
&& 0 == g_ventoy_suppress_esc
)
817 grub_cmdline_run (1, 0);
823 grub_menu_entry_t e
= grub_menu_get_entry (menu
, current_entry
);
825 grub_menu_entry_run (e
);
829 case GRUB_TERM_KEY_F2
:
831 if (0 == g_ventoy_fn_mutex
) {
832 cmdstr
= grub_env_get("VTOY_F2_CMD");
836 g_ventoy_fn_mutex
= 1;
837 grub_script_execute_sourcecode(cmdstr
);
838 g_ventoy_fn_mutex
= 0;
843 case GRUB_TERM_KEY_F3
:
845 if (0 == g_ventoy_fn_mutex
) {
846 cmdstr
= grub_env_get("VTOY_F3_CMD");
850 grub_script_execute_sourcecode(cmdstr
);
855 case GRUB_TERM_KEY_F4
:
857 if (0 == g_ventoy_fn_mutex
) {
858 cmdstr
= grub_env_get("VTOY_F4_CMD");
862 g_ventoy_fn_mutex
= 1;
863 grub_script_execute_sourcecode(cmdstr
);
864 g_ventoy_fn_mutex
= 0;
869 case GRUB_TERM_KEY_F5
:
871 if (0 == g_ventoy_fn_mutex
) {
872 cmdstr
= grub_env_get("VTOY_F5_CMD");
876 g_ventoy_fn_mutex
= 1;
877 grub_script_execute_sourcecode(cmdstr
);
878 g_ventoy_fn_mutex
= 0;
883 case GRUB_TERM_KEY_F6
:
885 if (0 == g_ventoy_fn_mutex
) {
886 cmdstr
= grub_env_get("VTOY_F6_CMD");
890 g_ventoy_fn_mutex
= 1;
891 grub_script_execute_sourcecode(cmdstr
);
892 g_ventoy_fn_mutex
= 0;
897 case GRUB_TERM_KEY_F7
:
899 if (g_ventoy_terminal_output
== 0)
901 grub_script_execute_sourcecode("terminal_output console");
902 g_ventoy_terminal_output
= 1;
906 grub_script_execute_sourcecode("terminal_output gfxterm");
907 g_ventoy_terminal_output
= 0;
910 case GRUB_TERM_KEY_F1
:
913 g_ventoy_memdisk_mode
= 1 - g_ventoy_memdisk_mode
;
914 g_ventoy_menu_refresh
= 1;
917 case (GRUB_TERM_CTRL
| 'i'):
919 g_ventoy_iso_raw
= 1 - g_ventoy_iso_raw
;
920 g_ventoy_menu_refresh
= 1;
923 case (GRUB_TERM_CTRL
| 'r'):
925 g_ventoy_grub2_mode
= 1 - g_ventoy_grub2_mode
;
926 g_ventoy_menu_refresh
= 1;
929 case (GRUB_TERM_CTRL
| 'w'):
931 g_ventoy_wimboot_mode
= 1 - g_ventoy_wimboot_mode
;
932 g_ventoy_menu_refresh
= 1;
935 case (GRUB_TERM_CTRL
| 'u'):
937 g_ventoy_iso_uefi_drv
= 1 - g_ventoy_iso_uefi_drv
;
938 g_ventoy_menu_refresh
= 1;
945 entry
= get_entry_index_by_hotkey (menu
, c
);
958 /* Never reach here. */
961 /* Callback invoked immediately before a menu entry is executed. */
963 notify_booting (grub_menu_entry_t entry
,
964 void *userdata
__attribute__((unused
)))
967 grub_printf_ (N_("Booting `%s'"), entry
->title
);
968 grub_printf ("\n\n");
971 /* Callback invoked when a default menu entry executed because of a timeout
972 has failed and an attempt will be made to execute the next fallback
975 notify_fallback (grub_menu_entry_t entry
,
976 void *userdata
__attribute__((unused
)))
979 grub_printf_ (N_("Falling back to `%s'"), entry
->title
);
980 grub_printf ("\n\n");
981 grub_millisleep (DEFAULT_ENTRY_ERROR_DELAY_MS
);
984 /* Callback invoked when a menu entry has failed and there is no remaining
985 fallback entry to attempt. */
987 notify_execution_failure (void *userdata
__attribute__((unused
)))
989 if (grub_errno
!= GRUB_ERR_NONE
)
992 grub_errno
= GRUB_ERR_NONE
;
995 grub_printf_ (N_("Failed to boot both default and fallback entries.\n"));
996 grub_wait_after_message ();
999 /* Callbacks used by the text menu to provide user feedback when menu entries
1001 static struct grub_menu_execute_callback execution_callback
=
1003 .notify_booting
= notify_booting
,
1004 .notify_fallback
= notify_fallback
,
1005 .notify_failure
= notify_execution_failure
1009 show_menu (grub_menu_t menu
, int nested
, int autobooted
)
1012 def
= grub_env_get("VTOY_DEFAULT_IMAGE");
1017 grub_menu_entry_t e
;
1020 boot_entry
= run_menu (menu
, nested
, &auto_boot
);
1024 if (auto_boot
&& def
&& grub_strcmp(def
, "VTOY_EXIT") == 0) {
1028 if (autobooted
== 0 && auto_boot
== 0) {
1029 g_ventoy_last_entry
= boot_entry
;
1030 if (g_ventoy_menu_esc
)
1034 e
= grub_menu_get_entry (menu
, boot_entry
);
1036 continue; /* Menu is empty. */
1038 if (2 == e
->argc
&& e
->args
&& e
->args
[1] && grub_strncmp(e
->args
[1], "VTOY_RET", 8) == 0)
1044 grub_menu_execute_with_fallback (menu
, e
, autobooted
,
1045 &execution_callback
, 0);
1047 grub_menu_execute_entry (e
, 0);
1051 if (2 == e
->argc
&& e
->args
&& e
->args
[1] && grub_strncmp(e
->args
[1], "VTOY_RUN_RET", 12) == 0)
1055 return GRUB_ERR_NONE
;
1059 grub_show_menu (grub_menu_t menu
, int nested
, int autoboot
)
1061 grub_err_t err1
, err2
;
1065 err1
= show_menu (menu
, nested
, autoboot
);
1067 grub_print_error ();
1069 if (grub_normal_exit_level
)
1072 err2
= grub_auth_check_authentication (NULL
);
1075 grub_print_error ();
1076 grub_errno
= GRUB_ERR_NONE
;