Commit 0a4f1bad authored by Christian Beier's avatar Christian Beier Committed by Johannes Schindelin

libvncclient: add a non-forking listen function.

Forking the whole process from deep within a library call does
not really work at all with apps that use multiple threads, i.e. every
reasonably modern GUI app. So, provide a non-forking listen function so
that the caller can decide if to fork, start a thread, etc.

This implementation adds a timeout parameter to be able to call the
listen function multiple times so that it's possible to do sth. else
in between, e.g. abort listening.
Signed-off-by: 's avatarChristian Beier <dontmind@freeshell.org>
Signed-off-by: 's avatarJohannes Schindelin <johannes.schindelin@gmx.de>
parent 3b608cd3
......@@ -27,6 +27,7 @@
#include <unistd.h>
#include <sys/types.h>
#ifdef __MINGW32__
#define close closesocket
#include <winsock2.h>
#else
#include <sys/wait.h>
......@@ -108,3 +109,59 @@ listenForIncomingConnections(rfbClient* client)
}
/*
* listenForIncomingConnectionsNoFork() - listen for incoming connections
* from servers, but DON'T fork, instead just wait timeout microseconds.
* If timeout is negative, block indefinitly.
*/
rfbBool
listenForIncomingConnectionsNoFork(rfbClient* client, int timeout)
{
fd_set fds;
struct timeval to;
to.tv_sec= timeout / 1000000;
to.tv_usec= timeout % 1000000;
client->listenSpecified = TRUE;
if (! client->listenSock)
{
client->listenSock = ListenAtTcpPort(client->listenPort);
if (client->listenSock < 0)
return FALSE;
rfbClientLog("%s -listennofork: Listening on port %d\n",
client->programName,client->listenPort);
rfbClientLog("%s -listennofork: Command line errors are not reported until "
"a connection comes in.\n", client->programName);
}
FD_ZERO(&fds);
FD_SET(client->listenSock, &fds);
if (timeout < 0)
select(FD_SETSIZE, &fds, NULL, NULL, NULL);
else
select(FD_SETSIZE, &fds, NULL, NULL, &to);
if (FD_ISSET(client->listenSock, &fds))
{
client->sock = AcceptTcpConnection(client->listenSock);
if (client->sock < 0)
return FALSE;
if (!SetNonBlocking(client->sock))
return FALSE;
close(client->listenSock);
return TRUE;
}
return FALSE;
}
......@@ -43,6 +43,7 @@ static void DummyRect(rfbClient* client, int x, int y, int w, int h) {
static char* NoPassword(rfbClient* client) {
return strdup("");
}
#define close closesocket
#else
#include <stdio.h>
#include <termios.h>
......@@ -247,6 +248,9 @@ rfbBool rfbInitClient(rfbClient* client,int* argc,char** argv) {
if (strcmp(argv[i], "-listen") == 0) {
listenForIncomingConnections(client);
break;
} else if (strcmp(argv[i], "-listennofork") == 0) {
listenForIncomingConnectionsNoFork(client, -1);
break;
} else if (strcmp(argv[i], "-play") == 0) {
client->serverPort = -1;
j++;
......
......@@ -151,6 +151,9 @@ typedef struct _rfbClient {
rfbPixelFormat format;
rfbServerInitMsg si;
/* listen.c */
int listenSock;
/* sockets.c */
#define RFB_BUF_SIZE 8192
char buf[RFB_BUF_SIZE];
......@@ -260,6 +263,7 @@ extern rfbBool HandleCursorShape(rfbClient* client,int xhot, int yhot, int width
/* listen.c */
extern void listenForIncomingConnections(rfbClient* viewer);
extern rfbBool listenForIncomingConnectionsNoFork(rfbClient* viewer, int usec_timeout);
/* rfbproto.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