summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon TURNEY <jon.turney@dronecode.org.uk>2010-09-20 15:35:42 +0100
committerJon TURNEY <jon.turney@dronecode.org.uk>2012-03-10 13:25:34 +0000
commit880208ec3bd0ed0629f7f00df8c20074ad3d9c58 (patch)
tree014335c94b615a342335fc588ec3d46673c40ae7
parent7ee41b6040f9f39d3b677f606b2366a9dd376aee (diff)
os: Add -displayfd option.
This option specifies a file descriptor in the launching process. X will scan for an available display number and write that number back to the launching process, at the same time as SIGUSR1 generation. This means display managers don't need to guess at available display numbers. As a consequence, if X fails to start when using -displayfd, it's not because the display was in use, so there's no point in retrying the X launch on a higher display number. Signed-off-by: Adam Jackson <ajax@redhat.com> Update for current X server Fix null DISPLAY crash when stderr is closed Rearrange init order to avoid null DISPLAY crash and correctly use DISPLAY in default logfile name when logfile isn't specified on command line Don't put '\'n on end of DISPLAY so internal XWin uses work correctly Do a bit more logging about what we are trying to do Signed-off-by: Jon TURNEY <jon.turney@dronecode.org.uk>
-rw-r--r--dix/globals.c1
-rw-r--r--dix/main.c7
-rw-r--r--include/opaque.h1
-rw-r--r--man/Xserver.man7
-rw-r--r--os/connection.c75
-rw-r--r--os/osinit.c2
-rw-r--r--os/utils.c11
7 files changed, 78 insertions, 26 deletions
diff --git a/dix/globals.c b/dix/globals.c
index 0a6b17085..0ee83c03e 100644
--- a/dix/globals.c
+++ b/dix/globals.c
@@ -126,6 +126,7 @@ int defaultColorVisualClass = -1;
int monitorResolution = 0;
char *display;
+int displayfd;
char *ConnectionInfo;
CARD32 TimeOutValue = DEFAULT_TIMEOUT * MILLI_PER_SECOND;
diff --git a/dix/main.c b/dix/main.c
index 16575ceba..3e944bdad 100644
--- a/dix/main.c
+++ b/dix/main.c
@@ -162,8 +162,7 @@ int main(int argc, char *argv[], char *envp[])
DPMSPowerLevel = 0;
#endif
InitBlockAndWakeupHandlers();
- /* Perform any operating system dependent initializations you'd like */
- OsInit();
+
if(serverGeneration == 1)
{
CreateWellKnownSockets();
@@ -176,6 +175,10 @@ int main(int argc, char *argv[], char *envp[])
}
else
ResetWellKnownSockets ();
+
+ /* Perform any operating system dependent initializations you'd like */
+ OsInit();
+
clients[0] = serverClient;
currentMaxClients = 1;
diff --git a/include/opaque.h b/include/opaque.h
index 5c707172c..f23203f0d 100644
--- a/include/opaque.h
+++ b/include/opaque.h
@@ -50,6 +50,7 @@ extern _X_EXPORT int ScreenSaverAllowExposures;
extern _X_EXPORT int defaultScreenSaverBlanking;
extern _X_EXPORT int defaultScreenSaverAllowExposures;
extern _X_EXPORT char *display;
+extern _X_EXPORT int displayfd;
extern _X_EXPORT int defaultBackingStore;
extern _X_EXPORT Bool disableBackingStore;
diff --git a/man/Xserver.man b/man/Xserver.man
index 0cd9b941c..b103551fa 100644
--- a/man/Xserver.man
+++ b/man/Xserver.man
@@ -127,6 +127,13 @@ Not obeyed by all servers.
.B \-core
causes the server to generate a core dump on fatal errors.
.TP 8
+.B \-displayfd \fIfd\fP
+specifies a file descriptor in the launching process. Rather than specify
+a display number, the X server will attempt to listen on successively higher
+display numbers, and upon finding a free one, will write the display number back
+on this file descriptor as a newline-terminated string. The \-pn option is
+ignored when using \-displayfd.
+.TP 8
.B \-deferglyphs \fIwhichfonts\fP
specifies the types of fonts for which the server should attempt to use
deferred glyph loading. \fIwhichfonts\fP can be all (all fonts),
diff --git a/os/connection.c b/os/connection.c
index f609de69c..4bca7f5ba 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -145,6 +145,7 @@ Bool AnyClientsWriteBlocked; /* true if some client blocked on write */
static Bool RunFromSmartParent; /* send SIGUSR1 to parent process */
Bool RunFromSigStopParent; /* send SIGSTOP to our own process; Upstart (or
equivalent) will send SIGCONT back. */
+static char dynamic_display[7];
Bool PartialNetwork; /* continue even if unable to bind all addrs */
static Pid_t ParentProcess;
@@ -375,9 +376,25 @@ NotifyParentProcess(void)
}
if (RunFromSigStopParent)
raise (SIGSTOP);
+ if (dynamic_display[0]) {
+ write(displayfd, dynamic_display, strlen(dynamic_display));
+ write(displayfd, "\n", 1);
+ }
#endif
}
+static Bool
+TryCreateSocket(int num, int *partial)
+{
+ char port[20];
+
+ snprintf (port, sizeof(port), "%d", atoi (display));
+
+ return _XSERVTransMakeAllCOTSServerListeners(port, partial,
+ &ListenTransCount,
+ &ListenTransConns);
+}
+
/*****************
* CreateWellKnownSockets
* At initialization, create the sockets to listen on for new clients.
@@ -388,7 +405,6 @@ CreateWellKnownSockets(void)
{
int i;
int partial;
- char port[20];
FD_ZERO(&AllSockets);
FD_ZERO(&AllClients);
@@ -403,32 +419,45 @@ CreateWellKnownSockets(void)
FD_ZERO (&WellKnownConnections);
- snprintf (port, sizeof(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 = malloc(ListenTransCount * sizeof (int));
-
- for (i = 0; i < ListenTransCount; i++)
+ ErrorF("Trying to create socket for display number %d\n", 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", i);
+ display = dynamic_display;
+ }
+
+ ListenTransFds = malloc(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/osinit.c b/os/osinit.c
index ff3c45de0..0a9436952 100644
--- a/os/osinit.c
+++ b/os/osinit.c
@@ -212,7 +212,7 @@ OsInit(void)
{
FILE *err;
- if (strlen (display) + strlen (ADMPATH) + 1 < sizeof fname)
+ if ((display) && (strlen (display) + strlen (ADMPATH) + 1 < sizeof fname))
snprintf (fname, sizeof(fname), ADMPATH, display);
else
strcpy (fname, devnull);
diff --git a/os/utils.c b/os/utils.c
index 5fee77d63..e63b691e8 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -661,6 +661,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)
/* ignored for compatibility */ ;