[PATCH] os: Add -displayfd option
Julien Cristau
jcristau at debian.org
Tue Apr 3 13:33:55 PDT 2012
On Tue, Apr 3, 2012 at 11:34:34 -0700, Chase Douglas wrote:
> 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 at redhat.com>
> Signed-off-by: Chase Douglas <chase.douglas at canonical.com>
> ---
> Adam originally submitted this back in 2007
> (http://patchwork.freedesktop.org/patch/3574/). I think this will be helpful for
> starting X servers for test suites, among other uses. I am resurrecting this
> with the following changes:
>
> * Reformatted to match master
> * Closed displayfd after writing display name (from previous review)
> * In TryCreateSocket(), return Bool value appropriately (from previous review)
> * In CreateWellKnownSockets(), use X_TCP_PORT as offset (from previous review)
> * Write to displayfd before signaling to parent
>
> Unfortunately, I'm not in a position to test this right now. I'm in the middle
> of fixing bugs for the impending Ubuntu release. I know that it does compile,
> cleanly I think (there are lots of other irrelevant warnings, though). If
> someone could give this a whirl to see that it functions properly I would
> appreciate it.
>
It doesn't actually work, but the fix seems easy enough, see below.
With that fixed:
Reviewed-by: Julien Cristau <jcristau at debian.org>
Tested-by: Julien Cristau <jcristau at debian.org>
> dix/globals.c | 1 +
> include/opaque.h | 1 +
> man/Xserver.man | 7 +++++
> os/connection.c | 65 +++++++++++++++++++++++++++++++++++++----------------
> os/utils.c | 9 +++++++
> 5 files changed, 63 insertions(+), 20 deletions(-)
>
> diff --git a/dix/globals.c b/dix/globals.c
> index a564575..332b91f 100644
> --- a/dix/globals.c
> +++ b/dix/globals.c
> @@ -128,6 +128,7 @@ int defaultColorVisualClass = -1;
> int monitorResolution = 0;
>
> char *display;
> +int displayfd;
> char *ConnectionInfo;
>
> CARD32 TimeOutValue = DEFAULT_TIMEOUT * MILLI_PER_SECOND;
> diff --git a/include/opaque.h b/include/opaque.h
> index 9ca408a..b76ab6e 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 0cd9b94..8d243d6 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 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),
> diff --git a/os/connection.c b/os/connection.c
> index 1099752..94e565d 100644
> --- a/os/connection.c
> +++ b/os/connection.c
> @@ -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];
> +
> + sprintf(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,38 @@ 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");
> + 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) {
you want this:
- if (!TryCreateSocket(i, &partial) && !partial) {
+ if (TryCreateSocket(i, &partial) && !partial) {
Cheers,
Julien
> + found = 1;
> + break;
> + }
> + else
> + CloseWellKnownConnections();
> }
> - else {
> - ListenTransFds = malloc(ListenTransCount * sizeof(int));
> + if (!found)
> + FatalError("Failed to find a socket to listen on");
> + sprintf(dynamic_display, "%d\n", i);
> + display = dynamic_display;
> + }
>
> - for (i = 0; i < ListenTransCount; i++) {
> - int fd = _XSERVTransGetConnectionNumber(ListenTransConns[i]);
> + ListenTransFds = malloc(ListenTransCount * sizeof (int));
>
> - ListenTransFds[i] = fd;
> - FD_SET(fd, &WellKnownConnections);
> + for (i = 0; i < ListenTransCount; i++) {
> + int fd = _XSERVTransGetConnectionNumber(ListenTransConns[i]);
>
> - if (!_XSERVTransIsLocal(ListenTransConns[i])) {
> - DefineSelf(fd);
> - }
> - }
> - }
> + ListenTransFds[i] = fd;
> + FD_SET(fd, &WellKnownConnections);
> +
> + if (!_XSERVTransIsLocal(ListenTransConns[i]))
> + DefineSelf (fd);
> }
>
> if (!XFD_ANYSET(&WellKnownConnections))
> diff --git a/os/utils.c b/os/utils.c
> index 30592d2..3a1ef93 100644
> --- a/os/utils.c
> +++ b/os/utils.c
> @@ -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 */ ;
> --
> 1.7.9.1
>
More information about the xorg-devel
mailing list