]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Wrap vec-push function in src/socket.c tmp-wrap-vec-push
authorTim Rühsen <tim.ruehsen@gmx.de>
Wed, 10 Apr 2019 15:53:09 +0000 (17:53 +0200)
committerTim Rühsen <tim.ruehsen@gmx.de>
Wed, 10 Apr 2019 15:54:06 +0000 (17:54 +0200)
Signed-off-by: Tim Rühsen <tim.ruehsen@gmx.de>
src/socket.c

index 9ba784fa3a751e7fc820f80a9997ccac04b9239f..a84dc7580e66d7b198b706cf17472ca38fd44873 100644 (file)
 #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);