Skip to content

Commit

Permalink
waitforx changes
Browse files Browse the repository at this point in the history
1) Changed alarm message from "Timed out waiting for RandR outputs" to
   "Timed out waiting for X display". The former was confusing, and the
   times where this message was triggered were nothing to do with
   RandR
2) Don't try to open a display of the form ":n" or ":n.m" directly
   (n,m >= 0). If the X server hasn't yet opened its local socket,
   the XOpenDisplay() call can go to the network and possibly block
   for a long time. Instead, use the (undocumented) "unix:n" display
   specification, whih never goes to the network, and doesn't block.
  • Loading branch information
matt335672 committed Nov 27, 2024
1 parent a0989d9 commit 80fab03
Showing 1 changed file with 57 additions and 2 deletions.
59 changes: 57 additions & 2 deletions waitforx/waitforx.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/signal.h>
#include <unistd.h>

Expand All @@ -21,11 +22,48 @@ alarm_handler(int signal_num)
*
* Prefix the message with a newline in case another message
* has been partly output */
const char msg[] = "\n<E>Timed out waiting for RandR outputs\n";
const char msg[] = "\n<E>Timed out waiting for X display\n";
g_file_write(1, msg, g_strlen(msg));
exit(XW_STATUS_TIMED_OUT);
}

/*****************************************************************************/
/***
* Checks whether display is local.
*
* Local displays are of the form ':n' or ':n.m' where 'n' and 'm'
* are unsigned numbers
*
* @param display Display string
* @return boolean
*/
static int
is_local_display(const char *display)
{
int result = 0;
if (display != NULL && *display++ == ':' && isdigit(*display))
{
do
{
++display;
}
while (isdigit(*display));

// Skip the optional screen identifier
if (*display == '.' && isdigit(*(display + 1)))
{
do
{
++display;
}
while (isdigit(*display));
}

result = (*display == '\0');
}
return result;
}

/*****************************************************************************/
static Display *
open_display(const char *display)
Expand All @@ -36,7 +74,7 @@ open_display(const char *display)

for (n = 1; n <= ATTEMPTS; ++n)
{
printf("<D>Opening display %s. Attempt %u of %u\n", display, n, wait);
printf("<D>Opening display '%s'. Attempt %u of %u\n", display, n, wait);
dpy = XOpenDisplay(display);
if (dpy != NULL)
{
Expand Down Expand Up @@ -112,6 +150,7 @@ usage(const char *argv0, int status)
int
main(int argc, char **argv)
{
char unix_display[64]; // Used for local (unix) displays only
const char *display_name = NULL;
int opt;
int status = XW_STATUS_MISC_ERROR;
Expand Down Expand Up @@ -140,6 +179,22 @@ main(int argc, char **argv)

g_set_alarm(alarm_handler, ALARM_WAIT);

if (is_local_display(display_name))
{
// Don't use the raw display value, as this goes to the
// network if the X server port is not yet open. This can
// block if the network is configured in an unexpected way,
// which leads to use failing to detect the X server starting
// up shortly after.
//
// This code attempts to use a string such as "unix:10" to open
// the display. This is undocumented in the X11 man pages but
// is implemented in _xcb_open() from libxcb
// (which libX11 is now layered on).
snprintf(unix_display, sizeof(unix_display), "unix%s", display_name);
display_name = unix_display;
}

dpy = open_display(display_name);
if (!dpy)
{
Expand Down

0 comments on commit 80fab03

Please sign in to comment.