diff options
author | Jay Sorg <jay.sorg@gmail.com> | 2012-07-31 16:54:54 -0700 |
---|---|---|
committer | Jay Sorg <jay.sorg@gmail.com> | 2012-07-31 16:54:54 -0700 |
commit | 02751f91a3c90651becf552729f86a37ec7055e1 (patch) | |
tree | 24d8008dbb3a4699749a113a78612eb13bbfecab /sesman/chansrv | |
parent | 536a8eea66b1f27e4f8e8489124eeb11832f1f6e (diff) | |
download | xrdp-proprietary-02751f91a3c90651becf552729f86a37ec7055e1.tar.gz xrdp-proprietary-02751f91a3c90651becf552729f86a37ec7055e1.zip |
rail: implement TS_RAIL_ORDER_EXEC
Diffstat (limited to 'sesman/chansrv')
-rw-r--r-- | sesman/chansrv/chansrv.c | 65 | ||||
-rw-r--r-- | sesman/chansrv/rail.c | 80 |
2 files changed, 136 insertions, 9 deletions
diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c index 2877a376..aefa8791 100644 --- a/sesman/chansrv/chansrv.c +++ b/sesman/chansrv/chansrv.c @@ -52,6 +52,11 @@ int g_rdpsnd_chan_id = -1; /* rdpsnd */ int g_rdpdr_chan_id = -1; /* rdpdr */ int g_rail_chan_id = -1; /* rail */ +char* g_exec_name; +tbus g_exec_event; +tbus g_exec_mutex; +tbus g_exec_sem; + /*****************************************************************************/ /* returns error */ int APP_CC @@ -544,7 +549,20 @@ void DEFAULT_CC nil_signal_handler(int sig) { LOGM((LOG_LEVEL_INFO, "nil_signal_handler: got signal %d", sig)); - g_set_wait_obj(g_term_event); +} + +/*****************************************************************************/ +void DEFAULT_CC +child_signal_handler(int sig) +{ + int i1; + + LOG(10, ("child_signal_handler:")); + do + { + i1 = g_waitchild(); + LOG(10, (" %d", i1)); + } while (i1 >= 0); } /*****************************************************************************/ @@ -609,6 +627,8 @@ main_cleanup(void) { g_delete_wait_obj(g_term_event); g_delete_wait_obj(g_thread_done_event); + g_delete_wait_obj(g_exec_event); + tc_mutex_delete(g_exec_mutex); g_deinit(); /* os_calls */ return 0; } @@ -652,9 +672,34 @@ read_ini(void) } /*****************************************************************************/ +static int APP_CC +run_exec(void) +{ + int pid; + + LOG(10, ("run_exec:")); + pid = g_fork(); + if (pid == 0) + { + trans_delete(g_con_trans); + g_close_wait_obj(g_term_event); + g_close_wait_obj(g_thread_done_event); + g_close_wait_obj(g_exec_event); + tc_mutex_delete(g_exec_mutex); + tc_sem_delete(g_exec_sem); + g_execlp3(g_exec_name, g_exec_name, 0); + g_exit(0); + } + tc_sem_inc(g_exec_sem); + + return 0; +} + +/*****************************************************************************/ int DEFAULT_CC main(int argc, char** argv) { + tbus waiters[4]; int pid = 0; char text[256] = ""; char* display_text = (char *)NULL; @@ -696,6 +741,7 @@ main(int argc, char** argv) g_signal_terminate(term_signal_handler); /* SIGTERM */ g_signal_user_interrupt(term_signal_handler); /* SIGINT */ g_signal_pipe(nil_signal_handler); /* SIGPIPE */ + g_signal_child_stop(child_signal_handler); /* SIGCHLD */ display_text = g_getenv("DISPLAY"); LOGM((LOG_LEVEL_INFO, "main: DISPLAY env var set to %s", display_text)); get_display_num_from_display(display_text); @@ -709,14 +755,29 @@ main(int argc, char** argv) g_term_event = g_create_wait_obj(text); g_snprintf(text, 255, "xrdp_chansrv_%8.8x_thread_done", pid); g_thread_done_event = g_create_wait_obj(text); + g_snprintf(text, 255, "xrdp_chansrv_%8.8x_exec", pid); + g_exec_event = g_create_wait_obj(text); + g_exec_mutex = tc_mutex_create(); + g_exec_sem = tc_sem_create(0); tc_thread_create(channel_thread_loop, 0); while (g_term_event > 0 && !g_is_wait_obj_set(g_term_event)) { - if (g_obj_wait(&g_term_event, 1, 0, 0, 0) != 0) + waiters[0] = g_term_event; + waiters[1] = g_exec_event; + if (g_obj_wait(waiters, 2, 0, 0, 0) != 0) { LOGM((LOG_LEVEL_ERROR, "main: error, g_obj_wait failed")); break; } + if (g_is_wait_obj_set(g_term_event)) + { + break; + } + if (g_is_wait_obj_set(g_exec_event)) + { + g_reset_wait_obj(g_exec_event); + run_exec(); + } } while (g_thread_done_event > 0 && !g_is_wait_obj_set(g_thread_done_event)) { diff --git a/sesman/chansrv/rail.c b/sesman/chansrv/rail.c index 25c21bee..6b47f867 100644 --- a/sesman/chansrv/rail.c +++ b/sesman/chansrv/rail.c @@ -27,9 +27,14 @@ #include "xcommon.h" #include "log.h" #include "os_calls.h" +#include "thread_calls.h" extern int g_rail_chan_id; /* in chansrv.c */ extern int g_display_num; /* in chansrv.c */ +extern char* g_exec_name; /* in chansrv.c */ +extern tbus g_exec_event; /* in chansrv.c */ +extern tbus g_exec_mutex; /* in chansrv.c */ +extern tbus g_exec_sem; /* in chansrv.c */ extern Display* g_display; /* in xcommon.c */ extern Screen* g_screen; /* in xcommon.c */ @@ -207,14 +212,75 @@ rail_deinit(void) } /*****************************************************************************/ +static char* APP_CC +read_uni(struct stream* s, int num_chars) +{ + twchar* rchrs; + char* rv; + int index; + int lchars; + + rchrs = 0; + rv = 0; + if (num_chars > 0) + { + rchrs = (twchar*)g_malloc((num_chars + 1) * sizeof(twchar), 0); + for (index = 0; index < num_chars; index++) + { + in_uint16_le(s, rchrs[index]); + } + rchrs[num_chars] = 0; + lchars = g_wcstombs(0, rchrs, 0); + if (lchars > 0) + { + rv = (char*)g_malloc((lchars + 1) * 4, 0); + g_wcstombs(rv, rchrs, lchars); + rv[lchars] = 0; + } + } + g_free(rchrs); + return rv; +} + +/*****************************************************************************/ static int APP_CC rail_process_exec(struct stream* s, int size) { + int pid; int flags; - - LOG(10, ("chansrv::rail_process_exec:")); + int ExeOrFileLength; + int WorkingDirLength; + int ArgumentsLen; + char* ExeOrFile; + char* WorkingDir; + char* Arguments; + + LOG(0, ("chansrv::rail_process_exec:")); in_uint16_le(s, flags); - LOG(10, (" flags 0x%8.8x", flags)); + in_uint16_le(s, ExeOrFileLength); + in_uint16_le(s, WorkingDirLength); + in_uint16_le(s, ArgumentsLen); + ExeOrFile = read_uni(s, ExeOrFileLength); + WorkingDir = read_uni(s, WorkingDirLength); + Arguments = read_uni(s, ArgumentsLen); + LOG(10, (" flags 0x%8.8x ExeOrFileLength %d WorkingDirLength %d " + "ArgumentsLen %d ExeOrFile [%s] WorkingDir [%s] " + "Arguments [%s]", flags, ExeOrFileLength, WorkingDirLength, + ArgumentsLen, ExeOrFile, WorkingDir, Arguments)); + if (g_strlen(ExeOrFile) > 0) + { + LOG(10, ("rail_process_exec: pre")); + /* ask main thread to fork */ + tc_mutex_lock(g_exec_mutex); + g_exec_name = ExeOrFile; + g_set_wait_obj(g_exec_event); + tc_sem_dec(g_exec_sem); + tc_mutex_unlock(g_exec_mutex); + LOG(10, ("rail_process_exec: post")); + } + g_free(ExeOrFile); + g_free(WorkingDir); + g_free(Arguments); return 0; } @@ -231,9 +297,9 @@ rail_process_activate(struct stream* s, int size) LOG(10, (" window_id 0x%8.8x enabled %d", window_id, enabled)); if (enabled) { - LOG(0, ("chansrv::rail_process_activate: calling XRaiseWindow 0x%8.8x", window_id)); + LOG(10, ("chansrv::rail_process_activate: calling XRaiseWindow 0x%8.8x", window_id)); XRaiseWindow(g_display, window_id); - LOG(0, ("chansrv::rail_process_activate: calling XSetInputFocus 0x%8.8x", window_id)); + LOG(10, ("chansrv::rail_process_activate: calling XSetInputFocus 0x%8.8x", window_id)); XSetInputFocus(g_display, window_id, RevertToParent, CurrentTime); } return 0; @@ -354,13 +420,13 @@ rail_process_window_move(struct stream* s, int size) int right; int bottom; - LOG(0, ("chansrv::rail_process_window_move:")); + LOG(10, ("chansrv::rail_process_window_move:")); in_uint32_le(s, window_id); in_uint16_le(s, left); in_uint16_le(s, top); in_uint16_le(s, right); in_uint16_le(s, bottom); - LOG(0, (" window_id 0x%8.8x left %d top %d right %d bottom %d width %d height %d", + LOG(10, (" window_id 0x%8.8x left %d top %d right %d bottom %d width %d height %d", window_id, left, top, right, bottom, right - left, bottom - top)); XMoveResizeWindow(g_display, window_id, left, top, right - left, bottom - top); return 0; |