console: Support paging with single characters

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.

Series-changes: 2
- Drop unnecessary '!= NULL'

Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass
2025-08-21 18:49:56 -06:00
parent 3b30dd23bd
commit 28311413de
2 changed files with 53 additions and 5 deletions

View File

@@ -257,14 +257,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)
dev->putc(dev, c);
}
}
}

View File

@@ -429,3 +429,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);