diff options
Diffstat (limited to 'libvncserver/sockets.c')
-rwxr-xr-x | libvncserver/sockets.c | 168 |
1 files changed, 86 insertions, 82 deletions
diff --git a/libvncserver/sockets.c b/libvncserver/sockets.c index fb61fcd..a4c6cad 100755 --- a/libvncserver/sockets.c +++ b/libvncserver/sockets.c @@ -213,7 +213,7 @@ void rfbShutdownSockets(rfbScreenInfoPtr rfbScreen) * rfbProcessClientMessage, etc). */ -void +int rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec) { int nfds; @@ -232,108 +232,112 @@ rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec) rfbScreen->inetdInitDone = TRUE; } - memcpy((char *)&fds, (char *)&(rfbScreen->allFds), sizeof(fd_set)); - tv.tv_sec = 0; - tv.tv_usec = usec; - nfds = select(rfbScreen->maxFd + 1, &fds, NULL, NULL /* &fds */, &tv); - if (nfds == 0) { - return; - } - if (nfds < 0) { + do { + memcpy((char *)&fds, (char *)&(rfbScreen->allFds), sizeof(fd_set)); + tv.tv_sec = 0; + tv.tv_usec = usec; + nfds = select(rfbScreen->maxFd + 1, &fds, NULL, NULL /* &fds */, &tv); + if (nfds == 0) { + return 0; + } + if (nfds < 0) { #ifdef WIN32 - errno = WSAGetLastError(); + errno = WSAGetLastError(); #endif - if (errno != EINTR) + if (errno != EINTR) rfbLogPerror("rfbCheckFds: select"); - return; - } + return 0; + } - if (rfbScreen->listenSock != -1 && FD_ISSET(rfbScreen->listenSock, &fds)) { + if (rfbScreen->listenSock != -1 && FD_ISSET(rfbScreen->listenSock, &fds)) { - if ((sock = accept(rfbScreen->listenSock, - (struct sockaddr *)&addr, &addrlen)) < 0) { - rfbLogPerror("rfbCheckFds: accept"); - return; - } + if ((sock = accept(rfbScreen->listenSock, + (struct sockaddr *)&addr, &addrlen)) < 0) { + rfbLogPerror("rfbCheckFds: accept"); + return 0; + } #ifndef WIN32 - if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) { - rfbLogPerror("rfbCheckFds: fcntl"); - closesocket(sock); - return; - } + if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) { + rfbLogPerror("rfbCheckFds: fcntl"); + closesocket(sock); + return 0; + } #endif - if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, - (char *)&one, sizeof(one)) < 0) { - rfbLogPerror("rfbCheckFds: setsockopt"); - closesocket(sock); - return; - } + if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, + (char *)&one, sizeof(one)) < 0) { + rfbLogPerror("rfbCheckFds: setsockopt"); + closesocket(sock); + return 0; + } #ifdef USE_LIBWRAP - if(!hosts_ctl("vnc",STRING_UNKNOWN,inet_ntoa(addr.sin_addr), - STRING_UNKNOWN)) { - rfbLog("Rejected connection from client %s\n", - inet_ntoa(addr.sin_addr)); - closesocket(sock); - return; - } + if(!hosts_ctl("vnc",STRING_UNKNOWN,inet_ntoa(addr.sin_addr), + STRING_UNKNOWN)) { + rfbLog("Rejected connection from client %s\n", + inet_ntoa(addr.sin_addr)); + closesocket(sock); + return 0; + } #endif - rfbLog("Got connection from client %s\n", inet_ntoa(addr.sin_addr)); + rfbLog("Got connection from client %s\n", inet_ntoa(addr.sin_addr)); - rfbNewClient(rfbScreen,sock); - - FD_CLR(rfbScreen->listenSock, &fds); - if (--nfds == 0) - return; - } + rfbNewClient(rfbScreen,sock); + + FD_CLR(rfbScreen->listenSock, &fds); + if (--nfds == 0) + return 0; + } - if ((rfbScreen->udpSock != -1) && FD_ISSET(rfbScreen->udpSock, &fds)) { - if(!rfbScreen->udpClient) - rfbNewUDPClient(rfbScreen); - if (recvfrom(rfbScreen->udpSock, buf, 1, MSG_PEEK, - (struct sockaddr *)&addr, &addrlen) < 0) { - rfbLogPerror("rfbCheckFds: UDP: recvfrom"); - rfbDisconnectUDPSock(rfbScreen); - rfbScreen->udpSockConnected = FALSE; - } else { - if (!rfbScreen->udpSockConnected || - (memcmp(&addr, &rfbScreen->udpRemoteAddr, addrlen) != 0)) - { - /* new remote end */ - rfbLog("rfbCheckFds: UDP: got connection\n"); - - memcpy(&rfbScreen->udpRemoteAddr, &addr, addrlen); - rfbScreen->udpSockConnected = TRUE; - - if (connect(rfbScreen->udpSock, - (struct sockaddr *)&addr, addrlen) < 0) { - rfbLogPerror("rfbCheckFds: UDP: connect"); - rfbDisconnectUDPSock(rfbScreen); - return; + if ((rfbScreen->udpSock != -1) && FD_ISSET(rfbScreen->udpSock, &fds)) { + if(!rfbScreen->udpClient) + rfbNewUDPClient(rfbScreen); + if (recvfrom(rfbScreen->udpSock, buf, 1, MSG_PEEK, + (struct sockaddr *)&addr, &addrlen) < 0) { + rfbLogPerror("rfbCheckFds: UDP: recvfrom"); + rfbDisconnectUDPSock(rfbScreen); + rfbScreen->udpSockConnected = FALSE; + } else { + if (!rfbScreen->udpSockConnected || + (memcmp(&addr, &rfbScreen->udpRemoteAddr, addrlen) != 0)) + { + /* new remote end */ + rfbLog("rfbCheckFds: UDP: got connection\n"); + + memcpy(&rfbScreen->udpRemoteAddr, &addr, addrlen); + rfbScreen->udpSockConnected = TRUE; + + if (connect(rfbScreen->udpSock, + (struct sockaddr *)&addr, addrlen) < 0) { + rfbLogPerror("rfbCheckFds: UDP: connect"); + rfbDisconnectUDPSock(rfbScreen); + return 0; + } + + rfbNewUDPConnection(rfbScreen,rfbScreen->udpSock); } - rfbNewUDPConnection(rfbScreen,rfbScreen->udpSock); + rfbProcessUDPInput(rfbScreen); } - rfbProcessUDPInput(rfbScreen); + FD_CLR(rfbScreen->udpSock, &fds); + if (--nfds == 0) + return 0; } - FD_CLR(rfbScreen->udpSock, &fds); - if (--nfds == 0) - return; - } - - i = rfbGetClientIterator(rfbScreen); - while((cl = rfbClientIteratorNext(i))) { - if (cl->onHold) - continue; - if (FD_ISSET(cl->sock, &fds) && FD_ISSET(cl->sock, &(rfbScreen->allFds))) - rfbProcessClientMessage(cl); - } - rfbReleaseClientIterator(i); + i = rfbGetClientIterator(rfbScreen); + while((cl = rfbClientIteratorNext(i))) { + if (cl->onHold) + continue; + if (FD_ISSET(cl->sock, &fds) && + FD_ISSET(cl->sock, &(rfbScreen->allFds))) + rfbProcessClientMessage(cl); + } + rfbReleaseClientIterator(i); + } while(rfbScreen->handleEventsEagerly); + return 1; } |