summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Beier <dontmind@freeshell.org>2009-10-26 22:24:21 +0100
committerJohannes Schindelin <johannes.schindelin@gmx.de>2009-10-30 18:29:05 +0100
commit0a4f1bada4f6e62e1cb4ffd6c34e6c8313c39aef (patch)
treed881e3baa675fa505fc449b955358d72dfee2d71
parent3b608cd39b0f335658dc56525d1d099722d27333 (diff)
downloadlibtdevnc-0a4f1bad.tar.gz
libtdevnc-0a4f1bad.zip
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: Christian Beier <dontmind@freeshell.org> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
-rw-r--r--libvncclient/listen.c57
-rw-r--r--libvncclient/vncviewer.c4
-rw-r--r--rfb/rfbclient.h4
3 files changed, 65 insertions, 0 deletions
diff --git a/libvncclient/listen.c b/libvncclient/listen.c
index 7347a27..d1e98ae 100644
--- a/libvncclient/listen.c
+++ b/libvncclient/listen.c
@@ -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;
+}
+
+
diff --git a/libvncclient/vncviewer.c b/libvncclient/vncviewer.c
index 7e678fb..f29bd5f 100644
--- a/libvncclient/vncviewer.c
+++ b/libvncclient/vncviewer.c
@@ -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++;
diff --git a/rfb/rfbclient.h b/rfb/rfbclient.h
index 40c1775..aa9d2e4 100644
--- a/rfb/rfbclient.h
+++ b/rfb/rfbclient.h
@@ -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 */