[PATCH 01/13] console: Report an error when output buffer is exhausted
Simon Glass
sjg at chromium.org
Wed Mar 17 19:18:28 CET 2021
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 <sjg at 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
More information about the U-Boot
mailing list