Skip to content
Merged
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ SUBDIRS = \
xrdp \
fontutils \
keygen \
waitforx \
docs \
instfiles \
genkeymap \
Expand Down
16 changes: 16 additions & 0 deletions common/os_calls.c
Original file line number Diff line number Diff line change
Expand Up @@ -2808,6 +2808,22 @@ g_execlp3(const char *a1, const char *a2, const char *a3)
#endif
}

/*****************************************************************************/
/* does not work in win32 */
unsigned int
g_set_alarm(void (*func)(int), unsigned int secs)
{
#if defined(_WIN32)
return 0;
#else
/* Cancel any previous alarm to prevent a race */
unsigned int rv = alarm(0);
signal(SIGALRM, func);
(void)alarm(secs);
return rv;
#endif
}

/*****************************************************************************/
/* does not work in win32 */
void
Expand Down
1 change: 1 addition & 0 deletions common/os_calls.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ char *g_get_strerror(void);
int g_get_errno(void);
int g_execvp(const char *p1, char *args[]);
int g_execlp3(const char *a1, const char *a2, const char *a3);
unsigned int g_set_alarm(void (*func)(int), unsigned int secs);
void g_signal_child_stop(void (*func)(int));
void g_signal_segfault(void (*func)(int));
void g_signal_hang_up(void (*func)(int));
Expand Down
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,7 @@ AC_CONFIG_FILES([
instfiles/pulse/Makefile
instfiles/rc.d/Makefile
keygen/Makefile
waitforx/Makefile
libipm/Makefile
libxrdp/Makefile
Makefile
Expand Down
5 changes: 4 additions & 1 deletion sesman/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ AM_CPPFLAGS = \
-DXRDP_SYSCONF_PATH=\"${sysconfdir}\" \
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
-DXRDP_SBIN_PATH=\"${sbindir}\" \
-DXRDP_BIN_PATH=\"${bindir}\" \
-DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
-DXRDP_PID_PATH=\"${localstatedir}/run\" \
-DXRDP_SOCKET_PATH=\"${socketdir}\" \
Expand Down Expand Up @@ -34,7 +35,9 @@ xrdp_sesman_SOURCES = \
sig.c \
sig.h \
xauth.c \
xauth.h
xauth.h \
xwait.c \
xwait.h

# Possible authentication modules
# See https://www.gnu.org/software/automake/manual/html_node/Conditional-Sources.html
Expand Down
72 changes: 2 additions & 70 deletions sesman/session.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#include "sesman.h"
#include "string_calls.h"
#include "xauth.h"
#include "xwait.h"
#include "xrdp_sockets.h"

#ifndef PR_SET_NO_NEW_PRIVS
Expand Down Expand Up @@ -285,42 +286,6 @@ x_server_running_check_ports(int display)
return x_running;
}

/******************************************************************************/
/**
*
* @brief checks if there's a server running on a display
* @param display the display to check
* @return 0 if there isn't a display running, nonzero otherwise
*
*/
static int
x_server_running(int display)
{
char text[256];
int x_running;

g_sprintf(text, "/tmp/.X11-unix/X%d", display);
x_running = g_file_exist(text);

if (!x_running)
{
LOG(LOG_LEVEL_DEBUG, "Did not find a running X server at %s", text);
g_sprintf(text, "/tmp/.X%d-lock", display);
x_running = g_file_exist(text);
}

if (x_running)
{
LOG(LOG_LEVEL_INFO, "Found X server running at %s", text);
}
else
{
LOG(LOG_LEVEL_DEBUG, "Did not find a running X server at %s", text);
}

return x_running;
}

/******************************************************************************/
/* called with the main thread
returns boolean */
Expand Down Expand Up @@ -375,37 +340,6 @@ session_get_avail_display_from_chain(void)
return 0;
}

/******************************************************************************/
static int
wait_for_xserver(int display)
{
int i;

/* give X a bit to start */
/* wait up to 10 secs for x server to start */
i = 0;

LOG(LOG_LEVEL_DEBUG, "Waiting for X server to start on display %d", display);

while (!x_server_running(display))
{
i++;

if (i > 40)
{
LOG(LOG_LEVEL_WARNING,
"Timed out waiting for X server on display %d to startup",
display);
break;
}

g_sleep(250);
}

return 0;
}

