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> Signed-off-by: Chase Douglas <chase.douglas@canonical.com> Reviewed-by: Julien Cristau <jcristau@debian.org> Tested-by: Julien Cristau <jcristau@debian.org> Reviewed-by: Alan Coopersmith <alan.coopersmith@oracle.com> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
1d82ec9594
commit
88bacc49f0
|
@ -128,6 +128,7 @@ int defaultColorVisualClass = -1;
|
|||
int monitorResolution = 0;
|
||||
|
||||
char *display;
|
||||
int displayfd;
|
||||
char *ConnectionInfo;
|
||||
|
||||
CARD32 TimeOutValue = DEFAULT_TIMEOUT * MILLI_PER_SECOND;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 port 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),
|
||||
|
|
|
@ -142,6 +142,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]; /* display name */
|
||||
Bool PartialNetwork; /* continue even if unable to bind all addrs */
|
||||
static Pid_t ParentProcess;
|
||||
|
||||
|
@ -350,6 +351,10 @@ void
|
|||
NotifyParentProcess(void)
|
||||
{
|
||||
#if !defined(WIN32)
|
||||
if (dynamic_display[0]) {
|
||||
write(displayfd, dynamic_display, strlen(dynamic_display));
|
||||
close(displayfd);
|
||||
}
|
||||
if (RunFromSmartParent) {
|
||||
if (ParentProcess > 1) {
|
||||
kill(ParentProcess, SIGUSR1);
|
||||
|
@ -360,6 +365,18 @@ NotifyParentProcess(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
static Bool
|
||||
TryCreateSocket(int num, int *partial)
|
||||
{
|
||||
char port[20];
|
||||
|
||||
snprintf(port, sizeof(port), "%d", num);
|
||||
|
||||
return (_XSERVTransMakeAllCOTSServerListeners(port, partial,
|
||||
&ListenTransCount,
|
||||
&ListenTransConns) >= 0);
|
||||
}
|
||||
|
||||
/*****************
|
||||
* CreateWellKnownSockets
|
||||
* At initialization, create the sockets to listen on for new clients.
|
||||
|
@ -370,7 +387,6 @@ CreateWellKnownSockets(void)
|
|||
{
|
||||
int i;
|
||||
int partial;
|
||||
char port[20];
|
||||
|
||||
FD_ZERO(&AllSockets);
|
||||
FD_ZERO(&AllClients);
|
||||
|
@ -386,29 +402,41 @@ CreateWellKnownSockets(void)
|
|||
|
||||
FD_ZERO(&WellKnownConnections);
|
||||
|
||||
snprintf(port, sizeof(port), "%d", atoi(display));
|
||||
|
||||
if ((_XSERVTransMakeAllCOTSServerListeners(port, &partial,
|
||||
&ListenTransCount,
|
||||
&ListenTransConns) >= 0) &&
|
||||
(ListenTransCount >= 1)) {
|
||||
if (!PartialNetwork && partial) {
|
||||
FatalError("Failed to establish all listening sockets");
|
||||
}
|
||||
else {
|
||||
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);
|
||||
}
|
||||
/* display is initialized to "0" by main(). It is then set to the display
|
||||
* number if specified on the command line, or to NULL when the -displayfd
|
||||
* option is used. */
|
||||
if (display) {
|
||||
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 - X_TCP_PORT; i++) {
|
||||
if (TryCreateSocket(i, &partial) && !partial) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
CloseWellKnownConnections();
|
||||
}
|
||||
if (!found)
|
||||
FatalError("Failed to find a socket to listen on");
|
||||
snprintf(dynamic_display, sizeof(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);
|
||||
}
|
||||
|
||||
if (!XFD_ANYSET(&WellKnownConnections))
|
||||
|
|
|
@ -659,6 +659,15 @@ 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 */ ;
|
||||
|
|
Loading…
Reference in New Issue
Block a user