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>
pull/1/head
Christian Beier 14 years ago
parent 0df84e5c27
commit c0373e9cd4

@ -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)
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)
} }
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)
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);
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); close(rfbScreen->httpSock);
rfbScreen->httpSock=-1; rfbScreen->httpSock=-1;
return; return;
} }
#endif #endif
if(!rfbSetNonBlocking(rfbScreen->httpSock)) {
close(rfbScreen->httpSock);
rfbScreen->httpSock=-1;
return;
}
/*AddEnabledDevice(httpSock);*/ /*AddEnabledDevice(httpSock);*/
} }
} }

@ -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)
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)
return -1; return -1;
} }
#ifndef WIN32 if(!rfbSetNonBlocking(sock)) {
if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) { closesocket(sock);
rfbLogPerror("rfbCheckFds: fcntl");
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,
return -1; return -1;
} }
#ifndef WIN32 if(!rfbSetNonBlocking(sock)) {
if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) { closesocket(sock);
rfbLogPerror("fcntl failed");
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,
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);
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 */

Loading…
Cancel
Save