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

Reply via email to