Replace select() system call with poll()
poll() is specified in POSIX.1-2001 as a simpler interface for multiplexed file descriptors than select(). It also provides more functionality. This PR replaces the select() calls used in xrdp with poll() equivalents.
This commit is contained in:
parent
b414cfcd5e
commit
78fa1c15b2
@ -44,6 +44,7 @@
|
|||||||
#if defined(XRDP_ENABLE_VSOCK)
|
#if defined(XRDP_ENABLE_VSOCK)
|
||||||
#include <linux/vm_sockets.h>
|
#include <linux/vm_sockets.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <poll.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/times.h>
|
#include <sys/times.h>
|
||||||
@ -1594,26 +1595,24 @@ g_sck_socket_ok(int sck)
|
|||||||
int
|
int
|
||||||
g_sck_can_send(int sck, int millis)
|
g_sck_can_send(int sck, int millis)
|
||||||
{
|
{
|
||||||
fd_set wfds;
|
int rv = 0;
|
||||||
struct timeval time;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
time.tv_sec = millis / 1000;
|
|
||||||
time.tv_usec = (millis * 1000) % 1000000;
|
|
||||||
FD_ZERO(&wfds);
|
|
||||||
|
|
||||||
if (sck > 0)
|
if (sck > 0)
|
||||||
{
|
{
|
||||||
FD_SET(((unsigned int)sck), &wfds);
|
struct pollfd pollfd;
|
||||||
rv = select(sck + 1, 0, &wfds, 0, &time);
|
|
||||||
|
|
||||||
if (rv > 0)
|
pollfd.fd = sck;
|
||||||
|
pollfd.events = POLLOUT;
|
||||||
|
pollfd.revents = 0;
|
||||||
|
if (poll(&pollfd, 1, millis) > 0)
|
||||||
{
|
{
|
||||||
return 1;
|
if ((pollfd.revents & POLLOUT) != 0)
|
||||||
|
{
|
||||||
|
rv = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@ -1622,78 +1621,65 @@ g_sck_can_send(int sck, int millis)
|
|||||||
int
|
int
|
||||||
g_sck_can_recv(int sck, int millis)
|
g_sck_can_recv(int sck, int millis)
|
||||||
{
|
{
|
||||||
fd_set rfds;
|
int rv = 0;
|
||||||
struct timeval time;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
g_memset(&time, 0, sizeof(time));
|
|
||||||
time.tv_sec = millis / 1000;
|
|
||||||
time.tv_usec = (millis * 1000) % 1000000;
|
|
||||||
FD_ZERO(&rfds);
|
|
||||||
|
|
||||||
if (sck > 0)
|
if (sck > 0)
|
||||||
{
|
{
|
||||||
FD_SET(((unsigned int)sck), &rfds);
|
struct pollfd pollfd;
|
||||||
rv = select(sck + 1, &rfds, 0, 0, &time);
|
|
||||||
|
|
||||||
if (rv > 0)
|
pollfd.fd = sck;
|
||||||
|
pollfd.events = POLLIN;
|
||||||
|
pollfd.revents = 0;
|
||||||
|
if (poll(&pollfd, 1, millis) > 0)
|
||||||
{
|
{
|
||||||
return 1;
|
if ((pollfd.revents & (POLLIN | POLLHUP)) != 0)
|
||||||
|
{
|
||||||
|
rv = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
int
|
int
|
||||||
g_sck_select(int sck1, int sck2)
|
g_sck_select(int sck1, int sck2)
|
||||||
{
|
{
|
||||||
fd_set rfds;
|
struct pollfd pollfd[2] = {0};
|
||||||
struct timeval time;
|
int rvmask[2] = {0}; /* Output masks corresponding to fds in pollfd */
|
||||||
int max;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
g_memset(&time, 0, sizeof(struct timeval));
|
unsigned int i = 0;
|
||||||
FD_ZERO(&rfds);
|
int rv = 0;
|
||||||
|
|
||||||
if (sck1 > 0)
|
if (sck1 > 0)
|
||||||
{
|
{
|
||||||
FD_SET(((unsigned int)sck1), &rfds);
|
pollfd[i].fd = sck1;
|
||||||
|
pollfd[i].events = POLLIN;
|
||||||
|
rvmask[i] = 1;
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sck2 > 0)
|
if (sck2 > 0)
|
||||||
{
|
{
|
||||||
FD_SET(((unsigned int)sck2), &rfds);
|
pollfd[i].fd = sck2;
|
||||||
|
pollfd[i].events = POLLIN;
|
||||||
|
rvmask[i] = 2;
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
max = sck1;
|
if (poll(pollfd, i, 0) > 0)
|
||||||
|
|
||||||
if (sck2 > max)
|
|
||||||
{
|
{
|
||||||
max = sck2;
|
if ((pollfd[0].revents & (POLLIN | POLLHUP)) != 0)
|
||||||
}
|
|
||||||
|
|
||||||
rv = select(max + 1, &rfds, 0, 0, &time);
|
|
||||||
|
|
||||||
if (rv > 0)
|
|
||||||
{
|
|
||||||
rv = 0;
|
|
||||||
|
|
||||||
if (FD_ISSET(((unsigned int)sck1), &rfds))
|
|
||||||
{
|
{
|
||||||
rv = rv | 1;
|
rv |= rvmask[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FD_ISSET(((unsigned int)sck2), &rfds))
|
if ((pollfd[1].revents & (POLLIN | POLLHUP)) != 0)
|
||||||
{
|
{
|
||||||
rv = rv | 2;
|
rv |= rvmask[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
rv = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@ -1703,19 +1689,24 @@ g_sck_select(int sck1, int sck2)
|
|||||||
static int
|
static int
|
||||||
g_fd_can_read(int fd)
|
g_fd_can_read(int fd)
|
||||||
{
|
{
|
||||||
fd_set rfds;
|
int rv = 0;
|
||||||
struct timeval time;
|
if (fd > 0)
|
||||||
int rv;
|
|
||||||
|
|
||||||
g_memset(&time, 0, sizeof(time));
|
|
||||||
FD_ZERO(&rfds);
|
|
||||||
FD_SET(((unsigned int)fd), &rfds);
|
|
||||||
rv = select(fd + 1, &rfds, 0, 0, &time);
|
|
||||||
if (rv == 1)
|
|
||||||
{
|
{
|
||||||
return 1;
|
struct pollfd pollfd;
|
||||||
|
|
||||||
|
pollfd.fd = fd;
|
||||||
|
pollfd.events = POLLIN;
|
||||||
|
pollfd.revents = 0;
|
||||||
|
if (poll(&pollfd, 1, 0) > 0)
|
||||||
|
{
|
||||||
|
if ((pollfd.revents & (POLLIN | POLLHUP)) != 0)
|
||||||
|
{
|
||||||
|
rv = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@ -1982,8 +1973,9 @@ int
|
|||||||
g_obj_wait(tintptr *read_objs, int rcount, tintptr *write_objs, int wcount,
|
g_obj_wait(tintptr *read_objs, int rcount, tintptr *write_objs, int wcount,
|
||||||
int mstimeout)
|
int mstimeout)
|
||||||
{
|
{
|
||||||
|
#define MAX_HANDLES 256
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
HANDLE handles[256];
|
HANDLE handles[MAX_HANDLES];
|
||||||
DWORD count;
|
DWORD count;
|
||||||
DWORD error;
|
DWORD error;
|
||||||
int j;
|
int j;
|
||||||
@ -2016,96 +2008,62 @@ g_obj_wait(tintptr *read_objs, int rcount, tintptr *write_objs, int wcount,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
#else
|
||||||
fd_set rfds;
|
struct pollfd pollfd[MAX_HANDLES];
|
||||||
fd_set wfds;
|
int sck;
|
||||||
struct timeval time;
|
|
||||||
struct timeval *ptime;
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int res = 0;
|
unsigned int j = 0;
|
||||||
int max = 0;
|
int rv = 1;
|
||||||
int sck = 0;
|
|
||||||
|
|
||||||
max = 0;
|
if (read_objs == NULL && rcount != 0)
|
||||||
if (mstimeout < 1)
|
|
||||||
{
|
{
|
||||||
ptime = 0;
|
LOG(LOG_LEVEL_ERROR, "Programming error read_objs is null");
|
||||||
|
}
|
||||||
|
else if (write_objs == NULL && wcount != 0)
|
||||||
|
{
|
||||||
|
LOG(LOG_LEVEL_ERROR, "Programming error write_objs is null");
|
||||||
|
}
|
||||||
|
/* Check carefully for int overflow in passed-in counts */
|
||||||
|
else if ((unsigned int)rcount > MAX_HANDLES ||
|
||||||
|
(unsigned int)wcount > MAX_HANDLES ||
|
||||||
|
((unsigned int)rcount + (unsigned int)wcount) > MAX_HANDLES)
|
||||||
|
{
|
||||||
|
LOG(LOG_LEVEL_ERROR, "Programming error too many handles");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_memset(&time, 0, sizeof(struct timeval));
|
if (mstimeout < 1)
|
||||||
time.tv_sec = mstimeout / 1000;
|
{
|
||||||
time.tv_usec = (mstimeout % 1000) * 1000;
|
mstimeout = -1;
|
||||||
ptime = &time;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
FD_ZERO(&rfds);
|
for (i = 0; i < rcount ; ++i)
|
||||||
FD_ZERO(&wfds);
|
|
||||||
|
|
||||||
/* Find the highest descriptor number in read_obj */
|
|
||||||
if (read_objs != NULL)
|
|
||||||
{
|
|
||||||
for (i = 0; i < rcount; i++)
|
|
||||||
{
|
{
|
||||||
sck = read_objs[i] & 0xffff;
|
sck = read_objs[i] & 0xffff;
|
||||||
|
|
||||||
if (sck > 0)
|
if (sck > 0)
|
||||||
{
|
{
|
||||||
FD_SET(sck, &rfds);
|
pollfd[j].fd = sck;
|
||||||
|
pollfd[j].events = POLLIN;
|
||||||
if (sck > max)
|
++j;
|
||||||
{
|
|
||||||
max = sck; /* max holds the highest socket/descriptor number */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if (rcount > 0)
|
|
||||||
{
|
|
||||||
LOG(LOG_LEVEL_ERROR, "Programming error read_objs is null");
|
|
||||||
return 1; /* error */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (write_objs != NULL)
|
for (i = 0; i < wcount; ++i)
|
||||||
{
|
|
||||||
for (i = 0; i < wcount; i++)
|
|
||||||
{
|
{
|
||||||
sck = (int)(write_objs[i]);
|
sck = write_objs[i];
|
||||||
|
|
||||||
if (sck > 0)
|
if (sck > 0)
|
||||||
{
|
{
|
||||||
FD_SET(sck, &wfds);
|
pollfd[j].fd = sck;
|
||||||
|
pollfd[j].events = POLLOUT;
|
||||||
if (sck > max)
|
++j;
|
||||||
{
|
|
||||||
max = sck; /* max holds the highest socket/descriptor number */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if (wcount > 0)
|
rv = (poll(pollfd, j, mstimeout) < 0);
|
||||||
{
|
|
||||||
LOG(LOG_LEVEL_ERROR, "Programming error write_objs is null");
|
|
||||||
return 1; /* error */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
res = select(max + 1, &rfds, &wfds, 0, ptime);
|
return rv;
|
||||||
|
|
||||||
if (res < 0)
|
|
||||||
{
|
|
||||||
/* these are not really errors */
|
|
||||||
if ((errno == EAGAIN) ||
|
|
||||||
(errno == EWOULDBLOCK) ||
|
|
||||||
(errno == EINPROGRESS) ||
|
|
||||||
(errno == EINTR)) /* signal occurred */
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1; /* error */
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
#endif
|
#endif
|
||||||
|
#undef MAX_HANDLES
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -167,6 +167,21 @@ int g_set_wait_obj(tintptr obj);
|
|||||||
int g_reset_wait_obj(tintptr obj);
|
int g_reset_wait_obj(tintptr obj);
|
||||||
int g_is_wait_obj_set(tintptr obj);
|
int g_is_wait_obj_set(tintptr obj);
|
||||||
int g_delete_wait_obj(tintptr obj);
|
int g_delete_wait_obj(tintptr obj);
|
||||||
|
/**
|
||||||
|
* Wait for the specified readable and writeable objs
|
||||||
|
*
|
||||||
|
* The wait finishes when at least one of the objects becomes
|
||||||
|
* readable or writeable
|
||||||
|
*
|
||||||
|
* @param read_objs Array of read objects
|
||||||
|
* @param rcount Number of elements in read_objs
|
||||||
|
* @param write_objs Array of write objects
|
||||||
|
* @param rcount Number of elements in write_objs
|
||||||
|
* @param mstimeout Timeout in milliseconds. <= 0 means an infinite timeout.
|
||||||
|
*
|
||||||
|
* @return 0 for success. The objects will need to be polled to
|
||||||
|
* find out what is readable or writeable.
|
||||||
|
*/
|
||||||
int g_obj_wait(tintptr *read_objs, int rcount, tintptr *write_objs,
|
int g_obj_wait(tintptr *read_objs, int rcount, tintptr *write_objs,
|
||||||
int wcount, int mstimeout);
|
int wcount, int mstimeout);
|
||||||
void g_random(char *data, int len);
|
void g_random(char *data, int len);
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <poll.h>
|
||||||
|
|
||||||
#include "string_calls.h"
|
#include "string_calls.h"
|
||||||
|
|
||||||
@ -263,29 +264,24 @@ get_message(int *code, char *data, int *bytes)
|
|||||||
int max_bytes;
|
int max_bytes;
|
||||||
int error;
|
int error;
|
||||||
int recv_rv;
|
int recv_rv;
|
||||||
int max;
|
|
||||||
int lcode;
|
int lcode;
|
||||||
struct timeval time;
|
struct pollfd pollfd;
|
||||||
fd_set rd_set;
|
|
||||||
|
|
||||||
LLOGLN(10, ("get_message:"));
|
LLOGLN(10, ("get_message:"));
|
||||||
max = g_sck + 1;
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
LLOGLN(10, ("get_message: loop"));
|
LLOGLN(10, ("get_message: loop"));
|
||||||
time.tv_sec = 1;
|
pollfd.fd = g_sck;
|
||||||
time.tv_usec = 0;
|
pollfd.events = POLLIN;
|
||||||
FD_ZERO(&rd_set);
|
pollfd.revents = 0;
|
||||||
FD_SET(((unsigned int)g_sck), &rd_set);
|
error = poll(&pollfd, 1, 1000);
|
||||||
error = select(max, &rd_set, 0, 0, &time);
|
|
||||||
if (error == 1)
|
if (error == 1)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&g_mutex);
|
pthread_mutex_lock(&g_mutex);
|
||||||
time.tv_sec = 0;
|
pollfd.fd = g_sck;
|
||||||
time.tv_usec = 0;
|
pollfd.events = POLLIN;
|
||||||
FD_ZERO(&rd_set);
|
pollfd.revents = 0;
|
||||||
FD_SET(((unsigned int)g_sck), &rd_set);
|
error = poll(&pollfd, 1, 0);
|
||||||
error = select(max, &rd_set, 0, 0, &time);
|
|
||||||
if (error == 1)
|
if (error == 1)
|
||||||
{
|
{
|
||||||
/* just take a look at the next message */
|
/* just take a look at the next message */
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <poll.h>
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
|
|
||||||
@ -32,7 +33,6 @@ int g_x_socket = 0;
|
|||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
fd_set rfds;
|
|
||||||
int i1;
|
int i1;
|
||||||
XEvent xevent;
|
XEvent xevent;
|
||||||
|
|
||||||
@ -48,9 +48,11 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
FD_ZERO(&rfds);
|
struct pollfd pollfd;
|
||||||
FD_SET(g_x_socket, &rfds);
|
pollfd.fd = g_x_socket;
|
||||||
i1 = select(g_x_socket + 1, &rfds, 0, 0, 0);
|
pollfd.events = POLLIN;
|
||||||
|
pollfd.revents = 0;
|
||||||
|
i1 = poll(&pollfd, 1, -1);
|
||||||
|
|
||||||
if (i1 < 0)
|
if (i1 < 0)
|
||||||
{
|
{
|
||||||
|
@ -267,26 +267,24 @@ int tcp_connect(int skt, const char *hostname, const char *port)
|
|||||||
|
|
||||||
int tcp_can_send(int skt, int millis)
|
int tcp_can_send(int skt, int millis)
|
||||||
{
|
{
|
||||||
fd_set wfds;
|
int rv = 0;
|
||||||
struct timeval time;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
time.tv_sec = millis / 1000;
|
|
||||||
time.tv_usec = (millis * 1000) % 1000000;
|
|
||||||
FD_ZERO(&wfds);
|
|
||||||
|
|
||||||
if (skt > 0)
|
if (skt > 0)
|
||||||
{
|
{
|
||||||
FD_SET(((unsigned int) skt), &wfds);
|
struct pollfd pollfd;
|
||||||
rv = select(skt + 1, 0, &wfds, 0, &time);
|
|
||||||
|
|
||||||
if (rv > 0)
|
pollfd.fd = skt;
|
||||||
|
pollfd.events = POLLOUT;
|
||||||
|
pollfd.revents = 0;
|
||||||
|
if (poll(&pollfd, 1, millis) > 0)
|
||||||
{
|
{
|
||||||
return tcp_socket_ok(skt);
|
if ((pollfd.revents & POLLOUT) != 0)
|
||||||
|
{
|
||||||
|
rv = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -317,56 +315,40 @@ int tcp_socket_ok(int skt)
|
|||||||
|
|
||||||
int tcp_select(int sck1, int sck2)
|
int tcp_select(int sck1, int sck2)
|
||||||
{
|
{
|
||||||
fd_set rfds;
|
struct pollfd pollfd[2] = {0};
|
||||||
struct timeval time;
|
int rvmask[2] = {0}; /* Output masks corresponding to fds in pollfd */
|
||||||
|
|
||||||
int max = 0;
|
unsigned int i = 0;
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
|
|
||||||
memset(&rfds, 0, sizeof(fd_set));
|
|
||||||
memset(&time, 0, sizeof(struct timeval));
|
|
||||||
|
|
||||||
time.tv_sec = 0;
|
|
||||||
time.tv_usec = 0;
|
|
||||||
FD_ZERO(&rfds);
|
|
||||||
|
|
||||||
if (sck1 > 0)
|
if (sck1 > 0)
|
||||||
{
|
{
|
||||||
FD_SET(((unsigned int) sck1), &rfds);
|
pollfd[i].fd = sck1;
|
||||||
|
pollfd[i].events = POLLIN;
|
||||||
|
rvmask[i] = 1;
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sck2 > 0)
|
if (sck2 > 0)
|
||||||
{
|
{
|
||||||
FD_SET(((unsigned int) sck2), &rfds);
|
pollfd[i].fd = sck2;
|
||||||
|
pollfd[i].events = POLLIN;
|
||||||
|
rvmask[i] = 2;
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
max = sck1;
|
if (poll(pollfd, i, 0) > 0)
|
||||||
|
|
||||||
if (sck2 > max)
|
|
||||||
{
|
{
|
||||||
max = sck2;
|
if ((pollfd[0].revents & (POLLIN | POLLHUP)) != 0)
|
||||||
}
|
|
||||||
|
|
||||||
rv = select(max + 1, &rfds, 0, 0, &time);
|
|
||||||
|
|
||||||
if (rv > 0)
|
|
||||||
{
|
|
||||||
rv = 0;
|
|
||||||
|
|
||||||
if (FD_ISSET(((unsigned int) sck1), &rfds))
|
|
||||||
{
|
{
|
||||||
rv = rv | 1;
|
rv |= rvmask[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FD_ISSET(((unsigned int)sck2), &rfds))
|
if ((pollfd[1].revents & (POLLIN | POLLHUP)) != 0)
|
||||||
{
|
{
|
||||||
rv = rv | 2;
|
rv |= rvmask[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
rv = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -105,6 +105,7 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
|
#include <poll.h>
|
||||||
|
|
||||||
#define _PATH_DEVNULL "/dev/null"
|
#define _PATH_DEVNULL "/dev/null"
|
||||||
|
|
||||||
@ -275,14 +276,24 @@ handle_connection(int client_fd)
|
|||||||
int client_going = 1;
|
int client_going = 1;
|
||||||
while (client_going)
|
while (client_going)
|
||||||
{
|
{
|
||||||
/* Wait for data from RDP or the client */
|
struct pollfd pollfd[2];
|
||||||
fd_set readfds;
|
enum
|
||||||
FD_ZERO(&readfds);
|
{
|
||||||
FD_SET(client_fd, &readfds);
|
RDP_FD = 0,
|
||||||
FD_SET(rdp_fd, &readfds);
|
CLIENT_FD
|
||||||
select(FD_SETSIZE, &readfds, NULL, NULL, NULL);
|
};
|
||||||
|
|
||||||
if (FD_ISSET(rdp_fd, &readfds))
|
/* Wait for data from RDP or the client */
|
||||||
|
pollfd[RDP_FD].fd = rdp_fd;
|
||||||
|
pollfd[RDP_FD].events = POLLIN;
|
||||||
|
pollfd[RDP_FD].revents = 0;
|
||||||
|
pollfd[CLIENT_FD].fd = client_fd;
|
||||||
|
pollfd[CLIENT_FD].events = POLLIN;
|
||||||
|
pollfd[CLIENT_FD].revents = 0;
|
||||||
|
|
||||||
|
poll(pollfd, 2, -1);
|
||||||
|
|
||||||
|
if ((pollfd[RDP_FD].revents & (POLLIN | POLLHUP)) != 0)
|
||||||
{
|
{
|
||||||
/* Read from RDP and write to the client */
|
/* Read from RDP and write to the client */
|
||||||
char buffer[4096];
|
char buffer[4096];
|
||||||
@ -325,7 +336,7 @@ handle_connection(int client_fd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FD_ISSET(client_fd, &readfds))
|
if ((pollfd[CLIENT_FD].revents & (POLLIN | POLLHUP)) != 0)
|
||||||
{
|
{
|
||||||
/* Read from the client and write to RDP */
|
/* Read from the client and write to RDP */
|
||||||
char buffer[4096];
|
char buffer[4096];
|
||||||
@ -380,14 +391,18 @@ main(int argc, char **argv)
|
|||||||
/* Wait for a client to connect to the socket */
|
/* Wait for a client to connect to the socket */
|
||||||
while (is_going)
|
while (is_going)
|
||||||
{
|
{
|
||||||
fd_set readfds;
|
struct pollfd pollfd;
|
||||||
FD_ZERO(&readfds);
|
|
||||||
FD_SET(sa_uds_fd, &readfds);
|
pollfd.fd = sa_uds_fd;
|
||||||
select(FD_SETSIZE, &readfds, NULL, NULL, NULL);
|
pollfd.events = POLLIN;
|
||||||
|
pollfd.revents = 0;
|
||||||
|
|
||||||
|
poll(pollfd, 1, -1);
|
||||||
|
|
||||||
/* If something connected then get it...
|
/* If something connected then get it...
|
||||||
* (You can test this using "socat - UNIX-CONNECT:<udspath>".) */
|
* (You can test this using "socat - UNIX-CONNECT:<udspath>".) */
|
||||||
if (FD_ISSET(sa_uds_fd, &readfds))
|
if ((pollfd.revents & (POLLIN | POLLHUP)) != 0)
|
||||||
|
|
||||||
{
|
{
|
||||||
socklen_t addrsize = sizeof(addr);
|
socklen_t addrsize = sizeof(addr);
|
||||||
int client_fd = accept(sa_uds_fd,
|
int client_fd = accept(sa_uds_fd,
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
|
#include <poll.h>
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "xrdp_sockets.h"
|
#include "xrdp_sockets.h"
|
||||||
@ -481,40 +482,40 @@ WTSFreeMemory(void *pMemory)
|
|||||||
static int
|
static int
|
||||||
can_send(int sck, int millis)
|
can_send(int sck, int millis)
|
||||||
{
|
{
|
||||||
struct timeval time;
|
int rv = 0;
|
||||||
fd_set wfds;
|
struct pollfd pollfd;
|
||||||
int select_rv;
|
|
||||||
|
|
||||||
/* setup for a select call */
|
pollfd.fd = sck;
|
||||||
FD_ZERO(&wfds);
|
pollfd.events = POLLOUT;
|
||||||
FD_SET(sck, &wfds);
|
pollfd.revents = 0;
|
||||||
time.tv_sec = millis / 1000;
|
if (poll(&pollfd, 1, millis) > 0)
|
||||||
time.tv_usec = (millis * 1000) % 1000000;
|
{
|
||||||
|
if ((pollfd.revents & POLLOUT) != 0)
|
||||||
|
{
|
||||||
|
rv = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* check if it is ok to write to specified socket */
|
return rv;
|
||||||
select_rv = select(sck + 1, 0, &wfds, 0, &time);
|
|
||||||
|
|
||||||
return (select_rv > 0) ? 1 : 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
static int
|
static int
|
||||||
can_recv(int sck, int millis)
|
can_recv(int sck, int millis)
|
||||||
{
|
{
|
||||||
struct timeval time;
|
int rv = 0;
|
||||||
fd_set rfds;
|
struct pollfd pollfd;
|
||||||
int select_rv;
|
|
||||||
|
|
||||||
FD_ZERO(&rfds);
|
pollfd.fd = sck;
|
||||||
FD_SET(sck, &rfds);
|
pollfd.events = POLLIN;
|
||||||
time.tv_sec = millis / 1000;
|
pollfd.revents = 0;
|
||||||
time.tv_usec = (millis * 1000) % 1000000;
|
if (poll(&pollfd, 1, millis) > 0)
|
||||||
select_rv = select(sck + 1, &rfds, 0, 0, &time);
|
|
||||||
|
|
||||||
if (select_rv > 0)
|
|
||||||
{
|
{
|
||||||
return 1;
|
if ((pollfd.revents & (POLLIN | POLLHUP)) != 0)
|
||||||
|
{
|
||||||
|
rv = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return rv;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user