diff --git a/configure.in b/configure.in
index 6a7d7dec4d..b74e973a4a 100644
--- a/configure.in
+++ b/configure.in
@@ -474,7 +474,7 @@ AC_PROG_GCC_TRADITIONAL
 AC_FUNC_MALLOC
 AC_TYPE_SIGNAL
 AC_FUNC_STRFTIME
-AC_CHECK_FUNCS([gethostname vasprintf mmap mlock mlockall usleep getifaddrs timerfd_create])
+AC_CHECK_FUNCS([gethostname vasprintf mmap mlock mlockall usleep getifaddrs timerfd_create getdtablesize])
 AC_CHECK_FUNCS([sched_setscheduler setpriority setrlimit setgroups initgroups])
 AC_CHECK_FUNCS([wcsncmp setgroups asprintf setenv pselect gettimeofday localtime_r gmtime_r strcasecmp stricmp _stricmp])
 
diff --git a/src/include/switch_types.h b/src/include/switch_types.h
index 51ed3587e5..97fbc942af 100644
--- a/src/include/switch_types.h
+++ b/src/include/switch_types.h
@@ -306,7 +306,8 @@ typedef enum {
 	SCF_AUTO_SCHEMAS = (1 << 13),
 	SCF_MINIMAL = (1 << 14),
 	SCF_USE_NAT_MAPPING = (1 << 15),
-	SCF_CLEAR_SQL = (1 << 16)
+	SCF_CLEAR_SQL = (1 << 16),
+	SCF_THREADED_SYSTEM_EXEC = (1 << 17)
 } switch_core_flag_enum_t;
 typedef uint32_t switch_core_flag_t;
 
@@ -1677,7 +1678,8 @@ typedef enum {
 	SCSC_VERBOSE_EVENTS,
 	SCSC_SHUTDOWN_CHECK,
 	SCSC_PAUSE_CHECK,
-	SCSC_READY_CHECK
+	SCSC_READY_CHECK,
+	SCSC_THREADED_SYSTEM_EXEC
 } switch_session_ctl_t;
 
 typedef enum {
diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c
index dba27031b1..a5175299be 100644
--- a/src/mod/applications/mod_commands/mod_commands.c
+++ b/src/mod/applications/mod_commands/mod_commands.c
@@ -1840,6 +1840,15 @@ SWITCH_STANDARD_API(ctl_function)
 			switch_core_session_ctl(SCSC_VERBOSE_EVENTS, &arg);
 
 			stream->write_function(stream, "+OK verbose_events is %s \n", arg ? "on" : "off");
+		} else if (!strcasecmp(argv[0], "threaded_system_exec")) {
+			arg = -1;
+			if (argv[1]) {
+				arg = switch_true(argv[1]);
+			}
+
+			switch_core_session_ctl(SCSC_THREADED_SYSTEM_EXEC, &arg);
+
+			stream->write_function(stream, "+OK threaded_system_exec is %s \n", arg ? "true" : "false");
 			
 		} else if (!strcasecmp(argv[0], "save_history")) {
 			switch_core_session_ctl(SCSC_SAVE_HISTORY, NULL);
diff --git a/src/switch.c b/src/switch.c
index 401829cf82..4ef38111f2 100644
--- a/src/switch.c
+++ b/src/switch.c
@@ -102,6 +102,7 @@ static void handle_SIGCHLD(int sig)
 	pid = wait(&status);
 	
 	if (pid > 0) {
+		printf("ASS %d\n", pid);
 		system_ready = -1;
 	}
 
diff --git a/src/switch_core.c b/src/switch_core.c
index e9e5b3871c..ba0350a7fe 100644
--- a/src/switch_core.c
+++ b/src/switch_core.c
@@ -647,6 +647,41 @@ SWITCH_DECLARE(void) switch_core_set_globals(void)
 	switch_assert(SWITCH_GLOBAL_dirs.temp_dir);
 }
 
+
+static int32_t set_low_priority(void)
+{
+#ifdef WIN32
+	SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS);
+#else
+#ifdef USE_SCHED_SETSCHEDULER
+	/*
+	 * Try to use a normal scheduler
+	 */
+	struct sched_param sched = { 0 };
+	sched.sched_priority = 0;
+	if (sched_setscheduler(0, SCHED_OTHER, &sched)) {
+		return -1;
+	}
+#endif
+
+#ifdef HAVE_SETPRIORITY
+	/*
+	 * setpriority() works on FreeBSD (6.2), nice() doesn't
+	 */
+	if (setpriority(PRIO_PROCESS, getpid(), 19) < 0) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not set nice level\n");
+		return -1;
+	}
+#else
+	if (nice(19) != 19) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not set nice level\n");
+		return -1;
+	}
+#endif
+#endif
+	return 0;
+}
+
 static int32_t set_priority(void)
 {
 #ifdef WIN32
@@ -1359,6 +1394,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc
 	switch_set_flag((&runtime.dummy_cng_frame), SFF_CNG);
 	switch_set_flag((&runtime), SCF_AUTO_SCHEMAS);
 	switch_set_flag((&runtime), SCF_CLEAR_SQL);
+	switch_set_flag((&runtime), SCF_THREADED_SYSTEM_EXEC);
 
 	switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS);
 	runtime.hard_log_level = SWITCH_LOG_DEBUG;
