From 97f42d429f3efe87b42aa8c6d3a1df72b8261ef1 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Tue, 6 Nov 2018 14:52:55 +0400 Subject: [PATCH] FS-11505: [core] System call with output capture on Linux and Windows without fork. Add switch_core test. --- Freeswitch.2017.sln | 11 ++ src/switch_core.c | 70 +++----- src/switch_xml.c | 2 +- tests/unit/Makefile.am | 2 +- tests/unit/conf/freeswitch.xml | 2 + tests/unit/switch_core.c | 88 ++++++++++ tests/unit/test_switch_core.2017.vcxproj | 203 +++++++++++++++++++++++ 7 files changed, 331 insertions(+), 47 deletions(-) create mode 100644 tests/unit/switch_core.c create mode 100644 tests/unit/test_switch_core.2017.vcxproj diff --git a/Freeswitch.2017.sln b/Freeswitch.2017.sln index 04b06b3539..2845b4af6a 100644 --- a/Freeswitch.2017.sln +++ b/Freeswitch.2017.sln @@ -570,6 +570,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{9388C266 EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_mod_av", "src\mod\applications\mod_av\test\test_mod_av.2017.vcxproj", "{7926CB0D-62CE-4A09-AE94-1DA2BC92D625}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_switch_core", "tests\unit\test_switch_core.2017.vcxproj", "{EF62B845-A0CE-44FD-B8E6-475FE87D06C3}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution All|Win32 = All|Win32 @@ -2589,6 +2591,14 @@ Global {7926CB0D-62CE-4A09-AE94-1DA2BC92D625}.Debug|x64.ActiveCfg = Debug|x64 {7926CB0D-62CE-4A09-AE94-1DA2BC92D625}.Release|Win32.ActiveCfg = Release|Win32 {7926CB0D-62CE-4A09-AE94-1DA2BC92D625}.Release|x64.ActiveCfg = Release|x64 + {EF62B845-A0CE-44FD-B8E6-475FE87D06C3}.All|Win32.ActiveCfg = Release|Win32 + {EF62B845-A0CE-44FD-B8E6-475FE87D06C3}.All|Win32.Build.0 = Release|Win32 + {EF62B845-A0CE-44FD-B8E6-475FE87D06C3}.All|x64.ActiveCfg = Release|x64 + {EF62B845-A0CE-44FD-B8E6-475FE87D06C3}.All|x64.Build.0 = Release|x64 + {EF62B845-A0CE-44FD-B8E6-475FE87D06C3}.Debug|Win32.ActiveCfg = Debug|Win32 + {EF62B845-A0CE-44FD-B8E6-475FE87D06C3}.Debug|x64.ActiveCfg = Debug|x64 + {EF62B845-A0CE-44FD-B8E6-475FE87D06C3}.Release|Win32.ActiveCfg = Release|Win32 + {EF62B845-A0CE-44FD-B8E6-475FE87D06C3}.Release|x64.ActiveCfg = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2795,6 +2805,7 @@ Global {4DFF29B4-2976-447D-A8B3-43476451517C} = {9ADF1E48-2F5C-4ED7-A893-596259FABFE0} {BC1FD72E-1CD5-4525-A7F5-17C5740BFDED} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B} {7926CB0D-62CE-4A09-AE94-1DA2BC92D625} = {9388C266-C3FC-468A-92EF-0CBC35941412} + {EF62B845-A0CE-44FD-B8E6-475FE87D06C3} = {9388C266-C3FC-468A-92EF-0CBC35941412} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {09840DE7-9208-45AA-9667-1A71EE93BD1E} diff --git a/src/switch_core.c b/src/switch_core.c index 22b35ed63b..ca87b5f8cd 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -58,6 +58,11 @@ #include #endif +#ifdef WIN32 +#define popen _popen +#define pclose _pclose +#endif + SWITCH_DECLARE_DATA switch_directories SWITCH_GLOBAL_dirs = { 0 }; SWITCH_DECLARE_DATA switch_filenames SWITCH_GLOBAL_filenames = { 0 }; @@ -3253,45 +3258,7 @@ SWITCH_DECLARE(int) switch_system(const char *cmd, switch_bool_t wait) SWITCH_DECLARE(int) switch_stream_system_fork(const char *cmd, switch_stream_handle_t *stream) { -#ifdef WIN32 - return switch_system(cmd, SWITCH_TRUE); -#else - int fds[2], pid = 0; - - if (pipe(fds)) { - goto end; - } else { /* good to go */ - pid = switch_fork(); - - if (pid < 0) { /* ok maybe not */ - close(fds[0]); - close(fds[1]); - goto end; - } else if (pid) { /* parent */ - char buf[1024] = ""; - int bytes; - close(fds[1]); - while ((bytes = read(fds[0], buf, sizeof(buf))) > 0) { - stream->raw_write_function(stream, (unsigned char *)buf, bytes); - } - close(fds[0]); - waitpid(pid, NULL, 0); - } else { /* child */ - switch_close_extra_files(fds, 2); - close(fds[0]); - dup2(fds[1], STDOUT_FILENO); - switch_system(cmd, SWITCH_TRUE); - close(fds[1]); - exit(0); - } - } - - end: - - return 0; - -#endif - + return switch_stream_system(cmd, stream); } SWITCH_DECLARE(switch_status_t) switch_core_get_stacksizes(switch_size_t *cur, switch_size_t *max) @@ -3320,13 +3287,26 @@ SWITCH_DECLARE(switch_status_t) switch_core_get_stacksizes(switch_size_t *cur, s SWITCH_DECLARE(int) switch_stream_system(const char *cmd, switch_stream_handle_t *stream) { -#ifdef WIN32 - stream->write_function(stream, "Capturing output not supported.\n"); - return switch_system(cmd, SWITCH_TRUE); -#else - return switch_stream_system_fork(cmd, stream); -#endif + char buffer[128]; + size_t bytes; + FILE* pipe = popen(cmd, "r"); + if (!pipe) return 1; + while (!feof(pipe)) { + while ((bytes = fread(buffer, 1, 128, pipe)) > 0) { + if (stream != NULL) { + stream->raw_write_function(stream, (unsigned char *)buffer, bytes); + } + } + } + + if (ferror(pipe)) { + pclose(pipe); + return 1; + } + + pclose(pipe); + return 0; } SWITCH_DECLARE(uint16_t) switch_core_get_rtp_port_range_start_port() diff --git a/src/switch_xml.c b/src/switch_xml.c index a815c92039..37400a13b5 100644 --- a/src/switch_xml.c +++ b/src/switch_xml.c @@ -124,7 +124,7 @@ static void preprocess_exec_set(char *keyval) if (key && val) { switch_stream_handle_t exec_result = { 0 }; SWITCH_STANDARD_STREAM(exec_result); - if (switch_stream_system_fork(val, &exec_result) == 0) { + if (switch_stream_system(val, &exec_result) == 0) { if (!zstr(exec_result.data)) { char *tmp = (char *) exec_result.data; tmp = &tmp[strlen(tmp)-1]; diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am index 8c25de5114..76f757ed82 100644 --- a/tests/unit/Makefile.am +++ b/tests/unit/Makefile.am @@ -1,6 +1,6 @@ include $(top_srcdir)/build/modmake.rulesam -bin_PROGRAMS = switch_event switch_hash switch_ivr_originate switch_utils +bin_PROGRAMS = switch_event switch_hash switch_ivr_originate switch_utils switch_core AM_LDFLAGS = -avoid-version -no-undefined $(SWITCH_AM_LDFLAGS) $(openssl_LIBS) AM_LDFLAGS += $(FREESWITCH_LIBS) $(switch_builddir)/libfreeswitch.la $(CORE_LIBS) $(APR_LIBS) AM_CFLAGS = $(SWITCH_AM_CPPFLAGS) diff --git a/tests/unit/conf/freeswitch.xml b/tests/unit/conf/freeswitch.xml index 2341258ecd..87e5233600 100644 --- a/tests/unit/conf/freeswitch.xml +++ b/tests/unit/conf/freeswitch.xml @@ -1,5 +1,7 @@ + +
diff --git a/tests/unit/switch_core.c b/tests/unit/switch_core.c new file mode 100644 index 0000000000..05b3b7f60d --- /dev/null +++ b/tests/unit/switch_core.c @@ -0,0 +1,88 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2018, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (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.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Chris Rienzo + * Seven Du + * + * + * switch_core.c -- tests core functions + * + */ +#include +#include + +#include + +FST_CORE_BEGIN("./conf") +{ + FST_SUITE_BEGIN(switch_ivr_originate) + { + FST_SETUP_BEGIN() + { + } + FST_SETUP_END() + + FST_TEARDOWN_BEGIN() + { + } + FST_TEARDOWN_END() + +#ifndef WIN32 + FST_TEST_BEGIN(test_fork) + { + switch_stream_handle_t exec_result = { 0 }; + SWITCH_STANDARD_STREAM(exec_result); + fst_requires(switch_stream_system_fork("ip ad sh", &exec_result) == 0); + fst_requires(!zstr(exec_result.data)); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s\n", (char *)exec_result.data); + + fst_requires(switch_stream_system_fork("ip ad sh | grep link", &exec_result) == 0); + fst_requires(!zstr(exec_result.data)); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s\n", (char *)exec_result.data); + + switch_safe_free(exec_result.data); + } + FST_TEST_END() +#endif + + FST_TEST_BEGIN(test_non_fork_exec_set) + { + char *var_test = switch_core_get_variable_dup("test"); + char *var_default_password = switch_core_get_variable_dup("default_password"); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "global_getvar test: %s\n", switch_str_nil(var_test)); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "global_getvar default_password: %s\n", switch_str_nil(var_default_password)); + + fst_check_string_not_equals(var_test, ""); + fst_check_string_not_equals(var_default_password, ""); + fst_check_string_equals(var_test, var_default_password); + + switch_safe_free(var_test); + switch_safe_free(var_default_password); + } + FST_TEST_END() + } + FST_SUITE_END() +} +FST_CORE_END() diff --git a/tests/unit/test_switch_core.2017.vcxproj b/tests/unit/test_switch_core.2017.vcxproj new file mode 100644 index 0000000000..c12e24a5e7 --- /dev/null +++ b/tests/unit/test_switch_core.2017.vcxproj @@ -0,0 +1,203 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + test_switch_core + test_switch_core + Win32Proj + 10.0.17134.0 + {EF62B845-A0CE-44FD-B8E6-475FE87D06C3} + + + + Application + MultiByte + v141 + + + Application + MultiByte + v141 + + + Application + MultiByte + v141 + + + Application + MultiByte + v141 + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(PlatformName)\$(Configuration)\ + $(PlatformName)\$(Configuration)\ + false + $(SolutionDir)$(PlatformName)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(PlatformName)\$(Configuration)\ + $(PlatformName)\$(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + + + + $(SolutionDir)src\include;%(AdditionalIncludeDirectories) + SWITCH_TEST_BASE_DIR_FOR_CONF="..\\..\\tests\\unit\\";%(PreprocessorDefinitions) + + + + + + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level4 + ProgramDatabase + true + 6031;6340;6246;6011;6387;%(DisableSpecificWarnings) + + + $(OutDir);%(AdditionalLibraryDirectories) + true + Console + true + + + MachineX86 + + + + + + X64 + + + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level4 + ProgramDatabase + true + 6031;6340;6246;6011;6387;%(DisableSpecificWarnings) + + + $(OutDir);%(AdditionalLibraryDirectories) + true + Console + true + + + MachineX64 + + + + + + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level4 + ProgramDatabase + 6031;6340;6246;6011;6387;%(DisableSpecificWarnings) + + + $(OutDir);%(AdditionalLibraryDirectories) + false + Console + true + true + true + + + MachineX86 + + + + + + X64 + + + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level4 + ProgramDatabase + 6031;6340;6246;6011;6387;%(DisableSpecificWarnings) + + + $(OutDir);%(AdditionalLibraryDirectories) + false + Console + true + true + true + + + MachineX64 + + + + + + + + {202d7a4e-760d-4d0e-afa1-d7459ced30ff} + + + + + + \ No newline at end of file