From 1c1ddf463b76c3d13f8376a9d6279fe2b04cd432 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 29 Mar 2026 13:49:47 -1000 Subject: [PATCH] [api] Fix write_raw_iov_ not attempting write when called directly with empty overflow When called from cold paths (write_raw_buf_, write_frame_) with sent=-1 and empty overflow, the function would skip the write and read a stale errno. Now always attempts the write when overflow is empty, matching the original write_raw_ behavior. --- esphome/components/api/api_frame_helper.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/esphome/components/api/api_frame_helper.cpp b/esphome/components/api/api_frame_helper.cpp index 5c5f1e8785d..89ae9b3975f 100644 --- a/esphome/components/api/api_frame_helper.cpp +++ b/esphome/components/api/api_frame_helper.cpp @@ -130,20 +130,19 @@ APIError APIFrameHelper::write_raw_iov_(const struct iovec *iov, int iovcnt, uin #endif if (sent == -1) { - // Either the fast path got -1, or we were called with overflow backlog + // Either the fast path write returned -1, or we were called directly (cold path) if (!this->overflow_buf_.empty()) { // Drain existing backlog first APIError err = this->drain_overflow_and_handle_errors_(); if (err != APIError::OK) return err; - // Try again after drain - if (this->overflow_buf_.empty()) { - sent = - (iovcnt == 1) ? this->socket_->write(iov[0].iov_base, iov[0].iov_len) : this->socket_->writev(iov, iovcnt); - if (sent == static_cast(total_write_len)) - return APIError::OK; - // Partial write or -1: fall through to error check / enqueue below - } + } + // Try write if backlog is clear (either was empty, or drain succeeded) + if (this->overflow_buf_.empty()) { + sent = (iovcnt == 1) ? this->socket_->write(iov[0].iov_base, iov[0].iov_len) : this->socket_->writev(iov, iovcnt); + if (sent == static_cast(total_write_len)) + return APIError::OK; + // Partial write or -1: fall through to error check / enqueue below } if (sent == -1) { int err = errno;