diff --git a/cores/ardulinux/linux/LinuxSerial.cpp b/cores/ardulinux/linux/LinuxSerial.cpp index 8cc349d..beed04b 100644 --- a/cores/ardulinux/linux/LinuxSerial.cpp +++ b/cores/ardulinux/linux/LinuxSerial.cpp @@ -262,6 +262,25 @@ namespace arduino { // --- SimSerial: stdout-backed simulated serial (used as the console) --- + /** + * Line-buffer stdout the first time a SimSerial is constructed. + * + * The global `Serial` instance is constructed at static-init, before any + * output, so this runs before the first write. With line buffering, each + * log line is flushed on its terminating newline, so `Serial.print(...)` + * output reaches the terminal / journald promptly without wrapping the + * process in `stdbuf -oL`. Guarded to run only once: setvbuf() is undefined + * once I/O has occurred, and additional SimSerial instances may be created + * (e.g. in tests) after output has already started. + */ + SimSerial::SimSerial() { + static bool configured = [] { + setvbuf(stdout, nullptr, _IOLBF, 0); + return true; + }(); + (void)configured; + } + /** No-op: simulated port requires no hardware setup. */ void SimSerial::begin(unsigned long baudrate, uint16_t config) {} diff --git a/cores/ardulinux/linux/LinuxSerial.h b/cores/ardulinux/linux/LinuxSerial.h index 5dbb12a..1f435a8 100644 --- a/cores/ardulinux/linux/LinuxSerial.h +++ b/cores/ardulinux/linux/LinuxSerial.h @@ -114,6 +114,12 @@ namespace arduino { */ class SimSerial : public HardwareSerial { public: + /** + * Line-buffer stdout (once, at static init) so log lines reach the + * terminal / journald promptly, without needing an external + * `stdbuf -oL` wrapper around the process. + */ + SimSerial(); /** No-op; the simulated port is always "open". */ virtual void begin(unsigned long baudrate) { begin(baudrate, SERIAL_8N1); } /** No-op. */