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.
pull/12758/head
Hugues Kamba 2020-04-03 19:01:03 +01:00
parent c8ab263388
commit eca09b7c17
1 changed files with 14 additions and 12 deletions

View File

@ -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.