From 32ea03079bc5b4a824311fced39aebb0657ec91b Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Mon, 23 Jan 2023 12:55:41 +0100 Subject: [PATCH] Add sock_splice_all() --- src/lib/sock.c | 29 +++++++++++++++++++++++------ src/lib/sock.h | 2 ++ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/lib/sock.c b/src/lib/sock.c index 4e58beb..2bd7417 100644 --- a/src/lib/sock.c +++ b/src/lib/sock.c @@ -182,11 +182,31 @@ long sock_splice(sock *dst, sock *src, void *buf, unsigned long buf_len, unsigne return send_len; } +long sock_splice_all(sock *dst, sock *src, void *buf, unsigned long buf_len) { + long send_len = 0; + for (long ret;; send_len += ret) { + if ((ret = sock_recv(src, buf, buf_len, 0)) <= 0) { + if (errno == EINTR) { + errno = 0, ret = 0; + continue; + } else if (ret == 0) { + break; + } else { + return -1; + } + } + + if (sock_send_x(dst, buf, ret, 0) == -1) + return -1; + } + return send_len; +} + long sock_splice_chunked(sock *dst, sock *src, void *buf, unsigned long buf_len, int flags) { long ret; unsigned long send_len = 0, next_len; - while (!(flags & SOCK_SINGLE_CHUNK)) { + do { ret = sock_get_chunk_header(src); if (ret < 0) { errno = EPROTO; @@ -200,9 +220,6 @@ long sock_splice_chunked(sock *dst, sock *src, void *buf, unsigned long buf_len, return -1; } - if (next_len == 0) - break; - if ((ret = sock_splice(dst, src, buf, buf_len, next_len)) < 0) return ret; @@ -219,7 +236,7 @@ long sock_splice_chunked(sock *dst, sock *src, void *buf, unsigned long buf_len, errno = EPROTO; return -2; } - } + } while (!(flags & SOCK_SINGLE_CHUNK) && next_len != 0); return (long) send_len; } @@ -263,7 +280,7 @@ long sock_parse_chunk_header(const char *buf, long len, long *ret_len) { } long sock_get_chunk_header(sock *s) { - long ret, len; + long ret, len = 0; char buf[16]; do { diff --git a/src/lib/sock.h b/src/lib/sock.h index 8371b3d..4a273b3 100644 --- a/src/lib/sock.h +++ b/src/lib/sock.h @@ -51,6 +51,8 @@ long sock_recv_x(sock *s, void *buf, unsigned long len, int flags); long sock_splice(sock *dst, sock *src, void *buf, unsigned long buf_len, unsigned long len); +long sock_splice_all(sock *dst, sock *src, void *buf, unsigned long buf_len); + long sock_splice_chunked(sock *dst, sock *src, void *buf, unsigned long buf_len, int flags); int sock_close(sock *s);