1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-17 05:12:57 +01:00

sys/fmt: fix interaction with stdio

Use fwrite instead of write to not bypass caching stdio. Other fmt's
print function are too much of a footgun to use.
This commit is contained in:
Marian Buschsieweke 2022-06-02 14:50:15 +02:00
parent d98211f339
commit 68dcf27eab
No known key found for this signature in database
GPG Key ID: CB8E3238CE715A94

View File

@ -21,15 +21,9 @@
#include <assert.h>
#include <stdarg.h>
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#if defined(__WITH_AVRLIBC__) || defined(__mips__)
#include <stdio.h> /* for fwrite() */
#else
/* work around broken sys/posix/unistd.h */
ssize_t write(int fildes, const void *buf, size_t nbyte);
#endif
#include <unistd.h>
#include "kernel_defines.h"
#include "fmt.h"
@ -505,19 +499,28 @@ uint32_t scn_u32_hex(const char *str, size_t n)
void print(const char *s, size_t n)
{
#ifdef __WITH_AVRLIBC__
/* AVR's libc doesn't offer write(), so use fwrite() instead */
fwrite(s, n, 1, stdout);
#else
while (n > 0) {
ssize_t written = write(STDOUT_FILENO, s, n);
ssize_t written;
if (IS_USED(MODULE_STDIO_NATIVE)) {
/* for native fwrite is not wrapped and would use the system's
* write directly, resulting in corrupted output. Instead, use the
* stdio_write wrapper directly here to force all output from
* puts() / printf() and fmt to be handled the same. */
extern ssize_t stdio_write(const void* buffer, size_t len);
written = stdio_write(s, n);
}
else {
/* For all but native: Use fwrite rather than the cheaper unbuffered
* write() to avoid corrupted output when mixing stdio and fmt
* for C libs that use buffered output */
written = fwrite(s, 1, n, stdout);
}
if (written < 0) {
break;
}
n -= written;
s += written;
}
#endif /* __WITH_AVRLIBC__ */
}
void print_u32_dec(uint32_t val)