vlc | branch: master | Rémi Denis-Courmont <[email protected]> | 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; +} _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
