From 8c1e1831c4a11202aa6881dafe8b6de0bd5c73a4 Mon Sep 17 00:00:00 2001 From: Tobias Junghans Date: Tue, 24 Jan 2023 11:19:07 +0100 Subject: [PATCH] Revert "Revert "libvncclient: use poll() if available"" This reverts commit 7dd27504951ef141156b2d5ba29ba023e53aab34. --- CMakeLists.txt | 2 ++ include/rfb/rfbconfig.h.cmakein | 6 ++++++ src/common/sockets.c | 13 ++++++++++++- src/common/sockets.h | 5 +++++ src/libvncclient/sockets.c | 29 +++++++++++++++++++++++++++++ 5 files changed, 54 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0e391f422..00342b9cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -183,6 +183,7 @@ check_include_file("dirent.h" LIBVNCSERVER_HAVE_DIRENT_H) check_include_file("endian.h" LIBVNCSERVER_HAVE_ENDIAN_H) check_include_file("fcntl.h" LIBVNCSERVER_HAVE_FCNTL_H) check_include_file("netinet/in.h" LIBVNCSERVER_HAVE_NETINET_IN_H) +check_include_file("poll.h" LIBVNCSERVER_HAVE_POLL_H) check_include_file("sys/endian.h" LIBVNCSERVER_HAVE_SYS_ENDIAN_H) check_include_file("sys/socket.h" LIBVNCSERVER_HAVE_SYS_SOCKET_H) check_include_file("sys/stat.h" LIBVNCSERVER_HAVE_SYS_STAT_H) @@ -218,6 +219,7 @@ check_function_exists(inet_ntoa LIBVNCSERVER_HAVE_INET_NTOA) check_function_exists(memmove LIBVNCSERVER_HAVE_MEMMOVE) check_function_exists(memset LIBVNCSERVER_HAVE_MEMSET) check_function_exists(mkfifo LIBVNCSERVER_HAVE_MKFIFO) +check_function_exists(poll LIBVNCSERVER_HAVE_POLL) check_function_exists(select LIBVNCSERVER_HAVE_SELECT) check_function_exists(socket LIBVNCSERVER_HAVE_SOCKET) check_function_exists(strchr LIBVNCSERVER_HAVE_STRCHR) diff --git a/include/rfb/rfbconfig.h.cmakein b/include/rfb/rfbconfig.h.cmakein index d50c3c965..1271282ac 100644 --- a/include/rfb/rfbconfig.h.cmakein +++ b/include/rfb/rfbconfig.h.cmakein @@ -42,6 +42,9 @@ /* Define to 1 if you have the `mkfifo' function. */ #cmakedefine LIBVNCSERVER_HAVE_MKFIFO 1 +/* Define to 1 if you have the `poll' function. */ +#cmakedefine LIBVNCSERVER_HAVE_POLL 1 + /* Define to 1 if you have the `select' function. */ #cmakedefine LIBVNCSERVER_HAVE_SELECT 1 @@ -84,6 +87,9 @@ /* Define to 1 if you have the header file. */ #cmakedefine LIBVNCSERVER_HAVE_NETINET_IN_H 1 +/* Define to 1 if you have the header file. */ +#cmakedefine LIBVNCSERVER_HAVE_POLL_H 1 + /* Define to 1 if you have the header file. */ #cmakedefine LIBVNCSERVER_HAVE_SYS_ENDIAN_H 1 diff --git a/src/common/sockets.c b/src/common/sockets.c index de66fa768..9ffa47b96 100644 --- a/src/common/sockets.c +++ b/src/common/sockets.c @@ -53,6 +53,15 @@ rfbBool sock_set_nonblocking(rfbSocket sock, rfbBool non_blocking, void (*log)(c rfbBool sock_wait_for_connected(int socket, unsigned int timeout_seconds) { +#ifdef LIBVNCSERVER_HAVE_POLL + struct pollfd pfd; + pfd.fd = socket; + pfd.events = POLLIN | POLLPRI; + + if (poll(&pfd, 1, timeout_seconds*1000)==1) { + if ((pfd.revents & POLLERR) || (pfd.revents & POLLHUP)) + return FALSE; +#else fd_set writefds; fd_set exceptfds; struct timeval timeout; @@ -68,7 +77,9 @@ rfbBool sock_wait_for_connected(int socket, unsigned int timeout_seconds) #ifdef WIN32 if (FD_ISSET(socket, &exceptfds)) return FALSE; -#else +#endif +#endif +#ifndef WIN32 int so_error; socklen_t len = sizeof so_error; getsockopt(socket, SOL_SOCKET, SO_ERROR, &so_error, &len); diff --git a/src/common/sockets.h b/src/common/sockets.h index 99a2f15e8..b7f41ca2e 100644 --- a/src/common/sockets.h +++ b/src/common/sockets.h @@ -64,6 +64,11 @@ #include #endif +#include "rfb/rfbconfig.h" +#if LIBVNCSERVER_HAVE_POLL_H +#include +#endif + /* Common internal socket functions */ diff --git a/src/libvncclient/sockets.c b/src/libvncclient/sockets.c index 1bd41818f..f97138633 100644 --- a/src/libvncclient/sockets.c +++ b/src/libvncclient/sockets.c @@ -249,7 +249,11 @@ ReadFromRFBServer(rfbClient* client, char *out, unsigned int n) rfbBool WriteToRFBServer(rfbClient* client, const char *buf, unsigned int n) { +#ifdef LIBVNCSERVER_HAVE_POLL + struct pollfd pfd; +#else fd_set fds; +#endif int i = 0; int j; const char *obuf = buf; @@ -296,6 +300,18 @@ WriteToRFBServer(rfbClient* client, const char *buf, unsigned int n) errno == ENOENT || #endif errno == EAGAIN) { +#ifdef LIBVNCSERVER_HAVE_POLL + struct pollfd pfd; + pfd.fd = client->sock; + pfd.events = POLLOUT; + + if (poll(&pfd, 1, -1) <= 0) { + if ((pfd.revents & POLLERR) || (pfd.revents & POLLHUP)) { + rfbClientErr("poll\n"); + return FALSE; + } + } +#else FD_ZERO(&fds); FD_SET(client->sock,&fds); @@ -303,6 +319,7 @@ WriteToRFBServer(rfbClient* client, const char *buf, unsigned int n) rfbClientErr("select\n"); return FALSE; } +#endif j = 0; } else { rfbClientErr("write\n"); @@ -847,14 +864,25 @@ PrintInHex(char *buf, int len) int WaitForMessage(rfbClient* client,unsigned int usecs) { +#ifdef LIBVNCSERVER_HAVE_POLL + struct pollfd pfd; +#else fd_set fds; struct timeval timeout; +#endif int num; if (client->serverPort==-1) /* playing back vncrec file */ return 1; +#ifdef LIBVNCSERVER_HAVE_POLL + pfd.fd = client->sock; + pfd.events = POLLIN | POLLPRI; + num = poll(&pfd, 1, usecs/1000); + if ((pfd.revents & POLLERR) || (pfd.revents & POLLHUP)) + return -1; +#else timeout.tv_sec=(usecs/1000000); timeout.tv_usec=(usecs%1000000); @@ -862,6 +890,7 @@ int WaitForMessage(rfbClient* client,unsigned int usecs) FD_SET(client->sock,&fds); num=select(client->sock+1, &fds, NULL, NULL, &timeout); +#endif if(num<0) { #ifdef WIN32 errno=WSAGetLastError();