summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Beier <dontmind@freeshell.org>2010-09-07 17:43:58 +0200
committerChristian Beier <dontmind@freeshell.org>2010-09-13 14:19:15 +0200
commitc0373e9cd48b0fc22ac295fdab51a29e3df7a0cd (patch)
tree253b193dfb1805cd6de337f26cf6f82e74a42cad
parent0df84e5c27eefad8b731b12d58f8fbede71823e0 (diff)
downloadlibtdevnc-c0373e9c.tar.gz
libtdevnc-c0373e9c.zip
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: Christian Beier <dontmind@freeshell.org>
-rw-r--r--TODO1
-rw-r--r--libvncclient/sockets.c15
-rwxr-xr-xlibvncserver/httpd.c25
-rw-r--r--libvncserver/rfbserver.c5
-rwxr-xr-xlibvncserver/sockets.c40
-rw-r--r--rfb/rfb.h1
6 files changed, 41 insertions, 46 deletions
diff --git a/TODO b/TODO
index 2afffc8..d9e2721 100644
--- a/TODO
+++ b/TODO
@@ -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
diff --git a/libvncclient/sockets.c b/libvncclient/sockets.c
index 0171a5c..28b0256 100644
--- a/libvncclient/sockets.c
+++ b/libvncclient/sockets.c
@@ -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;
}
diff --git a/libvncserver/httpd.c b/libvncserver/httpd.c
index c183543..320e6d2 100755
--- a/libvncserver/httpd.c
+++ b/libvncserver/httpd.c
@@ -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);*/
}
}
diff --git a/libvncserver/rfbserver.c b/libvncserver/rfbserver.c
index 471dac3..5f8d22a 100644
--- a/libvncserver/rfbserver.c
+++ b/libvncserver/rfbserver.c
@@ -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) {
diff --git a/libvncserver/sockets.c b/libvncserver/sockets.c
index fa7ea92..01f5642 100755
--- a/libvncserver/sockets.c
+++ b/libvncserver/sockets.c
@@ -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;
+}
diff --git a/rfb/rfb.h b/rfb/rfb.h
index 006cc2e..e58e59e 100644
--- a/rfb/rfb.h
+++ b/rfb/rfb.h
@@ -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 */