diff options
author | Christian Beier <dontmind@freeshell.org> | 2010-09-07 17:43:58 +0200 |
---|---|---|
committer | Christian Beier <dontmind@freeshell.org> | 2010-09-13 14:19:15 +0200 |
commit | c0373e9cd48b0fc22ac295fdab51a29e3df7a0cd (patch) | |
tree | 253b193dfb1805cd6de337f26cf6f82e74a42cad | |
parent | 0df84e5c27eefad8b731b12d58f8fbede71823e0 (diff) | |
download | libvncserver-c0373e9cd48b0fc22ac295fdab51a29e3df7a0cd.zip libvncserver-c0373e9cd48b0fc22ac295fdab51a29e3df7a0cd.tar.gz |
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-- | TODO | 1 | ||||
-rw-r--r-- | libvncclient/sockets.c | 15 | ||||
-rwxr-xr-x | libvncserver/httpd.c | 25 | ||||
-rw-r--r-- | libvncserver/rfbserver.c | 5 | ||||
-rwxr-xr-x | libvncserver/sockets.c | 40 | ||||
-rw-r--r-- | rfb/rfb.h | 1 |
6 files changed, 41 insertions, 46 deletions
@@ -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; +} @@ -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 */ |