@@ -1483,6 +1519,24 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc
 }
 
 
+#ifndef WIN32
+static void handle_SIGCHLD(int sig)
+{
+	int status = 0;
+	int pid = 0;
+
+	if (sig);
+
+	pid = wait(&status);
+	
+	if (pid > 0) {
+		printf("ASS %d\n", pid);
+	}
+
+	return;
+}
+#endif
+
 #ifdef TRAP_BUS
 static void handle_SIGBUS(int sig)
 {
@@ -1690,6 +1744,17 @@ static void switch_load_core_config(const char *file)
 					} else {
 						switch_clear_flag((&runtime), SCF_VERBOSE_EVENTS);
 					}
+				} else if (!strcasecmp(var, "threaded-system-exec") && !zstr(val)) {
+#ifdef WIN32
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "threaded-system-exec is not implemented on this platform\n");
+#else
+					int v = switch_true(val);
+					if (v) {
+						switch_set_flag((&runtime), SCF_THREADED_SYSTEM_EXEC);
+					} else {
+						switch_clear_flag((&runtime), SCF_THREADED_SYSTEM_EXEC);
+					}
+#endif
 				} else if (!strcasecmp(var, "min-idle-cpu") && !zstr(val)) {
 					switch_core_min_idle_cpu(atof(val));
 				} else if (!strcasecmp(var, "tipping-point") && !zstr(val)) {
@@ -1870,7 +1935,9 @@ SWITCH_DECLARE(void) switch_core_set_signal_handlers(void)
 {
 	/* set signal handlers */
 	signal(SIGINT, SIG_IGN);
-
+#ifndef WIN32
+	signal(SIGCHLD, handle_SIGCHLD);
+#endif
 #ifdef SIGPIPE
 	signal(SIGPIPE, SIG_IGN);
 #endif
@@ -1924,6 +1991,18 @@ SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, void *
 			newintval = switch_test_flag((&runtime), SCF_VERBOSE_EVENTS);
 		}
 		break;
+	case SCSC_THREADED_SYSTEM_EXEC:
+		if (intval) {
+			if (oldintval > -1) {
+				if (oldintval) {
+					switch_set_flag((&runtime), SCF_THREADED_SYSTEM_EXEC);
+				} else {
+					switch_clear_flag((&runtime), SCF_THREADED_SYSTEM_EXEC);
+				}
+			}
+			newintval = switch_test_flag((&runtime), SCF_THREADED_SYSTEM_EXEC);
+		}
+		break;
 	case SCSC_CALIBRATE_CLOCK:
 		switch_time_calibrate_clock();
 		break;
@@ -2256,7 +2335,8 @@ static void *SWITCH_THREAD_FUNC system_thread(switch_thread_t *thread, void *obj
 	return NULL;
 }
 
-SWITCH_DECLARE(int) switch_system(const char *cmd, switch_bool_t wait)
+
+static int switch_system_thread(const char *cmd, switch_bool_t wait)
 {
 	switch_thread_t *thread;
 	switch_threadattr_t *thd_attr;
@@ -2296,6 +2376,68 @@ SWITCH_DECLARE(int) switch_system(const char *cmd, switch_bool_t wait)
 }
 
 
+#ifdef WIN32
+static int switch_system_fork(const char *cmd, switch_bool_t wait)
+{
+	return switch_system_thread(cmd, wait);
+}
+
+#else
+static int max_open(void)
+{
+	int max;
+
+#if defined(HAVE_GETDTABLESIZE)
+	max = getdtablesize();
+#else
+	max = sysconf(_SC_OPEN_MAX);
+#endif
+
+	return max;
+
+}
+
+static int switch_system_fork(const char *cmd, switch_bool_t wait)
+{
+	int pid;
+
+	switch_core_set_signal_handlers();
+
+	pid = fork();
+	
+	if (pid) {
+		if (wait) {
+			waitpid(pid, NULL, 0);
+		}
+	} else {
+		int open_max = max_open();
+		int i;
+
+		for (i = 3; i < open_max; i++) {
+			close(i);
+		}
+		
+		set_low_priority();
+		system(cmd);
+		exit(0);
+	}
+
+	return 0;
+}
+#endif
+
+
+
+SWITCH_DECLARE(int) switch_system(const char *cmd, switch_bool_t wait)
+{
+	int (*sys_p)(const char *cmd, switch_bool_t wait);
+
+	sys_p = switch_test_flag((&runtime), SCF_THREADED_SYSTEM_EXEC) ? switch_system_thread : switch_system_fork;
+
+	return sys_p(cmd, wait);
+
+}
+
 
 /* For Emacs:
  * Local Variables: