summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Rühsen <tim.ruehsen@gmx.de>2019-04-10 17:53:09 +0200
committerTim Rühsen <tim.ruehsen@gmx.de>2019-04-10 17:54:06 +0200
commit31db29a0d434374f26a92c4998b3667cf31e3a31 (patch)
tree3831770923fc0b61ba3a353cdbb54457fa2bc31e
parent12bfa526605d2eb078e0244dc47ea21c2033491d (diff)
downloadgnutls-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.c40
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);