Hello, we needed a way for GRUB to show a rather large text file in pager mode (set pager=1) while still allowing the user to abort without scrolling all the way to the bottom of the file.
>From the original commit message: [...] The reason is that "cat" scans for key strokes but does not block waiting for them. This results in a race between the pager that eats all the keystrokes and "cat" that scans for them in non-blocking mode. To fix this, we let the pager report if a keypress was ESC, 'q' or 'Q'. The caller can check for this and stop the printing of data. The behaviour of the pager itself is not affected by this. Please note that this is a rather quick fix and there might be a better solution (possibly entirely inside the term layer?). If anyone has a better solution, please let me know. Otherwise I could submit a proper patch using this fix. Original patch by Christian Ehrhardt <[email protected]>. Thanks Valentin
>From dd878255a7d5a071e7fb8843ce104d27f7404867 Mon Sep 17 00:00:00 2001 From: Valentin Dornauer <[email protected]> Date: Wed, 14 Jan 2015 11:44:22 +0100 Subject: [PATCH] Support abort of cat even if in paging mode --- grub-core/commands/cat.c | 5 ++++- grub-core/normal/term.c | 19 ++++++++++++++++++- include/grub/normal.h | 2 ++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/grub-core/commands/cat.c b/grub-core/commands/cat.c index 8a7f1af..448f14b 100644 --- a/grub-core/commands/cat.c +++ b/grub-core/commands/cat.c @@ -25,6 +25,7 @@ #include <grub/extcmd.h> #include <grub/i18n.h> #include <grub/charset.h> +#include <grub/normal.h> GRUB_MOD_LICENSE ("GPLv3+"); @@ -50,6 +51,8 @@ grub_cmd_cat (grub_extcmd_context_t ctxt, int argc, char **args) int is_0d = 0; int j; + grub_set_more_abort(0); + if (state[0].set) dos = 1; @@ -61,7 +64,7 @@ grub_cmd_cat (grub_extcmd_context_t ctxt, int argc, char **args) return grub_errno; while ((size = grub_file_read (file, buf, sizeof (buf))) > 0 - && key != GRUB_TERM_ESC) + && key != GRUB_TERM_ESC && !grub_get_more_abort()) { int i; diff --git a/grub-core/normal/term.c b/grub-core/normal/term.c index 4c2238b..5d1a5a8 100644 --- a/grub-core/normal/term.c +++ b/grub-core/normal/term.c @@ -57,6 +57,7 @@ static struct term_state *term_states = NULL; /* If the more pager is active. */ static int grub_more; +static int grub_more_abort; static void putcode_real (grub_uint32_t code, struct grub_term_output *term, int fixed_tab); @@ -118,7 +119,11 @@ print_more (void) state->num_lines--; } else - grub_normal_reset_more (); + { + if (key == GRUB_TERM_ESC || key == 'q' || key == 'Q') + grub_set_more_abort(1); + grub_normal_reset_more (); + } } void @@ -128,6 +133,18 @@ grub_set_more (int onoff) grub_normal_reset_more (); } +void +grub_set_more_abort(int val) +{ + grub_more_abort = !!val; +} + +int +grub_get_more_abort(void) +{ + return !!grub_more_abort; +} + enum { GRUB_CP437_UPDOWNARROW = 0x12, diff --git a/include/grub/normal.h b/include/grub/normal.h index 218cbab..318f329 100644 --- a/include/grub/normal.h +++ b/include/grub/normal.h @@ -133,6 +133,8 @@ void read_crypto_list (const char *prefix); void read_terminal_list (const char *prefix); void grub_set_more (int onoff); +void grub_set_more_abort(int onoff); +int grub_get_more_abort(void); void grub_normal_reset_more (void); -- 1.7.10.4
_______________________________________________ Grub-devel mailing list [email protected] https://lists.gnu.org/mailman/listinfo/grub-devel
