diff options
Diffstat (limited to 'lib')
32 files changed, 504 insertions, 470 deletions
diff --git a/lib/common_test/doc/src/common_test_app.xml b/lib/common_test/doc/src/common_test_app.xml index ea4522c40b..f63f9581a6 100644 --- a/lib/common_test/doc/src/common_test_app.xml +++ b/lib/common_test/doc/src/common_test_app.xml @@ -252,7 +252,7 @@ </func> <func> - <name>Module:end_per_suite(Config) -> void() | + <name>Module:end_per_suite(Config) -> term() | {save_config,SaveConfig}</name> <fsummary>Test suite finalization. </fsummary> <type> @@ -385,7 +385,7 @@ </func> <func> - <name>Module:end_per_group(GroupName, Config) -> void() | + <name>Module:end_per_group(GroupName, Config) -> term() | {return_group_result,Status}</name> <fsummary>Test case group finalization.</fsummary> <type> @@ -440,7 +440,7 @@ </func> <func> - <name>Module:end_per_testcase(TestCase, Config) -> void() | {fail,Reason} | {save_config,SaveConfig}</name> + <name>Module:end_per_testcase(TestCase, Config) -> term() | {fail,Reason} | {save_config,SaveConfig}</name> <fsummary>Test case finalization.</fsummary> <type> <v> TestCase = atom()</v> @@ -538,7 +538,7 @@ <func> - <name>Module:Testcase(Config) -> void() | {skip,Reason} | {comment,Comment} | {save_config,SaveConfig} | {skip_and_save,Reason,SaveConfig} | exit() </name> + <name>Module:Testcase(Config) -> term() | {skip,Reason} | {comment,Comment} | {save_config,SaveConfig} | {skip_and_save,Reason,SaveConfig} | exit() </name> <fsummary>A test case</fsummary> <type> <v> Config = SaveConfig = [{Key,Value}]</v> diff --git a/lib/common_test/doc/src/ct_run.xml b/lib/common_test/doc/src/ct_run.xml index d8e79ca80e..3ac8691fb5 100644 --- a/lib/common_test/doc/src/ct_run.xml +++ b/lib/common_test/doc/src/ct_run.xml @@ -86,98 +86,99 @@ <marker id="ct_run"></marker> <title>Run tests from command line</title> <pre> - ct_run [-dir TestDir1 TestDir2 .. TestDirN] | - [[-dir TestDir] -suite Suite1 Suite2 .. SuiteN - [[-group Groups1 Groups2 .. GroupsN] [-case Case1 Case2 .. CaseN]]] - [-step [config | keep_inactive]] - [-config ConfigFile1 ConfigFile2 .. ConfigFileN] - [-userconfig CallbackModule1 ConfigString1 and CallbackModule2 - ConfigString2 and .. CallbackModuleN ConfigStringN] - [-decrypt_key Key] | [-decrypt_file KeyFile] - [-label Label] - [-logdir LogDir] - [-logopts LogOpts] - [-verbosity GenVLevel | [Category1 VLevel1 and - Category2 VLevel2 and .. CategoryN VLevelN]] - [-silent_connections [ConnType1 ConnType2 .. ConnTypeN]] - [-stylesheet CSSFile] - [-cover CoverCfgFile] - [-cover_stop Bool] - [-event_handler EvHandler1 EvHandler2 .. EvHandlerN] | - [-event_handler_init EvHandler1 InitArg1 and - EvHandler2 InitArg2 and .. EvHandlerN InitArgN] - [-include InclDir1 InclDir2 .. InclDirN] - [-no_auto_compile] - [-abort_if_missing_suites] - [-muliply_timetraps Multiplier] - [-scale_timetraps] - [-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc] - [-repeat N] | - [-duration HHMMSS [-force_stop [skip_rest]]] | - [-until [YYMoMoDD]HHMMSS [-force_stop [skip_rest]]] - [-basic_html] - [-ct_hooks CTHModule1 CTHOpts1 and CTHModule2 CTHOpts2 and .. - CTHModuleN CTHOptsN] - [-exit_status ignore_config] + ct_run -dir TestDir1 TestDir2 .. TestDirN | + [-dir TestDir] -suite Suite1 Suite2 .. SuiteN + [-group Groups1 Groups2 .. GroupsN] [-case Case1 Case2 .. CaseN] + [-step [config | keep_inactive]] + [-config ConfigFile1 ConfigFile2 .. ConfigFileN] + [-userconfig CallbackModule1 ConfigString1 and CallbackModule2 + ConfigString2 and .. CallbackModuleN ConfigStringN] + [-decrypt_key Key] | [-decrypt_file KeyFile] + [-label Label] + [-logdir LogDir] + [-logopts LogOpts] + [-verbosity GenVLevel | [Category1 VLevel1 and + Category2 VLevel2 and .. CategoryN VLevelN]] + [-silent_connections [ConnType1 ConnType2 .. ConnTypeN]] + [-stylesheet CSSFile] + [-cover CoverCfgFile] + [-cover_stop Bool] + [-event_handler EvHandler1 EvHandler2 .. EvHandlerN] | + [-event_handler_init EvHandler1 InitArg1 and + EvHandler2 InitArg2 and .. EvHandlerN InitArgN] + [-include InclDir1 InclDir2 .. InclDirN] + [-no_auto_compile] + [-abort_if_missing_suites] + [-muliply_timetraps Multiplier] + [-scale_timetraps] + [-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc] + [-repeat N] | + [-duration HHMMSS [-force_stop [skip_rest]]] | + [-until [YYMoMoDD]HHMMSS [-force_stop [skip_rest]]] + [-basic_html] + [-ct_hooks CTHModule1 CTHOpts1 and CTHModule2 CTHOpts2 and .. + CTHModuleN CTHOptsN] + [-exit_status ignore_config] + [-help] </pre> </section> <section> <title>Run tests using test specification</title> <pre> ct_run -spec TestSpec1 TestSpec2 .. TestSpecN - [-join_specs] - [-config ConfigFile1 ConfigFile2 .. ConfigFileN] - [-userconfig CallbackModule1 ConfigString1 and CallbackModule2 - ConfigString2 and .. and CallbackModuleN ConfigStringN] - [-decrypt_key Key] | [-decrypt_file KeyFile] - [-label Label] - [-logdir LogDir] - [-logopts LogOpts] - [-verbosity GenVLevel | [Category1 VLevel1 and - Category2 VLevel2 and .. CategoryN VLevelN]] - [-allow_user_terms] - [-silent_connections [ConnType1 ConnType2 .. ConnTypeN]] - [-stylesheet CSSFile] - [-cover CoverCfgFile] - [-cover_stop Bool] - [-event_handler EvHandler1 EvHandler2 .. EvHandlerN] | - [-event_handler_init EvHandler1 InitArg1 and - EvHandler2 InitArg2 and .. EvHandlerN InitArgN] - [-include InclDir1 InclDir2 .. InclDirN] - [-no_auto_compile] - [-abort_if_missing_suites] - [-muliply_timetraps Multiplier] - [-scale_timetraps] - [-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc] - [-repeat N] | - [-duration HHMMSS [-force_stop [skip_rest]]] | - [-until [YYMoMoDD]HHMMSS [-force_stop [skip_rest]]] - [-basic_html] - [-ct_hooks CTHModule1 CTHOpts1 and CTHModule2 CTHOpts2 and .. - CTHModuleN CTHOptsN] - [-exit_status ignore_config] + [-join_specs] + [-config ConfigFile1 ConfigFile2 .. ConfigFileN] + [-userconfig CallbackModule1 ConfigString1 and CallbackModule2 + ConfigString2 and .. and CallbackModuleN ConfigStringN] + [-decrypt_key Key] | [-decrypt_file KeyFile] + [-label Label] + [-logdir LogDir] + [-logopts LogOpts] + [-verbosity GenVLevel | [Category1 VLevel1 and + Category2 VLevel2 and .. CategoryN VLevelN]] + [-allow_user_terms] + [-silent_connections [ConnType1 ConnType2 .. ConnTypeN]] + [-stylesheet CSSFile] + [-cover CoverCfgFile] + [-cover_stop Bool] + [-event_handler EvHandler1 EvHandler2 .. EvHandlerN] | + [-event_handler_init EvHandler1 InitArg1 and + EvHandler2 InitArg2 and .. EvHandlerN InitArgN] + [-include InclDir1 InclDir2 .. InclDirN] + [-no_auto_compile] + [-abort_if_missing_suites] + [-muliply_timetraps Multiplier] + [-scale_timetraps] + [-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc] + [-repeat N] | + [-duration HHMMSS [-force_stop [skip_rest]]] | + [-until [YYMoMoDD]HHMMSS [-force_stop [skip_rest]]] + [-basic_html] + [-ct_hooks CTHModule1 CTHOpts1 and CTHModule2 CTHOpts2 and .. + CTHModuleN CTHOptsN] + [-exit_status ignore_config] </pre> </section> <section> <title>Run tests in web based GUI</title> <pre> ct_run -vts [-browser Browser] - [-dir TestDir1 TestDir2 .. TestDirN] | - [[dir TestDir] -suite Suite [[-group Group] [-case Case]]] - [-config ConfigFile1 ConfigFile2 .. ConfigFileN] - [-userconfig CallbackModule1 ConfigString1 and CallbackModule2 - ConfigString2 and .. and CallbackModuleN ConfigStringN] - [-logopts LogOpts] - [-verbosity GenVLevel | [Category1 VLevel1 and - Category2 VLevel2 and .. CategoryN VLevelN]] - [-decrypt_key Key] | [-decrypt_file KeyFile] - [-include InclDir1 InclDir2 .. InclDirN] - [-no_auto_compile] - [-abort_if_missing_suites] - [-muliply_timetraps Multiplier] - [-scale_timetraps] - [-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc] - [-basic_html]</pre> + [-dir TestDir1 TestDir2 .. TestDirN] | + [[dir TestDir] -suite Suite [[-group Group] [-case Case]]] + [-config ConfigFile1 ConfigFile2 .. ConfigFileN] + [-userconfig CallbackModule1 ConfigString1 and CallbackModule2 + ConfigString2 and .. and CallbackModuleN ConfigStringN] + [-logopts LogOpts] + [-verbosity GenVLevel | [Category1 VLevel1 and + Category2 VLevel2 and .. CategoryN VLevelN]] + [-decrypt_key Key] | [-decrypt_file KeyFile] + [-include InclDir1 InclDir2 .. InclDirN] + [-no_auto_compile] + [-abort_if_missing_suites] + [-muliply_timetraps Multiplier] + [-scale_timetraps] + [-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc] + [-basic_html]</pre> </section> <section> <title>Refresh the HTML index files</title> @@ -188,10 +189,10 @@ <title>Run CT in interactive mode</title> <pre> ct_run -shell - [-config ConfigFile1 ConfigFile2 ... ConfigFileN] - [-userconfig CallbackModule1 ConfigString1 and CallbackModule2 - ConfigString2 and .. and CallbackModuleN ConfigStringN] - [-decrypt_key Key] | [-decrypt_file KeyFile]</pre> + [-config ConfigFile1 ConfigFile2 ... ConfigFileN] + [-userconfig CallbackModule1 ConfigString1 and CallbackModule2 + ConfigString2 and .. and CallbackModuleN ConfigStringN] + [-decrypt_key Key] | [-decrypt_file KeyFile]</pre> </section> <section> <title>Start a Common Test Master node</title> diff --git a/lib/common_test/doc/src/example_chapter.xml b/lib/common_test/doc/src/example_chapter.xml index 36781d152c..2bc8cfdbcc 100644 --- a/lib/common_test/doc/src/example_chapter.xml +++ b/lib/common_test/doc/src/example_chapter.xml @@ -81,7 +81,7 @@ init_per_suite(Config) -> [{con_ref, Ref },{table_name, TableName}| Config]. %%-------------------------------------------------------------------- -%% Function: end_per_suite(Config) -> void() +%% Function: end_per_suite(Config) -> term() %% %% Config = [tuple()] %% A list of key/value pairs, holding the test case configuration. @@ -110,7 +110,7 @@ init_per_testcase(Case, Config) -> Config. %%-------------------------------------------------------------------- -%% Function: end_per_testcase(TestCase, Config) -> void() +%% Function: end_per_testcase(TestCase, Config) -> term() %% %% TestCase = atom() %% Name of the test case that is finished. @@ -226,7 +226,7 @@ init_per_suite(Config) -> Config. %%-------------------------------------------------------------------- -%% Function: end_per_suite(Config0) -> void() | {save_config,Config1} +%% Function: end_per_suite(Config0) -> term() | {save_config,Config1} %% %% Config0 = Config1 = [tuple()] %% A list of key/value pairs, holding the test case configuration. @@ -254,7 +254,7 @@ init_per_group(_GroupName, Config) -> %%-------------------------------------------------------------------- %% Function: end_per_group(GroupName, Config0) -> -%% void() | {save_config,Config1} +%% term() | {save_config,Config1} %% %% GroupName = atom() %% Name of the test case group that is finished. @@ -287,7 +287,7 @@ init_per_testcase(_TestCase, Config) -> %%-------------------------------------------------------------------- %% Function: end_per_testcase(TestCase, Config0) -> -%% void() | {save_config,Config1} | {fail,Reason} +%% term() | {save_config,Config1} | {fail,Reason} %% %% TestCase = atom() %% Name of the test case that is finished. @@ -414,7 +414,7 @@ init_per_suite(Config) -> Config. %%-------------------------------------------------------------------- -%% Function: end_per_suite(Config0) -> void() | {save_config,Config1} +%% Function: end_per_suite(Config0) -> term() | {save_config,Config1} %% Config0 = Config1 = [tuple()] %%-------------------------------------------------------------------- end_per_suite(_Config) -> @@ -432,7 +432,7 @@ init_per_group(_GroupName, Config) -> %%-------------------------------------------------------------------- %% Function: end_per_group(GroupName, Config0) -> -%% void() | {save_config,Config1} +%% term() | {save_config,Config1} %% GroupName = atom() %% Config0 = Config1 = [tuple()] %%-------------------------------------------------------------------- @@ -451,7 +451,7 @@ init_per_testcase(_TestCase, Config) -> %%-------------------------------------------------------------------- %% Function: end_per_testcase(TestCase, Config0) -> -%% void() | {save_config,Config1} | {fail,Reason} +%% term() | {save_config,Config1} | {fail,Reason} %% TestCase = atom() %% Config0 = Config1 = [tuple()] %% Reason = term() diff --git a/lib/common_test/doc/src/run_test_chapter.xml b/lib/common_test/doc/src/run_test_chapter.xml index df60e5f7f2..fc8d82c2c3 100644 --- a/lib/common_test/doc/src/run_test_chapter.xml +++ b/lib/common_test/doc/src/run_test_chapter.xml @@ -149,6 +149,7 @@ <p>Other flags that may be used with <c>ct_run</c>:</p> <list> + <item><c><![CDATA[-help]]></c>, lists all available start flags.</item> <item><c><![CDATA[-logdir <dir>]]></c>, specifies where the HTML log files are to be written.</item> <item><c><![CDATA[-label <name_of_test_run>]]></c>, associates the test run with a name that gets printed in the overview HTML log files.</item> @@ -223,6 +224,9 @@ behaviour using start flag:</p> <pre>-exit_status ignore_config</pre> + <note><p>Executing <c>ct_run</c> without start flags, is equal to the command: + <c>ct_run -dir ./</c></p></note> + <p>For more information about the <c>ct_run</c> program, see the <seealso marker="ct_run">Reference Manual</seealso> and the <seealso marker="install_chapter#general">Installation</seealso> chapter. @@ -251,6 +255,10 @@ <c>{error,Reason}</c>, where the term <c>Reason</c> explains the failure.</p> + <p>The default start option <c>{dir,Cwd}</c> (run all suites in the current + working directory) is used if the function is called with an empty + list of options.</p> + <section> <title>Releasing the Erlang shell</title> <p>During execution of tests, started with diff --git a/lib/common_test/src/ct.erl b/lib/common_test/src/ct.erl index 5ed1346f1e..208632e2dc 100644 --- a/lib/common_test/src/ct.erl +++ b/lib/common_test/src/ct.erl @@ -729,7 +729,7 @@ capture_get([]) -> test_server:capture_get(). %%%----------------------------------------------------------------- -%%% @spec fail(Reason) -> void() +%%% @spec fail(Reason) -> ok %%% Reason = term() %%% %%% @doc Terminate a test case with the given error @@ -747,7 +747,7 @@ fail(Reason) -> end. %%%----------------------------------------------------------------- -%%% @spec fail(Format, Args) -> void() +%%% @spec fail(Format, Args) -> ok %%% Format = string() %%% Args = list() %%% @@ -773,7 +773,7 @@ fail(Format, Args) -> end. %%%----------------------------------------------------------------- -%%% @spec comment(Comment) -> void() +%%% @spec comment(Comment) -> ok %%% Comment = term() %%% %%% @doc Print the given <c>Comment</c> in the comment field in @@ -796,7 +796,7 @@ comment(Comment) -> send_html_comment(lists:flatten(Formatted)). %%%----------------------------------------------------------------- -%%% @spec comment(Format, Args) -> void() +%%% @spec comment(Format, Args) -> ok %%% Format = string() %%% Args = list() %%% diff --git a/lib/common_test/src/ct_event.erl b/lib/common_test/src/ct_event.erl index c1c1d943b9..729d3fbfac 100644 --- a/lib/common_test/src/ct_event.erl +++ b/lib/common_test/src/ct_event.erl @@ -259,8 +259,8 @@ handle_info(_Info, State) -> {ok, State}. %%-------------------------------------------------------------------- -%% Function: terminate(Reason, State) -> void() -%% Description:Whenever an event handler is deleted from an event manager, +%% Function: terminate(Reason, State) -> ok +%% Description: Whenever an event handler is deleted from an event manager, %% this function is called. It should be the opposite of Module:init/1 and %% do any necessary cleaning up. %%-------------------------------------------------------------------- diff --git a/lib/common_test/src/ct_master_event.erl b/lib/common_test/src/ct_master_event.erl index fd97ab16f7..d127b98afe 100644 --- a/lib/common_test/src/ct_master_event.erl +++ b/lib/common_test/src/ct_master_event.erl @@ -168,7 +168,7 @@ handle_info(_Info,State) -> {ok,State}. %%-------------------------------------------------------------------- -%% Function: terminate(Reason, State) -> void() +%% Function: terminate(Reason, State) -> ok %% Description:Whenever an event handler is deleted from an event manager, %% this function is called. It should be the opposite of Module:init/1 and %% do any necessary cleaning up. diff --git a/lib/common_test/src/ct_master_status.erl b/lib/common_test/src/ct_master_status.erl index f9f511ecca..b49a906236 100644 --- a/lib/common_test/src/ct_master_status.erl +++ b/lib/common_test/src/ct_master_status.erl @@ -100,8 +100,8 @@ handle_info(_Info, State) -> {ok, State}. %%-------------------------------------------------------------------- -%% Function: terminate(Reason, State) -> void() -%% Description:Whenever an event handler is deleted from an event manager, +%% Function: terminate(Reason, State) -> ok +%% Description: Whenever an event handler is deleted from an event manager, %% this function is called. It should be the opposite of Module:init/1 and %% do any necessary cleaning up. %%-------------------------------------------------------------------- diff --git a/lib/common_test/src/ct_run.erl b/lib/common_test/src/ct_run.erl index 0eafe72020..e9f685c685 100644 --- a/lib/common_test/src/ct_run.erl +++ b/lib/common_test/src/ct_run.erl @@ -83,7 +83,7 @@ starter}). %%%----------------------------------------------------------------- -%%% @spec script_start() -> void() +%%% @spec script_start() -> term() %%% %%% @doc Start tests via the ct_run program or script. %%% @@ -687,8 +687,10 @@ script_start3(Opts, Args) -> if Opts#opts.vts ; Opts#opts.shell -> script_start4(Opts#opts{tests = []}, Args); true -> - script_usage(), - {error,missing_start_options} + %% no start options, use default "-dir ./" + {ok,Dir} = file:get_cwd(), + io:format("ct_run -dir ~ts~n~n", [Dir]), + script_start4(Opts#opts{tests = tests([Dir])}, Args) end end. @@ -767,82 +769,84 @@ script_start4(Opts = #opts{tests = Tests}, Args) -> %%% @spec script_usage() -> ok %%% @doc Print usage information for <code>ct_run</code>. script_usage() -> - io:format("\n\nUsage:\n\n"), + io:format("\nUsage:\n\n"), io:format("Run tests from command line:\n\n" - "\tct_run [-dir TestDir1 TestDir2 .. TestDirN] |" - "\n\t[[-dir TestDir] -suite Suite1 Suite2 .. SuiteN" - "\n\t [[-group Groups1 Groups2 .. GroupsN] [-case Case1 Case2 .. CaseN]]]" - "\n\t[-step [config | keep_inactive]]" - "\n\t[-config ConfigFile1 ConfigFile2 .. ConfigFileN]" - "\n\t[-userconfig CallbackModule ConfigFile1 .. ConfigFileN]" - "\n\t[-decrypt_key Key] | [-decrypt_file KeyFile]" - "\n\t[-logdir LogDir]" - "\n\t[-logopts LogOpt1 LogOpt2 .. LogOptN]" - "\n\t[-verbosity GenVLvl | [CategoryVLvl1 .. CategoryVLvlN]]" - "\n\t[-silent_connections [ConnType1 ConnType2 .. ConnTypeN]]" - "\n\t[-stylesheet CSSFile]" - "\n\t[-cover CoverCfgFile]" - "\n\t[-cover_stop Bool]" - "\n\t[-event_handler EvHandler1 EvHandler2 .. EvHandlerN]" - "\n\t[-ct_hooks CTHook1 CTHook2 .. CTHookN]" - "\n\t[-include InclDir1 InclDir2 .. InclDirN]" - "\n\t[-no_auto_compile]" - "\n\t[-abort_if_missing_suites]" - "\n\t[-multiply_timetraps N]" - "\n\t[-scale_timetraps]" - "\n\t[-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc]" - "\n\t[-basic_html]" - "\n\t[-repeat N] |" - "\n\t[-duration HHMMSS [-force_stop [skip_rest]]] |" - "\n\t[-until [YYMoMoDD]HHMMSS [-force_stop [skip_rest]]]\n\n"), + "\tct_run -dir TestDir1 TestDir2 .. TestDirN |" + "\n\t [-dir TestDir] -suite Suite1 Suite2 .. SuiteN" + "\n\t [-group Group1 Group2 .. GroupN] [-case Case1 Case2 .. CaseN]" + "\n\t [-step [config | keep_inactive]]" + "\n\t [-config ConfigFile1 ConfigFile2 .. ConfigFileN]" + "\n\t [-userconfig CallbackModule ConfigFile1 .. ConfigFileN]" + "\n\t [-decrypt_key Key] | [-decrypt_file KeyFile]" + "\n\t [-logdir LogDir]" + "\n\t [-logopts LogOpt1 LogOpt2 .. LogOptN]" + "\n\t [-verbosity GenVLvl | [CategoryVLvl1 .. CategoryVLvlN]]" + "\n\t [-silent_connections [ConnType1 ConnType2 .. ConnTypeN]]" + "\n\t [-stylesheet CSSFile]" + "\n\t [-cover CoverCfgFile]" + "\n\t [-cover_stop Bool]" + "\n\t [-event_handler EvHandler1 EvHandler2 .. EvHandlerN]" + "\n\t [-ct_hooks CTHook1 CTHook2 .. CTHookN]" + "\n\t [-include InclDir1 InclDir2 .. InclDirN]" + "\n\t [-no_auto_compile]" + "\n\t [-abort_if_missing_suites]" + "\n\t [-multiply_timetraps N]" + "\n\t [-scale_timetraps]" + "\n\t [-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc]" + "\n\t [-basic_html]" + "\n\t [-repeat N] |" + "\n\t [-duration HHMMSS [-force_stop [skip_rest]]] |" + "\n\t [-until [YYMoMoDD]HHMMSS [-force_stop [skip_rest]]]" + "\n\t [-exit_status ignore_config]" + "\n\t [-help]\n\n"), io:format("Run tests using test specification:\n\n" "\tct_run -spec TestSpec1 TestSpec2 .. TestSpecN" - "\n\t[-config ConfigFile1 ConfigFile2 .. ConfigFileN]" - "\n\t[-decrypt_key Key] | [-decrypt_file KeyFile]" - "\n\t[-logdir LogDir]" - "\n\t[-logopts LogOpt1 LogOpt2 .. LogOptN]" - "\n\t[-verbosity GenVLvl | [CategoryVLvl1 .. CategoryVLvlN]]" - "\n\t[-allow_user_terms]" - "\n\t[-join_specs]" - "\n\t[-silent_connections [ConnType1 ConnType2 .. ConnTypeN]]" - "\n\t[-stylesheet CSSFile]" - "\n\t[-cover CoverCfgFile]" - "\n\t[-cover_stop Bool]" - "\n\t[-event_handler EvHandler1 EvHandler2 .. EvHandlerN]" - "\n\t[-ct_hooks CTHook1 CTHook2 .. CTHookN]" - "\n\t[-include InclDir1 InclDir2 .. InclDirN]" - "\n\t[-no_auto_compile]" - "\n\t[-abort_if_missing_suites]" - "\n\t[-multiply_timetraps N]" - "\n\t[-scale_timetraps]" - "\n\t[-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc]" - "\n\t[-basic_html]" - "\n\t[-repeat N] |" - "\n\t[-duration HHMMSS [-force_stop [skip_rest]]] |" - "\n\t[-until [YYMoMoDD]HHMMSS [-force_stop [skip_rest]]]\n\n"), + "\n\t [-config ConfigFile1 ConfigFile2 .. ConfigFileN]" + "\n\t [-decrypt_key Key] | [-decrypt_file KeyFile]" + "\n\t [-logdir LogDir]" + "\n\t [-logopts LogOpt1 LogOpt2 .. LogOptN]" + "\n\t [-verbosity GenVLvl | [CategoryVLvl1 .. CategoryVLvlN]]" + "\n\t [-allow_user_terms]" + "\n\t [-join_specs]" + "\n\t [-silent_connections [ConnType1 ConnType2 .. ConnTypeN]]" + "\n\t [-stylesheet CSSFile]" + "\n\t [-cover CoverCfgFile]" + "\n\t [-cover_stop Bool]" + "\n\t [-event_handler EvHandler1 EvHandler2 .. EvHandlerN]" + "\n\t [-ct_hooks CTHook1 CTHook2 .. CTHookN]" + "\n\t [-include InclDir1 InclDir2 .. InclDirN]" + "\n\t [-no_auto_compile]" + "\n\t [-abort_if_missing_suites]" + "\n\t [-multiply_timetraps N]" + "\n\t [-scale_timetraps]" + "\n\t [-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc]" + "\n\t [-basic_html]" + "\n\t [-repeat N] |" + "\n\t [-duration HHMMSS [-force_stop [skip_rest]]] |" + "\n\t [-until [YYMoMoDD]HHMMSS [-force_stop [skip_rest]]]\n\n"), io:format("Refresh the HTML index files:\n\n" "\tct_run -refresh_logs [LogDir]" - "[-logdir LogDir] " - "[-basic_html]\n\n"), + " [-logdir LogDir] " + " [-basic_html]\n\n"), io:format("Run CT in interactive mode:\n\n" "\tct_run -shell" - "\n\t[-config ConfigFile1 ConfigFile2 .. ConfigFileN]" - "\n\t[-decrypt_key Key] | [-decrypt_file KeyFile]\n\n"), + "\n\t [-config ConfigFile1 ConfigFile2 .. ConfigFileN]" + "\n\t [-decrypt_key Key] | [-decrypt_file KeyFile]\n\n"), io:format("Run tests in web based GUI:\n\n" "\tct_run -vts [-browser Browser]" - "\n\t[-config ConfigFile1 ConfigFile2 .. ConfigFileN]" - "\n\t[-decrypt_key Key] | [-decrypt_file KeyFile]" - "\n\t[-dir TestDir1 TestDir2 .. TestDirN] |" - "\n\t[-suite Suite [-case Case]]" - "\n\t[-logopts LogOpt1 LogOpt2 .. LogOptN]" - "\n\t[-verbosity GenVLvl | [CategoryVLvl1 .. CategoryVLvlN]]" - "\n\t[-include InclDir1 InclDir2 .. InclDirN]" - "\n\t[-no_auto_compile]" - "\n\t[-abort_if_missing_suites]" - "\n\t[-multiply_timetraps N]" - "\n\t[-scale_timetraps]" - "\n\t[-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc]" - "\n\t[-basic_html]\n\n"). + "\n\t [-config ConfigFile1 ConfigFile2 .. ConfigFileN]" + "\n\t [-decrypt_key Key] | [-decrypt_file KeyFile]" + "\n\t [-dir TestDir1 TestDir2 .. TestDirN] |" + "\n\t [-suite Suite [-case Case]]" + "\n\t [-logopts LogOpt1 LogOpt2 .. LogOptN]" + "\n\t [-verbosity GenVLvl | [CategoryVLvl1 .. CategoryVLvlN]]" + "\n\t [-include InclDir1 InclDir2 .. InclDirN]" + "\n\t [-no_auto_compile]" + "\n\t [-abort_if_missing_suites]" + "\n\t [-multiply_timetraps N]" + "\n\t [-scale_timetraps]" + "\n\t [-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc]" + "\n\t [-basic_html]\n\n"). %%%----------------------------------------------------------------- %%% @hidden @@ -1347,7 +1351,9 @@ run_dir(Opts = #opts{logdir = LogDir, end; {undefined,undefined,[]} -> - exit({error,no_test_specified}); + {ok,Dir} = file:get_cwd(), + %% No start options, use default {dir,CWD} + reformat_result(catch do_run(tests(Dir), [], Opts1, StartOpts)); {Dir,Suite,GsAndCs} -> exit({error,{incorrect_start_options,{Dir,Suite,GsAndCs}}}) diff --git a/lib/inets/src/http_client/httpc_handler.erl b/lib/inets/src/http_client/httpc_handler.erl index a4971cec0f..ce9a0e3d26 100644 --- a/lib/inets/src/http_client/httpc_handler.erl +++ b/lib/inets/src/http_client/httpc_handler.erl @@ -1390,6 +1390,8 @@ case_insensitive_header(Str) -> activate_once(#session{socket = Socket, socket_type = SocketType}) -> http_transport:setopts(SocketType, Socket, [{active, once}]). +close_socket(#session{socket = {remote_close,_}}) -> + ok; close_socket(#session{socket = Socket, socket_type = SocketType}) -> http_transport:close(SocketType, Socket). diff --git a/lib/inets/src/http_server/httpd_conf.erl b/lib/inets/src/http_server/httpd_conf.erl index 9c70f8d1b8..89a7e96f3e 100644 --- a/lib/inets/src/http_server/httpd_conf.erl +++ b/lib/inets/src/http_server/httpd_conf.erl @@ -19,141 +19,29 @@ %% -module(httpd_conf). -%% EWSAPI --export([is_directory/1, is_file/1, make_integer/1, clean/1, - custom_clean/3, check_enum/2]). - %% Application internal API -export([load/1, load/2, load_mime_types/1, store/1, store/2, remove/1, remove_all/1, get_config/3, get_config/4, lookup_socket_type/1, lookup/2, lookup/3, lookup/4, - validate_properties/1]). + validate_properties/1, white_space_clean/1]). + +%% Deprecated +-export([is_directory/1, is_file/1, make_integer/1, clean/1, + custom_clean/3, check_enum/2]). + +-deprecated({is_directory, 1, next_major_release}). +-deprecated({is_file, 1, next_major_release}). +-deprecated({make_integer, 1, next_major_release}). +-deprecated({clean, 1, next_major_release}). +-deprecated({custom_clean, 3, next_major_release}). +-deprecated({check_enum, 2, next_major_release}). -define(VMODULE,"CONF"). -include("httpd_internal.hrl"). -include("httpd.hrl"). -include_lib("inets/src/http_lib/http_internal.hrl"). - -%%%========================================================================= -%%% EWSAPI -%%%========================================================================= -%%------------------------------------------------------------------------- -%% is_directory(FilePath) -> Result -%% FilePath = string() -%% Result = {ok,Directory} | {error,Reason} -%% Directory = string() -%% Reason = string() | enoent | eacces | enotdir | FileInfo -%% FileInfo = File info record -%% -%% Description: Checks if FilePath is a directory in which case it is -%% returned. -%%------------------------------------------------------------------------- -is_directory(Directory) -> - case file:read_file_info(Directory) of - {ok,FileInfo} -> - #file_info{type = Type, access = Access} = FileInfo, - is_directory(Type,Access,FileInfo,Directory); - {error,Reason} -> - {error,Reason} - end. -is_directory(directory,read,_FileInfo,Directory) -> - {ok,Directory}; -is_directory(directory,read_write,_FileInfo,Directory) -> - {ok,Directory}; -is_directory(_Type,_Access,FileInfo,_Directory) -> - {error,FileInfo}. - - -%%------------------------------------------------------------------------- -%% is_file(FilePath) -> Result -%% FilePath = string() -%% Result = {ok,File} | {error,Reason} -%% File = string() -%% Reason = string() | enoent | eacces | enotdir | FileInfo -%% FileInfo = File info record -%% -%% Description: Checks if FilePath is a regular file in which case it -%% is returned. -%%------------------------------------------------------------------------- -is_file(File) -> - case file:read_file_info(File) of - {ok,FileInfo} -> - #file_info{type = Type, access = Access} = FileInfo, - is_file(Type,Access,FileInfo,File); - {error,Reason} -> - {error,Reason} - end. -is_file(regular,read,_FileInfo,File) -> - {ok,File}; -is_file(regular,read_write,_FileInfo,File) -> - {ok,File}; -is_file(_Type,_Access,FileInfo,_File) -> - {error,FileInfo}. - - -%%------------------------------------------------------------------------- -%% make_integer(String) -> Result -%% String = string() -%% Result = {ok,integer()} | {error,nomatch} -%% -%% Description: make_integer/1 returns an integer representation of String. -%%------------------------------------------------------------------------- -make_integer(String) -> - case inets_regexp:match(clean(String),"[0-9]+") of - {match, _, _} -> - {ok, list_to_integer(clean(String))}; - nomatch -> - {error, nomatch} - end. - - -%%------------------------------------------------------------------------- -%% clean(String) -> Stripped -%% String = Stripped = string() -%% -%% Description:clean/1 removes leading and/or trailing white spaces -%% from String. -%%------------------------------------------------------------------------- -clean(String) -> - {ok,CleanedString,_} = - inets_regexp:gsub(String, "^[ \t\n\r\f]*|[ \t\n\r\f]*\$",""), - CleanedString. - - -%%------------------------------------------------------------------------- -%% custom_clean(String,Before,After) -> Stripped -%% Before = After = regexp() -%% String = Stripped = string() -%% -%% Description: custom_clean/3 removes leading and/or trailing white -%% spaces and custom characters from String. -%%------------------------------------------------------------------------- -custom_clean(String,MoreBefore,MoreAfter) -> - {ok,CleanedString,_} = inets_regexp:gsub(String,"^[ \t\n\r\f"++MoreBefore++ - "]*|[ \t\n\r\f"++MoreAfter++"]*\$",""), - CleanedString. - - -%%------------------------------------------------------------------------- -%% check_enum(EnumString,ValidEnumStrings) -> Result -%% EnumString = string() -%% ValidEnumStrings = [string()] -%% Result = {ok,atom()} | {error,not_valid} -%% -%% Description: check_enum/2 checks if EnumString is a valid -%% enumeration of ValidEnumStrings in which case it is returned as an -%% atom. -%%------------------------------------------------------------------------- -check_enum(_Enum,[]) -> - {error, not_valid}; -check_enum(Enum,[Enum|_Rest]) -> - {ok, list_to_atom(Enum)}; -check_enum(Enum, [_NotValid|Rest]) -> - check_enum(Enum, Rest). - - %%%========================================================================= %%% Application internal API %%%========================================================================= @@ -192,7 +80,7 @@ load("MaxHeaderSize " ++ MaxHeaderSize, []) -> {ok, Integer} -> {ok, [], {max_header_size,Integer}}; {error, _} -> - {error, ?NICE(clean(MaxHeaderSize)++ + {error, ?NICE(string:strip(MaxHeaderSize)++ " is an invalid number of MaxHeaderSize")} end; @@ -201,7 +89,7 @@ load("MaxURISize " ++ MaxHeaderSize, []) -> {ok, Integer} -> {ok, [], {max_uri_size, Integer}}; {error, _} -> - {error, ?NICE(clean(MaxHeaderSize)++ + {error, ?NICE(string:strip(MaxHeaderSize)++ " is an invalid number of MaxHeaderSize")} end; @@ -210,12 +98,12 @@ load("MaxContentLength " ++ Max, []) -> {ok, Integer} -> {ok, [], {max_content_length, Integer}}; {error, _} -> - {error, ?NICE(clean(Max) ++ + {error, ?NICE(string:strip(Max) ++ " is an invalid number of MaxContentLength")} end; load("ServerName " ++ ServerName, []) -> - {ok,[], {server_name, clean(ServerName)}}; + {ok,[], {server_name, string:strip(ServerName)}}; load("ServerTokens " ++ ServerTokens, []) -> %% These are the valid *plain* server tokens: @@ -223,28 +111,28 @@ load("ServerTokens " ++ ServerTokens, []) -> %% It can also be a "private" server token: private:<any string> case string:tokens(ServerTokens, [$:]) of ["private", Private] -> - {ok,[], {server_tokens, clean(Private)}}; + {ok,[], {server_tokens, string:strip(Private)}}; [TokStr] -> - Tok = list_to_atom(clean(TokStr)), + Tok = list_to_atom(string:strip(TokStr)), case lists:member(Tok, [none, prod, major, minor, minimum, os, full]) of true -> {ok,[], {server_tokens, Tok}}; false -> - {error, ?NICE(clean(ServerTokens) ++ + {error, ?NICE(string:strip(ServerTokens) ++ " is an invalid ServerTokens")} end; _ -> - {error, ?NICE(clean(ServerTokens) ++ " is an invalid ServerTokens")} + {error, ?NICE(string:strip(ServerTokens) ++ " is an invalid ServerTokens")} end; load("SocketType " ++ SocketType, []) -> %% ssl is the same as HTTP_DEFAULT_SSL_KIND %% essl is the pure Erlang-based ssl (the "new" ssl) - case check_enum(clean(SocketType), ["ssl", "essl", "ip_comm"]) of + case check_enum(string:strip(SocketType), ["ssl", "essl", "ip_comm"]) of {ok, ValidSocketType} -> {ok, [], {socket_type, ValidSocketType}}; {error,_} -> - {error, ?NICE(clean(SocketType) ++ " is an invalid SocketType")} + {error, ?NICE(string:strip(SocketType) ++ " is an invalid SocketType")} end; load("Port " ++ Port, []) -> @@ -252,7 +140,7 @@ load("Port " ++ Port, []) -> {ok, Integer} -> {ok, [], {port, Integer}}; {error, _} -> - {error, ?NICE(clean(Port)++" is an invalid Port")} + {error, ?NICE(string:strip(Port)++" is an invalid Port")} end; load("BindAddress " ++ Address0, []) -> @@ -308,7 +196,7 @@ load("BindAddress " ++ Address0, []) -> end; load("KeepAlive " ++ OnorOff, []) -> - case list_to_atom(clean(OnorOff)) of + case list_to_atom(string:strip(OnorOff)) of off -> {ok, [], {keep_alive, false}}; _ -> @@ -320,7 +208,7 @@ load("MaxKeepAliveRequests " ++ MaxRequests, []) -> {ok, Integer} -> {ok, [], {max_keep_alive_request, Integer}}; {error, _} -> - {error, ?NICE(clean(MaxRequests) ++ + {error, ?NICE(string:strip(MaxRequests) ++ " is an invalid MaxKeepAliveRequests")} end; @@ -330,7 +218,7 @@ load("MaxKeepAliveRequest " ++ MaxRequests, []) -> {ok, Integer} -> {ok, [], {max_keep_alive_request, Integer}}; {error, _} -> - {error, ?NICE(clean(MaxRequests) ++ + {error, ?NICE(string:strip(MaxRequests) ++ " is an invalid MaxKeepAliveRequest")} end; @@ -339,7 +227,7 @@ load("KeepAliveTimeout " ++ Timeout, []) -> {ok, Integer} -> {ok, [], {keep_alive_timeout, Integer}}; {error, _} -> - {error, ?NICE(clean(Timeout)++" is an invalid KeepAliveTimeout")} + {error, ?NICE(string:strip(Timeout)++" is an invalid KeepAliveTimeout")} end; load("Modules " ++ Modules, []) -> @@ -347,18 +235,18 @@ load("Modules " ++ Modules, []) -> {ok, [], {modules,[list_to_atom(X) || X <- ModuleList]}}; load("ServerAdmin " ++ ServerAdmin, []) -> - {ok, [], {server_admin,clean(ServerAdmin)}}; + {ok, [], {server_admin,string:strip(ServerAdmin)}}; load("ServerRoot " ++ ServerRoot, []) -> - case is_directory(clean(ServerRoot)) of + case is_directory(string:strip(ServerRoot)) of {ok, Directory} -> {ok, [], [{server_root,string:strip(Directory,right,$/)}]}; {error, _} -> - {error, ?NICE(clean(ServerRoot)++" is an invalid ServerRoot")} + {error, ?NICE(string:strip(ServerRoot)++" is an invalid ServerRoot")} end; load("MimeTypes " ++ MimeTypes, []) -> - case load_mime_types(clean(MimeTypes)) of + case load_mime_types(white_space_clean(MimeTypes)) of {ok, MimeTypesList} -> {ok, [], [{mime_types, MimeTypesList}]}; {error, Reason} -> @@ -370,24 +258,24 @@ load("MaxClients " ++ MaxClients, []) -> {ok, Integer} -> {ok, [], {max_clients,Integer}}; {error, _} -> - {error, ?NICE(clean(MaxClients) ++ + {error, ?NICE(string:strip(MaxClients) ++ " is an invalid number of MaxClients")} end; load("DocumentRoot " ++ DocumentRoot,[]) -> - case is_directory(clean(DocumentRoot)) of + case is_directory(string:strip(DocumentRoot)) of {ok, Directory} -> {ok, [], {document_root,string:strip(Directory,right,$/)}}; {error, _} -> - {error, ?NICE(clean(DocumentRoot)++" is an invalid DocumentRoot")} + {error, ?NICE(string:strip(DocumentRoot)++" is an invalid DocumentRoot")} end; load("DefaultType " ++ DefaultType, []) -> - {ok, [], {default_type,clean(DefaultType)}}; + {ok, [], {default_type,string:strip(DefaultType)}}; load("SSLCertificateFile " ++ SSLCertificateFile, []) -> - case is_file(clean(SSLCertificateFile)) of + case is_file(string:strip(SSLCertificateFile)) of {ok, File} -> {ok, [], {ssl_certificate_file,File}}; {error, _} -> - {error, ?NICE(clean(SSLCertificateFile)++ + {error, ?NICE(string:strip(SSLCertificateFile)++ " is an invalid SSLCertificateFile")} end; load("SSLLogLevel " ++ SSLLogAlert, []) -> @@ -398,69 +286,69 @@ load("SSLLogLevel " ++ SSLLogAlert, []) -> {ok, [], {ssl_log_alert, true}} end; load("SSLCertificateKeyFile " ++ SSLCertificateKeyFile, []) -> - case is_file(clean(SSLCertificateKeyFile)) of + case is_file(string:strip(SSLCertificateKeyFile)) of {ok, File} -> {ok, [], {ssl_certificate_key_file,File}}; {error, _} -> - {error, ?NICE(clean(SSLCertificateKeyFile)++ + {error, ?NICE(string:strip(SSLCertificateKeyFile)++ " is an invalid SSLCertificateKeyFile")} end; load("SSLVerifyClient " ++ SSLVerifyClient, []) -> - case make_integer(clean(SSLVerifyClient)) of + case make_integer(string:strip(SSLVerifyClient)) of {ok, Integer} when (Integer >=0) andalso (Integer =< 2) -> {ok, [], {ssl_verify_client,Integer}}; {ok, _Integer} -> - {error,?NICE(clean(SSLVerifyClient) ++ + {error,?NICE(string:strip(SSLVerifyClient) ++ " is an invalid SSLVerifyClient")}; {error, nomatch} -> - {error,?NICE(clean(SSLVerifyClient) ++ + {error,?NICE(string:strip(SSLVerifyClient) ++ " is an invalid SSLVerifyClient")} end; load("SSLVerifyDepth " ++ SSLVerifyDepth, []) -> - case make_integer(clean(SSLVerifyDepth)) of + case make_integer(string:strip(SSLVerifyDepth)) of {ok, Integer} when Integer > 0 -> {ok, [], {ssl_verify_client_depth,Integer}}; {ok, _Integer} -> - {error,?NICE(clean(SSLVerifyDepth) ++ + {error,?NICE(string:strip(SSLVerifyDepth) ++ " is an invalid SSLVerifyDepth")}; {error, nomatch} -> - {error,?NICE(clean(SSLVerifyDepth) ++ + {error,?NICE(string:strip(SSLVerifyDepth) ++ " is an invalid SSLVerifyDepth")} end; load("SSLCiphers " ++ SSLCiphers, []) -> - {ok, [], {ssl_ciphers, clean(SSLCiphers)}}; + {ok, [], {ssl_ciphers, string:strip(SSLCiphers)}}; load("SSLCACertificateFile " ++ SSLCACertificateFile, []) -> - case is_file(clean(SSLCACertificateFile)) of + case is_file(string:strip(SSLCACertificateFile)) of {ok, File} -> {ok, [], {ssl_ca_certificate_file,File}}; {error, _} -> - {error, ?NICE(clean(SSLCACertificateFile)++ + {error, ?NICE(string:strip(SSLCACertificateFile)++ " is an invalid SSLCACertificateFile")} end; load("SSLPasswordCallbackModule " ++ SSLPasswordCallbackModule, []) -> {ok, [], {ssl_password_callback_module, - list_to_atom(clean(SSLPasswordCallbackModule))}}; + list_to_atom(string:strip(SSLPasswordCallbackModule))}}; load("SSLPasswordCallbackFunction " ++ SSLPasswordCallbackFunction, []) -> {ok, [], {ssl_password_callback_function, - list_to_atom(clean(SSLPasswordCallbackFunction))}}; + list_to_atom(string:strip(SSLPasswordCallbackFunction))}}; load("SSLPasswordCallbackArguments " ++ SSLPasswordCallbackArguments, []) -> {ok, [], {ssl_password_callback_arguments, SSLPasswordCallbackArguments}}; load("DisableChunkedTransferEncodingSend " ++ TrueOrFalse, []) -> - case list_to_atom(clean(TrueOrFalse)) of + case list_to_atom(string:strip(TrueOrFalse)) of true -> {ok, [], {disable_chunked_transfer_encoding_send, true}}; _ -> {ok, [], {disable_chunked_transfer_encoding_send, false}} end; load("LogFormat " ++ LogFormat, []) -> - {ok,[],{log_format, list_to_atom(httpd_conf:clean(LogFormat))}}; + {ok,[],{log_format, list_to_atom(string:strip(LogFormat))}}; load("ErrorLogFormat " ++ LogFormat, []) -> - {ok,[],{error_log_format, list_to_atom(httpd_conf:clean(LogFormat))}}. + {ok,[],{error_log_format, list_to_atom(string:strip(LogFormat))}}. clean_address(Addr) -> - string:strip(string:strip(clean(Addr), left, $[), right, $]). + string:strip(string:strip(string:strip(Addr), left, $[), right, $]). make_ipfamily(IpFamilyStr) -> @@ -1086,7 +974,7 @@ verify_modules([]) -> verify_modules([Mod|Rest]) -> case code:which(Mod) of non_existing -> - {error, ?NICE(atom_to_list(Mod)++" does not exist")}; + {error, ?NICE(string:strip(atom_to_list(Mod), right, $\n) ++" does not exist")}; _Path -> verify_modules(Rest) end. @@ -1128,7 +1016,7 @@ parse_mime_types(Stream,MimeTypesList) -> eof -> eof; String -> - clean(String) + white_space_clean(String) end, parse_mime_types(Stream, MimeTypesList, Line). parse_mime_types(Stream, MimeTypesList, eof) -> @@ -1314,4 +1202,68 @@ plain_server_tokens() -> error_report(Where,M,F,Error) -> error_logger:error_report([{?MODULE, Where}, {apply, {M, F, []}}, Error]). +white_space_clean(String) -> + {ok,CleanedString,_} = + inets_regexp:gsub(String, "^[ \t\n\r\f]*|[ \t\n\r\f]*\$",""), + CleanedString. + + +%%%========================================================================= +%%% Deprecated remove in 19 +%%%========================================================================= +is_directory(Directory) -> + case file:read_file_info(Directory) of + {ok,FileInfo} -> + #file_info{type = Type, access = Access} = FileInfo, + is_directory(Type,Access,FileInfo,Directory); + {error,Reason} -> + {error,Reason} + end. +is_directory(directory,read,_FileInfo,Directory) -> + {ok,Directory}; +is_directory(directory,read_write,_FileInfo,Directory) -> + {ok,Directory}; +is_directory(_Type,_Access,FileInfo,_Directory) -> + {error,FileInfo}. + +is_file(File) -> + case file:read_file_info(File) of + {ok,FileInfo} -> + #file_info{type = Type, access = Access} = FileInfo, + is_file(Type,Access,FileInfo,File); + {error,Reason} -> + {error,Reason} + end. +is_file(regular,read,_FileInfo,File) -> + {ok,File}; +is_file(regular,read_write,_FileInfo,File) -> + {ok,File}; +is_file(_Type,_Access,FileInfo,_File) -> + {error,FileInfo}. + +make_integer(String) -> + case inets_regexp:match(string:strip(String),"[0-9]+") of + {match, _, _} -> + {ok, list_to_integer(string:strip(String))}; + nomatch -> + {error, nomatch} + end. + +clean(String) -> + {ok,CleanedString,_} = + inets_regexp:gsub(String, "^[ \t\n\r\f]*|[ \t\n\r\f]*\$",""), + CleanedString. + +custom_clean(String,MoreBefore,MoreAfter) -> + {ok,CleanedString,_} = inets_regexp:gsub(String,"^[ \t\n\r\f"++MoreBefore++ + "]*|[ \t\n\r\f"++MoreAfter++"]*\$",""), + CleanedString. + +check_enum(_Enum,[]) -> + {error, not_valid}; +check_enum(Enum,[Enum|_Rest]) -> + {ok, list_to_atom(Enum)}; +check_enum(Enum, [_NotValid|Rest]) -> + check_enum(Enum, Rest). + diff --git a/lib/inets/src/http_server/httpd_example.erl b/lib/inets/src/http_server/httpd_example.erl index 6fc07f033c..b2c2ea7480 100644 --- a/lib/inets/src/http_server/httpd_example.erl +++ b/lib/inets/src/http_server/httpd_example.erl @@ -126,9 +126,7 @@ delay(Time) when is_integer(Time) -> i("httpd_example:delay(~p) -> done, now reply",[Time]), delay_reply("delay ok"); delay(Time) when is_list(Time) -> - delay(httpd_conf:make_integer(Time)); -delay({ok,Time}) when is_integer(Time) -> - delay(Time); + delay(list_to_integer(Time)); delay({error,_Reason}) -> i("delay -> called with invalid time"), delay_reply("delay failed: invalid delay time"). diff --git a/lib/inets/src/http_server/mod_actions.erl b/lib/inets/src/http_server/mod_actions.erl index c3946ff9b4..e493ddbf93 100644 --- a/lib/inets/src/http_server/mod_actions.erl +++ b/lib/inets/src/http_server/mod_actions.erl @@ -84,14 +84,14 @@ load("Action "++ Action, []) -> {ok,[MimeType, CGIScript]} -> {ok,[],{action, {MimeType, CGIScript}}}; {ok,_} -> - {error,?NICE(httpd_conf:clean(Action)++" is an invalid Action")} + {error,?NICE(string:strip(Action)++" is an invalid Action")} end; load("Script " ++ Script,[]) -> case inets_regexp:split(Script, " ") of {ok,[Method, CGIScript]} -> {ok,[],{script, {Method, CGIScript}}}; {ok,_} -> - {error,?NICE(httpd_conf:clean(Script)++" is an invalid Script")} + {error,?NICE(string:strip(Script)++" is an invalid Script")} end. store({action, {MimeType, CGIScript}} = Conf, _) when is_list(MimeType), diff --git a/lib/inets/src/http_server/mod_alias.erl b/lib/inets/src/http_server/mod_alias.erl index 5039cd56b5..e0d34288cd 100644 --- a/lib/inets/src/http_server/mod_alias.erl +++ b/lib/inets/src/http_server/mod_alias.erl @@ -212,7 +212,7 @@ load("Alias " ++ Alias, []) -> {ok, [FakeName, RealName]} -> {ok,[],{alias,{FakeName,RealName}}}; {ok, _} -> - {error,?NICE(httpd_conf:clean(Alias)++" is an invalid Alias")} + {error,?NICE(string:strip(Alias)++" is an invalid Alias")} end; load("ReWrite " ++ Rule, Acc) -> load_re_write(Rule, Acc, "ReWrite", re_write); @@ -223,7 +223,7 @@ load("ScriptAlias " ++ ScriptAlias, []) -> RealName1 = filename:join(filename:split(RealName)), {ok, [], {script_alias, {FakeName, RealName1++"/"}}}; {ok, _} -> - {error, ?NICE(httpd_conf:clean(ScriptAlias)++ + {error, ?NICE(string:strip(ScriptAlias)++ " is an invalid ScriptAlias")} end; load("ScriptReWrite " ++ Rule, Acc) -> @@ -234,7 +234,7 @@ load_re_write(Rule0, Acc, Type, Tag) -> fun ($\s) -> true; ($\t) -> true; (_) -> false end, Rule0) of "" -> - {error, ?NICE(httpd_conf:clean(Rule0)++" is an invalid "++Type)}; + {error, ?NICE(string:strip(Rule0)++" is an invalid "++Type)}; Rule -> case string:chr(Rule, $\s) of 0 -> diff --git a/lib/inets/src/http_server/mod_auth.erl b/lib/inets/src/http_server/mod_auth.erl index 1f4470622d..ae716a6cff 100644 --- a/lib/inets/src/http_server/mod_auth.erl +++ b/lib/inets/src/http_server/mod_auth.erl @@ -127,35 +127,35 @@ do(Info) -> %% state it was previously. load("<Directory " ++ Directory,[]) -> - Dir = httpd_conf:custom_clean(Directory,"",">"), + Dir = string:strip(string:strip(Directory),right, $>), {ok,[{directory, {Dir, [{path, Dir}]}}]}; load(eof,[{directory, {Directory, _DirData}}|_]) -> {error, ?NICE("Premature end-of-file in "++ Directory)}; load("AuthName " ++ AuthName, [{directory, {Directory, DirData}}|Rest]) -> {ok, [{directory, {Directory, - [{auth_name, httpd_conf:clean(AuthName)} | DirData]}} + [{auth_name, string:strip(AuthName)} | DirData]}} | Rest ]}; load("AuthUserFile " ++ AuthUserFile0, [{directory, {Directory, DirData}}|Rest]) -> - AuthUserFile = httpd_conf:clean(AuthUserFile0), + AuthUserFile = string:strip(AuthUserFile0), {ok, [{directory, {Directory, [{auth_user_file, AuthUserFile}|DirData]}} | Rest ]}; load("AuthGroupFile " ++ AuthGroupFile0, [{directory, {Directory, DirData}}|Rest]) -> - AuthGroupFile = httpd_conf:clean(AuthGroupFile0), + AuthGroupFile = string:strip(AuthGroupFile0), {ok,[{directory, {Directory, [{auth_group_file, AuthGroupFile}|DirData]}} | Rest]}; load("AuthAccessPassword " ++ AuthAccessPassword0, [{directory, {Directory, DirData}}|Rest]) -> - AuthAccessPassword = httpd_conf:clean(AuthAccessPassword0), + AuthAccessPassword = string:strip(AuthAccessPassword0), {ok,[{directory, {Directory, [{auth_access_password, AuthAccessPassword}|DirData]}} | Rest]}; load("AuthDBType " ++ Type, [{directory, {Dir, DirData}}|Rest]) -> - case httpd_conf:clean(Type) of + case string:strip(Type) of "plain" -> {ok, [{directory, {Dir, [{auth_type, plain}|DirData]}} | Rest ]}; "mnesia" -> @@ -163,7 +163,7 @@ load("AuthDBType " ++ Type, "dets" -> {ok, [{directory, {Dir, [{auth_type, dets}|DirData]}} | Rest ]}; _ -> - {error, ?NICE(httpd_conf:clean(Type)++" is an invalid AuthDBType")} + {error, ?NICE(string:strip(Type)++" is an invalid AuthDBType")} end; load("require " ++ Require,[{directory, {Directory, DirData}}|Rest]) -> @@ -175,7 +175,7 @@ load("require " ++ Require,[{directory, {Directory, DirData}}|Rest]) -> {ok,[{directory, {Directory, [{require_group,Groups}|DirData]}} | Rest]}; {ok,_} -> - {error,?NICE(httpd_conf:clean(Require) ++" is an invalid require")} + {error,?NICE(string:strip(Require) ++" is an invalid require")} end; load("allow " ++ Allow,[{directory, {Directory, DirData}}|Rest]) -> @@ -187,7 +187,7 @@ load("allow " ++ Allow,[{directory, {Directory, DirData}}|Rest]) -> {ok,[{directory, {Directory, [{allow_from,Hosts}|DirData]}} | Rest]}; {ok,_} -> - {error,?NICE(httpd_conf:clean(Allow) ++" is an invalid allow")} + {error,?NICE(string:strip(Allow) ++" is an invalid allow")} end; load("deny " ++ Deny,[{directory, {Directory, DirData}}|Rest]) -> @@ -199,7 +199,7 @@ load("deny " ++ Deny,[{directory, {Directory, DirData}}|Rest]) -> {ok,[{{directory, Directory, [{deny_from, Hosts}|DirData]}} | Rest]}; {ok, _} -> - {error,?NICE(httpd_conf:clean(Deny) ++" is an invalid deny")} + {error,?NICE(string:strip(Deny) ++" is an invalid deny")} end; load("</Directory>",[{directory, {Directory, DirData}}|Rest]) -> @@ -207,14 +207,14 @@ load("</Directory>",[{directory, {Directory, DirData}}|Rest]) -> load("AuthMnesiaDB " ++ AuthMnesiaDB, [{directory, {Dir, DirData}}|Rest]) -> - case httpd_conf:clean(AuthMnesiaDB) of + case string:strip(AuthMnesiaDB) of "On" -> {ok,[{directory, {Dir,[{auth_type,mnesia}|DirData]}}|Rest]}; "Off" -> {ok,[{directory, {Dir,[{auth_type,plain}|DirData]}}|Rest]}; _ -> - {error, ?NICE(httpd_conf:clean(AuthMnesiaDB) ++ - " is an invalid AuthMnesiaDB")} + {error, ?NICE(string:strip(AuthMnesiaDB) ++ + " is an invalid AuthMnesiaDB")} end. store({directory, {Directory, DirData}}, ConfigList) diff --git a/lib/inets/src/http_server/mod_auth_plain.erl b/lib/inets/src/http_server/mod_auth_plain.erl index 7bb86fc812..b411202efc 100644 --- a/lib/inets/src/http_server/mod_auth_plain.erl +++ b/lib/inets/src/http_server/mod_auth_plain.erl @@ -231,7 +231,7 @@ parse_group(Stream, GroupList) -> eof -> eof; String -> - httpd_conf:clean(String) + httpd_conf:white_space_clean(String) end, parse_group(Stream, GroupList, Line). @@ -265,7 +265,7 @@ parse_passwd(Stream, PasswdList) -> eof -> eof; String -> - httpd_conf:clean(String) + httpd_conf:white_space_clean(String) end, parse_passwd(Stream, PasswdList, Line). diff --git a/lib/inets/src/http_server/mod_cgi.erl b/lib/inets/src/http_server/mod_cgi.erl index d933b0a4ba..fbcfa78e5f 100644 --- a/lib/inets/src/http_server/mod_cgi.erl +++ b/lib/inets/src/http_server/mod_cgi.erl @@ -95,24 +95,24 @@ do(ModData) -> %% or cache %% load("ScriptNoCache " ++ CacheArg, [])-> - case catch list_to_atom(httpd_conf:clean(CacheArg)) of + case catch list_to_atom(string:strip(CacheArg)) of true -> {ok, [], {script_nocache, true}}; false -> {ok, [], {script_nocache, false}}; _ -> - {error, ?NICE(httpd_conf:clean(CacheArg)++ + {error, ?NICE(string:strip(CacheArg)++ " is an invalid ScriptNoCache directive")} end; %% ScriptTimeout Seconds, The number of seconds that the server %% maximum will wait for the script to %% generate a part of the document load("ScriptTimeout " ++ Timeout, [])-> - case catch list_to_integer(httpd_conf:clean(Timeout)) of + case catch list_to_integer(string:strip(Timeout)) of TimeoutSec when is_integer(TimeoutSec) -> {ok, [], {script_timeout,TimeoutSec*1000}}; _ -> - {error, ?NICE(httpd_conf:clean(Timeout)++ + {error, ?NICE(string:strip(Timeout)++ " is an invalid ScriptTimeout")} end. diff --git a/lib/inets/src/http_server/mod_disk_log.erl b/lib/inets/src/http_server/mod_disk_log.erl index 5a3766de66..89a3193aa3 100644 --- a/lib/inets/src/http_server/mod_disk_log.erl +++ b/lib/inets/src/http_server/mod_disk_log.erl @@ -139,70 +139,70 @@ do(Info) -> load("TransferDiskLogSize " ++ TransferDiskLogSize, []) -> case inets_regexp:split(TransferDiskLogSize," ") of {ok,[MaxBytes,MaxFiles]} -> - case httpd_conf:make_integer(MaxBytes) of + case make_integer(MaxBytes) of {ok,MaxBytesInteger} -> - case httpd_conf:make_integer(MaxFiles) of + case make_integer(MaxFiles) of {ok,MaxFilesInteger} -> {ok,[],{transfer_disk_log_size, {MaxBytesInteger,MaxFilesInteger}}}; {error,_} -> {error, - ?NICE(httpd_conf:clean(TransferDiskLogSize)++ + ?NICE(string:strip(TransferDiskLogSize)++ " is an invalid TransferDiskLogSize")} end; {error,_} -> - {error,?NICE(httpd_conf:clean(TransferDiskLogSize)++ + {error,?NICE(string:strip(TransferDiskLogSize)++ " is an invalid TransferDiskLogSize")} end end; load("TransferDiskLog " ++ TransferDiskLog,[]) -> - {ok,[],{transfer_disk_log,httpd_conf:clean(TransferDiskLog)}}; + {ok,[],{transfer_disk_log,string:strip(TransferDiskLog)}}; load("ErrorDiskLogSize " ++ ErrorDiskLogSize, []) -> case inets_regexp:split(ErrorDiskLogSize," ") of {ok,[MaxBytes,MaxFiles]} -> - case httpd_conf:make_integer(MaxBytes) of + case make_integer(MaxBytes) of {ok,MaxBytesInteger} -> - case httpd_conf:make_integer(MaxFiles) of + case make_integer(MaxFiles) of {ok,MaxFilesInteger} -> {ok,[],{error_disk_log_size, {MaxBytesInteger,MaxFilesInteger}}}; {error,_} -> - {error,?NICE(httpd_conf:clean(ErrorDiskLogSize)++ + {error,?NICE(string:strip(ErrorDiskLogSize)++ " is an invalid ErrorDiskLogSize")} end; {error,_} -> - {error,?NICE(httpd_conf:clean(ErrorDiskLogSize)++ + {error,?NICE(string:strip(ErrorDiskLogSize)++ " is an invalid ErrorDiskLogSize")} end end; load("ErrorDiskLog " ++ ErrorDiskLog, []) -> - {ok, [], {error_disk_log, httpd_conf:clean(ErrorDiskLog)}}; + {ok, [], {error_disk_log, string:strip(ErrorDiskLog)}}; load("SecurityDiskLogSize " ++ SecurityDiskLogSize, []) -> case inets_regexp:split(SecurityDiskLogSize, " ") of {ok, [MaxBytes, MaxFiles]} -> - case httpd_conf:make_integer(MaxBytes) of + case make_integer(MaxBytes) of {ok, MaxBytesInteger} -> - case httpd_conf:make_integer(MaxFiles) of + case make_integer(MaxFiles) of {ok, MaxFilesInteger} -> {ok, [], {security_disk_log_size, {MaxBytesInteger, MaxFilesInteger}}}; {error,_} -> {error, - ?NICE(httpd_conf:clean(SecurityDiskLogSize) ++ + ?NICE(string:strip(SecurityDiskLogSize) ++ " is an invalid SecurityDiskLogSize")} end; {error, _} -> - {error, ?NICE(httpd_conf:clean(SecurityDiskLogSize) ++ + {error, ?NICE(string:strip(SecurityDiskLogSize) ++ " is an invalid SecurityDiskLogSize")} end end; load("SecurityDiskLog " ++ SecurityDiskLog, []) -> - {ok, [], {security_disk_log, httpd_conf:clean(SecurityDiskLog)}}; + {ok, [], {security_disk_log, string:strip(SecurityDiskLog)}}; load("DiskLogFormat " ++ Format, []) -> - case httpd_conf:clean(Format) of + case string:strip(Format) of "internal" -> {ok, [], {disk_log_format,internal}}; "external" -> @@ -314,7 +314,7 @@ log_size(ConfigList, Tag) -> proplists:get_value(Tag, ConfigList, {500*1024,8}). create_disk_log(LogFile, SizeTag, ConfigList) -> - Filename = httpd_conf:clean(LogFile), + Filename = string:strip(LogFile), {MaxBytes, MaxFiles} = log_size(ConfigList, SizeTag), case filename:pathtype(Filename) of absolute -> @@ -413,3 +413,11 @@ log_internal_info(Info,Date,[{internal_info,Reason}|Rest]) -> log_internal_info(Info,Date,[_|Rest]) -> log_internal_info(Info,Date,Rest). +make_integer(List) -> + try list_to_integer(List) of + N -> + {ok, N} + catch + _:_ -> + {error, {badarg, list_to_integer, List}} + end. diff --git a/lib/inets/src/http_server/mod_esi.erl b/lib/inets/src/http_server/mod_esi.erl index b11df34f9e..d385afbd70 100644 --- a/lib/inets/src/http_server/mod_esi.erl +++ b/lib/inets/src/http_server/mod_esi.erl @@ -98,40 +98,40 @@ load("ErlScriptAlias " ++ ErlScriptAlias, []) -> case inets_regexp:split(ErlScriptAlias," ") of {ok, [ErlName | StrModules]} -> Modules = lists:map(fun(Str) -> - list_to_atom(httpd_conf:clean(Str)) + list_to_atom(string:strip(Str)) end, StrModules), {ok, [], {erl_script_alias, {ErlName, Modules}}}; {ok, _} -> - {error, ?NICE(httpd_conf:clean(ErlScriptAlias) ++ + {error, ?NICE(string:strip(ErlScriptAlias) ++ " is an invalid ErlScriptAlias")} end; load("EvalScriptAlias " ++ EvalScriptAlias, []) -> case inets_regexp:split(EvalScriptAlias, " ") of {ok, [EvalName | StrModules]} -> Modules = lists:map(fun(Str) -> - list_to_atom(httpd_conf:clean(Str)) + list_to_atom(string:strip(Str)) end, StrModules), {ok, [], {eval_script_alias, {EvalName, Modules}}}; {ok, _} -> - {error, ?NICE(httpd_conf:clean(EvalScriptAlias) ++ + {error, ?NICE(string:strip(EvalScriptAlias) ++ " is an invalid EvalScriptAlias")} end; load("ErlScriptTimeout " ++ Timeout, [])-> - case catch list_to_integer(httpd_conf:clean(Timeout)) of + case catch list_to_integer(string:strip(Timeout)) of TimeoutSec when is_integer(TimeoutSec) -> {ok, [], {erl_script_timeout, TimeoutSec * 1000}}; _ -> - {error, ?NICE(httpd_conf:clean(Timeout) ++ + {error, ?NICE(string:strip(Timeout) ++ " is an invalid ErlScriptTimeout")} end; load("ErlScriptNoCache " ++ CacheArg, [])-> - case catch list_to_atom(httpd_conf:clean(CacheArg)) of + case catch list_to_atom(string:strip(CacheArg)) of true -> {ok, [], {erl_script_nocache, true}}; false -> {ok, [], {erl_script_nocache, false}}; _ -> - {error, ?NICE(httpd_conf:clean(CacheArg)++ + {error, ?NICE(string:strip(CacheArg)++ " is an invalid ErlScriptNoCache directive")} end. diff --git a/lib/inets/src/http_server/mod_htaccess.erl b/lib/inets/src/http_server/mod_htaccess.erl index e1f66d01c8..d526fbe156 100644 --- a/lib/inets/src/http_server/mod_htaccess.erl +++ b/lib/inets/src/http_server/mod_htaccess.erl @@ -34,7 +34,7 @@ % Names on accessfiles %---------------------------------------------------------------------- load("AccessFileName" ++ FileNames, _Context)-> - CleanFileNames=httpd_conf:clean(FileNames), + CleanFileNames=string:strip(FileNames), {ok,[],{access_files,string:tokens(CleanFileNames," ")}}. store({access_files, Files} = Conf, _) when is_list(Files)-> diff --git a/lib/inets/src/http_server/mod_log.erl b/lib/inets/src/http_server/mod_log.erl index a912f5616c..2367d9cfeb 100644 --- a/lib/inets/src/http_server/mod_log.erl +++ b/lib/inets/src/http_server/mod_log.erl @@ -127,11 +127,11 @@ do(Info) -> %% Description: See httpd(3) ESWAPI CALLBACK FUNCTIONS %%------------------------------------------------------------------------- load("TransferLog " ++ TransferLog, []) -> - {ok,[],{transfer_log,httpd_conf:clean(TransferLog)}}; + {ok,[],{transfer_log,string:strip(TransferLog)}}; load("ErrorLog " ++ ErrorLog, []) -> - {ok,[],{error_log,httpd_conf:clean(ErrorLog)}}; + {ok,[],{error_log,string:strip(ErrorLog)}}; load("SecurityLog " ++ SecurityLog, []) -> - {ok, [], {security_log, httpd_conf:clean(SecurityLog)}}. + {ok, [], {security_log, string:strip(SecurityLog)}}. %%-------------------------------------------------------------------------- %% store(Directive, DirectiveList) -> {ok, NewDirective} | @@ -200,7 +200,7 @@ transfer_log(Info,RFC931,AuthUser,Date,StatusCode,Bytes) -> end. create_log(LogFile, ConfigList) -> - Filename = httpd_conf:clean(LogFile), + Filename = string:strip(LogFile), case filename:pathtype(Filename) of absolute -> case file:open(Filename, [read, write]) of diff --git a/lib/inets/src/http_server/mod_security.erl b/lib/inets/src/http_server/mod_security.erl index a85383a921..b09bd5e008 100644 --- a/lib/inets/src/http_server/mod_security.erl +++ b/lib/inets/src/http_server/mod_security.erl @@ -101,38 +101,38 @@ do(Info) -> end. load("<Directory " ++ Directory, []) -> - Dir = httpd_conf:custom_clean(Directory,"",">"), + Dir = string:strip(string:strip(Directory),right, $>), {ok, [{security_directory, {Dir, [{path, Dir}]}}]}; load(eof,[{security_directory, {Directory, _DirData}}|_]) -> {error, ?NICE("Premature end-of-file in "++Directory)}; load("SecurityDataFile " ++ FileName, [{security_directory, {Dir, DirData}}]) -> - File = httpd_conf:clean(FileName), + File = string:strip(FileName), {ok, [{security_directory, {Dir, [{data_file, File}|DirData]}}]}; load("SecurityCallbackModule " ++ ModuleName, [{security_directory, {Dir, DirData}}]) -> - Mod = list_to_atom(httpd_conf:clean(ModuleName)), + Mod = list_to_atom(string:strip(ModuleName)), {ok, [{security_directory, {Dir, [{callback_module, Mod}|DirData]}}]}; load("SecurityMaxRetries " ++ Retries, [{security_directory, {Dir, DirData}}]) -> load_return_int_tag("SecurityMaxRetries", max_retries, - httpd_conf:clean(Retries), Dir, DirData); + string:strip(Retries), Dir, DirData); load("SecurityBlockTime " ++ Time, [{security_directory, {Dir, DirData}}]) -> load_return_int_tag("SecurityBlockTime", block_time, - httpd_conf:clean(Time), Dir, DirData); + string:strip(Time), Dir, DirData); load("SecurityFailExpireTime " ++ Time, [{security_directory, {Dir, DirData}}]) -> load_return_int_tag("SecurityFailExpireTime", fail_expire_time, - httpd_conf:clean(Time), Dir, DirData); + string:strip(Time), Dir, DirData); load("SecurityAuthTimeout " ++ Time0, [{security_directory, {Dir, DirData}}]) -> - Time = httpd_conf:clean(Time0), + Time = string:strip(Time0), load_return_int_tag("SecurityAuthTimeout", auth_timeout, - httpd_conf:clean(Time), Dir, DirData); + string:strip(Time), Dir, DirData); load("AuthName " ++ Name0, [{security_directory, {Dir, DirData}}]) -> - Name = httpd_conf:clean(Name0), + Name = string:strip(Name0), {ok, [{security_directory, {Dir, [{auth_name, Name}|DirData]}}]}; load("</Directory>",[{security_directory, {Dir, DirData}}]) -> {ok, [], {security_directory, {Dir, DirData}}}. diff --git a/lib/kernel/src/rpc.erl b/lib/kernel/src/rpc.erl index 2300b7e901..d8250418f9 100644 --- a/lib/kernel/src/rpc.erl +++ b/lib/kernel/src/rpc.erl @@ -22,7 +22,7 @@ %% facility %% This code used to reside in net.erl, but has now been moved to -%% a searate module. +%% a separate module. -define(NAME, rex). diff --git a/lib/ssh/doc/src/ssh_connection.xml b/lib/ssh/doc/src/ssh_connection.xml index 5422633dc3..e2b4e2ceb7 100644 --- a/lib/ssh/doc/src/ssh_connection.xml +++ b/lib/ssh/doc/src/ssh_connection.xml @@ -85,7 +85,7 @@ <tag><em>data_events()</em></tag> <item> <taglist> - <tag><c><![CDATA[{data, ssh_channel_id(), ssh_data_type_code(), binary() = Data}]]></c></tag> + <tag><c><![CDATA[{data, ssh_channel_id(), ssh_data_type_code(), Data :: binary()}]]></c></tag> <item><p>Data has arrived on the channel. This event is sent as a result of calling <seealso marker="ssh_connection#send-3"> ssh_connection:send/[3,4,5]</seealso>.</p></item> @@ -110,15 +110,15 @@ referred to are on OS-level and not something generated by an Erlang program.</p></item> - <tag><c><![CDATA[{exit_signal, ssh_channel_id(), string() = ExitSignal, string() = ErrorMsg, - string() = LanguageString}]]></c></tag> + <tag><c><![CDATA[{exit_signal, ssh_channel_id(), ExitSignal :: string(), ErrorMsg ::string(), + LanguageString :: string()}]]></c></tag> <item><p>A remote execution can terminate violently because of a signal. Then this message can be received. For details on valid string values, see <url href="http://www.ietf.org/rfc/rfc4254.txt">RFC 4254</url> Section 6.10, which shows a special case of these signals.</p></item> - <tag><c><![CDATA[{exit_status, ssh_channel_id(), integer() = ExitStatus}]]></c></tag> + <tag><c><![CDATA[{exit_status, ssh_channel_id(), ExitStatus :: integer()}]]></c></tag> <item><p>When the command running at the other end terminates, the following message can be sent to return the exit status of the command. A zero <c>exit_status</c> usually means that the command @@ -148,18 +148,18 @@ with the boolean value of <c>WantReply</c> as the second argument.</p> <taglist> - <tag><c><![CDATA[{env, ssh_channel_id(), boolean() = WantReply, - string() = Var, string() = Value}]]></c></tag> + <tag><c><![CDATA[{env, ssh_channel_id(), WantReply :: boolean(), + Var ::string(), Value :: string()}]]></c></tag> <item><p>Environment variables can be passed to the shell/command to be started later. This event is sent as a result of calling <seealso marker="ssh_connection#setenv-5"> ssh_connection:setenv/5</seealso>. </p></item> <tag><c><![CDATA[{pty, ssh_channel_id(), - boolean() = WantReply, {string() = Terminal, integer() = CharWidth, - integer() = RowHeight, integer() = PixelWidth, integer() = PixelHeight, - [{atom() | integer() = Opcode, - integer() = Value}] = TerminalModes}}]]></c></tag> + WantReply :: boolean(), {Terminal :: string(), CharWidth :: integer(), + RowHeight :: integer(), PixelWidth :: integer(), PixelHeight :: integer(), + TerminalModes :: [{Opcode :: atom() | integer(), + Value :: integer()}]}}]]></c></tag> <item><p>A pseudo-terminal has been requested for the session. <c>Terminal</c> is the value of the TERM environment variable value, that is, <c>vt100</c>. Zero dimension parameters must @@ -174,20 +174,20 @@ echo</c>. This event is sent as a result of calling <seealso marker="ssh_connection#ptty_alloc/4">ssh_connection:ptty_alloc/4</seealso>.</p></item> - <tag><c><![CDATA[{shell, boolean() = WantReply}]]></c></tag> + <tag><c><![CDATA[{shell, WantReply :: boolean()}]]></c></tag> <item><p>This message requests that the user default shell is started at the other end. This event is sent as a result of calling <seealso marker="ssh_connection#shell-2"> ssh_connection:shell/2</seealso>. </p></item> - <tag><c><![CDATA[{window_change, ssh_channel_id(), integer() = CharWidth, - integer() = RowHeight, integer() = PixWidth, integer() = PixHeight}]]></c></tag> + <tag><c><![CDATA[{window_change, ssh_channel_id(), CharWidth() :: integer(), + RowHeight :: integer(), PixWidth :: integer(), PixHeight :: integer()}]]></c></tag> <item><p>When the window (terminal) size changes on the client side, it <em>can</em> send a message to the server side to inform it of the new dimensions. No API function generates this event.</p></item> <tag><c><![CDATA[{exec, ssh_channel_id(), - boolean() = WantReply, string() = Cmd}]]></c></tag> + WantReply :: boolean(), Cmd :: string()}]]></c></tag> <item><p>This message requests that the server starts execution of the given command. This event is sent as a result of calling <seealso marker="ssh_connection#exec-4">ssh_connection:exec/4 </seealso>. @@ -256,7 +256,7 @@ <taglist> <tag><c>N x {ssh_cm, ssh_connection_ref(), - {data, ssh_channel_id(), ssh_data_type_code(), binary() = Data}}</c></tag> + {data, ssh_channel_id(), ssh_data_type_code(), Data :: binary()}}</c></tag> <item><p>The result of executing the command can be only one line or thousands of lines depending on the command.</p></item> @@ -265,12 +265,12 @@ <tag><c>0 or 1 x {ssh_cm, ssh_connection_ref(), {exit_signal, - ssh_channel_id(), string() = ExitSignal, string() = ErrorMsg, string() = LanguageString}}</c></tag> + ssh_channel_id(), ExitSignal :: string(), ErrorMsg :: string(), LanguageString :: string()}}</c></tag> <item><p>Not all systems send signals. For details on valid string values, see RFC 4254, Section 6.10</p></item> <tag><c>0 or 1 x {ssh_cm, ssh_connection_ref(), {exit_status, - ssh_channel_id(), integer() = ExitStatus}}</c></tag> + ssh_channel_id(), ExitStatus :: integer()}}</c></tag> <item><p>It is recommended by the SSH Connection Protocol to send this message, but that is not always the case.</p></item> diff --git a/lib/stdlib/doc/src/unicode_usage.xml b/lib/stdlib/doc/src/unicode_usage.xml index 29b8940c62..eb3a556e10 100644 --- a/lib/stdlib/doc/src/unicode_usage.xml +++ b/lib/stdlib/doc/src/unicode_usage.xml @@ -850,8 +850,9 @@ Eshell V5.10.1 (abort with ^G) expected to be in Unicode.</p> <p>If Unicode file names are enabled, the calls to <seealso marker="kernel:os#getenv/0"><c>os:getenv/0</c></seealso>, - <seealso marker="kernel:os#getenv/1"><c>os:getenv/1</c></seealso> and - <seealso marker="kernel:os#putenv/2"><c>os:putenv/2</c></seealso> + <seealso marker="kernel:os#getenv/1"><c>os:getenv/1</c></seealso>, + <seealso marker="kernel:os#putenv/2"><c>os:putenv/2</c></seealso> and + <seealso marker="kernel:os#unsetenv/1"><c>os:unsetenv/1</c></seealso> will handle Unicode strings. On Unix-like platforms, the built-in functions will translate environment variables in UTF-8 to/from Unicode strings, possibly with code points > 255. On Windows the diff --git a/lib/stdlib/src/ets.erl b/lib/stdlib/src/ets.erl index 0e2d59d0c3..bec64861c3 100644 --- a/lib/stdlib/src/ets.erl +++ b/lib/stdlib/src/ets.erl @@ -1308,18 +1308,30 @@ create_tab(I, TabArg) -> {name, Name} = lists:keyfind(name, 1, I), {type, Type} = lists:keyfind(type, 1, I), {protection, P} = lists:keyfind(protection, 1, I), - {named_table, Val} = lists:keyfind(named_table, 1, I), {keypos, _Kp} = Keypos = lists:keyfind(keypos, 1, I), {size, Sz} = lists:keyfind(size, 1, I), - Comp = case lists:keyfind(compressed, 1, I) of - {compressed, true} -> [compressed]; - {compressed, false} -> []; - false -> [] - end, + L1 = [Type, P, Keypos], + L2 = case lists:keyfind(named_table, 1, I) of + {named_table, true} -> [named_table | L1]; + {named_table, false} -> L1 + end, + L3 = case lists:keyfind(compressed, 1, I) of + {compressed, true} -> [compressed | L2]; + {compressed, false} -> L2; + false -> L2 + end, + L4 = case lists:keyfind(write_concurrency, 1, I) of + {write_concurrency, _}=Wcc -> [Wcc | L3]; + _ -> L3 + end, + L5 = case lists:keyfind(read_concurrency, 1, I) of + {read_concurrency, _}=Rcc -> [Rcc | L4]; + false -> L4 + end, case TabArg of [] -> try - Tab = ets:new(Name, [Type, P, Keypos] ++ named_table(Val) ++ Comp), + Tab = ets:new(Name, L5), {ok, Tab, Sz} catch _:_ -> throw(cannot_create_table) @@ -1328,8 +1340,6 @@ create_tab(I, TabArg) -> {ok, TabArg, Sz} end. -named_table(true) -> [named_table]; -named_table(false) -> []. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% tabfile_info/1 reads the head information in an ets table dumped to diff --git a/lib/stdlib/src/otp_internal.erl b/lib/stdlib/src/otp_internal.erl index 0340015c35..62807e2e54 100644 --- a/lib/stdlib/src/otp_internal.erl +++ b/lib/stdlib/src/otp_internal.erl @@ -634,6 +634,19 @@ obsolete_1(ssl, negotiated_next_protocol, 1) -> obsolete_1(ssl, connection_info, 1) -> {deprecated, "deprecated; use connection_information/[1,2] instead"}; +obsolete_1(httpd_conf, check_enum, 2) -> + {deprecated, "deprecated; use lists:member/2 instead"}; +obsolete_1(httpd_conf, clean, 1) -> + {deprecated, "deprecated; use sting:strip/1 instead or possible the re module"}; +obsolete_1(httpd_conf, custom_clean, 3) -> + {deprecated, "deprecated; use sting:strip/3 instead or possible the re module"}; +obsolete_1(httpd_conf, is_directory, 1) -> + {deprecated, "deprecated; use filelib:is_dir/1 instead"}; +obsolete_1(httpd_conf, is_file, 1) -> + {deprecated, "deprecated; use filelib:is_file/1 instead"}; +obsolete_1(httpd_conf, make_integer, 1) -> + {deprecated, "deprecated; use erlang:list_to_integer/1 instead"}; + obsolete_1(_, _, _) -> no. diff --git a/lib/stdlib/src/supervisor.erl b/lib/stdlib/src/supervisor.erl index 1d7396adee..ac51bb3b79 100644 --- a/lib/stdlib/src/supervisor.erl +++ b/lib/stdlib/src/supervisor.erl @@ -393,6 +393,15 @@ handle_call({start_child, EArgs}, _From, State) when ?is_simple(State) -> {reply, What, State} end; +handle_call({start_child, ChildSpec}, _From, State) -> + case check_childspec(ChildSpec) of + {ok, Child} -> + {Resp, NState} = handle_start_child(Child, State), + {reply, Resp, NState}; + What -> + {reply, {error, What}, State} + end; + %% terminate_child for simple_one_for_one can only be done with pid handle_call({terminate_child, Name}, _From, State) when not is_pid(Name), ?is_simple(State) -> @@ -411,20 +420,10 @@ handle_call({terminate_child, Name}, _From, State) -> {reply, {error, not_found}, State} end; -%%% The requests delete_child and restart_child are invalid for -%%% simple_one_for_one supervisors. -handle_call({_Req, _Data}, _From, State) when ?is_simple(State) -> +%% restart_child request is invalid for simple_one_for_one supervisors +handle_call({restart_child, _Name}, _From, State) when ?is_simple(State) -> {reply, {error, simple_one_for_one}, State}; -handle_call({start_child, ChildSpec}, _From, State) -> - case check_childspec(ChildSpec) of - {ok, Child} -> - {Resp, NState} = handle_start_child(Child, State), - {reply, Resp, NState}; - What -> - {reply, {error, What}, State} - end; - handle_call({restart_child, Name}, _From, State) -> case get_child(Name, State) of {value, Child} when Child#child.pid =:= undefined -> @@ -446,6 +445,10 @@ handle_call({restart_child, Name}, _From, State) -> {reply, {error, not_found}, State} end; +%% delete_child request is invalid for simple_one_for_one supervisors +handle_call({delete_child, _Name}, _From, State) when ?is_simple(State) -> + {reply, {error, simple_one_for_one}, State}; + handle_call({delete_child, Name}, _From, State) -> case get_child(Name, State) of {value, Child} when Child#child.pid =:= undefined -> diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl index 9f0135b68c..f47c2c518d 100644 --- a/lib/stdlib/test/ets_SUITE.erl +++ b/lib/stdlib/test/ets_SUITE.erl @@ -4090,8 +4090,11 @@ tab2file(Config) when is_list(Config) -> tab2file_do(FName, Opts) -> %% Write an empty ets table to a file, read back and check properties. - ?line Tab = ets_new(ets_SUITE_foo_tab, [named_table, set, private, - {keypos, 2}]), + ?line Tab = ets_new(ets_SUITE_foo_tab, [named_table, set, public, + {keypos, 2}, + compressed, + {write_concurrency,true}, + {read_concurrency,true}]), catch file:delete(FName), Res = ets:tab2file(Tab, FName, Opts), true = ets:delete(Tab), @@ -4099,10 +4102,14 @@ tab2file_do(FName, Opts) -> % ?line EtsMem = etsmem(), ?line {ok, Tab2} = ets:file2tab(FName), - ?line private = ets:info(Tab2, protection), + public = ets:info(Tab2, protection), ?line true = ets:info(Tab2, named_table), ?line 2 = ets:info(Tab2, keypos), ?line set = ets:info(Tab2, type), + true = ets:info(Tab2, compressed), + Smp = erlang:system_info(smp_support), + Smp = ets:info(Tab2, read_concurrency), + Smp = ets:info(Tab2, write_concurrency), ?line true = ets:delete(Tab2), ?line verify_etsmem(EtsMem). @@ -4321,7 +4328,7 @@ tabfile_ext4(Config) when is_list(Config) -> {error,Y} = ets:file2tab(FName,[{verify,true}]), ets:tab2file(TL,FName,[{extended_info,[md5sum]}]), {X,Y} - end || N <- lists:seq(400,500) ], + end || N <- lists:seq(500,600) ], io:format("~p~n",[Res]), file:delete(FName), ok. diff --git a/lib/stdlib/test/supervisor_SUITE.erl b/lib/stdlib/test/supervisor_SUITE.erl index 015b09f35e..31d4b44f30 100644 --- a/lib/stdlib/test/supervisor_SUITE.erl +++ b/lib/stdlib/test/supervisor_SUITE.erl @@ -39,7 +39,8 @@ sup_start_ignore_temporary_child_start_child_simple/1, sup_start_ignore_permanent_child_start_child_simple/1, sup_start_error_return/1, sup_start_fail/1, - sup_start_map/1, sup_start_map_faulty_specs/1, + sup_start_map/1, sup_start_map_simple/1, + sup_start_map_faulty_specs/1, sup_stop_infinity/1, sup_stop_timeout/1, sup_stop_brutal_kill/1, child_adm/1, child_adm_simple/1, child_specs/1, extra_return/1, sup_flags/1]). @@ -103,7 +104,7 @@ groups() -> sup_start_ignore_permanent_child_start_child_simple, sup_start_error_return, sup_start_fail]}, {sup_start_map, [], - [sup_start_map, sup_start_map_faulty_specs]}, + [sup_start_map, sup_start_map_simple, sup_start_map_faulty_specs]}, {sup_stop, [], [sup_stop_infinity, sup_stop_timeout, sup_stop_brutal_kill]}, @@ -323,6 +324,30 @@ sup_start_map(Config) when is_list(Config) -> terminate(Pid, shutdown). %%------------------------------------------------------------------------- +%% Tests that the supervisor process starts correctly with map +%% startspec, and that the full childspec can be read when using +%% simple_one_for_one strategy. +sup_start_map_simple(Config) when is_list(Config) -> + process_flag(trap_exit, true), + SupFlags = #{strategy=>simple_one_for_one}, + ChildSpec = #{id=>undefined, + start=>{supervisor_1, start_child, []}, + restart=>temporary}, + {ok, Pid} = start_link({ok, {SupFlags, [ChildSpec]}}), + + {ok, Child1} = supervisor:start_child(Pid, []), + {ok, Child2} = supervisor:start_child(Pid, []), + {ok, Child3} = supervisor:start_child(Pid, []), + + Spec = ChildSpec#{type=>worker, shutdown=>5000, modules=>[supervisor_1]}, + + {ok, Spec} = supervisor:get_childspec(Pid, Child1), + {ok, Spec} = supervisor:get_childspec(Pid, Child2), + {ok, Spec} = supervisor:get_childspec(Pid, Child3), + {error,not_found} = supervisor:get_childspec(Pid, self()), + terminate(Pid, shutdown). + +%%------------------------------------------------------------------------- %% Tests that the supervisor produces good error messages when start- %% and child specs are faulty. sup_start_map_faulty_specs(Config) when is_list(Config) -> diff --git a/lib/tools/emacs/erlang-skels-old.el b/lib/tools/emacs/erlang-skels-old.el index b88d7bcc4b..c8229300c8 100644 --- a/lib/tools/emacs/erlang-skels-old.el +++ b/lib/tools/emacs/erlang-skels-old.el @@ -838,7 +838,7 @@ Please see the function `tempo-define-template'.") "Config." n n (erlang-skel-separator 2) - "%% Function: end_per_suite(Config) -> void()" n + "%% Function: end_per_suite(Config) -> term()" n "%%" n "%% Config = [tuple()]" n "%% A list of key/value pairs, holding the test case configuration." n @@ -867,7 +867,7 @@ Please see the function `tempo-define-template'.") "Config." n n (erlang-skel-separator 2) - "%% Function: end_per_testcase(TestCase, Config) -> void()" n + "%% Function: end_per_testcase(TestCase, Config) -> term()" n "%%" n "%% TestCase = atom()" n "%% Name of the test case that is finished." n @@ -993,7 +993,7 @@ Please see the function `tempo-define-template'.") "Config." n n (erlang-skel-separator 2) - "%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}" n + "%% Function: end_per_suite(Config0) -> term() | {save_config,Config1}" n "%%" n "%% Config0 = Config1 = [tuple()]" n "%% A list of key/value pairs, holding the test case configuration." n @@ -1021,7 +1021,7 @@ Please see the function `tempo-define-template'.") (erlang-skel-separator 2) "%% Function: end_per_group(GroupName, Config0) ->" n - "%% void() | {save_config,Config1}" n + "%% term() | {save_config,Config1}" n "%%" n "%% GroupName = atom()" n "%% Name of the test case group that is finished." n @@ -1054,7 +1054,7 @@ Please see the function `tempo-define-template'.") (erlang-skel-separator 2) "%% Function: end_per_testcase(TestCase, Config0) ->" n - "%% void() | {save_config,Config1} | {fail,Reason}" n + "%% term() | {save_config,Config1} | {fail,Reason}" n "%%" n "%% TestCase = atom()" n "%% Name of the test case that is finished." n @@ -1175,7 +1175,7 @@ Please see the function `tempo-define-template'.") "Config." n n (erlang-skel-separator 2) - "%% Function: end_per_suite(Config0) -> void() | {save_config,Config1}" n + "%% Function: end_per_suite(Config0) -> term() | {save_config,Config1}" n "%% Config0 = Config1 = [tuple()]" n (erlang-skel-separator 2) "end_per_suite(_Config) ->" n > @@ -1193,7 +1193,7 @@ Please see the function `tempo-define-template'.") (erlang-skel-separator 2) "%% Function: end_per_group(GroupName, Config0) ->" n - "%% void() | {save_config,Config1}" n + "%% term() | {save_config,Config1}" n "%% GroupName = atom()" n "%% Config0 = Config1 = [tuple()]" n (erlang-skel-separator 2) @@ -1212,7 +1212,7 @@ Please see the function `tempo-define-template'.") (erlang-skel-separator 2) "%% Function: end_per_testcase(TestCase, Config0) ->" n - "%% void() | {save_config,Config1} | {fail,Reason}" n + "%% term() | {save_config,Config1} | {fail,Reason}" n "%% TestCase = atom()" n "%% Config0 = Config1 = [tuple()]" n "%% Reason = term()" n diff --git a/lib/tools/emacs/erlang-skels.el b/lib/tools/emacs/erlang-skels.el index 8d2c02e455..78b1e7ad19 100644 --- a/lib/tools/emacs/erlang-skels.el +++ b/lib/tools/emacs/erlang-skels.el @@ -1234,7 +1234,7 @@ Please see the function `tempo-define-template'.") "Config." n n (erlang-skel-separator-start 2) - "%% @spec end_per_suite(Config0) -> void() | {save_config,Config1}" n + "%% @spec end_per_suite(Config0) -> term() | {save_config,Config1}" n "%% Config0 = Config1 = [tuple()]" n (erlang-skel-separator-end 2) "end_per_suite(_Config) ->" n > @@ -1252,7 +1252,7 @@ Please see the function `tempo-define-template'.") (erlang-skel-separator-start 2) "%% @spec end_per_group(GroupName, Config0) ->" n - "%% void() | {save_config,Config1}" n + "%% term() | {save_config,Config1}" n "%% GroupName = atom()" n "%% Config0 = Config1 = [tuple()]" n (erlang-skel-separator-end 2) @@ -1271,7 +1271,7 @@ Please see the function `tempo-define-template'.") (erlang-skel-separator-start 2) "%% @spec end_per_testcase(TestCase, Config0) ->" n - "%% void() | {save_config,Config1} | {fail,Reason}" n + "%% term() | {save_config,Config1} | {fail,Reason}" n "%% TestCase = atom()" n "%% Config0 = Config1 = [tuple()]" n "%% Reason = term()" n @@ -1412,7 +1412,7 @@ Please see the function `tempo-define-template'.") "%% A list of key/value pairs, holding configuration data for the group." n "%%" n "%% @spec end_per_group(GroupName, Config0) ->" n - "%% void() | {save_config,Config1}" n + "%% term() | {save_config,Config1}" n (erlang-skel-separator-end 2) "end_per_group(_GroupName, _Config) ->" n > "ok." n n @@ -1446,7 +1446,7 @@ Please see the function `tempo-define-template'.") "%% A list of key/value pairs, holding the test case configuration." n "%%" n "%% @spec end_per_testcase(TestCase, Config0) ->" n - "%% void() | {save_config,Config1} | {fail,Reason}" n + "%% term() | {save_config,Config1} | {fail,Reason}" n (erlang-skel-separator-end 2) "end_per_testcase(_TestCase, _Config) ->" n > "ok." n n |