diff options
| -rw-r--r-- | configure.ac | 1 | ||||
| -rw-r--r-- | docs/man/Makefile.am | 3 | ||||
| -rw-r--r-- | docs/man/xrdp-sessvc.8.in | 26 | ||||
| -rw-r--r-- | sesman/Makefile.am | 1 | ||||
| -rw-r--r-- | sesman/scp_v0.c | 6 | ||||
| -rw-r--r-- | sesman/scp_v1.c | 4 | ||||
| -rw-r--r-- | sesman/session.c | 299 | ||||
| -rw-r--r-- | sesman/session.h | 3 | ||||
| -rw-r--r-- | sesman/sessvc/Makefile.am | 16 | ||||
| -rw-r--r-- | sesman/sessvc/sessvc.c | 141 | 
10 files changed, 137 insertions, 363 deletions
diff --git a/configure.ac b/configure.ac index 577777bc..b93cba6e 100644 --- a/configure.ac +++ b/configure.ac @@ -334,7 +334,6 @@ AC_CONFIG_FILES([    sesman/chansrv/Makefile    sesman/libscp/Makefile    sesman/Makefile -  sesman/sessvc/Makefile    sesman/tools/Makefile    vnc/Makefile    xrdpapi/Makefile diff --git a/docs/man/Makefile.am b/docs/man/Makefile.am index f6e0bd5a..841e13e1 100644 --- a/docs/man/Makefile.am +++ b/docs/man/Makefile.am @@ -8,8 +8,7 @@ man_MANS = \    xrdp-keygen.8 \    xrdp-sesadmin.8 \    xrdp-sesman.8 \ -  xrdp-sesrun.8 \ -  xrdp-sessvc.8 +  xrdp-sesrun.8  EXTRA_DIST = $(man_MANS:=.in) diff --git a/docs/man/xrdp-sessvc.8.in b/docs/man/xrdp-sessvc.8.in deleted file mode 100644 index 92ca7c29..00000000 --- a/docs/man/xrdp-sessvc.8.in +++ /dev/null @@ -1,26 +0,0 @@ -.TH "xrdp\-sessvc" "8" "@PACKAGE_VERSION@" "xrdp team" "" -.SH "NAME" -xrdp\-sessvc \- \fBxrdp\fR session supervisor - -.SH "SYNTAX" -.B xrdp\-sessvc -.I x_pid wm_pid - -.SH "DESCRIPTION" -\fBxrdp\-sessvc\fR is the \fBxrdp\fR(8) session supervisor, which monitors the running X server and Windows Manager. -As soon as one of them quits, the other process is terminated as well. -.br -This program is only executed internally by \fBxrdp\-sesman\fP(8). - -.SH "OPTIONS" -.TP -.I x_pid -The process ID of the forked X server to monitor. -.TP -.I wm_pid -The process ID of the forked Window Manager to monitor. - -.SH "SEE ALSO" -.BR xrdp\-sesrun (8). - -for more info on \fBxrdp\fR see http://www.xrdp.org/ diff --git a/sesman/Makefile.am b/sesman/Makefile.am index bef787a3..dfe60dc5 100644 --- a/sesman/Makefile.am +++ b/sesman/Makefile.am @@ -83,5 +83,4 @@ dist_sesmansysconf_SCRIPTS = \  SUBDIRS = \    libscp \    tools \ -  sessvc \    chansrv diff --git a/sesman/scp_v0.c b/sesman/scp_v0.c index a6a1060c..a1c919e2 100644 --- a/sesman/scp_v0.c +++ b/sesman/scp_v0.c @@ -122,18 +122,18 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)                  if (SCP_SESSION_TYPE_XVNC == s->type)                  {                      log_message( LOG_LEVEL_INFO, "starting Xvnc session..."); -                    display = session_start(data, SESMAN_SESSION_TYPE_XVNC, s); +                    display = session_start(data, SESMAN_SESSION_TYPE_XVNC, c, s);                  }                  else if (SCP_SESSION_TYPE_XRDP == s->type)                  {                      log_message(LOG_LEVEL_INFO, "starting X11rdp session..."); -                    display = session_start(data, SESMAN_SESSION_TYPE_XRDP, s); +                    display = session_start(data, SESMAN_SESSION_TYPE_XRDP, c, s);                  }                  else if (SCP_SESSION_TYPE_XORG == s->type)                  {                      /* type is SCP_SESSION_TYPE_XORG */                      log_message(LOG_LEVEL_INFO, "starting Xorg session..."); -                    display = session_start(data, SESMAN_SESSION_TYPE_XORG, s); +                    display = session_start(data, SESMAN_SESSION_TYPE_XORG, c, s);                  }              }              else diff --git a/sesman/scp_v1.c b/sesman/scp_v1.c index 74668efc..f865271b 100644 --- a/sesman/scp_v1.c +++ b/sesman/scp_v1.c @@ -126,12 +126,12 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)          if (SCP_SESSION_TYPE_XVNC == s->type)          {              log_message(LOG_LEVEL_INFO, "starting Xvnc session..."); -            display = session_start(data, SESMAN_SESSION_TYPE_XVNC, s); +            display = session_start(data, SESMAN_SESSION_TYPE_XVNC, c, s);          }          else          {              log_message(LOG_LEVEL_INFO, "starting X11rdp session..."); -            display = session_start(data, SESMAN_SESSION_TYPE_XRDP, s); +            display = session_start(data, SESMAN_SESSION_TYPE_XRDP, c, s);          }          e = scp_v1s_connect_new_session(c, display); diff --git a/sesman/session.c b/sesman/session.c index 1d06b802..8663fc83 100644 --- a/sesman/session.c +++ b/sesman/session.c @@ -269,77 +269,6 @@ x_server_running(int display)  }  /******************************************************************************/ -static void -session_start_sessvc(int xpid, int wmpid, long data, char *username, int display) -{ -    struct list *sessvc_params = (struct list *)NULL; -    char wmpid_str[25]; -    char xpid_str[25]; -    char exe_path[262]; -    int i = 0; - -    /* initialize (zero out) local variables: */ -    g_memset(wmpid_str, 0, sizeof(char) * 25); -    g_memset(xpid_str, 0, sizeof(char) * 25); -    g_memset(exe_path, 0, sizeof(char) * 262); - -    /* new style waiting for clients */ -    g_sprintf(wmpid_str, "%d", wmpid); -    g_sprintf(xpid_str, "%d",  xpid); -    log_message(LOG_LEVEL_INFO, -                "starting xrdp-sessvc - xpid=%s - wmpid=%s", -                xpid_str, wmpid_str); - -    sessvc_params = list_create(); -    sessvc_params->auto_free = 1; - -    /* building parameters */ -    g_snprintf(exe_path, 261, "%s/xrdp-sessvc", XRDP_SBIN_PATH); - -    list_add_item(sessvc_params, (tintptr)g_strdup(exe_path)); -    list_add_item(sessvc_params, (tintptr)g_strdup(xpid_str)); -    list_add_item(sessvc_params, (tintptr)g_strdup(wmpid_str)); -    list_add_item(sessvc_params, 0); /* mandatory */ - -    env_set_user(username, -                 0, -                 display, -                 g_cfg->session_variables1, -                 g_cfg->session_variables2); - -    /* executing sessvc */ -    g_execvp(exe_path, ((char **)sessvc_params->items)); - -    /* should not get here */ -    log_message(LOG_LEVEL_ALWAYS, -                "error starting xrdp-sessvc - pid %d - xpid=%s - wmpid=%s", -                g_getpid(), xpid_str, wmpid_str); - -    /* logging parameters */ -    /* no problem calling strerror for thread safety: other threads -       are blocked */ -    log_message(LOG_LEVEL_DEBUG, "errno: %d, description: %s", -                g_get_errno(), g_get_strerror()); -    log_message(LOG_LEVEL_DEBUG, "execve parameter list:"); - -    for (i = 0; i < (sessvc_params->count); i++) -    { -        log_message(LOG_LEVEL_DEBUG, "        argv[%d] = %s", i, -                    (char *)list_get_item(sessvc_params, i)); -    } - -    list_delete(sessvc_params); - -    /* keep the old waitpid if some error occurs during execlp */ -    g_waitpid(wmpid); -    g_sigterm(xpid); -    g_sigterm(wmpid); -    g_sleep(1000); -    auth_end(data); -    g_exit(0); -} - -/******************************************************************************/  /* called with the main thread     returns boolean */  static int @@ -420,15 +349,49 @@ wait_for_xserver(int display)  }  /******************************************************************************/ +static int +session_start_chansrv(char *username, int display) +{ +    struct list *chansrv_params; +    char exe_path[262]; +    int chansrv_pid; + +    chansrv_pid = g_fork(); +    if (chansrv_pid == 0) +    { +        chansrv_params = list_create();  +        chansrv_params->auto_free = 1; + +        /* building parameters */ +        g_snprintf(exe_path, sizeof(exe_path), "%s/xrdp-chansrv", +                   XRDP_SBIN_PATH); + +        list_add_item(chansrv_params, (intptr_t) g_strdup(exe_path)); +        list_add_item(chansrv_params, 0); /* mandatory */ + +        env_set_user(username, 0, display, +                     g_cfg->session_variables1, +                     g_cfg->session_variables2); + +        /* executing chansrv */ +        g_execvp(exe_path, (char **) (chansrv_params->items)); +        /* should not get here */ +        log_message(LOG_LEVEL_ALWAYS, "error starting chansrv " +                    "- user %s - pid %d", username, g_getpid()); +        list_delete(chansrv_params); +        g_exit(1); +    } +    return chansrv_pid; +} + +/******************************************************************************/  /* called with the main thread */  static int -session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s) +session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c, +                   struct SCP_SESSION *s)  {      int display = 0;      int pid = 0; -    int wmpid = 0; -    int pampid = 0; -    int xpid = 0;      int i = 0;      char geometry[32];      char depth[32]; @@ -443,6 +406,9 @@ session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s)      struct tm stime;      time_t ltime;      char authfile[256]; /* The filename for storing xauth informations */ +    int chansrv_pid; +    int display_pid; +    int window_manager_pid;      /* initialize (zero out) local variables: */      g_memset(<ime, 0, sizeof(time_t)); @@ -500,6 +466,7 @@ session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s)      {          g_delete_wait_obj(g_term_event);          g_tcp_close(g_sck); +        g_tcp_close(c->in_sck);          g_sprintf(geometry, "%dx%d", s->width, s->height);          g_sprintf(depth, "%d", s->bpp);          g_sprintf(screen, ":%d", display); @@ -531,118 +498,103 @@ session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s)                          g_getpid());          }  #endif -        wmpid = g_fork(); /* parent becomes X, +        auth_start_session(data, display); +        window_manager_pid = g_fork(); /* parent becomes X,                               child forks wm, and waits, todo */ -        if (wmpid == -1) +        if (window_manager_pid == -1)          {          } -        else if (wmpid == 0) +        else if (window_manager_pid == 0)          {              wait_for_xserver(display); -            auth_start_session(data, display); -            pampid = g_fork(); /* parent waits, todo -                                  child becomes wm */ -            if (pampid == -1) -            { -            } -            else if (pampid == 0) +            env_set_user(s->username, +                         0, +                         display, +                         g_cfg->session_variables1, +                         g_cfg->session_variables2); +            if (x_server_running(display))              { -                env_set_user(s->username, -                             0, -                             display, -                             g_cfg->session_variables1, -                             g_cfg->session_variables2); -                if (x_server_running(display)) +                auth_set_env(data); +                if (s->directory != 0)                  { -                    auth_set_env(data); -                    if (s->directory != 0) +                    if (s->directory[0] != 0)                      { -                        if (s->directory[0] != 0) -                        { -                            g_set_current_dir(s->directory); -                        } +                        g_set_current_dir(s->directory);                      } -                    if (s->program != 0) -                    { -                        if (s->program[0] != 0) -                        { -                            g_execlp3(s->program, s->program, 0); -                            log_message(LOG_LEVEL_ALWAYS, -                                        "error starting program %s for user %s - pid %d", -                                        s->program, s->username, g_getpid()); -                        } -                    } -                    /* try to execute user window manager if enabled */ -                    if (g_cfg->enable_user_wm) +                } +                if (s->program != 0) +                { +                    if (s->program[0] != 0)                      { -                        g_sprintf(text, "%s/%s", g_getenv("HOME"), g_cfg->user_wm); -                        if (g_file_exist(text)) -                        { -                            g_execlp3(text, g_cfg->user_wm, 0); -                            log_message(LOG_LEVEL_ALWAYS, "error starting user " -                                        "wm for user %s - pid %d", s->username, g_getpid()); -                            /* logging parameters */ -                            log_message(LOG_LEVEL_DEBUG, "errno: %d, " -                                        "description: %s", g_get_errno(), g_get_strerror()); -                            log_message(LOG_LEVEL_DEBUG, "execlp3 parameter " -                                        "list:"); -                            log_message(LOG_LEVEL_DEBUG, "        argv[0] = %s", -                                        text); -                            log_message(LOG_LEVEL_DEBUG, "        argv[1] = %s", -                                        g_cfg->user_wm); -                        } +                        g_execlp3(s->program, s->program, 0); +                        log_message(LOG_LEVEL_ALWAYS, +                                    "error starting program %s for user %s - pid %d", +                                    s->program, s->username, g_getpid());                      } -                    /* if we're here something happened to g_execlp3 -                       so we try running the default window manager */ -                    g_sprintf(text, "%s/%s", XRDP_CFG_PATH, g_cfg->default_wm); -                    g_execlp3(text, g_cfg->default_wm, 0); - -                    log_message(LOG_LEVEL_ALWAYS, "error starting default " -                                 "wm for user %s - pid %d", s->username, g_getpid()); -                    /* logging parameters */ -                    log_message(LOG_LEVEL_DEBUG, "errno: %d, description: " -                                "%s", g_get_errno(), g_get_strerror()); -                    log_message(LOG_LEVEL_DEBUG, "execlp3 parameter list:"); -                    log_message(LOG_LEVEL_DEBUG, "        argv[0] = %s", -                                text); -                    log_message(LOG_LEVEL_DEBUG, "        argv[1] = %s", -                                g_cfg->default_wm); - -                    /* still a problem starting window manager just start xterm */ -                    g_execlp3("xterm", "xterm", 0); - -                    /* should not get here */ -                    log_message(LOG_LEVEL_ALWAYS, "error starting xterm " -                                "for user %s - pid %d", s->username, g_getpid()); -                    /* logging parameters */ -                    log_message(LOG_LEVEL_DEBUG, "errno: %d, description: " -                                "%s", g_get_errno(), g_get_strerror());                  } -                else +                /* try to execute user window manager if enabled */ +                if (g_cfg->enable_user_wm)                  { -                    log_message(LOG_LEVEL_ERROR, "another Xserver might " -                                "already be active on display %d - see log", display); +                    g_sprintf(text, "%s/%s", g_getenv("HOME"), g_cfg->user_wm); +                    if (g_file_exist(text)) +                    { +                        g_execlp3(text, g_cfg->user_wm, 0); +                        log_message(LOG_LEVEL_ALWAYS, "error starting user " +                                    "wm for user %s - pid %d", s->username, g_getpid()); +                        /* logging parameters */ +                        log_message(LOG_LEVEL_DEBUG, "errno: %d, " +                                    "description: %s", g_get_errno(), g_get_strerror()); +                        log_message(LOG_LEVEL_DEBUG, "execlp3 parameter " +                                    "list:"); +                        log_message(LOG_LEVEL_DEBUG, "        argv[0] = %s", +                                    text); +                        log_message(LOG_LEVEL_DEBUG, "        argv[1] = %s", +                                    g_cfg->user_wm); +                    }                  } +                /* if we're here something happened to g_execlp3 +                   so we try running the default window manager */ +                g_sprintf(text, "%s/%s", XRDP_CFG_PATH, g_cfg->default_wm); +                g_execlp3(text, g_cfg->default_wm, 0); -                log_message(LOG_LEVEL_DEBUG, "aborting connection..."); -                g_exit(0); +                log_message(LOG_LEVEL_ALWAYS, "error starting default " +                             "wm for user %s - pid %d", s->username, g_getpid()); +                /* logging parameters */ +                log_message(LOG_LEVEL_DEBUG, "errno: %d, description: " +                            "%s", g_get_errno(), g_get_strerror()); +                log_message(LOG_LEVEL_DEBUG, "execlp3 parameter list:"); +                log_message(LOG_LEVEL_DEBUG, "        argv[0] = %s", +                            text); +                log_message(LOG_LEVEL_DEBUG, "        argv[1] = %s", +                            g_cfg->default_wm); + +                /* still a problem starting window manager just start xterm */ +                g_execlp3("xterm", "xterm", 0); + +                /* should not get here */ +                log_message(LOG_LEVEL_ALWAYS, "error starting xterm " +                            "for user %s - pid %d", s->username, g_getpid()); +                /* logging parameters */ +                log_message(LOG_LEVEL_DEBUG, "errno: %d, description: " +                            "%s", g_get_errno(), g_get_strerror());              }              else              { -                g_waitpid(pampid); -                auth_stop_session(data); -                g_deinit(); -                g_exit(0); +                log_message(LOG_LEVEL_ERROR, "another Xserver might " +                            "already be active on display %d - see log", display);              } + +            log_message(LOG_LEVEL_DEBUG, "aborting connection..."); +            g_exit(0);          }          else          { -            xpid = g_fork(); /* parent becomes scp, +            display_pid = g_fork(); /* parent becomes scp,                                  child becomes X */ -            if (xpid == -1) +            if (display_pid == -1)              {              } -            else if (xpid == 0) /* child */ +            else if (display_pid == 0) /* child */              {                  if (type == SESMAN_SESSION_TYPE_XVNC)                  { @@ -829,12 +781,18 @@ session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s)              else              {                  wait_for_xserver(display); -                g_snprintf(text, 255, "%d", display); -                g_setenv("XRDP_SESSVC_DISPLAY", text, 1); -                g_snprintf(text, 255, ":%d.0", display); -                g_setenv("DISPLAY", text, 1); -                /* new style waiting for clients */ -                session_start_sessvc(xpid, wmpid, data, s->username, display); +                chansrv_pid = session_start_chansrv(s->username, display); +                log_message(LOG_LEVEL_ALWAYS, "waiting for window manager " +                            "(pid %d) to exit", window_manager_pid); +                g_waitpid(window_manager_pid); +                log_message(LOG_LEVEL_ALWAYS, "window manager (pid %d) did " +                            "exit, cleaning up session", window_manager_pid); +                auth_stop_session(data); +                auth_end(data); +                g_sigterm(display_pid); +                g_sigterm(chansrv_pid); +                g_deinit(); +                g_exit(0);              }          }      } @@ -912,9 +870,10 @@ session_reconnect_fork(int display, char *username)  /* called by a worker thread, ask the main thread to call session_sync_start     and wait till done */  int -session_start(long data, tui8 type, struct SCP_SESSION *s) +session_start(long data, tui8 type, struct SCP_CONNECTION *c, +              struct SCP_SESSION *s)  { -    return session_start_fork(data, type, s); +    return session_start_fork(data, type, c, s);  }  /******************************************************************************/ diff --git a/sesman/session.h b/sesman/session.h index 4533a1a1..a9884a21 100644 --- a/sesman/session.h +++ b/sesman/session.h @@ -105,7 +105,8 @@ session_get_bydata(const char *name, int width, int height, int bpp, int type,   *   */  int -session_start(long data, tui8 type, struct SCP_SESSION *s); +session_start(long data, tui8 type, struct SCP_CONNECTION *c, +              struct SCP_SESSION *s);  int  session_reconnect(int display, char* username); diff --git a/sesman/sessvc/Makefile.am b/sesman/sessvc/Makefile.am deleted file mode 100644 index c2714b94..00000000 --- a/sesman/sessvc/Makefile.am +++ /dev/null @@ -1,16 +0,0 @@ - -AM_CPPFLAGS = \ -  -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \ -  -DXRDP_SBIN_PATH=\"${sbindir}\" \ -  -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \ -  -DXRDP_PID_PATH=\"${localstatedir}/run\" \ -  -I$(top_srcdir)/common - -sbin_PROGRAMS = \ -  xrdp-sessvc - -xrdp_sessvc_SOURCES = \ -  sessvc.c - -xrdp_sessvc_LDADD = \ -  $(top_builddir)/common/libcommon.la diff --git a/sesman/sessvc/sessvc.c b/sesman/sessvc/sessvc.c deleted file mode 100644 index c247027c..00000000 --- a/sesman/sessvc/sessvc.c +++ /dev/null @@ -1,141 +0,0 @@ -/** - * xrdp: A Remote Desktop Protocol server. - * - * Copyright (C) Jay Sorg 2004-2013 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - *     http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * - * @file sessvc.c - * @brief Session supervisor - * @author Simone Fedele - * - */ - -#if defined(HAVE_CONFIG_H) -#include "config_ac.h" -#endif -#include "file_loc.h" -#include "os_calls.h" -#include "arch.h" - -static int g_term = 0; - -/*****************************************************************************/ -void -term_signal_handler(int sig) -{ -    g_writeln("xrdp-sessvc: term_signal_handler: got signal %d", sig); -    g_term = 1; -} - -/*****************************************************************************/ -void -nil_signal_handler(int sig) -{ -    g_writeln("xrdp-sessvc: nil_signal_handler: got signal %d", sig); -} - -/******************************************************************************/ -int -main(int argc, char **argv) -{ -    int ret = 0; -    int chansrv_pid = 0; -    int wm_pid = 0; -    int x_pid = 0; -    int lerror = 0; -    char exe_path[262]; - -    g_init("xrdp-sessvc"); -    g_memset(exe_path, 0, sizeof(exe_path)); - -    if (argc < 3) -    { -        g_writeln("xrdp-sessvc: exiting, not enough parameters"); -        g_deinit(); -        return 1; -    } - -    g_signal_terminate(term_signal_handler); /* SIGTERM */ -    g_signal_user_interrupt(term_signal_handler); /* SIGINT */ -    g_signal_pipe(nil_signal_handler); /* SIGPIPE */ -    x_pid = g_atoi(argv[1]); -    wm_pid = g_atoi(argv[2]); -    g_writeln("xrdp-sessvc: waiting for X (pid %d) and WM (pid %d)", -              x_pid, wm_pid); -    /* run xrdp-chansrv as a separate process */ -    chansrv_pid = g_fork(); - -    if (chansrv_pid == -1) -    { -        g_writeln("xrdp-sessvc: fork error"); -        g_deinit(); -        return 1; -    } -    else if (chansrv_pid == 0) /* child */ -    { -        g_set_current_dir(XRDP_SBIN_PATH); -        g_snprintf(exe_path, 261, "%s/xrdp-chansrv", XRDP_SBIN_PATH); -        g_execlp3(exe_path, "xrdp-chansrv", 0); -        /* should not get here */ -        g_writeln("xrdp-sessvc: g_execlp3() failed"); -        g_deinit(); -        return 1; -    } - -    lerror = 0; -    /* wait for window manager to get done */ -    ret = g_waitpid(wm_pid); - -    while ((ret == 0) && !g_term) -    { -        ret = g_waitpid(wm_pid); -        g_sleep(1); -    } - -    if (ret < 0) -    { -        lerror = g_get_errno(); -    } - -    g_writeln("xrdp-sessvc: WM is dead (waitpid said %d, errno is %d) " -              "exiting...", ret, lerror); -    /* kill channel server */ -    g_writeln("xrdp-sessvc: stopping channel server"); -    g_sigterm(chansrv_pid); -    ret = g_waitpid(chansrv_pid); - -    while ((ret == 0) && !g_term) -    { -        ret = g_waitpid(chansrv_pid); -        g_sleep(1); -    } - -    /* kill X server */ -    g_writeln("xrdp-sessvc: stopping X server"); -    g_sigterm(x_pid); -    ret = g_waitpid(x_pid); - -    while ((ret == 0) && !g_term) -    { -        ret = g_waitpid(x_pid); -        g_sleep(1); -    } - -    g_writeln("xrdp-sessvc: clean exit"); -    g_deinit(); -    return 0; -}  | 
