This is an automated email from Gerrit.

"Jan Matyas <[email protected]>" just uploaded a new patch set to Gerrit, 
which you can find at https://review.openocd.org/c/openocd/+/9542

-- gerrit

commit 1a257c6b306e01ba6b8d7a60ded15d02dc1fb14a
Author: Jan Matyas <[email protected]>
Date:   Tue Mar 24 14:32:06 2026 +0100

    semihosting: Don't mix buffered and unbuffered write
    
    Buffered access to the same file should not be combined
    with unbuffered access.
    
    For that reason, when writing via semihosting to
    stdout/stderr, don't circumvent the libc via a direct
    write() system call. Instead use a fputc() from libc
    to avoid any clashes and unexpected behavior.
    
    In Codasip, we in past internally encountered one case
    of unexpected syscall output that could possibly be
    attributed to this mixing of printf() + write() on
    the standard streams.
    
    Change-Id: I7b98db25e518173ddde64379477100180e4a3d25
    Signed-off-by: Jan Matyas <[email protected]>

diff --git a/src/target/semihosting_common.c b/src/target/semihosting_common.c
index 345e542c3c..497f190b03 100644
--- a/src/target/semihosting_common.c
+++ b/src/target/semihosting_common.c
@@ -221,12 +221,25 @@ static ssize_t semihosting_redirect_write(struct 
semihosting *semihosting, void
        return retval;
 }
 
-static ssize_t semihosting_write(struct semihosting *semihosting, int fd, void 
*buf, int size)
+static ssize_t semihosting_write(struct semihosting *semihosting, int fd, void 
*buf, size_t size)
 {
        if (semihosting_is_redirected(semihosting, fd))
                return semihosting_redirect_write(semihosting, buf, size);
 
-       /* default write */
+       bool is_stdout = (fd == STDOUT_FILENO) || fd == semihosting->stdout_fd;
+       bool is_stderr = (fd == STDERR_FILENO) || fd == semihosting->stderr_fd;
+
+       if (is_stdout || is_stderr) {
+               /* Prevent mixing buffered and unbuffered functions when 
accessing stderr/stdout.
+                * Use fputc() instead of direct write(). */
+               for (size_t i = 0; i < size; i++) {
+                       int ch = ((char *)buf)[i];
+                       fputc(ch, is_stdout ? stdout : stderr);
+               }
+               return size;
+       }
+
+       /* Access to something else than stdout/stderr. */
        int result = write(fd, buf, size);
        if (result == -1)
                semihosting->sys_errno = errno;

-- 

Reply via email to