[vlc-commits] tls: add dedicated helpers for I/O

Rémi Denis-Courmont git at videolan.org
Tue May 12 21:39:20 CEST 2015


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Thu May  7 23:59:01 2015 +0300| [58686f3ce16c5c5f1b04cb7db31d11f948893e32] | committer: Rémi Denis-Courmont

tls: add dedicated helpers for I/O

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=58686f3ce16c5c5f1b04cb7db31d11f948893e32
---

 include/vlc_tls.h  |    9 ++--
 src/libvlccore.sym |    3 ++
 src/network/tls.c  |  126 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 134 insertions(+), 4 deletions(-)

diff --git a/include/vlc_tls.h b/include/vlc_tls.h
index 9386d9a..d668098 100644
--- a/include/vlc_tls.h
+++ b/include/vlc_tls.h
@@ -52,11 +52,12 @@ int vlc_tls_SessionHandshake (vlc_tls_t *, const char *host, const char *serv,
                               char ** /*restrict*/ alp);
 VLC_API void vlc_tls_SessionDelete (vlc_tls_t *);
 
-/* NOTE: It is assumed that a->sock.p_sys = a */
-# define tls_Send( a, b, c ) (((vlc_tls_t *)a)->sock.pf_send (a, b, c))
-
-# define tls_Recv( a, b, c ) (((vlc_tls_t *)a)->sock.pf_recv (a, b, c))
+VLC_API int vlc_tls_Read(vlc_tls_t *, void *buf, size_t len, bool waitall);
+VLC_API char *vlc_tls_GetLine(vlc_tls_t *);
+VLC_API int vlc_tls_Write(vlc_tls_t *, const void *buf, size_t len);
 
+# define tls_Recv(a,b,c) vlc_tls_Read(a,b,c,false)
+# define tls_Send(a,b,c) vlc_tls_Write(a,b,c)
 
 /** TLS credentials (certificate, private and trust settings) */
 struct vlc_tls_creds
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index e89cf4e..5350f96 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -421,6 +421,9 @@ vlc_tls_ClientCreate
 vlc_tls_Delete
 vlc_tls_ClientSessionCreate
 vlc_tls_SessionDelete
+vlc_tls_Read
+vlc_tls_Write
+vlc_tls_GetLine
 ToCharset
 update_Check
 update_Delete
diff --git a/src/network/tls.c b/src/network/tls.c
index b740bf8..3565ec1 100644
--- a/src/network/tls.c
+++ b/src/network/tls.c
@@ -34,6 +34,9 @@
 # include <poll.h>
 #endif
 #include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
 
 #include <vlc_common.h>
 #include "libvlc.h"
@@ -233,3 +236,126 @@ error:
     vlc_tls_SessionDelete (session);
     return NULL;
 }
+
+int vlc_tls_Read(vlc_tls_t *session, void *buf, size_t len, bool waitall)
+{
+    struct pollfd ufd[2];
+
+    ufd[0].fd = session->fd;
+    ufd[0].events = POLLIN;
+    ufd[1].fd = vlc_object_waitpipe(session->p_parent);
+    ufd[1].events = POLLIN;
+
+    if (unlikely(ufd[1].fd == -1))
+    {
+        vlc_testcancel();
+        return -1;
+    }
+
+    for (size_t rcvd = 0;;)
+    {
+        ssize_t val = session->sock.pf_recv(session, buf, len);
+        if (val > 0)
+        {
+            if (!waitall)
+                return val;
+            buf = ((char *)buf) + val;
+            len -= val;
+            rcvd += val;
+        }
+        if (len == 0 || val == 0)
+            return rcvd;
+        if (val == -1 && errno != EINTR && errno != EAGAIN)
+            return rcvd ? (ssize_t)rcvd : -1;
+
+        val = poll(ufd, 2, -1);
+        if (val == -1)
+            continue;
+
+        if (ufd[1].revents)
+        {
+            if (rcvd > 0)
+                return rcvd;
+
+            msg_Dbg(session, "socket %d polling interrupted", session->fd);
+            errno = EINTR;
+            return -1;
+        }
+    }
+}
+
+int vlc_tls_Write(vlc_tls_t *session, const void *buf, size_t len)
+{
+    struct pollfd ufd[2];
+
+    ufd[0].fd = session->fd;
+    ufd[0].events = POLLOUT;
+    ufd[1].fd = vlc_object_waitpipe(session->p_parent);
+    ufd[1].events = POLLIN;
+
+    if (unlikely(ufd[1].fd == -1))
+    {
+        vlc_testcancel();
+        return -1;
+    }
+
+    for (size_t sent = 0;;)
+    {
+        ssize_t val = session->sock.pf_send(session, buf, len);
+        if (val > 0)
+        {
+            buf = ((const char *)buf) + val;
+            len -= val;
+            sent += val;
+        }
+        if (len == 0 || val == 0)
+            return sent;
+        if (val == -1 && errno != EINTR && errno != EAGAIN)
+            return sent ? (ssize_t)sent : -1;
+
+        val = poll(ufd, 2, -1);
+        if (val == -1)
+            continue;
+
+        if (ufd[1].revents)
+        {
+            if (sent > 0)
+                return sent;
+
+            msg_Dbg(session, "socket %d polling interrupted", session->fd);
+            errno = EINTR;
+            return -1;
+        }
+    }
+}
+
+char *vlc_tls_GetLine(vlc_tls_t *session)
+{
+    char *line = NULL;
+    size_t linelen = 0, linesize = 0;
+
+    do
+    {
+        if (linelen == linesize)
+        {
+            linesize += 1024;
+
+            char *newline = realloc(line, linesize);
+            if (unlikely(newline == NULL))
+                goto error;
+            line = newline;
+        }
+
+        if (vlc_tls_Read(session, line + linelen, 1, false) <= 0)
+            goto error;
+    }
+    while (line[linelen++] != '\n');
+
+    if (linelen >= 2 && line[linelen - 2] == '\r')
+        line[linelen - 2] = '\0';
+    return line;
+
+error:
+    free(line);
+    return NULL;
+}



More information about the vlc-commits mailing list