]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
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 561cdf36a747983c4f4895fc9d64c26b69693381..73edb28799201c3f4a86c3777e63d82a914aa5a6 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 47921d27b13ebbd33cd803be152d151e9d9a95fc..e278d4c9413c0d86e3668d1b6f980462ab6f10e0 100644 (file)
@@ -571,30 +571,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,
 };
 
 #endif /* __ASSEMBLY__ */
index 7e628c0cf8360b94d705b789851d2c87c4bf9655..f848bcbf03764e7a5d0524760456a37a598e2a1b 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 ea0af153e4acd69131a935a5d31b8e8867533bd7..a0fe5facac7a20dff53be360b4d69d3820306921 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;
 }