console: Report an error when output buffer is exhausted
authorSimon Glass <sjg@chromium.org>
Sat, 8 May 2021 12:59:56 +0000 (06:59 -0600)
committerTom Rini <trini@konsulko.com>
Tue, 8 Jun 2021 15:39:09 +0000 (11:39 -0400)
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@chromium.org>
common/console.c
include/asm-generic/global_data.h
include/console.h
test/ut.c

index 561cdf3..73edb28 100644 (file)
@@ -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, ' ');
 }
index 47921d2..e278d4c 100644 (file)
@@ -572,29 +572,33 @@ enum gd_flags {
         */
        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,
 };
 
 #endif /* __ASSEMBLY__ */
index 7e628c0..f848bcb 100644 (file)
@@ -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);
 
index ea0af15..a0fe5fa 100644 (file)
--- 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;
 }