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: ...@@ -11,7 +11,6 @@ style fixes: use Linux' coding guidelines & ANSIfy tightvnc-filetransfer:
LibVNCClient cleanup: prefix with "rfbClient", and make sure it does LibVNCClient cleanup: prefix with "rfbClient", and make sure it does
not deliberately die() or exit() anywhere! not deliberately die() or exit() anywhere!
java vncviewer doesn't do colour cursors? java vncviewer doesn't do colour cursors?
MinGW32 doesn't do fcntl on sockets; use setsockopt instead...
make corre work again (libvncclient or libvncserver?) make corre work again (libvncclient or libvncserver?)
teach SDLvncviewer about CopyRect... teach SDLvncviewer about CopyRect...
implement "-record" in libvncclient implement "-record" in libvncclient
......
...@@ -551,14 +551,17 @@ AcceptTcpConnection(int listenSock) ...@@ -551,14 +551,17 @@ AcceptTcpConnection(int listenSock)
rfbBool rfbBool
SetNonBlocking(int sock) SetNonBlocking(int sock)
{ {
#ifndef __MINGW32__ #ifdef WIN32
if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) { unsigned long block=1;
rfbClientErr("AcceptTcpConnection: fcntl\n"); if(ioctlsocket(sock, FIONBIO, &block) == SOCKET_ERROR) {
return FALSE; errno=WSAGetLastError();
}
#else #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 #endif
rfbClientErr("Setting socket to non-blocking failed: %s\n",strerror(errno));
return FALSE;
}
return TRUE; return TRUE;
} }
......
...@@ -181,7 +181,6 @@ rfbHttpCheckFds(rfbScreenInfoPtr rfbScreen) ...@@ -181,7 +181,6 @@ rfbHttpCheckFds(rfbScreenInfoPtr rfbScreen)
} }
if (FD_ISSET(rfbScreen->httpListenSock, &fds)) { if (FD_ISSET(rfbScreen->httpListenSock, &fds)) {
int flags;
if (rfbScreen->httpSock >= 0) close(rfbScreen->httpSock); if (rfbScreen->httpSock >= 0) close(rfbScreen->httpSock);
if ((rfbScreen->httpSock = accept(rfbScreen->httpListenSock, if ((rfbScreen->httpSock = accept(rfbScreen->httpListenSock,
...@@ -189,35 +188,21 @@ rfbHttpCheckFds(rfbScreenInfoPtr rfbScreen) ...@@ -189,35 +188,21 @@ rfbHttpCheckFds(rfbScreenInfoPtr rfbScreen)
rfbLogPerror("httpCheckFds: accept"); rfbLogPerror("httpCheckFds: accept");
return; return;
} }
#ifdef __MINGW32__
rfbErr("O_NONBLOCK on MinGW32 NOT IMPLEMENTED");
#else
#ifdef USE_LIBWRAP #ifdef USE_LIBWRAP
if(!hosts_ctl("vnc",STRING_UNKNOWN,inet_ntoa(addr.sin_addr), if(!hosts_ctl("vnc",STRING_UNKNOWN,inet_ntoa(addr.sin_addr),
STRING_UNKNOWN)) { STRING_UNKNOWN)) {
rfbLog("Rejected HTTP connection from client %s\n", rfbLog("Rejected HTTP connection from client %s\n",
inet_ntoa(addr.sin_addr)); 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); close(rfbScreen->httpSock);
rfbScreen->httpSock = -1; rfbScreen->httpSock=-1;
return; return;
} }
#endif
flags=fcntl(rfbScreen->httpSock,F_GETFL); if(!rfbSetNonBlocking(rfbScreen->httpSock)) {
if(flags==-1 ||
fcntl(rfbScreen->httpSock,F_SETFL,flags|O_NONBLOCK)==-1) {
rfbLogPerror("httpCheckFds: fcntl");
close(rfbScreen->httpSock); close(rfbScreen->httpSock);
rfbScreen->httpSock=-1; rfbScreen->httpSock=-1;
return; return;
} }
#endif
/*AddEnabledDevice(httpSock);*/ /*AddEnabledDevice(httpSock);*/
} }
} }
......
...@@ -299,13 +299,10 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen, ...@@ -299,13 +299,10 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen,
} }
rfbReleaseClientIterator(iterator); rfbReleaseClientIterator(iterator);
#ifndef WIN32 if(!rfbSetNonBlocking(sock)) {
if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) {
rfbLogPerror("fcntl failed");
close(sock); close(sock);
return NULL; return NULL;
} }
#endif
if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
(char *)&one, sizeof(one)) < 0) { (char *)&one, sizeof(one)) < 0) {
......
...@@ -116,12 +116,8 @@ rfbInitSockets(rfbScreenInfoPtr rfbScreen) ...@@ -116,12 +116,8 @@ rfbInitSockets(rfbScreenInfoPtr rfbScreen)
if (rfbScreen->inetdSock != -1) { if (rfbScreen->inetdSock != -1) {
const int one = 1; const int one = 1;
#ifndef WIN32 if(!rfbSetNonBlocking(rfbScreen->inetdSock))
if (fcntl(rfbScreen->inetdSock, F_SETFL, O_NONBLOCK) < 0) {
rfbLogPerror("fcntl");
return; return;
}
#endif
if (setsockopt(rfbScreen->inetdSock, IPPROTO_TCP, TCP_NODELAY, if (setsockopt(rfbScreen->inetdSock, IPPROTO_TCP, TCP_NODELAY,
(char *)&one, sizeof(one)) < 0) { (char *)&one, sizeof(one)) < 0) {
...@@ -270,13 +266,10 @@ rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec) ...@@ -270,13 +266,10 @@ rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec)
return -1; return -1;
} }
#ifndef WIN32 if(!rfbSetNonBlocking(sock)) {
if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) {
rfbLogPerror("rfbCheckFds: fcntl");
closesocket(sock); closesocket(sock);
return -1; return -1;
} }
#endif
if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
(char *)&one, sizeof(one)) < 0) { (char *)&one, sizeof(one)) < 0) {
...@@ -418,13 +411,10 @@ rfbConnect(rfbScreenInfoPtr rfbScreen, ...@@ -418,13 +411,10 @@ rfbConnect(rfbScreenInfoPtr rfbScreen,
return -1; return -1;
} }
#ifndef WIN32 if(!rfbSetNonBlocking(sock)) {
if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) {
rfbLogPerror("fcntl failed");
closesocket(sock); closesocket(sock);
return -1; return -1;
} }
#endif
if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
(char *)&one, sizeof(one)) < 0) { (char *)&one, sizeof(one)) < 0) {
...@@ -705,3 +695,23 @@ rfbListenOnUDPPort(int port, ...@@ -705,3 +695,23 @@ rfbListenOnUDPPort(int port,
return sock; 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); ...@@ -664,6 +664,7 @@ extern int rfbConnectToTcpAddr(char* host, int port);
extern int rfbListenOnTCPPort(int port, in_addr_t iface); extern int rfbListenOnTCPPort(int port, in_addr_t iface);
extern int rfbListenOnUDPPort(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 int rfbStringToAddr(char* string,in_addr_t* addr);
extern rfbBool rfbSetNonBlocking(int sock);
/* rfbserver.c */ /* 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