From eda7493803991c167c1c8245281cffef6e270bab Mon Sep 17 00:00:00 2001 From: Andre Renaud Date: Tue, 5 May 2026 12:02:48 +1200 Subject: [PATCH] Separate flush/drain a bit better --- README.md | 12 +++++++++++- simple_uart.c | 22 +++++++++++++++++----- simple_uart.h | 7 ++++++- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index adb555d..04af5f0 100644 --- a/README.md +++ b/README.md @@ -204,7 +204,17 @@ Set the state of a hardware pin of the UART. See *simple_uart_get_pin* ```c int simple_uart_flush(struct simple_uart *uart); ``` -Ensure all outstanding data has been written to the wire and is not being buffered by the OS. +Discard all pending input and output data buffered by the OS without waiting for it to be transmitted. + + +### Drain +```c +int simple_uart_drain(struct simple_uart *uart); +``` +Block until all pending output data has been transmitted. Unlike *simple_uart_flush*, this does not discard data — it waits for the transmit buffer to empty. + +#### Return: +*0* on success. *< 0* on failure. ### Break diff --git a/simple_uart.c b/simple_uart.c index 58cc921..25007b7 100644 --- a/simple_uart.c +++ b/simple_uart.c @@ -986,11 +986,8 @@ int simple_uart_flush(struct simple_uart *uart) if (!uart) return -EINVAL; -#if defined(__linux__) - if (ioctl(uart->fd, TCFLSH, TCIOFLUSH) < 0) - return -errno; -#elif defined(__APPLE__) - if (tcdrain(uart->fd) < 0) +#ifndef _WIN32 + if (tcflush(uart->fd, TCIOFLUSH) < 0) return -errno; #else DWORD purge_all = PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR; @@ -999,3 +996,18 @@ int simple_uart_flush(struct simple_uart *uart) #endif return 0; } + +int simple_uart_drain(struct simple_uart *uart) +{ + if (!uart) + return -EINVAL; + +#ifndef _WIN32 + if (tcdrain(uart->fd) < 0) + return -errno; +#else + if (!FlushFileBuffers(uart->port)) + return win32_errno(); +#endif + return 0; +} diff --git a/simple_uart.h b/simple_uart.h index ca877fb..9f3d57e 100644 --- a/simple_uart.h +++ b/simple_uart.h @@ -77,10 +77,15 @@ int simple_uart_get_pin(struct simple_uart *uart, int pin); int simple_uart_set_pin(struct simple_uart *uart, int pin, bool high); /** - * Make sure all write data has been flushed out of the UART + * Make sure all read/write data has been flushed (discarded) out of the UART */ int simple_uart_flush(struct simple_uart *uart); +/** + * Block until all pending output has been transmitted + */ +int simple_uart_drain(struct simple_uart *uart); + /** * Send the break symbol */