diff options
Diffstat (limited to 'lib')
47 files changed, 1216 insertions, 700 deletions
diff --git a/lib/common_test/src/common_test.app.src b/lib/common_test/src/common_test.app.src index d847907d75..26bcf00824 100644 --- a/lib/common_test/src/common_test.app.src +++ b/lib/common_test/src/common_test.app.src @@ -53,7 +53,13 @@ ct_slave, cth_log_redirect, cth_conn_log, - cth_surefire + cth_surefire, + erl2html2, + test_server_ctrl, + test_server, + test_server_io, + test_server_node, + test_server_sup ]}, {registered, [ct_logs, ct_util_server, @@ -61,13 +67,27 @@ ct_make_ref, vts, ct_master, - ct_master_logs]}, + ct_master_logs, + test_server_ctrl, + test_server, + test_server_break_process]}, {applications, [kernel,stdlib]}, {env, []}, - {runtime_dependencies,["xmerl-1.3.8","tools-2.8", - "test_server-3.9","stdlib-2.5","ssh-4.0", - "snmp-5.1.2","sasl-2.4.2","runtime_tools-1.8.16", - "kernel-4.0","inets-6.0","erts-7.0", - "debugger-4.1","crypto-3.6","compiler-6.0", - "observer-2.1"]}]}. + {runtime_dependencies, + ["compiler-6.0", + "crypto-3.6", + "debugger-4.1", + "erts-7.0", + "inets-6.0", + "kernel-4.0", + "observer-2.1", + "runtime_tools-1.8.16", + "sasl-2.4.2", + "snmp-5.1.2", + "ssh-4.0", + "stdlib-2.5", + "syntax_tools-1.7", + "tools-2.8", + "xmerl-1.3.8" + ]}]}. diff --git a/lib/common_test/src/ct_conn_log_h.erl b/lib/common_test/src/ct_conn_log_h.erl index f7615fdc14..93f358462d 100644 --- a/lib/common_test/src/ct_conn_log_h.erl +++ b/lib/common_test/src/ct_conn_log_h.erl @@ -117,7 +117,7 @@ write_report(Time,#conn_log{module=ConnMod}=Info,Data,GL,State) -> ok; {LogType,Fd} -> case format_data(ConnMod,LogType,Data) of - [] -> + [] when Info#conn_log.action==send; Info#conn_log.action==recv -> ok; FormattedData -> io:format(Fd,"~n~ts~ts~ts",[format_head(ConnMod,LogType,Time), diff --git a/lib/common_test/src/ct_framework.erl b/lib/common_test/src/ct_framework.erl index f792269c41..8fb7a03bb0 100644 --- a/lib/common_test/src/ct_framework.erl +++ b/lib/common_test/src/ct_framework.erl @@ -28,7 +28,7 @@ -export([init_tc/3, end_tc/3, end_tc/4, get_suite/2, get_all_cases/1]). -export([report/2, warn/1, error_notification/4]). --export([get_logopts/0, format_comment/1, get_html_wrapper/4]). +-export([get_log_dir/0, get_logopts/0, format_comment/1, get_html_wrapper/4]). -export([error_in_suite/1, init_per_suite/1, end_per_suite/1, init_per_group/2, end_per_group/2]). @@ -1480,3 +1480,8 @@ get_html_wrapper(TestName, PrintLabel, Cwd, TableCols) -> get_html_wrapper(TestName, PrintLabel, Cwd, TableCols, Encoding) -> ct_logs:get_ts_html_wrapper(TestName, PrintLabel, Cwd, TableCols, Encoding). + +%%%----------------------------------------------------------------- +%%% @spec get_log_dir() -> {ok,LogDir} +get_log_dir() -> + ct_logs:get_log_dir(true). diff --git a/lib/common_test/src/ct_netconfc.erl b/lib/common_test/src/ct_netconfc.erl index 3da1115c76..8812514ad9 100644 --- a/lib/common_test/src/ct_netconfc.erl +++ b/lib/common_test/src/ct_netconfc.erl @@ -234,7 +234,6 @@ %% Internal defines %%---------------------------------------------------------------------- -define(APPLICATION,?MODULE). --define(VALID_SSH_OPTS,[user, password, user_dir]). -define(DEFAULT_STREAM,"NETCONF"). -define(error(ConnName,Report), @@ -1257,13 +1256,11 @@ check_options([{port,Port}|T], Host, _, #options{} = Options) -> check_options([{timeout, Timeout}|T], Host, Port, Options) when is_integer(Timeout); Timeout==infinity -> check_options(T, Host, Port, Options#options{timeout = Timeout}); -check_options([{X,_}=Opt|T], Host, Port, #options{ssh=SshOpts}=Options) -> - case lists:member(X,?VALID_SSH_OPTS) of - true -> - check_options(T, Host, Port, Options#options{ssh=[Opt|SshOpts]}); - false -> - {error, {invalid_option, Opt}} - end. +check_options([{timeout, _} = Opt|_T], _Host, _Port, _Options) -> + {error, {invalid_option, Opt}}; +check_options([Opt|T], Host, Port, #options{ssh=SshOpts}=Options) -> + %% Option verified by ssh + check_options(T, Host, Port, Options#options{ssh=[Opt|SshOpts]}). %%%----------------------------------------------------------------- set_request_timer(infinity) -> diff --git a/lib/common_test/src/ct_release_test.erl b/lib/common_test/src/ct_release_test.erl index 6438ea01c1..c4cbe0c424 100644 --- a/lib/common_test/src/ct_release_test.erl +++ b/lib/common_test/src/ct_release_test.erl @@ -753,7 +753,7 @@ create_relfile(AppsVsns,CreateDir,RelName0,RelVsn) -> %% Should test tools really be included? Some library functions %% here could be used by callback, but not everything since %% processes of these applications will not be running. - TestToolAppsVsns0 = get_vsns([test_server,common_test]), + TestToolAppsVsns0 = get_vsns([common_test]), TestToolAppsVsns = [{A,V,none} || {A,V} <- TestToolAppsVsns0, false == lists:keymember(A,1,AllAppsVsns0)], diff --git a/lib/common_test/src/test_server.app.src b/lib/common_test/src/test_server.app.src deleted file mode 100644 index 334be8109d..0000000000 --- a/lib/common_test/src/test_server.app.src +++ /dev/null @@ -1,39 +0,0 @@ -% This is an -*- erlang -*- file. -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2009-2013. All Rights Reserved. -%% -%% Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -%% -%% %CopyrightEnd% - -{application, test_server, - [{description, "The OTP Test Server application"}, - {vsn, "%VSN%"}, - {modules, [ - erl2html2, - test_server_ctrl, - test_server, - test_server_io, - test_server_node, - test_server_sup - ]}, - {registered, [test_server_ctrl, - test_server, - test_server_break_process]}, - {applications, [kernel,stdlib]}, - {env, []}, - {runtime_dependencies, ["tools-2.8","stdlib-2.5","runtime_tools-1.8.16", - "observer-2.1","kernel-4.0","inets-6.0", - "syntax_tools-1.7","erts-7.0"]}]}. - diff --git a/lib/common_test/src/test_server.appup.src b/lib/common_test/src/test_server.appup.src deleted file mode 100644 index 7c4aa630ae..0000000000 --- a/lib/common_test/src/test_server.appup.src +++ /dev/null @@ -1,22 +0,0 @@ -%% -*- erlang -*- -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2014. All Rights Reserved. -%% -%% Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -%% -%% %CopyrightEnd% -{"%VSN%", - [{<<".*">>,[{restart_application, test_server}]}], - [{<<".*">>,[{restart_application, test_server}]}] -}. diff --git a/lib/common_test/src/test_server.erl b/lib/common_test/src/test_server.erl index 73803030a3..671674c617 100644 --- a/lib/common_test/src/test_server.erl +++ b/lib/common_test/src/test_server.erl @@ -63,13 +63,11 @@ init_target_info() -> [$.|Emu] = code:objfile_extension(), {_, OTPRel} = init:script_id(), - TestServerDir = filename:absname(filename:dirname(code:which(?MODULE))), #target_info{os_family=test_server_sup:get_os_family(), os_type=os:type(), version=erlang:system_info(version), system_version=erlang:system_info(system_version), root_dir=code:root_dir(), - test_server_dir=TestServerDir, emulator=Emu, otp_release=OTPRel, username=test_server_sup:get_username(), diff --git a/lib/common_test/src/test_server_internal.hrl b/lib/common_test/src/test_server_internal.hrl index 578f359010..1ec2d83417 100644 --- a/lib/common_test/src/test_server_internal.hrl +++ b/lib/common_test/src/test_server_internal.hrl @@ -30,7 +30,6 @@ version, % string() system_version, % string() root_dir, % string() - test_server_dir, % string() emulator, % string() otp_release, % string() username, % string() diff --git a/lib/common_test/src/test_server_node.erl b/lib/common_test/src/test_server_node.erl index c12832e0d0..c64399e485 100644 --- a/lib/common_test/src/test_server_node.erl +++ b/lib/common_test/src/test_server_node.erl @@ -307,11 +307,11 @@ start_node_peer(SlaveName, OptList, From, TI) -> HostStr, " ", WaitPort]), % Support for erl_crash_dump files.. - CrashFile = filename:join([TI#target_info.test_server_dir, + CrashDir = test_server_sup:crash_dump_dir(), + CrashFile = filename:join([CrashDir, "erl_crash_dump."++cast_to_list(SlaveName)]), CrashArgs = lists:concat([" -env ERL_CRASH_DUMP \"",CrashFile,"\" "]), FailOnError = start_node_get_option_value(fail_on_error, OptList, true), - Pa = TI#target_info.test_server_dir, Prog0 = start_node_get_option_value(erl, OptList, default), Prog = quote_progname(pick_erl_program(Prog0)), Args = @@ -322,7 +322,6 @@ start_node_peer(SlaveName, OptList, From, TI) -> Cmd = lists:concat([Prog, " -detached ", TI#target_info.naming, " ", SlaveName, - " -pa \"", Pa,"\"", NodeStarted, CrashArgs, " ", Args]), @@ -370,15 +369,15 @@ wait_for_node_started_fun(LSock, Tmo, Cleanup, TI, Self) -> %% Slave nodes are started on a remote host if %% - the option remote is given when calling test_server:start_node/3 %% -start_node_slave(SlaveName, OptList, From, TI) -> +start_node_slave(SlaveName, OptList, From, _TI) -> SuppliedArgs = start_node_get_option_value(args, OptList, []), Cleanup = start_node_get_option_value(cleanup, OptList, true), - CrashFile = filename:join([TI#target_info.test_server_dir, + CrashDir = test_server_sup:crash_dump_dir(), + CrashFile = filename:join([CrashDir, "erl_crash_dump."++cast_to_list(SlaveName)]), CrashArgs = lists:concat([" -env ERL_CRASH_DUMP \"",CrashFile,"\" "]), - Pa = TI#target_info.test_server_dir, - Args = lists:concat([" -pa \"", Pa, "\" ", SuppliedArgs, CrashArgs]), + Args = lists:concat([" ", SuppliedArgs, CrashArgs]), Prog0 = start_node_get_option_value(erl, OptList, default), Prog = pick_erl_program(Prog0), diff --git a/lib/common_test/src/test_server_sup.erl b/lib/common_test/src/test_server_sup.erl index fc2cfd57bd..1c0eb18d70 100644 --- a/lib/common_test/src/test_server_sup.erl +++ b/lib/common_test/src/test_server_sup.erl @@ -594,7 +594,8 @@ cleanup_crash_dumps() -> delete_files(Dumps). crash_dump_dir() -> - filename:dirname(code:which(?MODULE)). + {ok,Dir} = test_server_sup:framework_call(get_log_dir,[]), + Dir. tar_crash_dumps() -> Dir = crash_dump_dir(), diff --git a/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl b/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl index 49b02d2bba..9d4c798795 100644 --- a/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl +++ b/lib/common_test/test/ct_netconfc_SUITE_data/netconfc1_SUITE.erl @@ -332,7 +332,8 @@ invalid_opt(Config) -> Opts1 = ?DEFAULT_SSH_OPTS(DataDir) ++ [{timeout,invalidvalue}], {error,{invalid_option,{timeout,invalidvalue}}} = ct_netconfc:open(Opts1), Opts2 = ?DEFAULT_SSH_OPTS(DataDir) ++ [{some_other_opt,true}], - {error,{invalid_option,{some_other_opt,true}}} = ct_netconfc:open(Opts2), + {error,{ssh,could_not_connect_to_server,{options,_}}} = + ct_netconfc:open(Opts2), ok. timeout_close_session(Config) -> diff --git a/lib/erl_interface/configure.in b/lib/erl_interface/configure.in index 3ac9212085..7a3b5ce378 100644 --- a/lib/erl_interface/configure.in +++ b/lib/erl_interface/configure.in @@ -251,7 +251,7 @@ case "$threads_disabled" in ;; win32_threads) EI_THREADS="true" - THR_DEFS="$THR_DEFS -D_WIN32_WINNT=0x0500 -DWINVER=0x0500" + THR_DEFS="$THR_DEFS -D_WIN32_WINNT=0x0600 -DWINVER=0x0600" ;; pthread) EI_THREADS="true" diff --git a/lib/inets/src/http_server/httpd_request_handler.erl b/lib/inets/src/http_server/httpd_request_handler.erl index 134576059d..8fae9ac46e 100644 --- a/lib/inets/src/http_server/httpd_request_handler.erl +++ b/lib/inets/src/http_server/httpd_request_handler.erl @@ -102,8 +102,8 @@ init([Manager, ConfigDB, AcceptTimeout]) -> KeepAliveTimeOut = 1000 * httpd_util:lookup(ConfigDB, keep_alive_timeout, 150), case http_transport:negotiate(SocketType, Socket, ?HANDSHAKE_TIMEOUT) of - {error, _Error} -> - exit(shutdown); %% Can be 'normal'. + {error, Error} -> + exit({shutdown, Error}); %% Can be 'normal'. ok -> continue_init(Manager, ConfigDB, SocketType, Socket, KeepAliveTimeOut) end. @@ -294,7 +294,10 @@ handle_info(Info, #state{mod = ModData} = State) -> %% cleaning up. When it returns, the gen_server terminates with Reason. %% The return value is ignored. %%-------------------------------------------------------------------- -terminate(normal, State) -> +terminate(Reason, State) when Reason == normal; + Reason == shutdown -> + do_terminate(State); +terminate({shutdown,_}, State) -> do_terminate(State); terminate(Reason, #state{response_sent = false, mod = ModData} = State) -> httpd_response:send_status(ModData, 500, none), diff --git a/lib/inets/test/ftp_suite_lib.erl b/lib/inets/test/ftp_suite_lib.erl index 2f9170fa0c..f15fa2fa8d 100644 --- a/lib/inets/test/ftp_suite_lib.erl +++ b/lib/inets/test/ftp_suite_lib.erl @@ -23,7 +23,6 @@ -include_lib("common_test/include/ct.hrl"). --include_lib("common_test/include/ct.hrl"). -include("inets_test_lib.hrl"). %% Test server specific exports diff --git a/lib/kernel/examples/uds_dist/c_src/uds_drv.c b/lib/kernel/examples/uds_dist/c_src/uds_drv.c index e32ad69adf..8c028ba910 100644 --- a/lib/kernel/examples/uds_dist/c_src/uds_drv.c +++ b/lib/kernel/examples/uds_dist/c_src/uds_drv.c @@ -957,28 +957,24 @@ static void put_packet_length(char *b, int len) /* ** Malloc wrappers -** Note! -** The function erl_exit is actually not a pert of the -** driver interface, but it is very nice to use if one wants to halt -** with a core and an erlang crash dump. */ static void *my_malloc(size_t size) { - void erl_exit(int, char *, ...); void *ptr; if ((ptr = driver_alloc(size)) == NULL) { - erl_exit(1,"Could not allocate %lu bytes of memory",(unsigned long) size); + fprintf(stderr, "Could not allocate %lu bytes of memory",(unsigned long) size); + abort(); } return ptr; } static void *my_realloc(void *ptr, size_t size) { - void erl_exit(int, char *, ...); void *nptr; if ((nptr = driver_realloc(ptr, size)) == NULL) { - erl_exit(1,"Could not reallocate %lu bytes of memory",(unsigned long) size); + fprintf(stderr, "Could not reallocate %lu bytes of memory",(unsigned long) size); + abort(); } return nptr; } diff --git a/lib/kernel/src/erl_epmd.erl b/lib/kernel/src/erl_epmd.erl index 55ce9a7e64..c6202dd796 100644 --- a/lib/kernel/src/erl_epmd.erl +++ b/lib/kernel/src/erl_epmd.erl @@ -32,7 +32,7 @@ %% External exports -export([start/0, start_link/0, stop/0, port_please/2, port_please/3, names/0, names/1, - register_node/2, open/0, open/1, open/2]). + register_node/2, register_node/3, open/0, open/1, open/2]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, @@ -102,7 +102,9 @@ names(EpmdAddr) -> register_node(Name, PortNo) -> - gen_server:call(erl_epmd, {register, Name, PortNo}, infinity). + register_node(Name, PortNo, inet). +register_node(Name, PortNo, Family) -> + gen_server:call(erl_epmd, {register, Name, PortNo, Family}, infinity). %%%---------------------------------------------------------------------- %%% Callback functions from gen_server @@ -120,10 +122,10 @@ init(_) -> -spec handle_call(calls(), term(), state()) -> {'reply', term(), state()} | {'stop', 'shutdown', 'ok', state()}. -handle_call({register, Name, PortNo}, _From, State) -> +handle_call({register, Name, PortNo, Family}, _From, State) -> case State#state.socket of P when P < 0 -> - case do_register_node(Name, PortNo) of + case do_register_node(Name, PortNo, Family) of {alive, Socket, Creation} -> S = State#state{socket = Socket, port_no = PortNo, @@ -206,8 +208,12 @@ open({A,B,C,D,E,F,G,H}=EpmdAddr, Timeout) when ?ip6(A,B,C,D,E,F,G,H) -> close(Socket) -> gen_tcp:close(Socket). -do_register_node(NodeName, TcpPort) -> - case open() of +do_register_node(NodeName, TcpPort, Family) -> + Localhost = case Family of + inet -> open({127,0,0,1}); + inet6 -> open({0,0,0,0,0,0,0,1}) + end, + case Localhost of {ok, Socket} -> Name = to_string(NodeName), Extra = "", diff --git a/lib/kernel/src/kernel.appup.src b/lib/kernel/src/kernel.appup.src index cc9e6f771a..a13819a183 100644 --- a/lib/kernel/src/kernel.appup.src +++ b/lib/kernel/src/kernel.appup.src @@ -18,9 +18,9 @@ %% %CopyrightEnd% {"%VSN%", %% Up from - max one major revision back - [{<<"4\\.[0-2](\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-18.* - {<<"3\\.[0-2](\\.[0-9]+)*">>,[restart_new_emulator]}], % OTP-17 + [{<<"5\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-19.* + {<<"4\\.[0-2](\\.[0-9]+)*">>,[restart_new_emulator]}], % OTP-18.* %% Down to - max one major revision back - [{<<"4\\.[0-2](\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-18.* - {<<"3\\.[0-2](\\.[0-9]+)*">>,[restart_new_emulator]}] % OTP-17 + [{<<"5\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-19.* + {<<"4\\.[0-2](\\.[0-9]+)*">>,[restart_new_emulator]}] % OTP-18.* }. diff --git a/lib/observer/test/crashdump_viewer_SUITE.erl b/lib/observer/test/crashdump_viewer_SUITE.erl index 2d47054600..a2b96ecb88 100644 --- a/lib/observer/test/crashdump_viewer_SUITE.erl +++ b/lib/observer/test/crashdump_viewer_SUITE.erl @@ -563,22 +563,11 @@ dump_with_strange_module_name(DataDir,Rel,DumpName) -> CD. dump(Node,DataDir,Rel,DumpName) -> + Crashdump = filename:join(DataDir, dump_prefix(Rel)++DumpName), + rpc:call(Node,os,putenv,["ERL_CRASH_DUMP",Crashdump]), rpc:call(Node,erlang,halt,[DumpName]), - Crashdump0 = filename:join(filename:dirname(code:which(?t)), - "erl_crash_dump.n1"), - Crashdump1 = filename:join(DataDir, dump_prefix(Rel)++DumpName), - ok = rename(Crashdump0,Crashdump1), - Crashdump1. - -rename(From,To) -> - ok = check_complete(From), - case file:rename(From,To) of - {error,exdev} -> - {ok,_} = file:copy(From,To), - ok = file:delete(From); - ok -> - ok - end. + ok = check_complete(Crashdump), + Crashdump. check_complete(File) -> check_complete1(File,10). diff --git a/lib/public_key/src/pubkey_pem.erl b/lib/public_key/src/pubkey_pem.erl index 6a722b0525..d163004c7c 100644 --- a/lib/public_key/src/pubkey_pem.erl +++ b/lib/public_key/src/pubkey_pem.erl @@ -103,7 +103,7 @@ encode_pem_entry({'PrivateKeyInfo', Der, EncParams}) -> [StartStr, "\n", b64encode_and_split(EncDer), "\n", pem_end(StartStr) ,"\n\n"]; encode_pem_entry({Type, Der, {Cipher, Salt}}) -> StartStr = pem_start(Type), - [StartStr,"\n", pem_decrypt(),"\n", pem_decrypt_info(Cipher, Salt),"\n", + [StartStr,"\n", pem_decrypt(),"\n", pem_decrypt_info(Cipher, Salt),"\n\n", b64encode_and_split(Der), "\n", pem_end(StartStr) ,"\n\n"]. decode_pem_entries([], Entries) -> diff --git a/lib/public_key/test/public_key_SUITE.erl b/lib/public_key/test/public_key_SUITE.erl index 5e677f31d6..ea5e036a7e 100644 --- a/lib/public_key/test/public_key_SUITE.erl +++ b/lib/public_key/test/public_key_SUITE.erl @@ -189,6 +189,8 @@ encrypted_pem(Config) when is_list(Config) -> erl_make_certs:der_to_pem(DesKeyFile, [Entry1]), [{'RSAPrivateKey', _, {"DES-CBC", Salt1}} =Entry2] = erl_make_certs:pem_to_der(DesKeyFile), + {ok, Pem} = file:read_file(DesKeyFile), + check_encapsulated_header(Pem), true = check_entry_type(public_key:pem_entry_decode(Entry2, "4567efgh"), 'RSAPrivateKey'). @@ -826,6 +828,15 @@ check_entry_type(#'Certificate'{}, 'Certificate') -> check_entry_type(_,_) -> false. +check_encapsulated_header(Pem) when is_binary(Pem)-> + check_encapsulated_header( binary:split(Pem, <<"\n">>, [global])); +check_encapsulated_header([<<"DEK-Info: DES-CBC,FB7577791A9056A1">>, <<>> | _]) -> + true; +check_encapsulated_header([ _ | Rest]) -> + check_encapsulated_header(Rest); +check_encapsulated_header([]) -> + false. + strip_ending_newlines(Bin) -> string:strip(binary_to_list(Bin), right, 10). diff --git a/lib/runtime_tools/c_src/trace_file_drv.c b/lib/runtime_tools/c_src/trace_file_drv.c index a63a7d3ad9..8863b0d6ac 100644 --- a/lib/runtime_tools/c_src/trace_file_drv.c +++ b/lib/runtime_tools/c_src/trace_file_drv.c @@ -75,12 +75,8 @@ #ifdef DEBUG -#ifndef __WIN32__ -#define ASSERT(X) do {if (!(X)) {erl_exit(1,"%s",#X);} } while(0) -#else #include <assert.h> #define ASSERT(X) assert(X) -#endif #else #define ASSERT(X) #endif diff --git a/lib/runtime_tools/c_src/trace_ip_drv.c b/lib/runtime_tools/c_src/trace_ip_drv.c index f7b5ea65cb..5b43f8179e 100644 --- a/lib/runtime_tools/c_src/trace_ip_drv.c +++ b/lib/runtime_tools/c_src/trace_ip_drv.c @@ -44,19 +44,8 @@ #endif #ifdef DEBUG -# ifndef __WIN32__ - /* erl_exit is not available to dll_drivers on windows. */ - void erl_exit(int, char *, ...); -# define ASSERT(X) \ - do { \ - if (!(X)) { \ - erl_exit(1,"%s",#X); \ - } \ - } while(0) -# else -# include <assert.h> -# define ASSERT(X) assert(X) -# endif +# include <assert.h> +# define ASSERT(X) assert(X) #else # define ASSERT(X) #endif diff --git a/lib/sasl/src/sasl.appup.src b/lib/sasl/src/sasl.appup.src index e08ae369b8..ca5122dab4 100644 --- a/lib/sasl/src/sasl.appup.src +++ b/lib/sasl/src/sasl.appup.src @@ -18,9 +18,9 @@ %% %CopyrightEnd% {"%VSN%", %% Up from - max one major revision back - [{<<"2\\.[5-7](\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-18.* - {<<"2\\.4(\\.[0-9]+)*">>,[restart_new_emulator]}], % OTP-17 + [{<<"3\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-19.* + {<<"2\\.[5-7](\\.[0-9]+)*">>,[restart_new_emulator]}], % OTP-18.* %% Down to - max one major revision back - [{<<"2\\.[5-7](\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-18.* - {<<"2\\.4(\\.[0-9]+)*">>,[restart_new_emulator]}] % OTP-17 + [{<<"3\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-19.* + {<<"2\\.[5-7](\\.[0-9]+)*">>,[restart_new_emulator]}] % OTP-18.* }. diff --git a/lib/ssh/test/ssh_algorithms_SUITE.erl b/lib/ssh/test/ssh_algorithms_SUITE.erl index a03a9ee0f2..49ed15698c 100644 --- a/lib/ssh/test/ssh_algorithms_SUITE.erl +++ b/lib/ssh/test/ssh_algorithms_SUITE.erl @@ -36,7 +36,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}, - {timetrap,{minutes,5}}]. + {timetrap,{minutes,10}}]. all() -> %% [{group,kex},{group,cipher}... etc diff --git a/lib/ssh/test/ssh_basic_SUITE.erl b/lib/ssh/test/ssh_basic_SUITE.erl index 564fb66586..094d28e879 100644 --- a/lib/ssh/test/ssh_basic_SUITE.erl +++ b/lib/ssh/test/ssh_basic_SUITE.erl @@ -79,7 +79,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}, - {timetrap,{minutes,5}}]. + {timetrap,{minutes,10}}]. all() -> [app_test, diff --git a/lib/ssh/test/ssh_connection_SUITE.erl b/lib/ssh/test/ssh_connection_SUITE.erl index 67d870bea4..6e90faf0e8 100644 --- a/lib/ssh/test/ssh_connection_SUITE.erl +++ b/lib/ssh/test/ssh_connection_SUITE.erl @@ -37,7 +37,7 @@ %% [{ct_hooks,[ts_install_cth]}]. suite() -> - [{timetrap,{minutes,5}}]. + [{timetrap,{minutes,2}}]. all() -> [ diff --git a/lib/ssh/test/ssh_options_SUITE.erl b/lib/ssh/test/ssh_options_SUITE.erl index e0ef3a4b05..ba0107efd6 100644 --- a/lib/ssh/test/ssh_options_SUITE.erl +++ b/lib/ssh/test/ssh_options_SUITE.erl @@ -80,7 +80,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}, - {timetrap,{minutes,5}}]. + {timetrap,{minutes,6}}]. all() -> [connectfun_disconnectfun_server, diff --git a/lib/ssh/test/ssh_protocol_SUITE.erl b/lib/ssh/test/ssh_protocol_SUITE.erl index cabdd35615..dbba48c726 100644 --- a/lib/ssh/test/ssh_protocol_SUITE.erl +++ b/lib/ssh/test/ssh_protocol_SUITE.erl @@ -43,7 +43,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}, - {timetrap,{minutes,5}}]. + {timetrap,{minutes,2}}]. all() -> [{group,tool_tests}, diff --git a/lib/ssh/test/ssh_renegotiate_SUITE.erl b/lib/ssh/test/ssh_renegotiate_SUITE.erl index fabe9a5829..6d2c97aa68 100644 --- a/lib/ssh/test/ssh_renegotiate_SUITE.erl +++ b/lib/ssh/test/ssh_renegotiate_SUITE.erl @@ -31,7 +31,7 @@ %%-------------------------------------------------------------------- suite() -> [{ct_hooks,[ts_install_cth]}, - {timetrap,{minutes,15}}]. + {timetrap,{minutes,12}}]. all() -> [{group,default_algs}, diff --git a/lib/ssh/test/ssh_sftp_SUITE.erl b/lib/ssh/test/ssh_sftp_SUITE.erl index 6066221fc7..c2b04d7a05 100644 --- a/lib/ssh/test/ssh_sftp_SUITE.erl +++ b/lib/ssh/test/ssh_sftp_SUITE.erl @@ -36,7 +36,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}, - {timetrap,{minutes,5}}]. + {timetrap,{minutes,2}}]. all() -> diff --git a/lib/ssh/test/ssh_sftpd_SUITE.erl b/lib/ssh/test/ssh_sftpd_SUITE.erl index 687f327206..45439ce0fa 100644 --- a/lib/ssh/test/ssh_sftpd_SUITE.erl +++ b/lib/ssh/test/ssh_sftpd_SUITE.erl @@ -45,7 +45,7 @@ %%-------------------------------------------------------------------- suite() -> - [{timetrap,{minutes,5}}]. + [{timetrap,{minutes,3}}]. all() -> [open_close_file, diff --git a/lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl b/lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl index 84410f60e6..02a2ac4cf9 100644 --- a/lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl +++ b/lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl @@ -37,7 +37,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}, - {timetrap,{minutes,5}}]. + {timetrap,{minutes,2}}]. all() -> diff --git a/lib/ssh/test/ssh_sup_SUITE.erl b/lib/ssh/test/ssh_sup_SUITE.erl index 5c77fcf1ef..18e91a9af3 100644 --- a/lib/ssh/test/ssh_sup_SUITE.erl +++ b/lib/ssh/test/ssh_sup_SUITE.erl @@ -34,6 +34,10 @@ %% Common Test interface functions ----------------------------------- %%-------------------------------------------------------------------- +suite() -> + [{ct_hooks,[ts_install_cth]}, + {timetrap,{minutes,1}}]. + all() -> [default_tree, sshc_subtree, sshd_subtree, sshd_subtree_profile]. diff --git a/lib/ssh/test/ssh_to_openssh_SUITE.erl b/lib/ssh/test/ssh_to_openssh_SUITE.erl index 37885dfdef..2788bc6b58 100644 --- a/lib/ssh/test/ssh_to_openssh_SUITE.erl +++ b/lib/ssh/test/ssh_to_openssh_SUITE.erl @@ -34,7 +34,7 @@ %%-------------------------------------------------------------------- suite() -> - [{timetrap,{minutes,5}}]. + [{timetrap,{minutes,1}}]. all() -> case os:find_executable("ssh") of diff --git a/lib/ssh/test/ssh_upgrade_SUITE.erl b/lib/ssh/test/ssh_upgrade_SUITE.erl index 006483d3ee..bf8874b118 100644 --- a/lib/ssh/test/ssh_upgrade_SUITE.erl +++ b/lib/ssh/test/ssh_upgrade_SUITE.erl @@ -39,7 +39,7 @@ %%% CommonTest callbacks %%% suite() -> - [{timetrap,{minutes,5}}]. + [{timetrap,{minutes,2}}]. all() -> [ diff --git a/lib/ssl/doc/src/ssl_distribution.xml b/lib/ssl/doc/src/ssl_distribution.xml index a347ce5ae6..dc04d446b0 100644 --- a/lib/ssl/doc/src/ssl_distribution.xml +++ b/lib/ssl/doc/src/ssl_distribution.xml @@ -271,4 +271,27 @@ Eshell V5.0 (abort with ^G) <p>The <c>init:get_arguments()</c> call verifies that the correct arguments are supplied to the emulator.</p> </section> + + <section> + <title>Using SSL distribution over IPv6</title> + <p>It is possible to use SSL distribution over IPv6 instead of + IPv4. To do this, pass the option <c>-proto_dist inet6_tls</c> + instead of <c>-proto_dist inet_tls</c> when starting Erlang, + either on the command line or in the <c>ERL_FLAGS</c> environment + variable.</p> + + <p>An example command line with this option would look like this:</p> + <code type="none"> +$ erl -boot /home/me/ssl/start_ssl -proto_dist inet6_tls + -ssl_dist_opt server_certfile "/home/me/ssl/erlserver.pem" + -ssl_dist_opt server_secure_renegotiate true client_secure_renegotiate true + -sname ssl_test +Erlang (BEAM) emulator version 5.0 [source] + +Eshell V5.0 (abort with ^G) +(ssl_test@myhost)1> </code> + + <p>A node started in this way will only be able to communicate with + other nodes using SSL distribution over IPv6.</p> + </section> </chapter> diff --git a/lib/ssl/src/Makefile b/lib/ssl/src/Makefile index 790328dc45..7a7a373487 100644 --- a/lib/ssl/src/Makefile +++ b/lib/ssl/src/Makefile @@ -51,6 +51,7 @@ MODULES= \ ssl_dist_sup\ ssl_sup \ inet_tls_dist \ + inet6_tls_dist \ ssl_certificate\ ssl_pkix_db\ ssl_cipher \ diff --git a/lib/ssl/src/inet6_tls_dist.erl b/lib/ssl/src/inet6_tls_dist.erl new file mode 100644 index 0000000000..ffd7296f93 --- /dev/null +++ b/lib/ssl/src/inet6_tls_dist.erl @@ -0,0 +1,46 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2015. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%% +%% %CopyrightEnd% +%% + +%% +-module(inet6_tls_dist). + +-export([childspecs/0, listen/1, accept/1, accept_connection/5, + setup/5, close/1, select/1]). + +childspecs() -> + inet_tls_dist:childspecs(). + +select(Node) -> + inet_tls_dist:gen_select(inet6_tcp, Node). + +listen(Name) -> + inet_tls_dist:gen_listen(inet6_tcp, Name). + +accept(Listen) -> + inet_tls_dist:gen_accept(inet6_tcp, Listen). + +accept_connection(AcceptPid, Socket, MyNode, Allowed, SetupTime) -> + inet_tls_dist:gen_accept_connection(inet6_tcp, AcceptPid, Socket, MyNode, Allowed, SetupTime). + +setup(Node, Type, MyNode, LongOrShortNames,SetupTime) -> + inet_tls_dist:gen_setup(inet6_tcp, Node, Type, MyNode, LongOrShortNames,SetupTime). + +close(Socket) -> + inet_tls_dist:close(Socket). diff --git a/lib/ssl/src/inet_tls_dist.erl b/lib/ssl/src/inet_tls_dist.erl index 6fe99a81c5..ec26142a75 100644 --- a/lib/ssl/src/inet_tls_dist.erl +++ b/lib/ssl/src/inet_tls_dist.erl @@ -24,6 +24,10 @@ -export([childspecs/0, listen/1, accept/1, accept_connection/5, setup/5, close/1, select/1, is_node_name/1]). +%% Generalized dist API +-export([gen_listen/2, gen_accept/2, gen_accept_connection/6, + gen_setup/6, gen_select/2]). + -include_lib("kernel/include/net_address.hrl"). -include_lib("kernel/include/dist.hrl"). -include_lib("kernel/include/dist_util.hrl"). @@ -33,9 +37,15 @@ childspecs() -> permanent, infinity, supervisor, [ssl_dist_sup]}]}. select(Node) -> + gen_select(inet_tcp, Node). + +gen_select(Driver, Node) -> case split_node(atom_to_list(Node), $@, []) of - [_,_Host] -> - true; + [_, Host] -> + case inet:getaddr(Host, Driver:family()) of + {ok, _} -> true; + _ -> false + end; _ -> false end. @@ -46,23 +56,35 @@ is_node_name(_) -> false. listen(Name) -> - ssl_tls_dist_proxy:listen(Name). + gen_listen(inet_tcp, Name). + +gen_listen(Driver, Name) -> + ssl_tls_dist_proxy:listen(Driver, Name). accept(Listen) -> - ssl_tls_dist_proxy:accept(Listen). + gen_accept(inet_tcp, Listen). + +gen_accept(Driver, Listen) -> + ssl_tls_dist_proxy:accept(Driver, Listen). accept_connection(AcceptPid, Socket, MyNode, Allowed, SetupTime) -> + gen_accept_connection(inet_tcp, AcceptPid, Socket, MyNode, Allowed, SetupTime). + +gen_accept_connection(Driver, AcceptPid, Socket, MyNode, Allowed, SetupTime) -> Kernel = self(), - spawn_link(fun() -> do_accept(Kernel, AcceptPid, Socket, + spawn_link(fun() -> do_accept(Driver, Kernel, AcceptPid, Socket, MyNode, Allowed, SetupTime) end). setup(Node, Type, MyNode, LongOrShortNames,SetupTime) -> + gen_setup(inet_tcp, Node, Type, MyNode, LongOrShortNames,SetupTime). + +gen_setup(Driver, Node, Type, MyNode, LongOrShortNames,SetupTime) -> Kernel = self(), - spawn_opt(fun() -> do_setup(Kernel, Node, Type, MyNode, LongOrShortNames, SetupTime) end, [link, {priority, max}]). + spawn_opt(fun() -> do_setup(Driver, Kernel, Node, Type, MyNode, LongOrShortNames, SetupTime) end, [link, {priority, max}]). -do_setup(Kernel, Node, Type, MyNode, LongOrShortNames, SetupTime) -> - [Name, Address] = splitnode(Node, LongOrShortNames), - case inet:getaddr(Address, inet) of +do_setup(Driver, Kernel, Node, Type, MyNode, LongOrShortNames, SetupTime) -> + [Name, Address] = splitnode(Driver, Node, LongOrShortNames), + case inet:getaddr(Address, Driver:family()) of {ok, Ip} -> Timer = dist_util:start_timer(SetupTime), case erl_epmd:port_please(Name, Ip) of @@ -70,7 +92,7 @@ do_setup(Kernel, Node, Type, MyNode, LongOrShortNames, SetupTime) -> ?trace("port_please(~p) -> version ~p~n", [Node,Version]), dist_util:reset_timer(Timer), - case ssl_tls_dist_proxy:connect(Ip, TcpPort) of + case ssl_tls_dist_proxy:connect(Driver, Ip, TcpPort) of {ok, Socket} -> HSData = connect_hs_data(Kernel, Node, MyNode, Socket, Timer, Version, Ip, TcpPort, Address, @@ -99,12 +121,12 @@ close(Socket) -> gen_tcp:close(Socket), ok. -do_accept(Kernel, AcceptPid, Socket, MyNode, Allowed, SetupTime) -> +do_accept(Driver, Kernel, AcceptPid, Socket, MyNode, Allowed, SetupTime) -> process_flag(priority, max), receive {AcceptPid, controller} -> Timer = dist_util:start_timer(SetupTime), - case check_ip(Socket) of + case check_ip(Driver, Socket) of true -> HSData = accept_hs_data(Kernel, MyNode, Socket, Timer, Allowed), dist_util:handshake_other_started(HSData); @@ -118,12 +140,12 @@ do_accept(Kernel, AcceptPid, Socket, MyNode, Allowed, SetupTime) -> %% Do only accept new connection attempts from nodes at our %% own LAN, if the check_ip environment parameter is true. %% ------------------------------------------------------------ -check_ip(Socket) -> +check_ip(Driver, Socket) -> case application:get_env(check_ip) of {ok, true} -> case get_ifs(Socket) of {ok, IFs, IP} -> - check_ip(IFs, IP); + check_ip(Driver, IFs, IP); _ -> ?shutdown(no_node) end; @@ -142,37 +164,21 @@ get_ifs(Socket) -> Error end. -check_ip([{OwnIP, _, Netmask}|IFs], PeerIP) -> - case {mask(Netmask, PeerIP), mask(Netmask, OwnIP)} of +check_ip(Driver, [{OwnIP, _, Netmask}|IFs], PeerIP) -> + case {Driver:mask(Netmask, PeerIP), Driver:mask(Netmask, OwnIP)} of {M, M} -> true; _ -> check_ip(IFs, PeerIP) end; -check_ip([], PeerIP) -> +check_ip(_Driver, [], PeerIP) -> {false, PeerIP}. -mask({M1,M2,M3,M4}, {IP1,IP2,IP3,IP4}) -> - {M1 band IP1, - M2 band IP2, - M3 band IP3, - M4 band IP4}; - -mask({M1,M2,M3,M4, M5, M6, M7, M8}, {IP1,IP2,IP3,IP4, IP5, IP6, IP7, IP8}) -> - {M1 band IP1, - M2 band IP2, - M3 band IP3, - M4 band IP4, - M5 band IP5, - M6 band IP6, - M7 band IP7, - M8 band IP8}. - %% If Node is illegal terminate the connection setup!! -splitnode(Node, LongOrShortNames) -> +splitnode(Driver, Node, LongOrShortNames) -> case split_node(atom_to_list(Node), $@, []) of [Name|Tail] when Tail =/= [] -> Host = lists:append(Tail), - check_node(Name, Node, Host, LongOrShortNames); + check_node(Driver, Name, Node, Host, LongOrShortNames); [_] -> error_logger:error_msg("** Nodename ~p illegal, no '@' character **~n", [Node]), @@ -182,15 +188,20 @@ splitnode(Node, LongOrShortNames) -> ?shutdown(Node) end. -check_node(Name, Node, Host, LongOrShortNames) -> +check_node(Driver, Name, Node, Host, LongOrShortNames) -> case split_node(Host, $., []) of [_] when LongOrShortNames == longnames -> - error_logger:error_msg("** System running to use " - "fully qualified " - "hostnames **~n" - "** Hostname ~s is illegal **~n", - [Host]), - ?shutdown(Node); + case Driver:parse_address(Host) of + {ok, _} -> + [Name, Host]; + _ -> + error_logger:error_msg("** System running to use " + "fully qualified " + "hostnames **~n" + "** Hostname ~s is illegal **~n", + [Host]), + ?shutdown(Node) + end; [_, _ | _] when LongOrShortNames == shortnames -> error_logger:error_msg("** System NOT running to use fully qualified " "hostnames **~n" diff --git a/lib/ssl/src/ssl.app.src b/lib/ssl/src/ssl.app.src index 619ab7b610..1a2bf90ccf 100644 --- a/lib/ssl/src/ssl.app.src +++ b/lib/ssl/src/ssl.app.src @@ -31,6 +31,7 @@ ssl_listen_tracker_sup, %% Erlang Distribution over SSL/TLS inet_tls_dist, + inet6_tls_dist, ssl_tls_dist_proxy, ssl_dist_sup, %% SSL/TLS session handling diff --git a/lib/ssl/src/ssl_tls_dist_proxy.erl b/lib/ssl/src/ssl_tls_dist_proxy.erl index 211badef56..4c789793ec 100644 --- a/lib/ssl/src/ssl_tls_dist_proxy.erl +++ b/lib/ssl/src/ssl_tls_dist_proxy.erl @@ -20,7 +20,7 @@ -module(ssl_tls_dist_proxy). --export([listen/1, accept/1, connect/2, get_tcp_address/1]). +-export([listen/2, accept/2, connect/3, get_tcp_address/1]). -export([init/1, start_link/0, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3, ssl_options/2]). @@ -39,14 +39,14 @@ %% Internal application API %%==================================================================== -listen(Name) -> - gen_server:call(?MODULE, {listen, Name}, infinity). +listen(Driver, Name) -> + gen_server:call(?MODULE, {listen, Driver, Name}, infinity). -accept(Listen) -> - gen_server:call(?MODULE, {accept, Listen}, infinity). +accept(Driver, Listen) -> + gen_server:call(?MODULE, {accept, Driver, Listen}, infinity). -connect(Ip, Port) -> - gen_server:call(?MODULE, {connect, Ip, Port}, infinity). +connect(Driver, Ip, Port) -> + gen_server:call(?MODULE, {connect, Driver, Ip, Port}, infinity). do_listen(Options) -> @@ -108,10 +108,11 @@ init([]) -> process_flag(priority, max), {ok, #state{}}. -handle_call({listen, Name}, _From, State) -> +handle_call({listen, Driver, Name}, _From, State) -> case gen_tcp:listen(0, [{active, false}, {packet,?PPRE}, {ip, loopback}]) of {ok, Socket} -> - {ok, World} = do_listen([{active, false}, binary, {packet,?PPRE}, {reuseaddr, true}]), + {ok, World} = do_listen([{active, false}, binary, {packet,?PPRE}, {reuseaddr, true}, + Driver:family()]), {ok, TcpAddress} = get_tcp_address(Socket), {ok, WorldTcpAddress} = get_tcp_address(World), {_,Port} = WorldTcpAddress#net_address.address, @@ -126,15 +127,15 @@ handle_call({listen, Name}, _From, State) -> {reply, Error, State} end; -handle_call({accept, Listen}, {From, _}, State = #state{listen={_, World}}) -> +handle_call({accept, _Driver, Listen}, {From, _}, State = #state{listen={_, World}}) -> Self = self(), ErtsPid = spawn_link(fun() -> accept_loop(Self, erts, Listen, From) end), WorldPid = spawn_link(fun() -> accept_loop(Self, world, World, Listen) end), {reply, ErtsPid, State#state{accept_loop={ErtsPid, WorldPid}}}; -handle_call({connect, Ip, Port}, {From, _}, State) -> +handle_call({connect, Driver, Ip, Port}, {From, _}, State) -> Me = self(), - Pid = spawn_link(fun() -> setup_proxy(Ip, Port, Me) end), + Pid = spawn_link(fun() -> setup_proxy(Driver, Ip, Port, Me) end), receive {Pid, go_ahead, LPort} -> Res = {ok, Socket} = try_connect(LPort), @@ -263,10 +264,11 @@ try_connect(Port) -> try_connect(Port) end. -setup_proxy(Ip, Port, Parent) -> +setup_proxy(Driver, Ip, Port, Parent) -> process_flag(trap_exit, true), Opts = connect_options(get_ssl_options(client)), - case ssl:connect(Ip, Port, [{active, true}, binary, {packet,?PPRE}, nodelay()] ++ Opts) of + case ssl:connect(Ip, Port, [{active, true}, binary, {packet,?PPRE}, nodelay(), + Driver:family()] ++ Opts) of {ok, World} -> {ok, ErtsL} = gen_tcp:listen(0, [{active, true}, {ip, loopback}, binary, {packet,?PPRE}]), {ok, #net_address{address={_,LPort}}} = get_tcp_address(ErtsL), diff --git a/lib/stdlib/doc/src/filename.xml b/lib/stdlib/doc/src/filename.xml index 77e262dbe6..65009753f3 100644 --- a/lib/stdlib/doc/src/filename.xml +++ b/lib/stdlib/doc/src/filename.xml @@ -47,7 +47,12 @@ <p>The module supports raw file names in the way that if a binary is present, or the file name cannot be interpreted according to the return value of <seealso marker="kernel:file#native_name_encoding/0">file:native_name_encoding/0</seealso>, a raw file name will also be returned. For example filename:join/1 provided with a path component being a binary (and also not being possible to interpret under the current native file name encoding) will result in a raw file name being returned (the join operation will have been performed of course). For more information about raw file names, see the <seealso marker="kernel:file">file</seealso> module.</p> </description> - + <datatypes> + <datatype> + <name name="basedir_type"/> + </datatype> + </datatypes> + <funcs> <func> <name name="absname" arity="1"/> @@ -102,6 +107,155 @@ </desc> </func> <func> + <name name="basedir" arity="2"/> + <fsummary>Equivalent to <c>basedir(<anno>Type</anno>,<anno>Application</anno>,#{})</c>.</fsummary> + <desc> + <p> + Equivalent to <seealso marker="#basedir-3"> + basedir(<anno>Type</anno>, <anno>Application</anno>, #{})</seealso>. + </p> + </desc> + </func> + <func> + <name name="basedir" arity="3"/> + <fsummary></fsummary> + <desc><marker id="basedir-3"/> + <p> + Returns a suitable path, or paths, for a given type. + If <c>os</c> is not set in <c><anno>Opts</anno></c> the function will default to + the native option, i.e. <c>'linux'</c>, <c>'darwin'</c> or <c>'windows'</c>, as understood + by <c>os:type/0</c>. Anything not recognized as <c>'darwin'</c> or <c>'windows'</c> is + interpreted as <c>'linux'</c>.</p> + <p> + The options <c>'author'</c> and <c>'version'</c> are only used with <c>'windows'</c> option mode. + </p> + <list type="bulleted"> + <item><c>user_cache</c> + <p>The path location is intended for transient data files on a local machine.</p> + <p> + On Linux: + Respects the os environment variable <c>XDG_CACHE_HOME</c>. + </p> + <pre> +1> <input>filename:basedir(user_cache, "my_application", #{os=>linux}).</input> +"/home/otptest/.cache/my_application"</pre> + On Darwin: <pre> +1> <input>filename:basedir(user_cache, "my_application", #{os=>darwin}).</input> +"/home/otptest/Library/Caches/my_application"</pre> + On Windows: <pre> +1> <input>filename:basedir(user_cache, "My App").</input> +"c:/Users/otptest/AppData/Local/My App/Cache" +2> <input>filename:basedir(user_cache, "My App").</input> +"c:/Users/otptest/AppData/Local/My App/Cache" +3> <input>filename:basedir(user_cache, "My App", #{author=>"Erlang"}).</input> +"c:/Users/otptest/AppData/Local/Erlang/My App/Cache" +4> <input>filename:basedir(user_cache, "My App", #{version=>"1.2"}).</input> +"c:/Users/otptest/AppData/Local/My App/1.2/Cache" +5> <input>filename:basedir(user_cache, "My App", #{author=>"Erlang",version=>"1.2"}).</input> +"c:/Users/otptest/AppData/Local/Erlang/My App/1.2/Cache"</pre> + </item> + <item><c>user_config</c> + <p> + The path location is intended for persistent configuration files. + </p> + <p> + On Linux: + Respects the os environment variable <c>XDG_CONFIG_HOME</c>. + </p> + <pre> +2> <input>filename:basedir(user_config, "my_application", #{os=>linux}).</input> +"/home/otptest/.config/my_application"</pre> + On Darwin:<pre> +2> <input>filename:basedir(user_config, "my_application", #{os=>darwin}).</input> +"/home/otptest/Library/Application Support/my_application"</pre> + On Windows:<pre> +1> <input>filename:basedir(user_config, "My App").</input> +"c:/Users/otptest/AppData/Roaming/My App" +2> <input>filename:basedir(user_config, "My App", #{author=>"Erlang", version=>"1.2"}).</input> +"c:/Users/otptest/AppData/Roaming/Erlang/My App/1.2"</pre> + </item> + <item><c>user_data</c> + <p> + The path location is intended for persistent data files. + </p> + <p> + On Linux: + Respects the os environment variable <c>XDG_DATA_HOME</c>. + </p> + <pre> +3> <input>filename:basedir(user_data, "my_application", #{os=>linux}).</input> +"/home/otptest/.local/my_application"</pre> + On Darwin:<pre> +3> <input>filename:basedir(user_data, "my_application", #{os=>darwin}).</input> +"/home/otptest/Library/Application Support/my_application"</pre> + On Windows:<pre> +8> <input>filename:basedir(user_data, "My App").</input> +"c:/Users/otptest/AppData/Local/My App" +9> <input>filename:basedir(user_data, "My App",#{author=>"Erlang",version=>"1.2"}).</input> +"c:/Users/otptest/AppData/Local/Erlang/My App/1.2"</pre> + </item> + <item><c>user_log</c> + <p>The path location is intended for transient log files on a local machine.</p> + <p> + On Linux: + Respects the os environment variable <c>XDG_CACHE_HOME</c>.</p> + <pre> +4> <input>filename:basedir(user_log, "my_application", #{os=>linux}).</input> +"/home/otptest/.cache/my_application/log"</pre> + On Darwin:<pre> +4> <input>filename:basedir(user_log, "my_application", #{os=>darwin}).</input> +"/home/otptest/Library/Caches/my_application"</pre> + On Windows:<pre> +12> <input>filename:basedir(user_log, "My App").</input> +"c:/Users/otptest/AppData/Local/My App/Logs" +13> <input>filename:basedir(user_log, "My App",#{author=>"Erlang",version=>"1.2"}).</input> +"c:/Users/otptest/AppData/Local/Erlang/My App/1.2/Logs"</pre> + </item> + <item><c>site_config</c><p> + On Linux: + Respects the os environment variable <c>XDG_CONFIG_DIRS</c>.</p> +<pre> +5> <input>filename:basedir(site_data, "my_application", #{os=>linux}).</input> +["/usr/local/share/my_application", + "/usr/share/my_application"] +6> <input>os:getenv("XDG_CONFIG_DIRS").</input> +"/etc/xdg/xdg-ubuntu:/usr/share/upstart/xdg:/etc/xdg" +7> <input>filename:basedir(site_config, "my_application", #{os=>linux}).</input> +["/etc/xdg/xdg-ubuntu/my_application", + "/usr/share/upstart/xdg/my_application", + "/etc/xdg/my_application"] +8> <input>os:unsetenv("XDG_CONFIG_DIRS").</input> +true +9> <input>filename:basedir(site_config, "my_application", #{os=>linux}).</input> +["/etc/xdg/my_application"]</pre> + On Darwin:<pre> +5> <input>filename:basedir(site_config, "my_application", #{os=>darwin}).</input> +["/Library/Application Support/my_application"]</pre> + </item> + <item><c>site_data</c><p> + On Linux: + Respects the os environment variable <c>XDG_DATA_DIRS</c>.</p> + <pre> +10> <input>os:getenv("XDG_DATA_DIRS").</input> +"/usr/share/ubuntu:/usr/share/gnome:/usr/local/share/:/usr/share/" +11> <input>filename:basedir(site_data, "my_application", #{os=>linux}).</input> +["/usr/share/ubuntu/my_application", + "/usr/share/gnome/my_application", + "/usr/local/share/my_application", + "/usr/share/my_application"] +12> <input>os:unsetenv("XDG_DATA_DIRS").</input> +true +13> <input>filename:basedir(site_data, "my_application", #{os=>linux}).</input> +["/usr/local/share/my_application", + "/usr/share/my_application"]</pre> + On Darwin:<pre> +5> <input>filename:basedir(site_data, "my_application", #{os=>darwin}).</input> +["/Library/Application Support/my_application"]</pre> + </item> + </list> + </desc> + </func> + <func> <name name="basename" arity="1"/> <fsummary>Return the last component of a filename</fsummary> <desc> diff --git a/lib/stdlib/src/filename.erl b/lib/stdlib/src/filename.erl index 008beb8b67..d921a69108 100644 --- a/lib/stdlib/src/filename.erl +++ b/lib/stdlib/src/filename.erl @@ -36,6 +36,7 @@ extension/1, join/1, join/2, pathtype/1, rootname/1, rootname/2, split/1, nativename/1]). -export([find_src/1, find_src/2, flatten/1]). +-export([basedir/2, basedir/3]). %% Undocumented and unsupported exports. -export([append/2]). @@ -139,6 +140,7 @@ absname_join(AbsBase, Name) -> -spec basename(Filename) -> file:filename_all() when Filename :: file:name_all(). + basename(Name) when is_binary(Name) -> case os:type() of {win32,_} -> @@ -954,3 +956,161 @@ filename_string_to_binary(List) -> Bin end. +%% Application Base Directories +%% basedir +%% http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html + +-type basedir_type() :: 'user_cache' | 'user_config' | 'user_data' + | 'user_log' + | 'site_config' | 'site_data'. + +-spec basedir(Type,Application) -> file:filename_all() when + Type :: basedir_type(), + Application :: string() | binary(). + +basedir(Type,Application) when is_atom(Type), is_list(Application) orelse + is_binary(Application) -> + basedir(Type, Application, #{}). + +-spec basedir(Type,Application,Opts) -> file:filename_all() when + Type :: basedir_type(), + Application :: string() | binary(), + Opts :: #{author => string() | binary(), + os => 'windows' | 'darwin' | 'linux', + version => string() | binary()}. + +basedir(Type,Application,Opts) when is_atom(Type), is_map(Opts), + is_list(Application) orelse + is_binary(Application) -> + Os = basedir_os_from_opts(Opts), + Name = basedir_name_from_opts(Os,Application,Opts), + Base = basedir_from_os(Type,Os), + case {Type,Os} of + {user_log,linux} -> + filename:join([Base,Name,"log"]); + {user_log,windows} -> + filename:join([Base,Name,"Logs"]); + {user_cache,windows} -> + filename:join([Base,Name,"Cache"]); + {Type,_} when Type =:= site_config orelse Type =:= site_data -> + [filename:join([B,Name]) || B <- Base]; + _ -> + filename:join([Base,Name]) + end. + +basedir_os_from_opts(#{os := linux}) -> linux; +basedir_os_from_opts(#{os := windows}) -> windows; +basedir_os_from_opts(#{os := darwin}) -> darwin; +basedir_os_from_opts(#{}) -> basedir_os_type(). + +basedir_name_from_opts(windows,App,#{author:=Author,version:=Vsn}) -> + filename:join([Author,App,Vsn]); +basedir_name_from_opts(windows,App,#{author:=Author}) -> + filename:join([Author,App]); +basedir_name_from_opts(_,App,#{version:=Vsn}) -> + filename:join([App,Vsn]); +basedir_name_from_opts(_,App,_) -> + App. + +basedir_from_os(Type,Os) -> + case Os of + linux -> basedir_linux(Type); + darwin -> basedir_darwin(Type); + windows -> basedir_windows(Type) + end. + +-define(basedir_linux_user_data, ".local/share"). +-define(basedir_linux_user_config, ".config"). +-define(basedir_linux_user_cache, ".cache"). +-define(basedir_linux_user_log, ".cache"). %% .cache/App/log +-define(basedir_linux_site_data, "/usr/local/share/:/usr/share/"). +-define(basedir_linux_site_config, "/etc/xdg"). + +basedir_linux(Type) -> + case Type of + user_data -> getenv("XDG_DATA_HOME", ?basedir_linux_user_data, true); + user_config -> getenv("XDG_CONFIG_HOME",?basedir_linux_user_config,true); + user_cache -> getenv("XDG_CACHE_HOME", ?basedir_linux_user_cache, true); + user_log -> getenv("XDG_CACHE_HOME", ?basedir_linux_user_log, true); + site_data -> + Base = getenv("XDG_DATA_DIRS",?basedir_linux_site_data,false), + string:tokens(Base,":"); + site_config -> + Base = getenv("XDG_CONFIG_DIRS",?basedir_linux_site_config,false), + string:tokens(Base,":") + end. + +-define(basedir_darwin_user_data, "Library/Application Support"). +-define(basedir_darwin_user_config, "Library/Application Support"). +-define(basedir_darwin_user_cache, "Library/Caches"). +-define(basedir_darwin_user_log, "Library/Logs"). +-define(basedir_darwin_site_data, "/Library/Application Support"). +-define(basedir_darwin_site_config, "/Library/Application Support"). + +basedir_darwin(Type) -> + case Type of + user_data -> basedir_join_home(?basedir_darwin_user_data); + user_config -> basedir_join_home(?basedir_darwin_user_config); + user_cache -> basedir_join_home(?basedir_darwin_user_cache); + user_log -> basedir_join_home(?basedir_darwin_user_log); + site_data -> [?basedir_darwin_site_data]; + site_config -> [?basedir_darwin_site_config] + end. + +%% On Windows: +%% ex. C:\Users\egil\AppData\Local\Ericsson\Erlang +%% %LOCALAPPDATA% is defined on Windows 7 and onwards +%% %APPDATA% is used instead of %LOCALAPPDATA% if it's not defined. +%% %APPDATA% is used for roaming, i.e. for user_config on Windows 7 and beyond. +%% +%% user_data %LOCALAPPDATA%[/$author]/$appname[/$version] +%% user_config %APPDATA%[/$author]/$appname[/$version] +%% user_cache %LOCALAPPDATA%[/$author]/$appname[/$version]/Cache +%% user_log %LOCALAPPDATA%[/$author]/$appname[/$version]/Logs + +basedir_windows(Type) -> + %% If LOCALAPPDATA is not defined we are likely on an + %% XP machine. Use APPDATA instead. + AppData = basedir_windows_appdata(), + case Type of + user_data -> getenv("LOCALAPPDATA", AppData); + user_config -> AppData; + user_cache -> getenv("LOCALAPPDATA", AppData); + user_log -> getenv("LOCALAPPDATA", AppData); + site_data -> []; + site_config -> [] + end. + +basedir_windows_appdata() -> + case os:getenv("APPDATA") of + Invalid when Invalid =:= false orelse Invalid =:= [] -> + erlang:error(noappdata); + Val -> Val + end. + +%% basedir aux + +getenv(K,Def,false) -> getenv(K,Def); +getenv(K,Def,true) -> getenv(K,basedir_join_home(Def)). + +getenv(K,Def) -> + case os:getenv(K) of + [] -> Def; + false -> Def; + Val -> Val + end. + +basedir_join_home(Dir) -> + case os:getenv("HOME") of + false -> + {ok,[[Home]]} = init:get_argument(home), + filename:join(Home,Dir); + Home -> filename:join(Home,Dir) + end. + +basedir_os_type() -> + case os:type() of + {unix,darwin} -> darwin; + {win32,_} -> windows; + _ -> linux + end. diff --git a/lib/stdlib/src/stdlib.appup.src b/lib/stdlib/src/stdlib.appup.src index 8a313591a7..15d8857656 100644 --- a/lib/stdlib/src/stdlib.appup.src +++ b/lib/stdlib/src/stdlib.appup.src @@ -18,9 +18,9 @@ %% %CopyrightEnd% {"%VSN%", %% Up from - max one major revision back - [{<<"2\\.[5-8](\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-18.* - {<<"2\\.[0-4](\\.[0-9]+)*">>,[restart_new_emulator]}], % 17.0-17.5 + [{<<"3\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-19.* + {<<"2\\.[5-8](\\.[0-9]+)*">>,[restart_new_emulator]}], % OTP-18.* %% Down to - max one major revision back - [{<<"2\\.[5-8](\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-18.* - {<<"2\\.[0-4](\\.[0-9]+)*">>,[restart_new_emulator]}] % 17.0-17.5 + [{<<"3\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-19.* + {<<"2\\.[5-8](\\.[0-9]+)*">>,[restart_new_emulator]}] % OTP-18.* }. diff --git a/lib/stdlib/test/filename_SUITE.erl b/lib/stdlib/test/filename_SUITE.erl index 8ecbc7eadf..7f2e4771f3 100644 --- a/lib/stdlib/test/filename_SUITE.erl +++ b/lib/stdlib/test/filename_SUITE.erl @@ -28,21 +28,29 @@ basename_bin_1/1, basename_bin_2/1, dirname_bin/1, extension_bin/1, join_bin/1, t_nativename_bin/1]). -export([pathtype_bin/1,rootname_bin/1,split_bin/1]). +-export([t_basedir_api/1, t_basedir_xdg/1, t_basedir_windows/1]). -include_lib("common_test/include/ct.hrl"). suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> - [absname, absname_2, basename_1, basename_2, dirname, - extension, - join, pathtype, rootname, split, t_nativename, find_src, - absname_bin, absname_bin_2, basename_bin_1, basename_bin_2, dirname_bin, - extension_bin, - join_bin, pathtype_bin, rootname_bin, split_bin, t_nativename_bin]. + [absname, absname_2, + find_src, + absname_bin, absname_bin_2, + {group,p}, + t_basedir_xdg, t_basedir_windows]. groups() -> - []. + [{p, [parallel], + [dirname, + extension, extension_bin, + join, pathtype, rootname, split, t_nativename, + basename_1, basename_2, + basename_bin_1, basename_bin_2, dirname_bin, + join_bin, pathtype_bin, rootname_bin, split_bin, + t_nativename_bin, + t_basedir_api]}]. init_per_suite(Config) -> Config. @@ -61,58 +69,59 @@ end_per_group(_GroupName, Config) -> absname(Config) when is_list(Config) -> case os:type() of - {win32, _} -> - ?line [Drive|_] = ?config(priv_dir, Config), - ?line Temp = filename:join([Drive|":/"], "temp"), - ?line case file:make_dir(Temp) of - ok -> ok; - {error,eexist} -> ok - end, - ?line {ok,Cwd} = file:get_cwd(), - ?line ok = file:set_cwd(Temp), - ?line [Drive|":/temp/foo"] = filename:absname(foo), - ?line [Drive|":/temp/foo"] = filename:absname("foo"), - ?line [Drive|":/temp/../ebin"] = filename:absname("../ebin"), - ?line [Drive|":/erlang"] = filename:absname("/erlang"), - ?line [Drive|":/erlang/src"] = filename:absname("/erlang/src"), - ?line [Drive|":/erlang/src"] = filename:absname("\\erlang\\src"), - ?line [Drive|":/temp/erlang"] = filename:absname([Drive|":erlang"]), - ?line [Drive|":/temp/erlang/src"] = - filename:absname([Drive|":erlang/src"]), - ?line [Drive|":/temp/erlang/src"] = - filename:absname([Drive|":erlang\\src\\"]), - ?line "a:/erlang" = filename:absname("a:erlang"), - - ?line file:set_cwd([Drive|":/"]), - ?line [Drive|":/foo"] = filename:absname(foo), - ?line [Drive|":/foo"] = filename:absname("foo"), - ?line [Drive|":/../ebin"] = filename:absname("../ebin"), - ?line [Drive|":/erlang"] = filename:absname("/erlang"), - ?line [Drive|":/erlang/src"] = filename:absname("/erlang/src"), - ?line [Drive|":/erlang/src"] = filename:absname(["/erlang",'/src']), - ?line [Drive|":/erlang/src"] = filename:absname("\\erlang\\\\src"), - ?line [Drive|":/erlang"] = filename:absname([Drive|":erlang"]), - ?line [Drive|":/erlang/src"] = filename:absname([Drive|":erlang/src"]), - ?line "a:/erlang" = filename:absname("a:erlang"), - - ?line file:set_cwd(Cwd), - ok; - {unix, _} -> - ?line ok = file:set_cwd("/usr"), - ?line "/usr/foo" = filename:absname(foo), - ?line "/usr/foo" = filename:absname("foo"), - ?line "/usr/../ebin" = filename:absname("../ebin"), - ?line file:set_cwd("/"), - ?line "/foo" = filename:absname(foo), - ?line "/foo" = filename:absname("foo"), - ?line "/../ebin" = filename:absname("../ebin"), - ?line "/erlang" = filename:absname("/erlang"), - ?line "/erlang/src" = filename:absname("/erlang/src"), - ?line "/erlang/src" = filename:absname(["/erl",'ang/s',"rc"]), - ?line "/erlang/src" = filename:absname(["/erl",'a','ng',"/",'s',"rc"]), - ?line "/erlang/src" = filename:absname("/erlang///src"), - ?line "/file_sorter.erl" = filename:absname([file_sorter|'.erl']), - ok + {win32, _} -> + [Drive|_] = ?config(priv_dir, Config), + Temp = filename:join([Drive|":/"], "temp"), + case file:make_dir(Temp) of + ok -> ok; + {error,eexist} -> ok + end, + {ok,Cwd} = file:get_cwd(), + ok = file:set_cwd(Temp), + [Drive|":/temp/foo"] = filename:absname(foo), + [Drive|":/temp/foo"] = filename:absname("foo"), + [Drive|":/temp/../ebin"] = filename:absname("../ebin"), + [Drive|":/erlang"] = filename:absname("/erlang"), + [Drive|":/erlang/src"] = filename:absname("/erlang/src"), + [Drive|":/erlang/src"] = filename:absname("\\erlang\\src"), + [Drive|":/temp/erlang"] = filename:absname([Drive|":erlang"]), + [Drive|":/temp/erlang/src"] = + filename:absname([Drive|":erlang/src"]), + [Drive|":/temp/erlang/src"] = + filename:absname([Drive|":erlang\\src\\"]), + "a:/erlang" = filename:absname("a:erlang"), + + file:set_cwd([Drive|":/"]), + [Drive|":/foo"] = filename:absname(foo), + [Drive|":/foo"] = filename:absname("foo"), + [Drive|":/../ebin"] = filename:absname("../ebin"), + [Drive|":/erlang"] = filename:absname("/erlang"), + [Drive|":/erlang/src"] = filename:absname("/erlang/src"), + [Drive|":/erlang/src"] = filename:absname(["/erlang",'/src']), + [Drive|":/erlang/src"] = filename:absname("\\erlang\\\\src"), + [Drive|":/erlang"] = filename:absname([Drive|":erlang"]), + [Drive|":/erlang/src"] = filename:absname([Drive|":erlang/src"]), + "a:/erlang" = filename:absname("a:erlang"), + + file:set_cwd(Cwd), + ok; + {unix, _} -> + ok = file:set_cwd("/usr"), + "/usr/foo" = filename:absname(foo), + "/usr/foo" = filename:absname("foo"), + "/usr/../ebin" = filename:absname("../ebin"), + + file:set_cwd("/"), + "/foo" = filename:absname(foo), + "/foo" = filename:absname("foo"), + "/../ebin" = filename:absname("../ebin"), + "/erlang" = filename:absname("/erlang"), + "/erlang/src" = filename:absname("/erlang/src"), + "/erlang/src" = filename:absname(["/erl",'ang/s',"rc"]), + "/erlang/src" = filename:absname(["/erl",'a','ng',"/",'s',"rc"]), + "/erlang/src" = filename:absname("/erlang///src"), + "/file_sorter.erl" = filename:absname([file_sorter|'.erl']), + ok end. @@ -120,125 +129,123 @@ absname(Config) when is_list(Config) -> absname_2(Config) when is_list(Config) -> case os:type() of - {win32, _} -> - ?line [Drive|_] = ?config(priv_dir, Config), - ?line [Drive|":/temp/foo"] = filename:absname(foo, [Drive|":/temp"]), - ?line [Drive|":/temp/foo"] = filename:absname("foo", [Drive|":/temp"]), - ?line [Drive|":/temp/../ebin"] = filename:absname("../ebin", - [Drive|":/temp"]), - ?line [Drive|":/erlang"] = filename:absname("/erlang", [Drive|":/temp"]), - ?line [Drive|":/erlang/src"] = filename:absname("/erlang/src", - [Drive|":/temp"]), - ?line [Drive|":/erlang/src"] = filename:absname("\\erlang\\src", - [Drive|":/temp"]), - ?line [Drive|":/temp/erlang"] = filename:absname([Drive|":erlang"], - [Drive|":/temp"]), - ?line [Drive|":/temp/erlang/src"] = filename:absname([Drive|":erlang/src"], - [Drive|":/temp"]), - ?line [Drive|":/temp/erlang/src"] = - filename:absname([Drive|":erlang\\src\\"], [Drive|":/temp"]), - ?line "a:/erlang" = filename:absname("a:erlang", [Drive|":/temp"]), - - ?line file:set_cwd([Drive|":/"]), - ?line [Drive|":/foo"] = filename:absname(foo, [Drive|":/"]), - ?line [Drive|":/foo"] = filename:absname("foo", [Drive|":/"]), - ?line [Drive|":/../ebin"] = filename:absname("../ebin", [Drive|":/"]), - ?line [Drive|":/erlang"] = filename:absname("/erlang", [Drive|":/"]), - ?line [Drive|":/erlang/src"] = filename:absname("/erlang/src", - [Drive|":/"]), - ?line [Drive|":/erlang/src"] = filename:absname("\\erlang\\\\src", - [Drive|":/"]), - ?line [Drive|":/erlang"] = filename:absname([Drive|":erlang"], - [Drive|":/"]), - ?line [Drive|":/erlang/src"] = filename:absname([Drive|":erlang/src"], - [Drive|":/"]), - ?line "a:/erlang" = filename:absname("a:erlang", [Drive|":/"]), - - ok; - _ -> - ?line "/usr/foo" = filename:absname(foo, "/usr"), - ?line "/usr/foo" = filename:absname("foo", "/usr"), - ?line "/usr/../ebin" = filename:absname("../ebin", "/usr"), - - ?line "/foo" = filename:absname(foo, "/"), - ?line "/foo" = filename:absname("foo", "/"), - ?line "/../ebin" = filename:absname("../ebin", "/"), - ?line "/erlang" = filename:absname("/erlang", "/"), - ?line "/erlang/src" = filename:absname("/erlang/src", "/"), - ?line "/erlang/src" = filename:absname("/erlang///src", "/"), - ok + {win32, _} -> + [Drive|_] = ?config(priv_dir, Config), + [Drive|":/temp/foo"] = filename:absname(foo, [Drive|":/temp"]), + [Drive|":/temp/foo"] = filename:absname("foo", [Drive|":/temp"]), + [Drive|":/temp/../ebin"] = filename:absname("../ebin", + [Drive|":/temp"]), + [Drive|":/erlang"] = filename:absname("/erlang", [Drive|":/temp"]), + [Drive|":/erlang/src"] = filename:absname("/erlang/src", + [Drive|":/temp"]), + [Drive|":/erlang/src"] = filename:absname("\\erlang\\src", + [Drive|":/temp"]), + [Drive|":/temp/erlang"] = filename:absname([Drive|":erlang"], + [Drive|":/temp"]), + [Drive|":/temp/erlang/src"] = filename:absname([Drive|":erlang/src"], + [Drive|":/temp"]), + [Drive|":/temp/erlang/src"] = + filename:absname([Drive|":erlang\\src\\"], [Drive|":/temp"]), + "a:/erlang" = filename:absname("a:erlang", [Drive|":/temp"]), + + file:set_cwd([Drive|":/"]), + [Drive|":/foo"] = filename:absname(foo, [Drive|":/"]), + [Drive|":/foo"] = filename:absname("foo", [Drive|":/"]), + [Drive|":/../ebin"] = filename:absname("../ebin", [Drive|":/"]), + [Drive|":/erlang"] = filename:absname("/erlang", [Drive|":/"]), + [Drive|":/erlang/src"] = filename:absname("/erlang/src", + [Drive|":/"]), + [Drive|":/erlang/src"] = filename:absname("\\erlang\\\\src", + [Drive|":/"]), + [Drive|":/erlang"] = filename:absname([Drive|":erlang"], + [Drive|":/"]), + [Drive|":/erlang/src"] = filename:absname([Drive|":erlang/src"], + [Drive|":/"]), + "a:/erlang" = filename:absname("a:erlang", [Drive|":/"]), + + ok; + _ -> + "/usr/foo" = filename:absname(foo, "/usr"), + "/usr/foo" = filename:absname("foo", "/usr"), + "/usr/../ebin" = filename:absname("../ebin", "/usr"), + + "/foo" = filename:absname(foo, "/"), + "/foo" = filename:absname("foo", "/"), + "/../ebin" = filename:absname("../ebin", "/"), + "/erlang" = filename:absname("/erlang", "/"), + "/erlang/src" = filename:absname("/erlang/src", "/"), + "/erlang/src" = filename:absname("/erlang///src", "/"), + ok end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% basename_1(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line "." = filename:basename("."), - ?line "foo" = filename:basename("foo"), - ?line "foo" = filename:basename("/usr/foo"), - ?line "foo.erl" = filename:basename("A:usr/foo.erl"), - ?line "foo" = filename:basename('/usr/foo'), - ?line "foo" = filename:basename(["/usr","/","f","o","o"]), - ?line "foo" = filename:basename(["/usr/",foo]), - ?line "foo" = filename:basename(["/usr/f",oo]), - ?line "foo" = filename:basename(["usr/", "foo"]), - ?line "foo" = filename:basename(["usr/"|foo]), - ?line "foo" = filename:basename(["usr/foo/"]), - ?line case os:type() of - {win32, _} -> - ?line "foo" = filename:basename(["usr\\foo\\"]), - ?line "foo" = filename:basename("A:\\usr\\foo"), - ?line "foo" = filename:basename("A:foo"); - _ -> - ?line "strange\\but\\true" = - filename:basename("strange\\but\\true") - end, - ?line test_server:timetrap_cancel(Dog), + Dog = test_server:timetrap(test_server:seconds(10)), + "." = filename:basename("."), + "foo" = filename:basename("foo"), + "foo" = filename:basename("/usr/foo"), + "foo.erl" = filename:basename("A:usr/foo.erl"), + "foo" = filename:basename('/usr/foo'), + "foo" = filename:basename(["/usr","/","f","o","o"]), + "foo" = filename:basename(["/usr/",foo]), + "foo" = filename:basename(["/usr/f",oo]), + "foo" = filename:basename(["usr/", "foo"]), + "foo" = filename:basename(["usr/"|foo]), + "foo" = filename:basename(["usr/foo/"]), + case os:type() of + {win32, _} -> + "foo" = filename:basename(["usr\\foo\\"]), + "foo" = filename:basename("A:\\usr\\foo"), + "foo" = filename:basename("A:foo"); + _ -> + "strange\\but\\true" = + filename:basename("strange\\but\\true") + end, + test_server:timetrap_cancel(Dog), ok. basename_2(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line "." = filename:basename(".", ".erl"), - ?line "foo" = filename:basename("foo.erl", ".erl"), - ?line "foo" = filename:basename('foo.erl', ".erl"), - ?line "foo" = filename:basename("foo.erl", '.erl'), - ?line "foo" = filename:basename(["/usr","/","f","oo"], ".erl"), - ?line "foo.erl" = filename:basename("/usr/foo.erl", ".hrl"), - ?line "foo.erl" = filename:basename("/usr.hrl/foo.erl", ".hrl"), - ?line "foo" = filename:basename("/usr.hrl/foo", ".hrl"), - ?line "foo" = filename:basename("usr/foo/", ".erl"), - ?line "foo.erl" = filename:basename("usr/foo.erl/", ".erl"), - ?line "foo.erl" = filename:basename("usr/foo.erl/", '.erl'), - ?line "foo" = filename:basename(["/usr",'/','f','oo'], ".erl"), - ?line "foo.erl" = filename:basename(["usr/foo.e",'rl/'], ".erl"), - ?line case os:type() of - {win32, _} -> - ?line "foo" = filename:basename("A:foo", ".erl"), - ?line "foo.erl" = filename:basename("a:\\usr\\foo.erl", - ".hrl"), - ?line "foo.erl" = filename:basename("c:\\usr.hrl\\foo.erl", - ".hrl"), - ?line "foo" = filename:basename("A:\\usr\\foo", ".hrl"); - _ -> - ?line "strange\\but\\true" = - filename:basename("strange\\but\\true.erl", ".erl"), - ?line "strange\\but\\true" = - filename:basename("strange\\but\\true", ".erl") - end, - ?line test_server:timetrap_cancel(Dog), + Dog = test_server:timetrap(test_server:seconds(10)), + "." = filename:basename(".", ".erl"), + "foo" = filename:basename("foo.erl", ".erl"), + "foo" = filename:basename('foo.erl', ".erl"), + "foo" = filename:basename("foo.erl", '.erl'), + "foo" = filename:basename(["/usr","/","f","oo"], ".erl"), + "foo.erl" = filename:basename("/usr/foo.erl", ".hrl"), + "foo.erl" = filename:basename("/usr.hrl/foo.erl", ".hrl"), + "foo" = filename:basename("/usr.hrl/foo", ".hrl"), + "foo" = filename:basename("usr/foo/", ".erl"), + "foo.erl" = filename:basename("usr/foo.erl/", ".erl"), + "foo.erl" = filename:basename("usr/foo.erl/", '.erl'), + "foo" = filename:basename(["/usr",'/','f','oo'], ".erl"), + "foo.erl" = filename:basename(["usr/foo.e",'rl/'], ".erl"), + case os:type() of + {win32, _} -> + "foo" = filename:basename("A:foo", ".erl"), + "foo.erl" = filename:basename("a:\\usr\\foo.erl", ".hrl"), + "foo.erl" = filename:basename("c:\\usr.hrl\\foo.erl", ".hrl"), + "foo" = filename:basename("A:\\usr\\foo", ".hrl"); + _ -> + "strange\\but\\true" = + filename:basename("strange\\but\\true.erl", ".erl"), + "strange\\but\\true" = + filename:basename("strange\\but\\true", ".erl") + end, + test_server:timetrap_cancel(Dog), ok. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% dirname(Config) when is_list(Config) -> case os:type() of - {win32,_} -> - "A:/usr" = filename:dirname("A:/usr/foo.erl"), - "A:usr" = filename:dirname("A:usr/foo.erl"), - "/usr" = filename:dirname("\\usr\\foo.erl"), - "/" = filename:dirname("\\usr"), - "A:" = filename:dirname("A:"); - _ -> true + {win32,_} -> + "A:/usr" = filename:dirname("A:/usr/foo.erl"), + "A:usr" = filename:dirname("A:usr/foo.erl"), + "/usr" = filename:dirname("\\usr\\foo.erl"), + "/" = filename:dirname("\\usr"), + "A:" = filename:dirname("A:"); + _ -> true end, "usr" = filename:dirname("usr///foo.erl"), "." = filename:dirname("foo.erl"), @@ -258,23 +265,22 @@ dirname(Config) when is_list(Config) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% extension(Config) when is_list(Config) -> - ?line ".erl" = filename:extension("A:/usr/foo.erl"), - ?line ".erl" = filename:extension("A:/usr/foo.nisse.erl"), - ?line ".erl" = filename:extension(["A:/usr/", 'foo.ni', "sse.erl"]), - ?line ".erl" = filename:extension(["A:/usr/", 'foo.ni', "sse.e", 'rl']), - ?line ".erl" = filename:extension(["A:/usr/", 'foo.ni', "sse.e"|'rl']), - ?line ".erl" = filename:extension("A:/usr.bar/foo.nisse.erl"), - ?line "" = filename:extension("A:/usr.bar/foo"), - ?line "" = filename:extension("A:/usr/foo"), - ?line case os:type() of - {win32, _} -> - ?line "" = filename:extension("A:\\usr\\foo"), - ?line ".erl" = - filename:extension("A:/usr.bar/foo.nisse.erl"), - ?line "" = filename:extension("A:/usr.bar/foo"), - ok; - _ -> ok - end. + ".erl" = filename:extension("A:/usr/foo.erl"), + ".erl" = filename:extension("A:/usr/foo.nisse.erl"), + ".erl" = filename:extension(["A:/usr/", 'foo.ni', "sse.erl"]), + ".erl" = filename:extension(["A:/usr/", 'foo.ni', "sse.e", 'rl']), + ".erl" = filename:extension(["A:/usr/", 'foo.ni', "sse.e"|'rl']), + ".erl" = filename:extension("A:/usr.bar/foo.nisse.erl"), + "" = filename:extension("A:/usr.bar/foo"), + "" = filename:extension("A:/usr/foo"), + case os:type() of + {win32, _} -> + "" = filename:extension("A:\\usr\\foo"), + ".erl" = filename:extension("A:/usr.bar/foo.nisse.erl"), + "" = filename:extension("A:/usr.bar/foo"), + ok; + _ -> ok + end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -282,8 +288,8 @@ join(Config) when is_list(Config) -> %% Whenever joining two elements, test the equivalence between %% join/1 and join/2 (OTP-12158) by using help function %% filename_join/2. - ?line "/" = filename:join(["/"]), - ?line "/" = filename:join(["//"]), + "/" = filename:join(["/"]), + "/" = filename:join(["//"]), "usr/foo.erl" = filename_join("usr","foo.erl"), "/src/foo.erl" = filename_join(usr, "/src/foo.erl"), "/src/foo.erl" = filename_join("/src/",'foo.erl'), @@ -291,7 +297,7 @@ join(Config) when is_list(Config) -> "/src/foo.erl" = filename_join("usr", "/src/foo.erl"), %% Make sure that redundant slashes work too. - ?line "a/b/c/d/e/f/g" = filename:join(["a//b/c/////d//e/f/g"]), + "a/b/c/d/e/f/g" = filename:join(["a//b/c/////d//e/f/g"]), "a/b/c/d/e/f/g" = filename_join("a//b/c/", "d//e/f/g"), "a/b/c/d/e/f/g" = filename_join("a//b/c", "d//e/f/g"), "/d/e/f/g" = filename_join("a//b/c", "/d//e/f/g"), @@ -324,30 +330,25 @@ join(Config) when is_list(Config) -> "/b" = filename_join("/a/","/b/"), "/a/b" = filename_join("/a/","b/"), - ?line case os:type() of - {win32, _} -> - ?line "d:/" = filename:join(["D:/"]), - ?line "d:/" = filename:join(["D:\\"]), - "d:/abc" = filename_join("D:/", "abc"), - "d:abc" = filename_join("D:", "abc"), - ?line "a/b/c/d/e/f/g" = - filename:join(["a//b\\c//\\/\\d/\\e/f\\g"]), - ?line "a:usr/foo.erl" = - filename:join(["A:","usr","foo.erl"]), - ?line "/usr/foo.erl" = - filename:join(["A:","/usr","foo.erl"]), - "c:usr" = filename_join("A:","C:usr"), - "a:usr" = filename_join("A:","usr"), - "c:/usr" = filename_join("A:", "C:/usr"), - ?line "c:/usr/foo.erl" = - filename:join(["A:","C:/usr","foo.erl"]), - ?line "c:usr/foo.erl" = - filename:join(["A:","C:usr","foo.erl"]), - ?line "d:/foo" = filename:join([$D, $:, $/, []], "foo"), - ok; - _ -> - ok - end. + case os:type() of + {win32, _} -> + "d:/" = filename:join(["D:/"]), + "d:/" = filename:join(["D:\\"]), + "d:/abc" = filename_join("D:/", "abc"), + "d:abc" = filename_join("D:", "abc"), + "a/b/c/d/e/f/g" = filename:join(["a//b\\c//\\/\\d/\\e/f\\g"]), + "a:usr/foo.erl" = filename:join(["A:","usr","foo.erl"]), + "/usr/foo.erl" = filename:join(["A:","/usr","foo.erl"]), + "c:usr" = filename_join("A:","C:usr"), + "a:usr" = filename_join("A:","usr"), + "c:/usr" = filename_join("A:", "C:/usr"), + "c:/usr/foo.erl" = filename:join(["A:","C:/usr","foo.erl"]), + "c:usr/foo.erl" = filename:join(["A:","C:usr","foo.erl"]), + "d:/foo" = filename:join([$D, $:, $/, []], "foo"), + ok; + _ -> + ok + end. %% Make sure join([A,B]) is equivalent to join(A,B) (OTP-12158) filename_join(A,B) -> @@ -355,92 +356,92 @@ filename_join(A,B) -> Res = filename:join([A,B]). pathtype(Config) when is_list(Config) -> - ?line relative = filename:pathtype(".."), - ?line relative = filename:pathtype("foo"), - ?line relative = filename:pathtype("foo/bar"), - ?line relative = filename:pathtype('foo/bar'), - ?line relative = filename:pathtype(['f','oo',"/bar"]), + relative = filename:pathtype(".."), + relative = filename:pathtype("foo"), + relative = filename:pathtype("foo/bar"), + relative = filename:pathtype('foo/bar'), + relative = filename:pathtype(['f','oo',"/bar"]), case os:type() of - {win32, _} -> - ?line volumerelative = filename:pathtype("/usr/local/bin"), - ?line volumerelative = filename:pathtype("A:usr/local/bin"), - ok; - _ -> - ?line absolute = filename:pathtype("/"), - ?line absolute = filename:pathtype("/usr/local/bin"), - ok + {win32, _} -> + volumerelative = filename:pathtype("/usr/local/bin"), + volumerelative = filename:pathtype("A:usr/local/bin"), + ok; + _ -> + absolute = filename:pathtype("/"), + absolute = filename:pathtype("/usr/local/bin"), + ok end. rootname(Config) when is_list(Config) -> - ?line "/jam.src/kalle" = filename:rootname("/jam.src/kalle"), - ?line "/jam.src/foo" = filename:rootname("/jam.src/foo.erl"), - ?line "/jam.src/foo" = filename:rootname(["/ja",'m.sr',"c/foo.erl"]), - ?line "/jam.src/foo" = filename:rootname("/jam.src/foo.erl", ".erl"), - ?line "/jam.src/foo.jam" = filename:rootname("/jam.src/foo.jam", ".erl"), - ?line "/jam.src/foo.jam" = filename:rootname(["/jam.sr",'c/foo.j',"am"],".erl"), - ?line "/jam.src/foo.jam" = filename:rootname(["/jam.sr",'c/foo.j'|am],".erl"), + "/jam.src/kalle" = filename:rootname("/jam.src/kalle"), + "/jam.src/foo" = filename:rootname("/jam.src/foo.erl"), + "/jam.src/foo" = filename:rootname(["/ja",'m.sr',"c/foo.erl"]), + "/jam.src/foo" = filename:rootname("/jam.src/foo.erl", ".erl"), + "/jam.src/foo.jam" = filename:rootname("/jam.src/foo.jam", ".erl"), + "/jam.src/foo.jam" = filename:rootname(["/jam.sr",'c/foo.j',"am"],".erl"), + "/jam.src/foo.jam" = filename:rootname(["/jam.sr",'c/foo.j'|am],".erl"), ok. split(Config) when is_list(Config) -> - ?line ["/","usr","local","bin"] = filename:split("/usr/local/bin"), - ?line ["foo","bar"]= filename:split("foo/bar"), - ?line ["foo", "bar", "hello"]= filename:split("foo////bar//hello"), - ?line ["foo", "bar", "hello"]= filename:split(["foo//",'//bar//h',"ello"]), - ?line ["foo", "bar", "hello"]= filename:split(["foo//",'//bar//h'|ello]), + ["/","usr","local","bin"] = filename:split("/usr/local/bin"), + ["foo","bar"]= filename:split("foo/bar"), + ["foo", "bar", "hello"]= filename:split("foo////bar//hello"), + ["foo", "bar", "hello"]= filename:split(["foo//",'//bar//h',"ello"]), + ["foo", "bar", "hello"]= filename:split(["foo//",'//bar//h'|ello]), ["/"] = filename:split("/"), [] = filename:split(""), case os:type() of - {win32,_} -> - ?line ["a:/","msdev","include"] = - filename:split("a:/msdev/include"), - ?line ["a:/","msdev","include"] = - filename:split("A:/msdev/include"), - ?line ["msdev","include"] = - filename:split("msdev\\include"), - ?line ["a:/","msdev","include"] = - filename:split("a:\\msdev\\include"), - ?line ["a:","msdev","include"] = - filename:split("a:msdev\\include"), - ok; - _ -> + {win32,_} -> + ["a:/","msdev","include"] = + filename:split("a:/msdev/include"), + ["a:/","msdev","include"] = + filename:split("A:/msdev/include"), + ["msdev","include"] = + filename:split("msdev\\include"), + ["a:/","msdev","include"] = + filename:split("a:\\msdev\\include"), + ["a:","msdev","include"] = + filename:split("a:msdev\\include"), + ok; + _ -> ok end. t_nativename(Config) when is_list(Config) -> - ?line "abcedf" = filename:nativename(abcedf), - ?line "abcedf" = filename:nativename(["abc", "edf"]), - ?line "abcgluff" = filename:nativename(["abc", gluff]), + "abcedf" = filename:nativename(abcedf), + "abcedf" = filename:nativename(["abc", "edf"]), + "abcgluff" = filename:nativename(["abc", gluff]), case os:type() of - {win32, _} -> - ?line "a:\\temp\\arne.exe" = - filename:nativename("A:/temp//arne.exe/"); - _ -> - ?line "/usr/tmp/arne" = - filename:nativename("/usr/tmp//arne/") + {win32, _} -> + "a:\\temp\\arne.exe" = + filename:nativename("A:/temp//arne.exe/"); + _ -> + "/usr/tmp/arne" = + filename:nativename("/usr/tmp//arne/") end. find_src(Config) when is_list(Config) -> - ?line {Source,_} = filename:find_src(file), - ?line ["file"|_] = lists:reverse(filename:split(Source)), - ?line {_,_} = filename:find_src(init, [{".","."}, {"ebin","src"}]), + {Source,_} = filename:find_src(file), + ["file"|_] = lists:reverse(filename:split(Source)), + {_,_} = filename:find_src(init, [{".","."}, {"ebin","src"}]), %% Try to find the source for a preloaded module. - ?line {error,{preloaded,init}} = filename:find_src(init), + {error,{preloaded,init}} = filename:find_src(init), %% Make sure that find_src works for a slim BEAM file. OldPath = code:get_path(), try - PrivDir = ?config(priv_dir, Config), - code:add_patha(PrivDir), - Src = "simple", - SrcPath = filename:join(PrivDir, Src) ++ ".erl", - SrcContents = "-module(simple).\n", - ok = file:write_file(SrcPath, SrcContents), - {ok,simple} = compile:file(SrcPath, [slim,{outdir,PrivDir}]), - BeamPath = filename:join(PrivDir, Src), - {BeamPath,[]} = filename:find_src(simple) + PrivDir = ?config(priv_dir, Config), + code:add_patha(PrivDir), + Src = "simple", + SrcPath = filename:join(PrivDir, Src) ++ ".erl", + SrcContents = "-module(simple).\n", + ok = file:write_file(SrcPath, SrcContents), + {ok,simple} = compile:file(SrcPath, [slim,{outdir,PrivDir}]), + BeamPath = filename:join(PrivDir, Src), + {BeamPath,[]} = filename:find_src(simple) after - code:set_path(OldPath) + code:set_path(OldPath) end, ok. @@ -452,50 +453,51 @@ find_src(Config) when is_list(Config) -> absname_bin(Config) when is_list(Config) -> case os:type() of - {win32, _} -> - ?line [Drive|_] = ?config(priv_dir, Config), - ?line Temp = filename:join([Drive|":/"], "temp"), - ?line case file:make_dir(Temp) of - ok -> ok; - {error,eexist} -> ok - end, - ?line {ok,Cwd} = file:get_cwd(), - ?line ok = file:set_cwd(Temp), - ?line <<Drive:8,":/temp/foo">> = filename:absname(<<"foo">>), - ?line <<Drive:8,":/temp/../ebin">> = filename:absname(<<"../ebin">>), - ?line <<Drive:8,":/erlang">> = filename:absname(<<"/erlang">>), - ?line <<Drive:8,":/erlang/src">> = filename:absname(<<"/erlang/src">>), - ?line <<Drive:8,":/erlang/src">> = filename:absname(<<"\\erlang\\src">>), - ?line <<Drive:8,":/temp/erlang">> = filename:absname(<<Drive:8,":erlang">>), - ?line <<Drive:8,":/temp/erlang/src">> = - filename:absname(<<Drive:8,":erlang/src">>), - ?line <<Drive:8,":/temp/erlang/src">> = - filename:absname(<<Drive:8,":erlang\\src\\">>), - ?line <<"a:/erlang">> = filename:absname(<<"a:erlang">>), - - ?line file:set_cwd(<<Drive:8,":/">>), - ?line <<Drive:8,":/foo">> = filename:absname(<<"foo">>), - ?line <<Drive:8,":/../ebin">> = filename:absname(<<"../ebin">>), - ?line <<Drive:8,":/erlang">> = filename:absname(<<"/erlang">>), - ?line <<Drive:8,":/erlang/src">> = filename:absname(<<"/erlang/src">>), - ?line <<Drive:8,":/erlang/src">> = filename:absname(<<"\\erlang\\\\src">>), - ?line <<Drive:8,":/erlang">> = filename:absname(<<Drive:8,":erlang">>), - ?line <<Drive:8,":/erlang/src">> = filename:absname(<<Drive:8,":erlang/src">>), - ?line <<"a:/erlang">> = filename:absname(<<"a:erlang">>), - - ?line file:set_cwd(Cwd), - ok; - {unix, _} -> - ?line ok = file:set_cwd(<<"/usr">>), - ?line <<"/usr/foo">> = filename:absname(<<"foo">>), - ?line <<"/usr/../ebin">> = filename:absname(<<"../ebin">>), - ?line file:set_cwd(<<"/">>), - ?line <<"/foo">> = filename:absname(<<"foo">>), - ?line <<"/../ebin">> = filename:absname(<<"../ebin">>), - ?line <<"/erlang">> = filename:absname(<<"/erlang">>), - ?line <<"/erlang/src">> = filename:absname(<<"/erlang/src">>), - ?line <<"/erlang/src">> = filename:absname(<<"/erlang///src">>), - ok + {win32, _} -> + [Drive|_] = ?config(priv_dir, Config), + Temp = filename:join([Drive|":/"], "temp"), + case file:make_dir(Temp) of + ok -> ok; + {error,eexist} -> ok + end, + {ok,Cwd} = file:get_cwd(), + ok = file:set_cwd(Temp), + <<Drive:8,":/temp/foo">> = filename:absname(<<"foo">>), + <<Drive:8,":/temp/../ebin">> = filename:absname(<<"../ebin">>), + <<Drive:8,":/erlang">> = filename:absname(<<"/erlang">>), + <<Drive:8,":/erlang/src">> = filename:absname(<<"/erlang/src">>), + <<Drive:8,":/erlang/src">> = filename:absname(<<"\\erlang\\src">>), + <<Drive:8,":/temp/erlang">> = filename:absname(<<Drive:8,":erlang">>), + <<Drive:8,":/temp/erlang/src">> = + filename:absname(<<Drive:8,":erlang/src">>), + <<Drive:8,":/temp/erlang/src">> = + filename:absname(<<Drive:8,":erlang\\src\\">>), + <<"a:/erlang">> = filename:absname(<<"a:erlang">>), + + file:set_cwd(<<Drive:8,":/">>), + <<Drive:8,":/foo">> = filename:absname(<<"foo">>), + <<Drive:8,":/../ebin">> = filename:absname(<<"../ebin">>), + <<Drive:8,":/erlang">> = filename:absname(<<"/erlang">>), + <<Drive:8,":/erlang/src">> = filename:absname(<<"/erlang/src">>), + <<Drive:8,":/erlang/src">> = filename:absname(<<"\\erlang\\\\src">>), + <<Drive:8,":/erlang">> = filename:absname(<<Drive:8,":erlang">>), + <<Drive:8,":/erlang/src">> = filename:absname(<<Drive:8,":erlang/src">>), + <<"a:/erlang">> = filename:absname(<<"a:erlang">>), + + file:set_cwd(Cwd), + ok; + {unix,_} -> + ok = file:set_cwd(<<"/usr">>), + <<"/usr/foo">> = filename:absname(<<"foo">>), + <<"/usr/../ebin">> = filename:absname(<<"../ebin">>), + + file:set_cwd(<<"/">>), + <<"/foo">> = filename:absname(<<"foo">>), + <<"/../ebin">> = filename:absname(<<"../ebin">>), + <<"/erlang">> = filename:absname(<<"/erlang">>), + <<"/erlang/src">> = filename:absname(<<"/erlang/src">>), + <<"/erlang/src">> = filename:absname(<<"/erlang///src">>), + ok end. @@ -503,108 +505,104 @@ absname_bin(Config) when is_list(Config) -> absname_bin_2(Config) when is_list(Config) -> case os:type() of - {win32, _} -> - ?line [Drive|_] = ?config(priv_dir, Config), - ?line <<Drive:8,":/temp/foo">> = filename:absname(<<"foo">>, <<Drive:8,":/temp">>), - ?line <<Drive:8,":/temp/../ebin">> = filename:absname(<<"../ebin">>, - <<Drive:8,":/temp">>), - ?line <<Drive:8,":/erlang">> = filename:absname(<<"/erlang">>, <<Drive:8,":/temp">>), - ?line <<Drive:8,":/erlang/src">> = filename:absname(<<"/erlang/src">>, - <<Drive:8,":/temp">>), - ?line <<Drive:8,":/erlang/src">> = filename:absname(<<"\\erlang\\src">>, - <<Drive:8,":/temp">>), - ?line <<Drive:8,":/temp/erlang">> = filename:absname(<<Drive:8,":erlang">>, - <<Drive:8,":/temp">>), - ?line <<Drive:8,":/temp/erlang/src">> = filename:absname(<<Drive:8,":erlang/src">>, - <<Drive:8,":/temp">>), - ?line <<Drive:8,":/temp/erlang/src">> = - filename:absname(<<Drive:8,":erlang\\src\\">>, <<Drive:8,":/temp">>), - ?line <<"a:/erlang">> = filename:absname(<<"a:erlang">>, <<Drive:8,":/temp">>), - - ?line file:set_cwd(<<Drive:8,":/">>), - ?line <<Drive:8,":/foo">> = filename:absname(foo, <<Drive:8,":/">>), - ?line <<Drive:8,":/foo">> = filename:absname(<<"foo">>, <<Drive:8,":/">>), - ?line <<Drive:8,":/../ebin">> = filename:absname(<<"../ebin">>, <<Drive:8,":/">>), - ?line <<Drive:8,":/erlang">> = filename:absname(<<"/erlang">>, <<Drive:8,":/">>), - ?line <<Drive:8,":/erlang/src">> = filename:absname(<<"/erlang/src">>, - <<Drive:8,":/">>), - ?line <<Drive:8,":/erlang/src">> = filename:absname(<<"\\erlang\\\\src">>, - <<Drive:8,":/">>), - ?line <<Drive:8,":/erlang">> = filename:absname(<<Drive:8,":erlang">>, - <<Drive:8,":/">>), - ?line <<Drive:8,":/erlang/src">> = filename:absname(<<Drive:8,":erlang/src">>, - <<Drive:8,":/">>), - ?line <<"a:/erlang">> = filename:absname(<<"a:erlang">>, <<Drive:8,":/">>), - - ok; - _ -> - ?line <<"/usr/foo">> = filename:absname(<<"foo">>, <<"/usr">>), - ?line <<"/usr/../ebin">> = filename:absname(<<"../ebin">>, <<"/usr">>), - - ?line <<"/foo">> = filename:absname(<<"foo">>, <<"/">>), - ?line <<"/../ebin">> = filename:absname(<<"../ebin">>, <<"/">>), - ?line <<"/erlang">> = filename:absname(<<"/erlang">>, <<"/">>), - ?line <<"/erlang/src">> = filename:absname(<<"/erlang/src">>, <<"/">>), - ?line <<"/erlang/src">> = filename:absname(<<"/erlang///src">>, <<"/">>), - ok + {win32, _} -> + [Drive|_] = ?config(priv_dir, Config), + <<Drive:8,":/temp/foo">> = filename:absname(<<"foo">>, <<Drive:8,":/temp">>), + <<Drive:8,":/temp/../ebin">> = filename:absname(<<"../ebin">>, + <<Drive:8,":/temp">>), + <<Drive:8,":/erlang">> = filename:absname(<<"/erlang">>, <<Drive:8,":/temp">>), + <<Drive:8,":/erlang/src">> = filename:absname(<<"/erlang/src">>, + <<Drive:8,":/temp">>), + <<Drive:8,":/erlang/src">> = filename:absname(<<"\\erlang\\src">>, + <<Drive:8,":/temp">>), + <<Drive:8,":/temp/erlang">> = filename:absname(<<Drive:8,":erlang">>, + <<Drive:8,":/temp">>), + <<Drive:8,":/temp/erlang/src">> = filename:absname(<<Drive:8,":erlang/src">>, + <<Drive:8,":/temp">>), + <<Drive:8,":/temp/erlang/src">> = + filename:absname(<<Drive:8,":erlang\\src\\">>, <<Drive:8,":/temp">>), + <<"a:/erlang">> = filename:absname(<<"a:erlang">>, <<Drive:8,":/temp">>), + + file:set_cwd(<<Drive:8,":/">>), + <<Drive:8,":/foo">> = filename:absname(foo, <<Drive:8,":/">>), + <<Drive:8,":/foo">> = filename:absname(<<"foo">>, <<Drive:8,":/">>), + <<Drive:8,":/../ebin">> = filename:absname(<<"../ebin">>, <<Drive:8,":/">>), + <<Drive:8,":/erlang">> = filename:absname(<<"/erlang">>, <<Drive:8,":/">>), + <<Drive:8,":/erlang/src">> = filename:absname(<<"/erlang/src">>, + <<Drive:8,":/">>), + <<Drive:8,":/erlang/src">> = filename:absname(<<"\\erlang\\\\src">>, + <<Drive:8,":/">>), + <<Drive:8,":/erlang">> = filename:absname(<<Drive:8,":erlang">>, + <<Drive:8,":/">>), + <<Drive:8,":/erlang/src">> = filename:absname(<<Drive:8,":erlang/src">>, + <<Drive:8,":/">>), + <<"a:/erlang">> = filename:absname(<<"a:erlang">>, <<Drive:8,":/">>), + + ok; + _ -> + <<"/usr/foo">> = filename:absname(<<"foo">>, <<"/usr">>), + <<"/usr/../ebin">> = filename:absname(<<"../ebin">>, <<"/usr">>), + <<"/foo">> = filename:absname(<<"foo">>, <<"/">>), + <<"/../ebin">> = filename:absname(<<"../ebin">>, <<"/">>), + <<"/erlang">> = filename:absname(<<"/erlang">>, <<"/">>), + <<"/erlang/src">> = filename:absname(<<"/erlang/src">>, <<"/">>), + <<"/erlang/src">> = filename:absname(<<"/erlang///src">>, <<"/">>), + ok end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% basename_bin_1(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line <<".">> = filename:basename(<<".">>), - ?line <<"foo">> = filename:basename(<<"foo">>), - ?line <<"foo">> = filename:basename(<<"/usr/foo">>), - ?line <<"foo.erl">> = filename:basename(<<"A:usr/foo.erl">>), - ?line case os:type() of - {win32, _} -> - ?line <<"foo">> = filename:basename(<<"A:\\usr\\foo">>), - ?line <<"foo">> = filename:basename(<<"A:foo">>); - _ -> - ?line <<"strange\\but\\true">> = - filename:basename(<<"strange\\but\\true">>) - end, - ?line test_server:timetrap_cancel(Dog), + Dog = test_server:timetrap(test_server:seconds(10)), + <<".">> = filename:basename(<<".">>), + <<"foo">> = filename:basename(<<"foo">>), + <<"foo">> = filename:basename(<<"/usr/foo">>), + <<"foo.erl">> = filename:basename(<<"A:usr/foo.erl">>), + case os:type() of + {win32, _} -> + <<"foo">> = filename:basename(<<"A:\\usr\\foo">>), + <<"foo">> = filename:basename(<<"A:foo">>); + _ -> + <<"strange\\but\\true">> = filename:basename(<<"strange\\but\\true">>) + end, + test_server:timetrap_cancel(Dog), ok. basename_bin_2(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line <<".">> = filename:basename(<<".">>, <<".erl">>), - ?line <<"foo">> = filename:basename(<<"foo.erl">>, <<".erl">>), - ?line <<"foo.erl">> = filename:basename(<<"/usr/foo.erl">>, <<".hrl">>), - ?line <<"foo.erl">> = filename:basename(<<"/usr.hrl/foo.erl">>, <<".hrl">>), - ?line <<"foo">> = filename:basename(<<"/usr.hrl/foo">>, <<".hrl">>), - ?line <<"foo">> = filename:basename(<<"usr/foo/">>, <<".erl">>), - ?line <<"foo.erl">> = filename:basename(<<"usr/foo.erl/">>, <<".erl">>), - ?line case os:type() of - {win32, _} -> - ?line <<"foo">> = filename:basename(<<"A:foo">>, <<".erl">>), - ?line <<"foo.erl">> = filename:basename(<<"a:\\usr\\foo.erl">>, - <<".hrl">>), - ?line <<"foo.erl">> = filename:basename(<<"c:\\usr.hrl\\foo.erl">>, - <<".hrl">>), - ?line <<"foo">> = filename:basename(<<"A:\\usr\\foo">>, <<".hrl">>); - _ -> - ?line <<"strange\\but\\true">> = - filename:basename(<<"strange\\but\\true.erl">>, <<".erl">>), - ?line <<"strange\\but\\true">> = - filename:basename(<<"strange\\but\\true">>, <<".erl">>) - end, - ?line test_server:timetrap_cancel(Dog), + Dog = test_server:timetrap(test_server:seconds(10)), + <<".">> = filename:basename(<<".">>, <<".erl">>), + <<"foo">> = filename:basename(<<"foo.erl">>, <<".erl">>), + <<"foo.erl">> = filename:basename(<<"/usr/foo.erl">>, <<".hrl">>), + <<"foo.erl">> = filename:basename(<<"/usr.hrl/foo.erl">>, <<".hrl">>), + <<"foo">> = filename:basename(<<"/usr.hrl/foo">>, <<".hrl">>), + <<"foo">> = filename:basename(<<"usr/foo/">>, <<".erl">>), + <<"foo.erl">> = filename:basename(<<"usr/foo.erl/">>, <<".erl">>), + case os:type() of + {win32, _} -> + <<"foo">> = filename:basename(<<"A:foo">>, <<".erl">>), + <<"foo.erl">> = filename:basename(<<"a:\\usr\\foo.erl">>, <<".hrl">>), + <<"foo.erl">> = filename:basename(<<"c:\\usr.hrl\\foo.erl">>, <<".hrl">>), + <<"foo">> = filename:basename(<<"A:\\usr\\foo">>, <<".hrl">>); + _ -> + <<"strange\\but\\true">> = + filename:basename(<<"strange\\but\\true.erl">>, <<".erl">>), + <<"strange\\but\\true">> = + filename:basename(<<"strange\\but\\true">>, <<".erl">>) + end, + test_server:timetrap_cancel(Dog), ok. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% dirname_bin(Config) when is_list(Config) -> case os:type() of - {win32,_} -> - <<"A:/usr">> = filename:dirname(<<"A:/usr/foo.erl">>), - <<"A:usr">> = filename:dirname(<<"A:usr/foo.erl">>), - <<"/usr">> = filename:dirname(<<"\\usr\\foo.erl">>), - <<"/">> = filename:dirname(<<"\\usr">>), - <<"A:">> = filename:dirname(<<"A:">>); - _ -> true + {win32,_} -> + <<"A:/usr">> = filename:dirname(<<"A:/usr/foo.erl">>), + <<"A:usr">> = filename:dirname(<<"A:usr/foo.erl">>), + <<"/usr">> = filename:dirname(<<"\\usr\\foo.erl">>), + <<"/">> = filename:dirname(<<"\\usr">>), + <<"A:">> = filename:dirname(<<"A:">>); + _ -> true end, <<"usr">> = filename:dirname(<<"usr///foo.erl">>), <<".">> = filename:dirname(<<"foo.erl">>), @@ -612,7 +610,6 @@ dirname_bin(Config) when is_list(Config) -> <<"/">> = filename:dirname(<<"/">>), <<"/">> = filename:dirname(<<"/usr">>), ok. - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -624,10 +621,9 @@ extension_bin(Config) when is_list(Config) -> <<"">> = filename:extension(<<"A:/usr/foo">>), case os:type() of {win32, _} -> - ?line <<"">> = filename:extension(<<"A:\\usr\\foo">>), - ?line <<".erl">> = - filename:extension(<<"A:/usr.bar/foo.nisse.erl">>), - ?line <<"">> = filename:extension(<<"A:/usr.bar/foo">>), + <<"">> = filename:extension(<<"A:\\usr\\foo">>), + <<".erl">> = filename:extension(<<"A:/usr.bar/foo.nisse.erl">>), + <<"">> = filename:extension(<<"A:/usr.bar/foo">>), ok; _ -> ok end. @@ -635,22 +631,22 @@ extension_bin(Config) when is_list(Config) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% join_bin(Config) when is_list(Config) -> - ?line <<"/">> = filename:join([<<"/">>]), - ?line <<"/">> = filename:join([<<"//">>]), - ?line <<"usr/foo.erl">> = filename:join(<<"usr">>,<<"foo.erl">>), - ?line <<"/src/foo.erl">> = filename:join(usr, <<"/src/foo.erl">>), - ?line <<"/src/foo.erl">> = filename:join([<<"/src/">>,'foo.erl']), - ?line <<"/src/foo.erl">> = filename:join(<<"usr">>, ["/sr", 'c/foo.erl']), - ?line <<"/src/foo.erl">> = filename:join(<<"usr">>, <<"/src/foo.erl">>), + <<"/">> = filename:join([<<"/">>]), + <<"/">> = filename:join([<<"//">>]), + <<"usr/foo.erl">> = filename:join(<<"usr">>,<<"foo.erl">>), + <<"/src/foo.erl">> = filename:join(usr, <<"/src/foo.erl">>), + <<"/src/foo.erl">> = filename:join([<<"/src/">>,'foo.erl']), + <<"/src/foo.erl">> = filename:join(<<"usr">>, ["/sr", 'c/foo.erl']), + <<"/src/foo.erl">> = filename:join(<<"usr">>, <<"/src/foo.erl">>), %% Make sure that redundant slashes work too. - ?line <<"a/b/c/d/e/f/g">> = filename:join([<<"a//b/c/////d//e/f/g">>]), - ?line <<"a/b/c/d/e/f/g">> = filename:join([<<"a//b/c/">>, <<"d//e/f/g">>]), - ?line <<"a/b/c/d/e/f/g">> = filename:join([<<"a//b/c">>, <<"d//e/f/g">>]), - ?line <<"/d/e/f/g">> = filename:join([<<"a//b/c">>, <<"/d//e/f/g">>]), - ?line <<"/d/e/f/g">> = filename:join([<<"a//b/c">>, <<"//d//e/f/g">>]), + <<"a/b/c/d/e/f/g">> = filename:join([<<"a//b/c/////d//e/f/g">>]), + <<"a/b/c/d/e/f/g">> = filename:join([<<"a//b/c/">>, <<"d//e/f/g">>]), + <<"a/b/c/d/e/f/g">> = filename:join([<<"a//b/c">>, <<"d//e/f/g">>]), + <<"/d/e/f/g">> = filename:join([<<"a//b/c">>, <<"/d//e/f/g">>]), + <<"/d/e/f/g">> = filename:join([<<"a//b/c">>, <<"//d//e/f/g">>]), - ?line <<"foo/bar">> = filename:join([$f,$o,$o,$/,[]], <<"bar">>), + <<"foo/bar">> = filename:join([$f,$o,$o,$/,[]], <<"bar">>), %% Single dots - should be removed if in the middle of the path, %% but not at the end of the path. @@ -699,30 +695,25 @@ join_bin(Config) when is_list(Config) -> <<"/a/b">> = filename:join([<<"/a/">>,<<"b/">>]), <<"/a/b">> = filename:join(<<"/a/">>,<<"b/">>), - ?line case os:type() of - {win32, _} -> - ?line <<"d:/">> = filename:join([<<"D:/">>]), - ?line <<"d:/">> = filename:join([<<"D:\\">>]), - ?line <<"d:/abc">> = filename:join([<<"D:/">>, <<"abc">>]), - ?line <<"d:abc">> = filename:join([<<"D:">>, <<"abc">>]), - ?line <<"a/b/c/d/e/f/g">> = - filename:join([<<"a//b\\c//\\/\\d/\\e/f\\g">>]), - ?line <<"a:usr/foo.erl">> = - filename:join([<<"A:">>,<<"usr">>,<<"foo.erl">>]), - ?line <<"/usr/foo.erl">> = - filename:join([<<"A:">>,<<"/usr">>,<<"foo.erl">>]), - ?line <<"c:usr">> = filename:join(<<"A:">>,<<"C:usr">>), - ?line <<"a:usr">> = filename:join(<<"A:">>,<<"usr">>), - ?line <<"c:/usr">> = filename:join(<<"A:">>, <<"C:/usr">>), - ?line <<"c:/usr/foo.erl">> = - filename:join([<<"A:">>,<<"C:/usr">>,<<"foo.erl">>]), - ?line <<"c:usr/foo.erl">> = - filename:join([<<"A:">>,<<"C:usr">>,<<"foo.erl">>]), - ?line <<"d:/foo">> = filename:join([$D, $:, $/, []], <<"foo">>), - ok; - _ -> - ok - end. + case os:type() of + {win32, _} -> + <<"d:/">> = filename:join([<<"D:/">>]), + <<"d:/">> = filename:join([<<"D:\\">>]), + <<"d:/abc">> = filename:join([<<"D:/">>, <<"abc">>]), + <<"d:abc">> = filename:join([<<"D:">>, <<"abc">>]), + <<"a/b/c/d/e/f/g">> = filename:join([<<"a//b\\c//\\/\\d/\\e/f\\g">>]), + <<"a:usr/foo.erl">> = filename:join([<<"A:">>,<<"usr">>,<<"foo.erl">>]), + <<"/usr/foo.erl">> = filename:join([<<"A:">>,<<"/usr">>,<<"foo.erl">>]), + <<"c:usr">> = filename:join(<<"A:">>,<<"C:usr">>), + <<"a:usr">> = filename:join(<<"A:">>,<<"usr">>), + <<"c:/usr">> = filename:join(<<"A:">>, <<"C:/usr">>), + <<"c:/usr/foo.erl">> = filename:join([<<"A:">>,<<"C:/usr">>,<<"foo.erl">>]), + <<"c:usr/foo.erl">> = filename:join([<<"A:">>,<<"C:usr">>,<<"foo.erl">>]), + <<"d:/foo">> = filename:join([$D, $:, $/, []], <<"foo">>), + ok; + _ -> + ok + end. pathtype_bin(Config) when is_list(Config) -> relative = filename:pathtype(<<"..">>), @@ -730,14 +721,14 @@ pathtype_bin(Config) when is_list(Config) -> relative = filename:pathtype(<<"foo/bar">>), relative = filename:pathtype('foo/bar'), case os:type() of - {win32, _} -> - volumerelative = filename:pathtype(<<"/usr/local/bin">>), - volumerelative = filename:pathtype(<<"A:usr/local/bin">>), - ok; - _ -> - absolute = filename:pathtype(<<"/">>), - absolute = filename:pathtype(<<"/usr/local/bin">>), - ok + {win32, _} -> + volumerelative = filename:pathtype(<<"/usr/local/bin">>), + volumerelative = filename:pathtype(<<"A:usr/local/bin">>), + ok; + _ -> + absolute = filename:pathtype(<<"/">>), + absolute = filename:pathtype(<<"/usr/local/bin">>), + ok end. rootname_bin(Config) when is_list(Config) -> @@ -756,29 +747,204 @@ split_bin(Config) when is_list(Config) -> [<<"/">>] = filename:split(<<"/">>), [] = filename:split(<<"">>), case os:type() of - {win32,_} -> - [<<"a:/">>,<<"msdev">>,<<"include">>] = - filename:split(<<"a:/msdev/include">>), - [<<"a:/">>,<<"msdev">>,<<"include">>] = - filename:split(<<"A:/msdev/include">>), - [<<"msdev">>,<<"include">>] = - filename:split(<<"msdev\\include">>), - [<<"a:/">>,<<"msdev">>,<<"include">>] = - filename:split(<<"a:\\msdev\\include">>), - [<<"a:">>,<<"msdev">>,<<"include">>] = - filename:split(<<"a:msdev\\include">>), - ok; - _ -> - ok + {win32,_} -> + [<<"a:/">>,<<"msdev">>,<<"include">>] = + filename:split(<<"a:/msdev/include">>), + [<<"a:/">>,<<"msdev">>,<<"include">>] = + filename:split(<<"A:/msdev/include">>), + [<<"msdev">>,<<"include">>] = + filename:split(<<"msdev\\include">>), + [<<"a:/">>,<<"msdev">>,<<"include">>] = + filename:split(<<"a:\\msdev\\include">>), + [<<"a:">>,<<"msdev">>,<<"include">>] = + filename:split(<<"a:msdev\\include">>), + ok; + _ -> + ok end. t_nativename_bin(Config) when is_list(Config) -> - ?line <<"abcedf">> = filename:nativename(<<"abcedf">>), + <<"abcedf">> = filename:nativename(<<"abcedf">>), + case os:type() of + {win32, _} -> + <<"a:\\temp\\arne.exe">> = + filename:nativename(<<"A:/temp//arne.exe/">>); + _ -> + <<"/usr/tmp/arne">> = + filename:nativename(<<"/usr/tmp//arne/">>) + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% basedirs +t_basedir_api(Config) when is_list(Config) -> + true = is_list(filename:basedir(site_data, "My App")), + true = is_list(filename:basedir(site_config, "My App")), + true = is_list(filename:basedir(user_data, "My App")), + true = is_list(filename:basedir(user_log, "My App")), + true = is_list(filename:basedir(user_config, "My App")), + true = is_list(filename:basedir(user_cache, "My App")), + + true = is_list(filename:basedir(site_data, <<"My App">>)), + true = is_list(filename:basedir(site_config, <<"My App">>)), + true = is_binary(filename:basedir(user_data, <<"My App">>)), + true = is_binary(filename:basedir(user_log, <<"My App">>)), + true = is_binary(filename:basedir(user_config, <<"My App">>)), + true = is_binary(filename:basedir(user_cache, <<"My App">>)), + + %% simulate for windows + case os:type() of + {win32,_} -> ok; + _ -> + os:putenv("APPDATA", "C:\\Documents and Settings\\otptest\\Application Data") + end, + + true = is_list(filename:basedir(site_data, "My App", #{})), + true = is_list(filename:basedir(site_config, "My App", #{os=>linux})), + true = is_list(filename:basedir(user_data, "My App", #{os=>darwin})), + true = is_list(filename:basedir(user_log, "My App", #{os=>windows})), + true = is_list(filename:basedir(user_config, "My App",#{author=>"Erl"})), + true = is_list(filename:basedir(user_config, "My App",#{os=>darwin, + author=>"Erl"})), + true = is_list(filename:basedir(user_config, "My App",#{os=>linux, + author=>"Erl"})), + true = is_list(filename:basedir(user_cache, "My App",#{os=>windows, + author=>"Erl"})), + true = is_list(filename:basedir(user_config, "My App",#{os=>darwin, + author=>"Erla", + version=>"1.0"})), + true = is_list(filename:basedir(user_config, "My App",#{os=>linux, + version=>"2.0.1", + author=>"Erl"})), + true = is_list(filename:basedir(user_cache, "My App",#{os=>windows, + version=>"3.1.2", + author=>"Erl"})), + true = is_binary(filename:basedir(user_config, "My App",#{os=>darwin, + author=>"Erla", + version=><<"1.0">>})), + true = is_binary(filename:basedir(user_config, "My App",#{os=>windows, + version=>"2.0.1", + author=><<"Erl">>})), + true = is_binary(filename:basedir(user_cache, "My App",#{os=>linux, + version=><<"3.1.2">>, + author=>"Erl"})), + %% simulate for windows + case os:type() of + {win32,_} -> ok; + _ -> os:unsetenv("APPDATA") + end, + + {'EXIT', _} = (catch filename:basedir(wrong_config, "My App")), + {'EXIT', _} = (catch filename:basedir(user_cache, {bad,name})), + {'EXIT', _} = (catch filename:basedir(user_cache, "My App", badopts)), + {'EXIT', _} = (catch filename:basedir(user_cache, "My App", [])), + ok. + +t_basedir_windows(Config) when is_list(Config) -> + Types = [user_data,user_log,user_config,user_cache], case os:type() of - {win32, _} -> - ?line <<"a:\\temp\\arne.exe">> = - filename:nativename(<<"A:/temp//arne.exe/">>); - _ -> - ?line <<"/usr/tmp/arne">> = - filename:nativename(<<"/usr/tmp//arne/">>) + {win32,_} -> + ok = check_basedir_windows(Types, #{}); + _ -> + %% Windows 7 and beyond + os:putenv("APPDATA", "C:\\Users\\otptest\\AppData\\Roaming"), + os:putenv("LOCALAPPDATA", "C:\\Users\\otptest\\AppData\\Local"), + io:format("APPDATA ~p~n", [os:getenv("APPDATA")]), + io:format("LOCALAPPDATA ~p~n", [os:getenv("LOCALAPPDATA")]), + ok = check_basedir_windows(Types,#{os=>windows}), + %% Windows XP + os:unsetenv("LOCALAPPDATA"), + os:putenv("APPDATA", "C:\\Documents and Settings\\otptest\\Application Data"), + io:format("APPDATA ~p~n", [os:getenv("APPDATA")]), + io:format("APPLOCALDATA ~p~n", [os:getenv("APPLOCALDATA")]), + ok = check_basedir_windows(Types,#{os=>windows}), + os:unsetenv("APPDATA") + end, + ok. + +check_basedir_windows([],_) -> ok; +check_basedir_windows([Type|Types],Opt) -> + Name = "Some Application", + io:format("type: ~p~n", [Type]), + ok = check_basedir_windows_path(Type, + [Name], + filename:basedir(Type, Name, Opt)), + ok = check_basedir_windows_path(Type, + ["Erl",Name], + filename:basedir(Type, Name, Opt#{author=>"Erl"})), + ok = check_basedir_windows_path(Type, + [Name,"1.0"], + filename:basedir(Type, Name, Opt#{version=>"1.0"})), + ok = check_basedir_windows_path(Type, + ["Erl",Name,"1.0"], + filename:basedir(Type, Name, Opt#{author=>"Erl", + version=>"1.0"})), + check_basedir_windows(Types, Opt). + +check_basedir_windows_path(Type,Check0,Basedir) -> + BDR = lists:reverse(filename:split(Basedir)), + Check = lists:reverse(Check0), + io:format("~w: ~p ~p~n", [Type,Check,BDR]), + case Type of + user_log -> check_basedir_windows_path_split(["Logs"|Check],BDR); + user_cache -> check_basedir_windows_path_split(["Cache"|Check],BDR); + _ -> check_basedir_windows_path_split(Check,BDR) + end. + +check_basedir_windows_path_split([],_) -> ok; +check_basedir_windows_path_split([Same|Check],[Same|BDR]) -> + check_basedir_windows_path_split(Check,BDR). + + +t_basedir_xdg(Config) when is_list(Config) -> + check_basedir_xdg([user_data,user_log,user_config,user_cache, + site_data,site_config]), + ok. + +check_basedir_xdg([]) -> ok; +check_basedir_xdg([Type|Types]) -> + Name = "some_app", + Opt = #{os=>linux}, + Key = basedir_xdg_env(Type), + io:format("type: ~p~n", [Type]), + Home = os:getenv("HOME"), + NDir = "/some/absolute/path", + DefPath = basedir_xdg_def(Type,Home,Name), + EnvPath = case Type of + user_log -> filename:join([NDir,Name,"log"]); + site_data -> [filename:join([NDir,Name])]; + site_config -> [filename:join([NDir,Name])]; + _ -> filename:join([NDir,Name]) + end, + os:unsetenv(Key), + ok = check_basedir(Type, DefPath, filename:basedir(Type, Name, Opt)), + os:putenv(Key, NDir), + ok = check_basedir(Type, EnvPath, filename:basedir(Type, Name, Opt)), + os:unsetenv(Key), + ok = check_basedir(Type, DefPath, filename:basedir(Type, Name, Opt)), + check_basedir_xdg(Types). + +check_basedir(Type, Path, Basedir) -> + io:format("~w: ~p = ~p~n", [Type,Path,Basedir]), + Path = Basedir, + ok. + +basedir_xdg_env(Type) -> + case Type of + user_data -> "XDG_DATA_HOME"; + user_config -> "XDG_CONFIG_HOME"; + user_cache -> "XDG_CACHE_HOME"; + user_log -> "XDG_CACHE_HOME"; + site_data -> "XDG_DATA_DIRS"; + site_config -> "XDG_CONFIG_DIRS" + end. + +basedir_xdg_def(Type,Home,Name) -> + case Type of + user_data -> filename:join([Home,".local","share",Name]); + user_config -> filename:join([Home,".config",Name]); + user_cache -> filename:join([Home,".cache",Name]); + user_log -> filename:join([Home,".cache",Name,"log"]); + site_data -> [filename:join([Dir,Name]) || + Dir <- ["/usr/local/share/","/usr/share/"]]; + site_config -> [filename:join(["/etc/xdg",Name])] end. diff --git a/lib/wx/configure.in b/lib/wx/configure.in index 48fcca640c..bf27b72aa7 100644 --- a/lib/wx/configure.in +++ b/lib/wx/configure.in @@ -164,14 +164,14 @@ case $host_os in CPPFLAGS="$CPPFLAGS -D_MACOSX $PTHR_CFLAGS" ;; mingw32) - CFLAGS="$CFLAGS -DWIN32 -DWINVER=0x0500 -D_WINDOWS -D_UNICODE -DUNICODE" - CPPFLAGS="$CPPFLAGS -D_WIN32_WINNT=0x0500" + CFLAGS="$CFLAGS -DWIN32 -DWINVER=0x0600 -D_WINDOWS -D_UNICODE -DUNICODE" + CPPFLAGS="$CPPFLAGS -D_WIN32_WINNT=0x0600" AC_MSG_WARN([Reverting to 32-bit time_t]) CPPFLAGS="$CPPFLAGS -D_USE_32BIT_TIME_T" ;; win32) - CFLAGS="$CFLAGS -DWIN32 -DWINVER=0x0500 -D_WINDOWS -D_UNICODE -DUNICODE" - CPPFLAGS="$CPPFLAGS -D_WIN32_WINNT=0x0500" + CFLAGS="$CFLAGS -DWIN32 -DWINVER=0x0600 -D_WINDOWS -D_UNICODE -DUNICODE" + CPPFLAGS="$CPPFLAGS -D_WIN32_WINNT=0x0600" ;; *) CFLAGS="$CFLAGS -Wno-deprecated-declarations" |