normal_exit command

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2009-12-25 16:28:31 +01:00
parent 0e76d18c5b
commit 6066889c88
4 changed files with 54 additions and 15 deletions

View file

@ -46,7 +46,7 @@ enum grub_completion_type
typedef enum grub_completion_type grub_completion_type_t; typedef enum grub_completion_type grub_completion_type_t;
extern struct grub_menu_viewer grub_normal_text_menu_viewer; extern struct grub_menu_viewer grub_normal_text_menu_viewer;
extern int grub_normal_exit_level;
/* Defined in `main.c'. */ /* Defined in `main.c'. */
void grub_enter_normal_mode (const char *config); void grub_enter_normal_mode (const char *config);

View file

@ -34,6 +34,9 @@
#define GRUB_DEFAULT_HISTORY_SIZE 50 #define GRUB_DEFAULT_HISTORY_SIZE 50
static int nested_level = 0;
int grub_normal_exit_level = 0;
/* Read a line from the file FILE. */ /* Read a line from the file FILE. */
char * char *
grub_file_getline (grub_file_t file) grub_file_getline (grub_file_t file)
@ -430,8 +433,6 @@ grub_normal_init_page (struct grub_term_output *term)
grub_free (unicode_msg); grub_free (unicode_msg);
} }
static int reader_nested;
/* Read the config file CONFIG and execute the menu interface or /* Read the config file CONFIG and execute the menu interface or
the command line interface if BATCH is false. */ the command line interface if BATCH is false. */
void void
@ -446,8 +447,6 @@ grub_normal_execute (const char *config, int nested, int batch)
read_terminal_list (); read_terminal_list ();
grub_command_execute ("parser.grub", 0, 0); grub_command_execute ("parser.grub", 0, 0);
reader_nested = nested;
if (config) if (config)
{ {
menu = read_config_file (config); menu = read_config_file (config);
@ -471,8 +470,12 @@ grub_normal_execute (const char *config, int nested, int batch)
void void
grub_enter_normal_mode (const char *config) grub_enter_normal_mode (const char *config)
{ {
nested_level++;
grub_normal_execute (config, 0, 0); grub_normal_execute (config, 0, 0);
grub_cmdline_run (1); grub_cmdline_run (0);
nested_level--;
if (grub_normal_exit_level)
grub_normal_exit_level--;
} }
/* Enter normal mode from rescue mode. */ /* Enter normal mode from rescue mode. */
@ -508,8 +511,20 @@ quit:
return 0; return 0;
} }
/* Exit from normal mode to rescue mode. */
static grub_err_t static grub_err_t
grub_normal_reader_init (void) grub_cmd_normal_exit (struct grub_command *cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)),
char *argv[] __attribute__ ((unused)))
{
if (nested_level <= grub_normal_exit_level)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "not in normal environment");
grub_normal_exit_level++;
return GRUB_ERR_NONE;
}
static grub_err_t
grub_normal_reader_init (int nested)
{ {
struct grub_term_output *term; struct grub_term_output *term;
const char *msg = _("Minimal BASH-like line editing is supported. For " const char *msg = _("Minimal BASH-like line editing is supported. For "
@ -519,7 +534,7 @@ grub_normal_reader_init (void)
char *msg_formatted = grub_malloc (sizeof (char) * (grub_strlen (msg) + char *msg_formatted = grub_malloc (sizeof (char) * (grub_strlen (msg) +
grub_strlen(msg_esc) + 1)); grub_strlen(msg_esc) + 1));
grub_sprintf (msg_formatted, msg, reader_nested ? msg_esc : ""); grub_sprintf (msg_formatted, msg, nested ? msg_esc : "");
FOR_ACTIVE_TERM_OUTPUTS(term) FOR_ACTIVE_TERM_OUTPUTS(term)
{ {
@ -536,12 +551,15 @@ grub_normal_reader_init (void)
static grub_err_t static grub_err_t
grub_normal_read_line (char **line, int cont) grub_normal_read_line_real (char **line, int cont, int nested)
{ {
grub_parser_t parser = grub_parser_get_current (); grub_parser_t parser = grub_parser_get_current ();
char prompt[sizeof("> ") + grub_strlen (parser->name)]; char prompt[sizeof("> ") + grub_strlen (parser->name)];
grub_sprintf (prompt, "%s> ", parser->name); if (cont)
grub_sprintf (prompt, "> ");
else
grub_sprintf (prompt, "%s> ", parser->name);
while (1) while (1)
{ {
@ -549,7 +567,7 @@ grub_normal_read_line (char **line, int cont)
if (*line) if (*line)
break; break;
if ((reader_nested) || (cont)) if (cont || nested)
{ {
grub_free (*line); grub_free (*line);
*line = 0; *line = 0;
@ -560,6 +578,12 @@ grub_normal_read_line (char **line, int cont)
return 0; return 0;
} }
static grub_err_t
grub_normal_read_line (char **line, int cont)
{
return grub_normal_read_line_real (line, cont, 0);
}
void void
grub_cmdline_run (int nested) grub_cmdline_run (int nested)
{ {
@ -574,19 +598,20 @@ grub_cmdline_run (int nested)
return; return;
} }
reader_nested = nested; grub_normal_reader_init (nested);
grub_normal_reader_init ();
while (1) while (1)
{ {
char *line; char *line;
if (grub_normal_exit_level)
break;
/* Print an error, if any. */ /* Print an error, if any. */
grub_print_error (); grub_print_error ();
grub_errno = GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE;
grub_normal_read_line (&line, 0); grub_normal_read_line_real (&line, 0, nested);
if (! line) if (! line)
break; break;
@ -623,6 +648,8 @@ GRUB_MOD_INIT(normal)
/* Register a command "normal" for the rescue mode. */ /* Register a command "normal" for the rescue mode. */
grub_register_command ("normal", grub_cmd_normal, grub_register_command ("normal", grub_cmd_normal,
0, "Enter normal mode"); 0, "Enter normal mode");
grub_register_command ("normal_exit", grub_cmd_normal_exit,
0, "Exit from normal mode");
/* Reload terminal colors when these variables are written to. */ /* Reload terminal colors when these variables are written to. */
grub_register_variable_hook ("color_normal", NULL, grub_env_write_color_normal); grub_register_variable_hook ("color_normal", NULL, grub_env_write_color_normal);

View file

@ -344,6 +344,9 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
int c; int c;
timeout = grub_menu_get_timeout (); timeout = grub_menu_get_timeout ();
if (grub_normal_exit_level)
return -1;
if (timeout > 0) if (timeout > 0)
{ {
grub_uint64_t current_time; grub_uint64_t current_time;
@ -554,6 +557,9 @@ grub_show_menu (grub_menu_t menu, int nested)
err1 = show_menu (menu, nested); err1 = show_menu (menu, nested);
grub_print_error (); grub_print_error ();
if (grub_normal_exit_level)
break;
err2 = grub_auth_check_authentication (NULL); err2 = grub_auth_check_authentication (NULL);
if (err2) if (err2)
{ {

View file

@ -1270,6 +1270,12 @@ grub_menu_entry_run (grub_menu_entry_t entry)
screen->completion_shown = 0; screen->completion_shown = 0;
} }
if (grub_normal_exit_level)
{
destroy_screen (screen);
return;
}
switch (c) switch (c)
{ {
case 16: /* C-p */ case 16: /* C-p */