
From: Simon Glass <sjg@chromium.org> A single character may result in a stall waiting for user input, which means that it may request that a string be output. So when the pager is active we never actually use the devices' putc() methods. Add a special case so they don't go to wrack and ruin. As before, the pager is only supported with CONFIG_CONSOLE_MUX enabled. Signed-off-by: Simon Glass <sjg@chromium.org> --- common/console.c | 22 +++++++++++++++------- test/common/pager.c | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 7 deletions(-) diff --git a/common/console.c b/common/console.c index 9bc506f0464..7bafe98375a 100644 --- a/common/console.c +++ b/common/console.c @@ -322,14 +322,22 @@ static int console_tstc(int file) return 0; } +static void console_puts_pager(int file, const char *s); + static void console_putc_pager(int file, const char c) { - int i; - struct stdio_dev *dev; + if (IS_ENABLED(CONFIG_CONSOLE_PAGER) && gd_pager()) { + char str[2] = {c, '\0'}; - for_each_console_dev(i, file, dev) { - if (dev->putc != NULL) - dev->putc(dev, c); + console_puts_pager(file, str); + } else { + int i; + struct stdio_dev *dev; + + for_each_console_dev(i, file, dev) { + if (dev->putc != NULL) + dev->putc(dev, c); + } } } @@ -757,8 +765,8 @@ void putc(const char c) return pre_console_putc(c); if (gd->flags & GD_FLG_DEVINIT) { - /* Send to the standard output */ - fputc(stdout, c); + /* Send to the standard output through pager system */ + console_putc_pager(stdout, c); } else { /* Send directly to the handler */ pre_console_putc(c); diff --git a/test/common/pager.c b/test/common/pager.c index 2512652ea01..c1c2d40f648 100644 --- a/test/common/pager.c +++ b/test/common/pager.c @@ -425,3 +425,43 @@ static int pager_test_bypass_mode(struct unit_test_state *uts) return 0; } COMMON_TEST(pager_test_bypass_mode, 0); + +/* Test that single character output via putc goes through pager */ +static int pager_test_putc(struct unit_test_state *uts) +{ + struct pager *pag; + const char *result; + + /* Init pager */ + ut_assertok(pager_init(&pag, 20, 1024)); + pager_set_bypass(pag, true); + + /* + * Test that individual characters can be posted via pager API + * This verifies that console_putc_pager() routes through the pager + * system + */ + result = pager_post(pag, true, "A"); + ut_asserteq_ptr("A", result); /* Bypass mode returns original pointer */ + + result = pager_post(pag, true, "\n"); + ut_asserteq_ptr("\n", result); + + result = pager_post(pag, true, "B"); + ut_asserteq_ptr("B", result); + + /* Disable bypass to test normal functionality with single chars */ + pager_set_bypass(pag, false); + + result = pager_post(pag, true, "X"); + ut_assertnonnull(result); + ut_asserteq_str("X", result); + + result = pager_next(pag, true, 0); + ut_assertnull(result); + + pager_uninit(pag); + + return 0; +} +COMMON_TEST(pager_test_putc, 0); -- 2.43.0