diff options
author | Tim Rühsen <tim.ruehsen@gmx.de> | 2019-04-10 17:53:09 +0200 |
---|---|---|
committer | Tim Rühsen <tim.ruehsen@gmx.de> | 2019-04-10 17:54:06 +0200 |
commit | 31db29a0d434374f26a92c4998b3667cf31e3a31 (patch) | |
tree | 3831770923fc0b61ba3a353cdbb54457fa2bc31e | |
parent | 12bfa526605d2eb078e0244dc47ea21c2033491d (diff) | |
download | gnutls-tmp-wrap-vec-push.tar.gz |
Wrap vec-push function in src/socket.ctmp-wrap-vec-push
Signed-off-by: Tim Rühsen <tim.ruehsen@gmx.de>
-rw-r--r-- | src/socket.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/src/socket.c b/src/socket.c index 9ba784fa3a..a84dc7580e 100644 --- a/src/socket.c +++ b/src/socket.c @@ -39,6 +39,10 @@ #include "sockets.h" #include "common.h" +#ifdef HAVE_SYS_UIO_H +#include <sys/uio.h> // writev() +#endif + #ifdef _WIN32 # undef endservent # define endservent() @@ -445,6 +449,41 @@ wrap_push(gnutls_transport_ptr_t ptr, const void *data, size_t len) return send(hd->fd, data, len, 0); } +static ssize_t +wrap_vec_push(gnutls_transport_ptr_t ptr, const giovec_t *iov, int iovcnt) +{ + socket_st *hd = ptr; + +#ifdef HAVE_WRITEV + return writev(hd->fd, iov, iovcnt); +#else + // emulating writev() + ssize_t total = 0; + + for (int j = 0; j < iovcnt; j++) { + size_t sent = 0; + size_t len = iov[j].iov_len; + char *data = iov[j].iov_base; + + if (hd->client_trace) { + fwrite(data, 1, len, hd->client_trace); + } + + while (sent < len) { + ssize_t ret = send(hd->fd, data + sent, len - sent, 0); + + if (ret < 0) + return total ? total : ret; + + sent += ret; + total += ret; + } + } + + return total; +#endif +} + /* inline is used to avoid a gcc warning if used in mini-eagain */ inline static int wrap_pull_timeout_func(gnutls_transport_ptr_t ptr, unsigned int ms) @@ -588,6 +627,7 @@ socket_open2(socket_st * hd, const char *hostname, const char *service, hd->client_trace = client_trace; gnutls_transport_set_push_function(hd->session, wrap_push); + gnutls_transport_set_vec_push_function(hd->session, wrap_vec_push); gnutls_transport_set_pull_function(hd->session, wrap_pull); gnutls_transport_set_pull_timeout_function(hd->session, wrap_pull_timeout_func); gnutls_transport_set_ptr(hd->session, hd); |