sockets: Replace select() with poll()
select() has been deprecated for a very long time and is considered harmfullibvncclient-integration
parent
fe239b3e54
commit
34ad07b267
141
src/sockets.c
141
src/sockets.c
|
@ -28,6 +28,7 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <poll.h>
|
||||||
#include "rfb/rfbclient.h"
|
#include "rfb/rfbclient.h"
|
||||||
#include "sockets.h"
|
#include "sockets.h"
|
||||||
#include "tls.h"
|
#include "tls.h"
|
||||||
|
@ -94,96 +95,86 @@ rfbBool ReadFromRFBServer(rfbClient* client, char *out, unsigned int n)
|
||||||
rfbBool
|
rfbBool
|
||||||
WriteToRFBServer(rfbClient* client, const char *buf, unsigned int n)
|
WriteToRFBServer(rfbClient* client, const char *buf, unsigned int n)
|
||||||
{
|
{
|
||||||
fd_set fds;
|
struct pollfd fds;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int j;
|
int j;
|
||||||
const char *obuf = buf;
|
const char *obuf = buf;
|
||||||
#ifdef LIBVNCSERVER_HAVE_SASL
|
#ifdef LIBVNCSERVER_HAVE_SASL
|
||||||
const char *output;
|
const char *output;
|
||||||
unsigned int outputlen;
|
unsigned int outputlen;
|
||||||
int err;
|
int err;
|
||||||
#endif /* LIBVNCSERVER_HAVE_SASL */
|
#endif /* LIBVNCSERVER_HAVE_SASL */
|
||||||
|
|
||||||
if (client->serverPort==-1)
|
if (client->serverPort==-1)
|
||||||
return TRUE; /* vncrec playing */
|
return TRUE; /* vncrec playing */
|
||||||
|
|
||||||
if (client->tlsSession) {
|
if (client->tlsSession) {
|
||||||
/* WriteToTLS() will guarantee either everything is written, or error/eof returns */
|
/* WriteToTLS() will guarantee either everything is written, or error/eof returns */
|
||||||
i = WriteToTLS(client, buf, n);
|
i = WriteToTLS(client, buf, n);
|
||||||
if (i <= 0) return FALSE;
|
if (i <= 0) return FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
|
||||||
#ifdef LIBVNCSERVER_HAVE_SASL
|
|
||||||
if (client->saslconn) {
|
|
||||||
err = sasl_encode(client->saslconn,
|
|
||||||
buf, n,
|
|
||||||
&output, &outputlen);
|
|
||||||
if (err != SASL_OK) {
|
|
||||||
rfbClientLog("Failed to encode SASL data %s",
|
|
||||||
sasl_errstring(err, NULL, NULL));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
obuf = output;
|
|
||||||
n = outputlen;
|
|
||||||
}
|
|
||||||
#endif /* LIBVNCSERVER_HAVE_SASL */
|
|
||||||
|
|
||||||
while (i < n) {
|
|
||||||
j = write(client->sock, obuf + i, (n - i));
|
|
||||||
if (j <= 0) {
|
|
||||||
if (j < 0) {
|
|
||||||
if (errno == EWOULDBLOCK ||
|
|
||||||
errno == EAGAIN) {
|
|
||||||
FD_ZERO(&fds);
|
|
||||||
FD_SET(client->sock,&fds);
|
|
||||||
|
|
||||||
if (select(client->sock+1, NULL, &fds, NULL, NULL) <= 0) {
|
|
||||||
rfbClientErr("select\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
j = 0;
|
|
||||||
} else {
|
|
||||||
rfbClientErr("write\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
} else {
|
#ifdef LIBVNCSERVER_HAVE_SASL
|
||||||
rfbClientLog("write failed\n");
|
if (client->saslconn) {
|
||||||
return FALSE;
|
err = sasl_encode(client->saslconn,
|
||||||
}
|
buf, n,
|
||||||
}
|
&output, &outputlen);
|
||||||
i += j;
|
if (err != SASL_OK) {
|
||||||
}
|
rfbClientLog("Failed to encode SASL data %s",
|
||||||
return TRUE;
|
sasl_errstring(err, NULL, NULL));
|
||||||
}
|
return FALSE;
|
||||||
|
}
|
||||||
|
obuf = output;
|
||||||
|
n = outputlen;
|
||||||
|
}
|
||||||
|
#endif /* LIBVNCSERVER_HAVE_SASL */
|
||||||
|
|
||||||
|
// TODO: Dispatch events while waiting
|
||||||
|
while (i < n) {
|
||||||
|
j = write(client->sock, obuf + i, (n - i));
|
||||||
|
if (j <= 0) {
|
||||||
|
if (j < 0) {
|
||||||
|
if (errno == EWOULDBLOCK || errno == EAGAIN) {
|
||||||
|
fds.fd = client->sock;
|
||||||
|
fds.events = POLLIN;
|
||||||
|
|
||||||
|
if (poll(&fds, 1, -1) <= 0) {
|
||||||
|
rfbClientErr("select\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
j = 0;
|
||||||
|
} else {
|
||||||
|
rfbClientErr("write\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rfbClientLog("write failed\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i += j;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static rfbBool WaitForConnected(int socket, unsigned int secs)
|
static rfbBool WaitForConnected(int socket, unsigned int secs)
|
||||||
{
|
{
|
||||||
fd_set writefds;
|
struct pollfd fds = {
|
||||||
fd_set exceptfds;
|
.fd = socket,
|
||||||
struct timeval timeout;
|
.events = POLLIN | POLLOUT | POLLERR | POLLHUP,
|
||||||
|
};
|
||||||
|
|
||||||
timeout.tv_sec=secs;
|
if (poll(&fds, 1, secs * 1000) != 1)
|
||||||
timeout.tv_usec=0;
|
return FALSE;
|
||||||
|
|
||||||
FD_ZERO(&writefds);
|
int so_error = 0;
|
||||||
FD_SET(socket, &writefds);
|
socklen_t len = sizeof(so_error);
|
||||||
FD_ZERO(&exceptfds);
|
getsockopt(socket, SOL_SOCKET, SO_ERROR, &so_error, &len);
|
||||||
FD_SET(socket, &exceptfds);
|
|
||||||
if (select(socket+1, NULL, &writefds, &exceptfds, &timeout)==1) {
|
|
||||||
int so_error;
|
|
||||||
socklen_t len = sizeof so_error;
|
|
||||||
getsockopt(socket, SOL_SOCKET, SO_ERROR, &so_error, &len);
|
|
||||||
if (so_error!=0)
|
|
||||||
return FALSE;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
return so_error == 0 ? TRUE : FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
rfbSocket
|
rfbSocket
|
||||||
ConnectClientToTcpAddr(unsigned int host, int port)
|
ConnectClientToTcpAddr(unsigned int host, int port)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue