Commit c0373e9c authored by Christian Beier's avatar Christian Beier

Non-blocking sockets for Windows.

Expands the SetNonBlocking() function in libvncclient/sockets.c to also
work under Windows and also changes it to honour maybe already present
socket flags.

A similar function was introduced for libvncserver as well and
all the #ifdef'ed fnctl calls replaced with calls to that one.
Signed-off-by: 's avatarChristian Beier <dontmind@freeshell.org>
parent 0df84e5c
......@@ -11,7 +11,6 @@ style fixes: use Linux' coding guidelines & ANSIfy tightvnc-filetransfer:
LibVNCClient cleanup: prefix with "rfbClient", and make sure it does
not deliberately die() or exit() anywhere!
java vncviewer doesn't do colour cursors?
MinGW32 doesn't do fcntl on sockets; use setsockopt instead...
make corre work again (libvncclient or libvncserver?)
teach SDLvncviewer about CopyRect...
implement "-record" in libvncclient
......
......@@ -551,14 +551,17 @@ AcceptTcpConnection(int listenSock)
rfbBool
SetNonBlocking(int sock)
{
#ifndef __MINGW32__
if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) {
rfbClientErr("AcceptTcpConnection: fcntl\n");
return FALSE;
}
#ifdef WIN32
unsigned long block=1;
if(ioctlsocket(sock, FIONBIO, &block) == SOCKET_ERROR) {
errno=WSAGetLastError();
#else
rfbClientErr("O_NONBLOCK on MinGW32 NOT IMPLEMENTED\n");
int flags = fcntl(sock, F_GETFL);
if(flags < 0 || fcntl(sock, F_SETFL, flags | O_NONBLOCK) < 0) {
#endif
rfbClientErr("Setting socket to non-blocking failed: %s\n",strerror(errno));
return FALSE;
}
return TRUE;
}
......
......@@ -181,7 +181,6 @@ rfbHttpCheckFds(rfbScreenInfoPtr rfbScreen)
}
if (FD_ISSET(rfbScreen->httpListenSock, &fds)) {
int flags;
if (rfbScreen->httpSock >= 0) close(rfbScreen->httpSock);
if ((rfbScreen->httpSock = accept(rfbScreen->httpListenSock,
......@@ -189,35 +188,21 @@ rfbHttpCheckFds(rfbScreenInfoPtr rfbScreen)
rfbLogPerror("httpCheckFds: accept");
return;
}
#ifdef __MINGW32__
rfbErr("O_NONBLOCK on MinGW32 NOT IMPLEMENTED");
#else
#ifdef USE_LIBWRAP
if(!hosts_ctl("vnc",STRING_UNKNOWN,inet_ntoa(addr.sin_addr),
STRING_UNKNOWN)) {
rfbLog("Rejected HTTP connection from client %s\n",
inet_ntoa(addr.sin_addr));
#else
flags = fcntl(rfbScreen->httpSock, F_GETFL);
if (flags < 0 || fcntl(rfbScreen->httpSock, F_SETFL, flags | O_NONBLOCK) == -1) {
rfbLogPerror("httpCheckFds: fcntl");
#endif
close(rfbScreen->httpSock);
rfbScreen->httpSock = -1;
return;
}
flags=fcntl(rfbScreen->httpSock,F_GETFL);
if(flags==-1 ||
fcntl(rfbScreen->httpSock,F_SETFL,flags|O_NONBLOCK)==-1) {
rfbLogPerror("httpCheckFds: fcntl");
close(rfbScreen->httpSock);
rfbScreen->httpSock=-1;
return;
}
#endif
if(!rfbSetNonBlocking(rfbScreen->httpSock)) {
close(rfbScreen->httpSock);
rfbScreen->httpSock=-1;
return;
}
/*AddEnabledDevice(httpSock);*/
}
}
......
......@@ -299,13 +299,10 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen,
}
rfbReleaseClientIterator(iterator);
#ifndef WIN32
if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) {
rfbLogPerror("fcntl failed");
if(!rfbSetNonBlocking(sock)) {
close(sock);
return NULL;
}
#endif
if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
(char *)&one, sizeof(one)) < 0) {
......
......@@ -116,12 +116,8 @@ rfbInitSockets(rfbScreenInfoPtr rfbScreen)
if (rfbScreen->inetdSock != -1) {
const int one = 1;
#ifndef WIN32
if (fcntl(rfbScreen->inetdSock, F_SETFL, O_NONBLOCK) < 0) {
rfbLogPerror("fcntl");
if(!rfbSetNonBlocking(rfbScreen->inetdSock))
return;
}
#endif
if (setsockopt(rfbScreen->inetdSock, IPPROTO_TCP, TCP_NODELAY,
(char *)&one, sizeof(one)) < 0) {
......@@ -270,13 +266,10 @@ rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec)
return -1;
}
#ifndef WIN32
if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) {
rfbLogPerror("rfbCheckFds: fcntl");
closesocket(sock);
if(!rfbSetNonBlocking(sock)) {
closesocket(sock);
return -1;
}
#endif
if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
(char *)&one, sizeof(one)) < 0) {
......@@ -418,13 +411,10 @@ rfbConnect(rfbScreenInfoPtr rfbScreen,
return -1;
}
#ifndef WIN32
if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) {
rfbLogPerror("fcntl failed");
closesocket(sock);
if(!rfbSetNonBlocking(sock)) {
closesocket(sock);
return -1;
}
#endif
if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
(char *)&one, sizeof(one)) < 0) {
......@@ -705,3 +695,23 @@ rfbListenOnUDPPort(int port,
return sock;
}
/*
* rfbSetNonBlocking sets a socket into non-blocking mode.
*/
rfbBool
rfbSetNonBlocking(int sock)
{
#ifdef WIN32
unsigned long block=1;
if(ioctlsocket(sock, FIONBIO, &block) == SOCKET_ERROR) {
errno=WSAGetLastError();
#else
int flags = fcntl(sock, F_GETFL);
if(flags < 0 || fcntl(sock, F_SETFL, flags | O_NONBLOCK) < 0) {
#endif
rfbLogPerror("Setting socket to non-blocking failed");
return FALSE;
}
return TRUE;
}
......@@ -664,6 +664,7 @@ extern int rfbConnectToTcpAddr(char* host, int port);
extern int rfbListenOnTCPPort(int port, in_addr_t iface);
extern int rfbListenOnUDPPort(int port, in_addr_t iface);
extern int rfbStringToAddr(char* string,in_addr_t* addr);
extern rfbBool rfbSetNonBlocking(int sock);
/* rfbserver.c */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment