summaryrefslogtreecommitdiffstats
path: root/xrdp/xrdp.c
diff options
context:
space:
mode:
Diffstat (limited to 'xrdp/xrdp.c')
-rw-r--r--xrdp/xrdp.c140
1 files changed, 117 insertions, 23 deletions
diff --git a/xrdp/xrdp.c b/xrdp/xrdp.c
index fb8dfbc0..4af8c4d7 100644
--- a/xrdp/xrdp.c
+++ b/xrdp/xrdp.c
@@ -21,6 +21,9 @@
*/
#include "xrdp.h"
+#include "log.h"
+
+#define THREAD_WAITING 100
static struct xrdp_listen* g_listen = 0;
static long g_threadid = 0; /* main threadid */
@@ -37,6 +40,9 @@ static long g_sync_param2 = 0;
static long (*g_sync_func)(long param1, long param2);
/*****************************************************************************/
+/* This function is used to run a function from the main thread.
+ Sync_func is the function pointer that will run from main thread
+ The function can have two long in parameters and must return long */
long APP_CC
g_xrdp_sync(long (*sync_func)(long param1, long param2), long sync_param1,
long sync_param2)
@@ -44,31 +50,46 @@ g_xrdp_sync(long (*sync_func)(long param1, long param2), long sync_param1,
long sync_result;
int sync_command;
+ /* If the function is called from the main thread, the function can
+ * be called directly. g_threadid= main thread ID*/
if (tc_threadid_equal(tc_get_threadid(), g_threadid))
{
/* this is the main thread, call the function directly */
+ /* in fork mode, this always happens too */
sync_result = sync_func(sync_param1, sync_param2);
+ /*g_writeln("g_xrdp_sync processed IN main thread -> continue");*/
}
else
{
+ /* All threads have to wait here until the main thread
+ * process the function. g_process_waiting_function() is called
+ * from the listening thread. g_process_waiting_function() process the function*/
tc_mutex_lock(g_sync1_mutex);
tc_mutex_lock(g_sync_mutex);
g_sync_param1 = sync_param1;
g_sync_param2 = sync_param2;
g_sync_func = sync_func;
- g_sync_command = 100;
+ /* set a value THREAD_WAITING so the g_process_waiting_function function
+ * know if any function must be processed */
+ g_sync_command = THREAD_WAITING;
tc_mutex_unlock(g_sync_mutex);
+ /* set this event so that the main thread know if
+ * g_process_waiting_function() must be called */
g_set_wait_obj(g_sync_event);
do
{
g_sleep(100);
tc_mutex_lock(g_sync_mutex);
+ /* load new value from global to see if the g_process_waiting_function()
+ * function has processed the function */
sync_command = g_sync_command;
sync_result = g_sync_result;
tc_mutex_unlock(g_sync_mutex);
}
- while (sync_command != 0);
+ while (sync_command != 0); /* loop until g_process_waiting_function()
+ * has processed the request */
tc_mutex_unlock(g_sync1_mutex);
+ /*g_writeln("g_xrdp_sync processed BY main thread -> continue");*/
}
return sync_result;
}
@@ -89,6 +110,32 @@ xrdp_shutdown(int sig)
}
/*****************************************************************************/
+void DEFAULT_CC
+xrdp_child(int sig)
+{
+ 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_close_wait_obj(g_term_event);
+ g_close_wait_obj(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)
{
@@ -132,15 +179,17 @@ pipe_sig(int sig_num)
}
/*****************************************************************************/
+/*Some function must be called from the main thread.
+ if g_sync_command==THREAD_WAITING a function is waiting to be processed*/
void APP_CC
-g_loop(void)
+g_process_waiting_function(void)
{
tc_mutex_lock(g_sync_mutex);
if (g_sync_command != 0)
{
if (g_sync_func != 0)
{
- if (g_sync_command == 100)
+ if (g_sync_command == THREAD_WAITING)
{
g_sync_result = g_sync_func(g_sync_param1, g_sync_param2);
}
@@ -213,6 +262,12 @@ 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_writeln("--fork parameter found, ini override");
+ }
else
{
return 1;
@@ -228,6 +283,8 @@ main(int argc, char** argv)
{
int test;
int host_be;
+ char cfg_file[256];
+ enum logReturns error;
struct xrdp_startup_params* startup_params;
int pid;
int fd;
@@ -271,6 +328,29 @@ main(int argc, char** argv)
g_writeln("unusable tui64 size, must be 8");
return 0;
}
+ g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH);
+
+ /* starting logging subsystem */
+ error = log_start(cfg_file, "XRDP");
+
+ if (error != LOG_STARTUP_OK)
+ {
+ switch (error)
+ {
+ case LOG_ERROR_MALLOC:
+ g_writeln("error on malloc. cannot start logging. quitting.");
+ break;
+ case LOG_ERROR_FILE_OPEN:
+ g_writeln("error opening log file [%s]. quitting.",
+ getLogFile(text, 255));
+ break;
+ default:
+ g_writeln("log_start error");
+ break;
+ }
+ g_deinit();
+ g_exit(1);
+ }
startup_params = (struct xrdp_startup_params*)
g_malloc(sizeof(struct xrdp_startup_params), 1);
@@ -297,7 +377,7 @@ main(int argc, char** argv)
}
if (fd == -1)
{
- g_writeln("problem opening to xrdp.pid");
+ g_writeln("problem opening to xrdp.pid [%s]", pid_file);
g_writeln("maybe its not running");
}
else
@@ -327,9 +407,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);
@@ -354,6 +436,10 @@ main(int argc, char** argv)
}
if (!no_daemon)
{
+
+ /* make sure containing directory exists */
+ g_create_path(pid_file);
+
/* make sure we can write to pid file */
fd = g_file_open(pid_file); /* xrdp.pid */
if (fd == -1)
@@ -389,16 +475,6 @@ main(int argc, char** argv)
g_exit(0);
}
g_sleep(1000);
- g_file_close(0);
- g_file_close(1);
- g_file_close(2);
- g_file_open("/dev/null");
- g_file_open("/dev/null");
- g_file_open("/dev/null");
- /* end of daemonizing code */
- }
- if (!no_daemon)
- {
/* write the pid to file */
pid = g_getpid();
fd = g_file_open(pid_file); /* xrdp.pid */
@@ -414,6 +490,14 @@ main(int argc, char** argv)
g_file_write(fd, text, g_strlen(text));
g_file_close(fd);
}
+ g_sleep(1000);
+ g_file_close(0);
+ g_file_close(1);
+ g_file_close(2);
+ g_file_open("/dev/null");
+ g_file_open("/dev/null");
+ g_file_open("/dev/null");
+ /* end of daemonizing code */
}
g_threadid = tc_get_threadid();
g_listen = xrdp_listen_create();
@@ -421,25 +505,35 @@ 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();
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);
if (g_term_event == 0)
{
g_writeln("error creating g_term_event");
}
- xrdp_listen_main_loop(g_listen, startup_params);
+ g_snprintf(text, 255, "xrdp_%8.8x_main_sync", pid);
+ g_sync_event = g_create_wait_obj(text);
+ if (g_sync_event == 0)
+ {
+ g_writeln("error creating g_sync_event");
+ }
+ 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);
g_delete_wait_obj(g_term_event);
g_delete_wait_obj(g_sync_event);
- /* delete the xrdp.pid file */
- g_file_delete(pid_file);
+ /* only main process should delete pid file */
+ if ((!no_daemon) && (pid == g_getpid()))
+ {
+ /* delete the xrdp.pid file */
+ g_file_delete(pid_file);
+ }
g_free(startup_params);
g_deinit();
return 0;