/******************************************************************************/
static int
session_start_chansrv(int uid, int display)
{
Expand Down Expand Up @@ -655,13 +589,12 @@ session_start(struct auth_info *auth_info,
}
else if (window_manager_pid == 0)
{
wait_for_xserver(display);
env_set_user(s->uid,
0,
display,
g_cfg->env_names,
g_cfg->env_values);
if (x_server_running(display))
if (wait_for_xserver(display))
{
auth_set_env(auth_info);
if (s->directory != 0)
Expand Down Expand Up @@ -912,7 +845,6 @@ session_start(struct auth_info *auth_info,
struct exit_status xserver_exit_status;
struct exit_status chansrv_exit_status;

wait_for_xserver(display);
chansrv_pid = session_start_chansrv(s->uid, display);

LOG(LOG_LEVEL_INFO,
Expand Down
47 changes: 47 additions & 0 deletions sesman/xwait.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#if defined(HAVE_CONFIG_H)
#include "config_ac.h"
#endif

#include "log.h"
#include "os_calls.h"
#include "string_calls.h"
#include "xwait.h"

#include <stdio.h>
#include <string.h>

/******************************************************************************/
int
wait_for_xserver(int display)
{
FILE *dp = NULL;
int ret = 0;
char buffer[100];
char exe_cmd[262];

LOG(LOG_LEVEL_DEBUG, "Waiting for X server to start on display %d", display);

g_snprintf(exe_cmd, sizeof(exe_cmd), "%s/xrdp-waitforx", XRDP_BIN_PATH);
dp = popen(exe_cmd, "r");
if (dp == NULL)
{
LOG(LOG_LEVEL_ERROR, "Unable to launch xrdp-waitforx");
return 1;
}

while (fgets(buffer, 100, dp))
{
g_strtrim(buffer, 2);
LOG(LOG_LEVEL_DEBUG, "%s", buffer);
}

ret = pclose(dp);
if (ret != 0)
{
LOG(LOG_LEVEL_ERROR, "An error occurred while running xrdp-waitforx");
return 0;
}


return 1;
}
12 changes: 12 additions & 0 deletions sesman/xwait.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef XWAIT_H
#define XWAIT_H
/**
*
* @brief waits for X to start
* @param display number
* @return 0 on error, 1 if X has outputs
*
*/
int
wait_for_xserver(int display);
#endif
10 changes: 10 additions & 0 deletions waitforx/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
bin_PROGRAMS = \
xrdp-waitforx

AM_LDFLAGS = -lX11 -lXrandr
AM_CFLAGS = -I$(top_srcdir)/common

xrdp_waitforx_SOURCES = waitforx.c

xrdp_waitforx_LDADD = \
$(top_builddir)/common/libcommon.la
101 changes: 101 additions & 0 deletions waitforx/waitforx.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#include <X11/extensions/Xrandr.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/signal.h>
#include <unistd.h>

#include "config_ac.h"
#include "os_calls.h"
#include "string_calls.h"

#define ATTEMPTS 10
#define ALARM_WAIT 30

void
alarm_handler(int signal_num)
{
/* Avoid printf() in signal handler (see signal-safety(7)) */
const char msg[] = "Timed out waiting for RandR outputs\n";
g_file_write(1, msg, g_strlen(msg));
exit(1);
}

int
main(int argc, char **argv)
{
char *display = NULL;
int error_base = 0;
int event_base = 0;
int n = 0;
int outputs = 0;
int wait = ATTEMPTS;

Display *dpy = NULL;
XRRScreenResources *res = NULL;

display = getenv("DISPLAY");

g_set_alarm(alarm_handler, ALARM_WAIT);

if (!display)
{
printf("DISPLAY is null");
exit(1);
}

for (n = 1; n <= wait; ++n)
{
dpy = XOpenDisplay(display);
printf("Opening display %s. Attempt %d of %d\n", display, n, wait);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using printf here raises an interesting question about some of the wrapper functions in common/os_calls.h.

Other bits of xrdp using printf() rather than g_printf()

Personally I can't see that we gain anything by using g_printf() over printf(). I think we should (over time) be removing the wrappers for standard C functions and simply use the <stdio.h> (etc) includes.

@metalefty - what's your take on this? Should we start a discussion?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding printf(), I personally think I would like to quit using wrapper function and use printf() directly.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I'll start a discussion about this.

if (dpy != NULL)
{
printf("Opened display %s\n", display);
break;
}
g_sleep(1000);
}

if (!dpy)
{
printf("Unable to open display %s\n", display);
exit(1);
}

if (!XRRQueryExtension(dpy, &event_base, &error_base))
{
printf("RandR not supported on display %s", display);
}
else
{
for (n = 1; n <= wait; ++n)
{
res = XRRGetScreenResources(dpy, DefaultRootWindow(dpy));
printf("Waiting for outputs. Attempt %d of %d\n", n, wait);
if (res != NULL)
{
if (res->noutput > 0)
{
outputs = res->noutput;
XRRFreeScreenResources(res);
printf("Found %d output[s]\n", outputs);
break;
}
XRRFreeScreenResources(res);
}
g_sleep(1000);
}

if (outputs > 0)
{
printf("display %s ready with %d outputs\n", display, res->noutput);
}
else
{
printf("Unable to find any outputs\n");
exit(1);
}
}

exit(0);
}