From eca09b7c176bea40e42cde7dc384d66f28164116 Mon Sep 17 00:00:00 2001 From: Hugues Kamba Date: Fri, 3 Apr 2020 19:01:03 +0100 Subject: [PATCH] Fix: Return the correct std I/O device handle for Microlib in retarget code Return the correct filehandle based on the mode requested. The mode is used as the pathname is always the default one (":tt") for Microlib. The previous implementation relied on three successive calls to open the std I/O device handles, this was not the case. --- platform/source/mbed_retarget.cpp | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/platform/source/mbed_retarget.cpp b/platform/source/mbed_retarget.cpp index 1bd5627cf7..9efc1558bc 100644 --- a/platform/source/mbed_retarget.cpp +++ b/platform/source/mbed_retarget.cpp @@ -91,13 +91,11 @@ asm(" .global __use_full_stdio\n"); using namespace mbed; -#if defined(__MICROLIB) -// Before version 5.03, we were using a patched version of microlib with proper names -extern const char __stdin_name[] = ":tt"; -extern const char __stdout_name[] = ":tt"; -extern const char __stderr_name[] = ":tt"; - -#else +// Microlib currently does not allow re-defining the pathnames for the +// standard I/O device handles (STDIN, STDOUT, and STDERR). +// It uses the default pathname ":tt" at library initialization to identify +// them all. +#if !defined(__MICROLIB) extern const char __stdin_name[] = "/stdin"; extern const char __stdout_name[] = "/stdout"; extern const char __stderr_name[] = "/stderr"; @@ -555,11 +553,15 @@ std::FILE *fdopen(FileHandle *fh, const char *mode) extern "C" FILEHANDLE PREFIX(_open)(const char *name, int openflags) { #if defined(__MICROLIB) - // Before version 5.03, we were using a patched version of microlib with proper names - // This is the workaround that the microlib author suggested us - static int n = 0; - if (std::strcmp(name, ":tt") == 0 && n < 3) { - return n++; + // Use the mode requested to select the standard I/O device handle to return. + if (std::strcmp(name, ":tt") == 0) { + if (openflags & OPEN_W) { + return STDOUT_FILENO; + } else if (openflags & OPEN_A) { + return STDERR_FILENO; + } else { + return STDIN_FILENO; + } } #else /* Use the posix convention that stdin,out,err are filehandles 0,1,2.