diff options
author | Jay Sorg <jay.sorg@gmail.com> | 2012-05-26 13:23:02 -0700 |
---|---|---|
committer | Jay Sorg <jay.sorg@gmail.com> | 2012-05-26 13:23:02 -0700 |
commit | c7bd96ba854b7e37071e9d3c70ec39b0e8717ef8 (patch) | |
tree | 5c617131be1ccb9c31104d9bfedd75739745c21c /xrdp | |
parent | 7fa4f936e43577c3529b10610ccf7ddcb2bd9fbe (diff) | |
download | xrdp-proprietary-c7bd96ba854b7e37071e9d3c70ec39b0e8717ef8.tar.gz xrdp-proprietary-c7bd96ba854b7e37071e9d3c70ec39b0e8717ef8.zip |
xrdp: added -f command line option to fork on connections
Diffstat (limited to 'xrdp')
-rw-r--r-- | xrdp/xrdp.c | 54 | ||||
-rw-r--r-- | xrdp/xrdp.h | 5 | ||||
-rw-r--r-- | xrdp/xrdp_listen.c | 49 | ||||
-rw-r--r-- | xrdp/xrdp_process.c | 4 | ||||
-rw-r--r-- | xrdp/xrdp_types.h | 2 |
5 files changed, 103 insertions, 11 deletions
diff --git a/xrdp/xrdp.c b/xrdp/xrdp.c index fb8dfbc0..d43870f2 100644 --- a/xrdp/xrdp.c +++ b/xrdp/xrdp.c @@ -25,6 +25,7 @@ static struct xrdp_listen* g_listen = 0; static long g_threadid = 0; /* main threadid */ +static int g_fork_not_thread = 0; static long g_sync_mutex = 0; static long g_sync1_mutex = 0; static tbus g_term_event = 0; @@ -44,7 +45,12 @@ g_xrdp_sync(long (*sync_func)(long param1, long param2), long sync_param1, long sync_result; int sync_command; - if (tc_threadid_equal(tc_get_threadid(), g_threadid)) + if (g_fork_not_thread) + { + /* always main thread, fork mode */ + sync_result = sync_func(sync_param1, sync_param2); + } + else if (tc_threadid_equal(tc_get_threadid(), g_threadid)) { /* this is the main thread, call the function directly */ sync_result = sync_func(sync_param1, sync_param2); @@ -89,6 +95,33 @@ xrdp_shutdown(int sig) } /*****************************************************************************/ +void DEFAULT_CC +xrdp_child(int sig) +{ + g_writeln("xrdp_child"); + g_waitchild(); +} + +/*****************************************************************************/ +/* called in child just after fork */ +int APP_CC +xrdp_child_fork(void) +{ + int pid; + char text[256]; + + /* close, don't delete these */ + g_tcp_close((int)g_term_event); + g_tcp_close((int)g_sync_event); + pid = g_getpid(); + g_snprintf(text, 255, "xrdp_%8.8x_main_term", pid); + g_term_event = g_create_wait_obj(text); + g_snprintf(text, 255, "xrdp_%8.8x_main_sync", pid); + g_sync_event = g_create_wait_obj(text); + return 0; +} + +/*****************************************************************************/ int APP_CC g_is_term(void) { @@ -213,6 +246,13 @@ xrdp_process_params(int argc, char** argv, startup_params->port); } } + else if ((g_strncasecmp(option, "-f", 255) == 0) || + (g_strncasecmp(option, "--fork", 255) == 0)) + { + startup_params->fork = 1; + g_fork_not_thread = 1; + g_writeln("running in fork mode"); + } else { return 1; @@ -327,9 +367,11 @@ main(int argc, char** argv) g_writeln("See http://xrdp.sourceforge.net for more information."); g_writeln(""); g_writeln("Usage: xrdp [options]"); - g_writeln(" -h: show help"); - g_writeln(" -nodaemon: don't fork into background"); - g_writeln(" -kill: shut down xrdp"); + g_writeln(" --help: show help"); + g_writeln(" --nodaemon: don't fork into background"); + g_writeln(" --kill: shut down xrdp"); + g_writeln(" --port: tcp listen port"); + g_writeln(" --fork: fork on new connection"); g_writeln(""); g_deinit(); g_exit(0); @@ -421,6 +463,7 @@ main(int argc, char** argv) g_signal_kill(xrdp_shutdown); /* SIGKILL */ g_signal_pipe(pipe_sig); /* SIGPIPE */ g_signal_terminate(xrdp_shutdown); /* SIGTERM */ + g_signal_child_stop(xrdp_child); /* SIGCHLD */ g_sync_mutex = tc_mutex_create(); g_sync1_mutex = tc_mutex_create(); pid = g_getpid(); @@ -432,7 +475,8 @@ main(int argc, char** argv) { g_writeln("error creating g_term_event"); } - xrdp_listen_main_loop(g_listen, startup_params); + g_listen->startup_params = startup_params; + xrdp_listen_main_loop(g_listen); xrdp_listen_delete(g_listen); tc_mutex_delete(g_sync_mutex); tc_mutex_delete(g_sync1_mutex); diff --git a/xrdp/xrdp.h b/xrdp/xrdp.h index 9b280bfc..0bc4a24d 100644 --- a/xrdp/xrdp.h +++ b/xrdp/xrdp.h @@ -159,8 +159,7 @@ xrdp_listen_create(void); void APP_CC xrdp_listen_delete(struct xrdp_listen* self); int APP_CC -xrdp_listen_main_loop(struct xrdp_listen* self, - struct xrdp_startup_params* startup_param); +xrdp_listen_main_loop(struct xrdp_listen* self); /* xrdp_region.c */ struct xrdp_region* APP_CC @@ -384,6 +383,8 @@ int DEFAULT_CC server_msg(struct xrdp_mod* mod, char* msg, int code); int DEFAULT_CC server_is_term(struct xrdp_mod* mod); +int APP_CC +xrdp_child_fork(void); int DEFAULT_CC server_set_clip(struct xrdp_mod* mod, int x, int y, int cx, int cy); int DEFAULT_CC diff --git a/xrdp/xrdp_listen.c b/xrdp/xrdp_listen.c index 23f532a8..665d5f36 100644 --- a/xrdp/xrdp_listen.c +++ b/xrdp/xrdp_listen.c @@ -181,6 +181,44 @@ xrdp_listen_get_port_address(char* port, int port_bytes, } /*****************************************************************************/ +static int APP_CC +xrdp_listen_fork(struct xrdp_listen* self, struct trans* server_trans) +{ + int pid; + char text[256]; + struct xrdp_process* process; + + pid = g_fork(); + if (pid == 0) + { + /* child */ + /* recreate some main globals */ + xrdp_child_fork(); + /* recreate the process done wait object, not used in fork mode */ + g_tcp_close((int)(self->pro_done_event)); + pid = g_getpid(); + g_snprintf(text, 255, "xrdp_%8.8x_listen_pro_done_event", pid); + self->pro_done_event = g_create_wait_obj(text); + self->process_list = list_create(); + /* delete listener, child need not listen */ + trans_delete(self->listen_trans); + self->listen_trans = 0; + /* new connect instance */ + process = xrdp_process_create(self, 0); + process->server_trans = server_trans; + g_process = process; + xrdp_process_run(0); + xrdp_process_delete(process); + /* mark this process to exit */ + g_set_term(1); + return 0; + } + /* parent */ + trans_delete(server_trans); + return 0; +} + +/*****************************************************************************/ /* a new connection is coming in */ int DEFAULT_CC xrdp_listen_conn_in(struct trans* self, struct trans* new_self) @@ -189,6 +227,10 @@ xrdp_listen_conn_in(struct trans* self, struct trans* new_self) struct xrdp_listen* lis; lis = (struct xrdp_listen*)(self->callback_data); + if (lis->startup_params->fork) + { + return xrdp_listen_fork(lis, new_self); + } process = xrdp_process_create(lis, lis->pro_done_event); if (xrdp_listen_add_pro(lis, process) == 0) { @@ -208,8 +250,7 @@ xrdp_listen_conn_in(struct trans* self, struct trans* new_self) /*****************************************************************************/ /* wait for incoming connections */ int APP_CC -xrdp_listen_main_loop(struct xrdp_listen* self, - struct xrdp_startup_params* startup_param) +xrdp_listen_main_loop(struct xrdp_listen* self) { int error; int robjs_count; @@ -226,7 +267,7 @@ xrdp_listen_main_loop(struct xrdp_listen* self, self->status = 1; if (xrdp_listen_get_port_address(port, sizeof(port), address, sizeof(address), - startup_param) != 0) + self->startup_params) != 0) { g_writeln("xrdp_listen_main_loop: xrdp_listen_get_port failed"); self->status = -1; @@ -276,7 +317,7 @@ xrdp_listen_main_loop(struct xrdp_listen* self, } if (trans_check_wait_objs(self->listen_trans) != 0) { - break; + break; } } /* stop listening */ diff --git a/xrdp/xrdp_process.c b/xrdp/xrdp_process.c index 905db928..df69d057 100644 --- a/xrdp/xrdp_process.c +++ b/xrdp/xrdp_process.c @@ -187,6 +187,10 @@ xrdp_process_main_loop(struct xrdp_process* self) } libxrdp_disconnect(self->session); } + else + { + g_writeln("xrdp_process_main_loop: libxrdp_process_incomming failed"); + } xrdp_process_mod_end(self); libxrdp_exit(self->session); self->session = 0; diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h index ce646a66..7f7caed4 100644 --- a/xrdp/xrdp_types.h +++ b/xrdp/xrdp_types.h @@ -310,6 +310,7 @@ struct xrdp_listen struct trans* listen_trans; /* in tcp listen mode */ struct list* process_list; tbus pro_done_event; + struct xrdp_startup_params* startup_params; }; /* region */ @@ -431,4 +432,5 @@ struct xrdp_startup_params int no_daemon; int help; int version; + int fork; }; |