[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