diff --git a/serial.go b/serial.go index 2bb7f3e..4420100 100644 --- a/serial.go +++ b/serial.go @@ -26,6 +26,9 @@ type Port interface { // Returns the number of bytes written. Write(p []byte) (n int, err error) + // Wait until all data in the buffer are sent + Drain() error + // ResetInputBuffer Purges port read buffer ResetInputBuffer() error diff --git a/serial_bsd.go b/serial_bsd.go new file mode 100644 index 0000000..4e1f226 --- /dev/null +++ b/serial_bsd.go @@ -0,0 +1,9 @@ +//go:build darwin || dragonfly || freebsd || netbsd || openbsd + +package serial + +import "golang.org/x/sys/unix" + +func (port *unixPort) Drain() error { + return unix.IoctlSetInt(port.handle, unix.TIOCDRAIN, 0) +} diff --git a/serial_linux.go b/serial_linux.go index 7ab05e7..32049a2 100644 --- a/serial_linux.go +++ b/serial_linux.go @@ -85,3 +85,10 @@ func setTermSettingsBaudrate(speed int, settings *unix.Termios) (error, bool) { settings.Ospeed = toTermiosSpeedType(baudrate) return nil, false } + +func (port *unixPort) Drain() error { + // It's not super well documented, but this is the same as calling tcdrain: + // - https://git.musl-libc.org/cgit/musl/tree/src/termios/tcdrain.c + // - https://elixir.bootlin.com/linux/v6.2.8/source/drivers/tty/tty_io.c#L2673 + return unix.IoctlSetInt(port.handle, unix.TCSBRK, 1) +} diff --git a/serial_windows.go b/serial_windows.go index e393d4e..5c4a576 100644 --- a/serial_windows.go +++ b/serial_windows.go @@ -119,6 +119,10 @@ func (port *windowsPort) Write(p []byte) (int, error) { return int(writed), err } +func (port *windowsPort) Drain() (err error) { + return syscall.FlushFileBuffers(port.handle) +} + const ( purgeRxAbort uint32 = 0x0002 purgeRxClear = 0x0008