If the console output buffer is exhausted, characters are silently dropped from the end. Detect this condition and report an error when reading back the characters.
Signed-off-by: Simon Glass <s...@chromium.org> --- common/console.c | 18 +++++++++++---- include/asm-generic/global_data.h | 16 ++++++++----- include/console.h | 3 ++- test/ut.c | 37 ++++++++++++++++++++++++++----- 4 files changed, 58 insertions(+), 16 deletions(-) diff --git a/common/console.c b/common/console.c index 561cdf36a74..73edb287992 100644 --- a/common/console.c +++ b/common/console.c @@ -95,16 +95,22 @@ static void console_record_putc(const char c) { if (!(gd->flags & GD_FLG_RECORD)) return; - if (gd->console_out.start) - membuff_putbyte((struct membuff *)&gd->console_out, c); + if (gd->console_out.start && + !membuff_putbyte((struct membuff *)&gd->console_out, c)) + gd->flags |= GD_FLG_RECORD_OVF; } static void console_record_puts(const char *s) { if (!(gd->flags & GD_FLG_RECORD)) return; - if (gd->console_out.start) - membuff_put((struct membuff *)&gd->console_out, s, strlen(s)); + if (gd->console_out.start) { + int len = strlen(s); + + if (membuff_put((struct membuff *)&gd->console_out, s, len) != + len) + gd->flags |= GD_FLG_RECORD_OVF; + } } static int console_record_getc(void) @@ -742,6 +748,7 @@ void console_record_reset(void) { membuff_purge((struct membuff *)&gd->console_out); membuff_purge((struct membuff *)&gd->console_in); + gd->flags &= ~GD_FLG_RECORD_OVF; } int console_record_reset_enable(void) @@ -754,6 +761,9 @@ int console_record_reset_enable(void) int console_record_readline(char *str, int maxlen) { + if (gd->flags & GD_FLG_RECORD_OVF) + return -ENOSPC; + return membuff_readline((struct membuff *)&gd->console_out, str, maxlen, ' '); } diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index c24f5e0e973..e60036ab847 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -561,30 +561,34 @@ enum gd_flags { * @GD_FLG_RECORD: record console */ GD_FLG_RECORD = 0x01000, + /** + * @GD_FLG_RECORD_OVF: record console overflow + */ + GD_FLG_RECORD_OVF = 0x02000, /** * @GD_FLG_ENV_DEFAULT: default variable flag */ - GD_FLG_ENV_DEFAULT = 0x02000, + GD_FLG_ENV_DEFAULT = 0x04000, /** * @GD_FLG_SPL_EARLY_INIT: early SPL initialization is done */ - GD_FLG_SPL_EARLY_INIT = 0x04000, + GD_FLG_SPL_EARLY_INIT = 0x08000, /** * @GD_FLG_LOG_READY: log system is ready for use */ - GD_FLG_LOG_READY = 0x08000, + GD_FLG_LOG_READY = 0x10000, /** * @GD_FLG_WDT_READY: watchdog is ready for use */ - GD_FLG_WDT_READY = 0x10000, + GD_FLG_WDT_READY = 0x20000, /** * @GD_FLG_SKIP_LL_INIT: don't perform low-level initialization */ - GD_FLG_SKIP_LL_INIT = 0x20000, + GD_FLG_SKIP_LL_INIT = 0x40000, /** * @GD_FLG_SMP_READY: SMP initialization is complete */ - GD_FLG_SMP_READY = 0x40000, + GD_FLG_SMP_READY = 0x80000, }; /** diff --git a/include/console.h b/include/console.h index 7e628c0cf83..f848bcbf037 100644 --- a/include/console.h +++ b/include/console.h @@ -72,7 +72,8 @@ int console_record_reset_enable(void); * * @str: Place to put string * @maxlen: Maximum length of @str including nul terminator - * @return length of string returned + * @return length of string returned, or -ENOSPC if the console buffer was + * overflowed by the output */ int console_record_readline(char *str, int maxlen); diff --git a/test/ut.c b/test/ut.c index ea0af153e4a..a0fe5facac7 100644 --- a/test/ut.c +++ b/test/ut.c @@ -51,14 +51,31 @@ long ut_check_delta(ulong last) return ut_check_free() - last; } +static int readline_check(struct unit_test_state *uts) +{ + int ret; + + ret = console_record_readline(uts->actual_str, sizeof(uts->actual_str)); + if (ret == -ENOSPC) { + ut_fail(uts, __FILE__, __LINE__, __func__, + "Console record buffer too small - increase CONFIG_CONSOLE_RECORD_OUT_SIZE"); + return ret; + } + + return 0; +} + int ut_check_console_line(struct unit_test_state *uts, const char *fmt, ...) { va_list args; + int ret; va_start(args, fmt); vsnprintf(uts->expect_str, sizeof(uts->expect_str), fmt, args); va_end(args); - console_record_readline(uts->actual_str, sizeof(uts->actual_str)); + ret = readline_check(uts); + if (ret < 0) + return ret; return strcmp(uts->expect_str, uts->actual_str); } @@ -66,11 +83,14 @@ int ut_check_console_line(struct unit_test_state *uts, const char *fmt, ...) int ut_check_console_linen(struct unit_test_state *uts, const char *fmt, ...) { va_list args; + int ret; va_start(args, fmt); vsnprintf(uts->expect_str, sizeof(uts->expect_str), fmt, args); va_end(args); - console_record_readline(uts->actual_str, sizeof(uts->actual_str)); + ret = readline_check(uts); + if (ret < 0) + return ret; return strncmp(uts->expect_str, uts->actual_str, strlen(uts->expect_str)); @@ -78,19 +98,26 @@ int ut_check_console_linen(struct unit_test_state *uts, const char *fmt, ...) int ut_check_skipline(struct unit_test_state *uts) { + int ret; + if (!console_record_avail()) return -ENFILE; - console_record_readline(uts->actual_str, sizeof(uts->actual_str)); + ret = readline_check(uts); + if (ret < 0) + return ret; return 0; } int ut_check_console_end(struct unit_test_state *uts) { + int ret; + if (!console_record_avail()) return 0; - - console_record_readline(uts->actual_str, sizeof(uts->actual_str)); + ret = readline_check(uts); + if (ret < 0) + return ret; return 1; } -- 2.31.0.rc2.261.g7f71774620-goog