[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