Blob Blame Raw
From ac43dac0a18778081ea784c98391f0333981ca13 Mon Sep 17 00:00:00 2001
From: Adam Jackson <ajax@redhat.com>
Date: Mon, 6 Apr 2009 15:44:05 -0400
Subject: [PATCH] displayfd hack

---
 dix/globals.c    |    1 +
 include/opaque.h |    1 +
 os/connection.c  |   72 ++++++++++++++++++++++++++++++++++++-----------------
 os/utils.c       |   11 ++++++++
 4 files changed, 62 insertions(+), 23 deletions(-)

diff --git a/dix/globals.c b/dix/globals.c
index dbd76bb..749bf9b 100644
--- a/dix/globals.c
+++ b/dix/globals.c
@@ -152,6 +152,7 @@ _X_EXPORT int defaultColorVisualClass = -1;
 _X_EXPORT int monitorResolution = 0;
 
 _X_EXPORT char *display;
+int displayfd;
 char *ConnectionInfo;
 
 CARD32 TimeOutValue = DEFAULT_TIMEOUT * MILLI_PER_SECOND;
diff --git a/include/opaque.h b/include/opaque.h
index be1577b..2ae6680 100644
--- a/include/opaque.h
+++ b/include/opaque.h
@@ -50,6 +50,7 @@ extern int ScreenSaverAllowExposures;
 extern int defaultScreenSaverBlanking;
 extern int defaultScreenSaverAllowExposures;
 extern char *display;
+extern int displayfd;
 
 extern int defaultBackingStore;
 extern Bool disableBackingStore;
diff --git a/os/connection.c b/os/connection.c
index 8f1f73e..4351117 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -146,6 +146,7 @@ Bool NewOutputPending;		/* not yet attempted to write some new output */
 Bool AnyClientsWriteBlocked;	/* true if some client blocked on write */
 
 static Bool RunFromSmartParent;	/* send SIGUSR1 to parent process */
+static char dynamic_display[7];
 Bool PartialNetwork;		/* continue even if unable to bind all addrs */
 static Pid_t ParentProcess;
 
@@ -367,9 +368,23 @@ NotifyParentProcess(void)
 	    kill (ParentProcess, SIGUSR1);
 	}
     }
+    if (dynamic_display[0])
+	write(displayfd, dynamic_display, strlen(dynamic_display));
 #endif
 }
 
+static Bool
+TryCreateSocket(int num, int *partial)
+{
+    char port[20];
+
+    sprintf(port, "%d", num);
+
+    return _XSERVTransMakeAllCOTSServerListeners(port, partial,
+						 &ListenTransCount,
+						 &ListenTransConns);
+}
+
 /*****************
  * CreateWellKnownSockets
  *    At initialization, create the sockets to listen on for new clients.
@@ -380,7 +395,6 @@ CreateWellKnownSockets(void)
 {
     int		i;
     int		partial;
-    char 	port[20];
 
     FD_ZERO(&AllSockets);
     FD_ZERO(&AllClients);
@@ -395,32 +409,44 @@ CreateWellKnownSockets(void)
 
     FD_ZERO (&WellKnownConnections);
 
-    sprintf (port, "%d", atoi (display));
-
-    if ((_XSERVTransMakeAllCOTSServerListeners (port, &partial,
-	&ListenTransCount, &ListenTransConns) >= 0) &&
-	(ListenTransCount >= 1))
+    if (display)
     {
-	if (!PartialNetwork && partial)
-	{
-	    FatalError ("Failed to establish all listening sockets");
-	}
-	else
+	if (TryCreateSocket(atoi(display), &partial) &&
+	    (ListenTransCount >= 1))
+	    if (!PartialNetwork && partial)
+		FatalError ("Failed to establish all listening sockets");
+    }
+    else /* -displayfd */
+    {
+	Bool found = 0;
+	for (i = 0; i < 65535 - 1024; i++)
 	{
-	    ListenTransFds = (int *) xalloc (ListenTransCount * sizeof (int));
-
-	    for (i = 0; i < ListenTransCount; i++)
+	    if (!TryCreateSocket(i, &partial) && !partial)
 	    {
-		int fd = _XSERVTransGetConnectionNumber (ListenTransConns[i]);
-		
-		ListenTransFds[i] = fd;
-		FD_SET (fd, &WellKnownConnections);
-
-		if (!_XSERVTransIsLocal (ListenTransConns[i]))
-		{
-		    DefineSelf (fd);
-		}
+		found = 1;
+		break;
 	    }
+	    else
+		CloseWellKnownConnections();
+	}
+	if (!found)
+	    FatalError("Failed to find a socket to listen on");
+	sprintf(dynamic_display, "%d\n", i);
+	display = dynamic_display;
+    }
+
+    ListenTransFds = xalloc (ListenTransCount * sizeof (int));
+
+    for (i = 0; i < ListenTransCount; i++)
+    {
+	int fd = _XSERVTransGetConnectionNumber (ListenTransConns[i]);
+	
+	ListenTransFds[i] = fd;
+	FD_SET (fd, &WellKnownConnections);
+
+	if (!_XSERVTransIsLocal (ListenTransConns[i]))
+	{
+	    DefineSelf (fd);
 	}
     }
 
diff --git a/os/utils.c b/os/utils.c
index c41b45b..2372588 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -674,6 +674,17 @@ ProcessCommandLine(int argc, char *argv[])
 	    else
 		UseMsg();
 	}
+	else if (strcmp(argv[i], "-displayfd") == 0)
+	{
+	    if (++i < argc)
+	    {
+		displayfd = atoi(argv[i]);
+		display = NULL;
+		nolock = TRUE;
+	    }
+	    else
+		UseMsg();
+	}
 #ifdef DPMSExtension
 	else if ( strcmp( argv[i], "dpms") == 0)
 	    DPMSEnabledSwitch = TRUE;
-- 
1.6.2