This is an automated email from the ASF dual-hosted git repository. ChristopherSchultz pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomcat-connectors.git
commit ed383e12ca21035f42c4bcb8cb128f8ee63363ae Author: Christopher Schultz <[email protected]> AuthorDate: Mon Jun 8 18:18:32 2026 -0400 Fix a few issues in jk_sb_send Tolerate situations where send() does not send the complete message on the first try Writing a zero-length buffer is always successful --- native/common/jk_sockbuf.c | 78 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 61 insertions(+), 17 deletions(-) diff --git a/native/common/jk_sockbuf.c b/native/common/jk_sockbuf.c index 32c53931a..b82d78fdb 100644 --- a/native/common/jk_sockbuf.c +++ b/native/common/jk_sockbuf.c @@ -37,33 +37,77 @@ int jk_sb_open(jk_sockbuf_t *sb, jk_sock_t sd) return JK_FALSE; } -int jk_sb_write(jk_sockbuf_t *sb, const void *buf, unsigned sz) +/* send all data in buf (up to len) to the file descriptor */ +static int jk_sb_send_all(int sd, const void *buf, size_t len) { - if (sb && buf && sz) { - if (sb->end >= SOCKBUF_SIZE) { - return JK_FALSE; - } + size_t total = 0; + + if (len == 0) { + return JK_TRUE; + } - if (sz <= SOCKBUF_SIZE - sb->end) { - memcpy(sb->buf + sb->end, buf, sz); - sb->end += sz; + while (total < len) { + ssize_t n = send(sd, + (const char *)buf + total, + len - total, + 0); + + if (n > 0) { + total += (size_t)n; + continue; } - else { - if (!jk_sb_flush(sb)) { - return JK_FALSE; - } - if (sz > SOCKBUF_SIZE) { - return (send(sb->sd, (char *)buf, sz, 0) == (int)sz); + + if (n == -1) { + if (errno == EINTR) { + continue; // interrupted, retry } - memcpy(sb->buf + sb->end, buf, sz); - sb->end += sz; + // Any other error is fatal for this write + return JK_FALSE; } + // n == 0: treat as connection closed or invalid state + return JK_FALSE; + } + + return JK_TRUE; +} + +int jk_sb_write(jk_sockbuf_t *sb, const void *buf, unsigned sz) +{ + if (!sb || !buf) { + return JK_FALSE; + } + if (sz == 0) { return JK_TRUE; } - return JK_FALSE; + if (sb->end >= SOCKBUF_SIZE) { + return JK_FALSE; + } + + if (sz <= SOCKBUF_SIZE - sb->end) { + memcpy(sb->buf + sb->end, buf, sz); + sb->end += sz; + + return JK_TRUE; + } + + /* write cannot fit into remaining buffer, so flush */ + if (!jk_sb_flush(sb)) { + return JK_FALSE; + } + + /* don't buffer writes that will never fit */ + if (sz > SOCKBUF_SIZE) { + return jk_sb_send_all(sb->sd, buf, sz); + } + + /* buffer small write-after-flush */ + memcpy(sb->buf + sb->end, buf, sz); + sb->end += sz; + + return JK_TRUE; } int jk_sb_flush(jk_sockbuf_t *sb) --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
