mirror of
https://code.videolan.org/videolan/vlc
synced 2024-09-28 23:09:59 +02:00
tls: add dedicated helpers for I/O
This commit is contained in:
parent
04d62b00d2
commit
58686f3ce1
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user