Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

waitforx changes #3297

Merged
merged 1 commit into from
Nov 27, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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