diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/kernel/test/Makefile | 1 | ||||
-rw-r--r-- | lib/kernel/test/socket_client.erl | 252 | ||||
-rw-r--r-- | lib/kernel/test/socket_lib.erl | 129 | ||||
-rw-r--r-- | lib/kernel/test/socket_server.erl | 237 |
4 files changed, 462 insertions, 157 deletions
diff --git a/lib/kernel/test/Makefile b/lib/kernel/test/Makefile index 07e7922d3d..051fac25af 100644 --- a/lib/kernel/test/Makefile +++ b/lib/kernel/test/Makefile @@ -25,6 +25,7 @@ include $(ERL_TOP)/make/$(TARGET)/otp.mk # ---------------------------------------------------- SOCKET_MODULES = \ + socket_lib \ socket_server \ socket_client diff --git a/lib/kernel/test/socket_client.erl b/lib/kernel/test/socket_client.erl index a284777046..0b570e1f71 100644 --- a/lib/kernel/test/socket_client.erl +++ b/lib/kernel/test/socket_client.erl @@ -1,17 +1,34 @@ -%%%------------------------------------------------------------------- -%%% @author Micael Karlberg <[email protected]> -%%% @copyright (C) 2018, Micael Karlberg -%%% @doc -%%% -%%% @end -%%% Created : 27 Jun 2018 by Micael Karlberg <[email protected]> -%%%------------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2018-2018. 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(socket_client). --export([start/1]). +-export([ + start/1, + start_tcp/1, start_tcp/2, + start_udp/1, start_udp/2 + ]). + +-define(LIB, socket_lib). --define(REQ, 0). --define(REP, 1). +-record(client, {socket, type, dest, msg_id = 1}). start(Port) -> start_tcp(Port). @@ -19,22 +36,77 @@ start(Port) -> start_tcp(Port) -> start(inet, stream, tcp, Port). +start_tcp(Addr, Port) when (size(Addr) =:= 4) -> + start(inet, stream, tcp, Addr, Port); +start_tcp(Addr, Port) when (size(Addr) =:= 8) -> + start(inet6, stream, tcp, Addr, Port). + + +start_udp(Port) -> + start(inet, dgram, udp, Port). + +start_udp(Addr, Port) when (size(Addr) =:= 4) -> + start(inet, dgram, udp, Addr, Port); +start_udp(Addr, Port) when (size(Addr) =:= 8) -> + start(inet6, dgram, udp, Addr, Port). + + start(Domain, Type, Proto, Port) -> + start(Domain, Type, Proto, which_addr(Domain), Port). + +start(Domain, Type, Proto, Addr, Port) -> + put(sname, "starter"), + SA = #{family => Domain, + addr => Addr, + port => Port}, + do_start(Domain, Type, Proto, SA). + +do_start(Domain, stream = Type, Proto, SA) -> try do_init(Domain, Type, Proto) of Sock -> - connect(Sock, Domain, Port), + connect(Sock, SA), + i("connected: " + "~n From: ~p" + "~n To: ~p", + [ + case socket:sockname(Sock) of + {ok, Name} -> Name; + {error, _} = NE -> NE + end, + case socket:peername(Sock) of + {ok, Name} -> Name; + {error, _} = PE -> PE + end + ]), %% Give the server some time... - p("wait some", []), - %% sleep(5000), + i("wait some", []), + ?LIB:sleep(5000), %% ok = socket:close(Sock), - send_loop(Sock) + send_loop(#client{socket = Sock, + type = Type}) + catch + throw:E -> + e("Failed initiate: " + "~n Error: ~p", [E]) + end; +do_start(Domain, dgram = Type, Proto, SA) -> + try do_init(Domain, Type, Proto) of + Sock -> + %% Give the server some time... + i("wait some", []), + ?LIB:sleep(5000), + %% ok = socket:close(Sock), + send_loop(#client{socket = Sock, + type = Type, + dest = SA}) catch throw:E -> e("Failed initiate: " "~n Error: ~p", [E]) end. -do_init(Domain, Type, Proto) -> + +do_init(Domain, stream = Type, Proto) -> i("try (socket) open"), Sock = case socket:open(Domain, Type, Proto) of {ok, S} -> @@ -48,8 +120,23 @@ do_init(Domain, Type, Proto) -> Sock; {error, BReason} -> throw({bind, BReason}) + end; +do_init(Domain, dgram = Type, Proto) -> + i("try (socket) open"), + Sock = case socket:open(Domain, Type, Proto) of + {ok, S} -> + S; + {error, OReason} -> + throw({open, OReason}) + end, + case socket:bind(Sock, any) of + {ok, _} -> + Sock; + {error, BReason} -> + throw({bind, BReason}) end. + which_addr(Domain) -> Iflist = case inet:getifaddrs() of {ok, IFL} -> @@ -60,16 +147,11 @@ which_addr(Domain) -> which_addr(Domain, Iflist). -connect(Sock, Domain, Port) -> - Addr = which_addr(Domain), - SA = #{family => Domain, - addr => Addr, - port => Port}, +connect(Sock, SA) -> i("try (socket) connect to:" "~n ~p", [SA]), case socket:connect(Sock, SA) of ok -> - i("connected"), ok; {error, Reason} -> e("connect failure: " @@ -78,22 +160,23 @@ connect(Sock, Domain, Port) -> end. -send_loop(Sock) -> - send_loop(Sock, 1). - -send_loop(Sock, N) when (N =< 10) -> +send_loop(#client{msg_id = N} = C) when (N =< 10) -> i("try send request ~w", [N]), - Req = enc_req_msg(N, "hejsan"), - case socket:send(Sock, Req) of + Req = ?LIB:enc_req_msg(N, "hejsan"), + case send(C, Req) of ok -> i("request ~w sent - now try read answer", [N]), - case socket:recv(Sock, 0) of - {ok, Msg} -> - i("received ~w bytes of data", [size(Msg)]), - case dec_msg(Msg) of + case recv(C) of + {ok, {Source, Msg}} -> + i("received ~w bytes of data~s", + [size(Msg), case Source of + undefined -> ""; + _ -> ?LIB:f(" from:~n ~p", [Source]) + end]), + case ?LIB:dec_msg(Msg) of {reply, N, Reply} -> i("received reply ~w: ~p", [N, Reply]), - send_loop(Sock, N+1) + send_loop(C#client{msg_id = N+1}) end; {error, RReason} -> e("Failed recv response for request ~w: " @@ -105,7 +188,7 @@ send_loop(Sock, N) when (N =< 10) -> "~n ~p", [SReason]), exit({failed_send, SReason}) end; -send_loop(Sock, _N) -> +send_loop(#client{socket = Sock}) -> i("we are done - close the socket when: " "~n ~p", [socket:info()]), ok = socket:close(Sock), @@ -113,6 +196,25 @@ send_loop(Sock, _N) -> "~n ~p", [socket:info()]). +send(#client{socket = Sock, type = stream}, Msg) -> + socket:send(Sock, Msg); +send(#client{socket = Sock, type = dgram, dest = Dest}, Msg) -> + %% i("try send to: " + %% "~n ~p", [Dest]), + %% ok = socket:setopt(Sock, otp, debug, true), + socket:sendto(Sock, Msg, Dest). + +recv(#client{socket = Sock, type = stream}) -> + case socket:recv(Sock) of + {ok, Msg} -> + {ok, {undefined, Msg}}; + {error, _} = ERROR -> + ERROR + end; +recv(#client{socket = Sock, type = dgram}) -> + socket:recvfrom(Sock). + + which_addr(_Domain, []) -> throw(no_address); which_addr(Domain, [{Name, IFO}|_IFL]) when (Name =/= "lo") -> @@ -130,68 +232,66 @@ which_addr2(Domain, [_|IFO]) -> %% --- -enc_req_msg(N, Data) -> - enc_msg(?REQ, N, Data). +%% enc_req_msg(N, Data) -> +%% enc_msg(?REQ, N, Data). -enc_rep_msg(N, Data) -> - enc_msg(?REP, N, Data). +%% enc_rep_msg(N, Data) -> +%% enc_msg(?REP, N, Data). -enc_msg(Type, N, Data) when is_list(Data) -> - enc_msg(Type, N, list_to_binary(Data)); -enc_msg(Type, N, Data) - when is_integer(Type) andalso is_integer(N) andalso is_binary(Data) -> - <<Type:32/integer, N:32/integer, Data/binary>>. +%% enc_msg(Type, N, Data) when is_list(Data) -> +%% enc_msg(Type, N, list_to_binary(Data)); +%% enc_msg(Type, N, Data) +%% when is_integer(Type) andalso is_integer(N) andalso is_binary(Data) -> +%% <<Type:32/integer, N:32/integer, Data/binary>>. -dec_msg(<<?REQ:32/integer, N:32/integer, Data/binary>>) -> - {request, N, Data}; -dec_msg(<<?REP:32/integer, N:32/integer, Data/binary>>) -> - {reply, N, Data}. +%% dec_msg(<<?REQ:32/integer, N:32/integer, Data/binary>>) -> +%% {request, N, Data}; +%% dec_msg(<<?REP:32/integer, N:32/integer, Data/binary>>) -> +%% {reply, N, Data}. %% --- -sleep(T) -> - receive after T -> ok end. +%% sleep(T) -> +%% receive after T -> ok end. %% --- -formated_timestamp() -> - format_timestamp(os:timestamp()). +%% formated_timestamp() -> +%% format_timestamp(os:timestamp()). -format_timestamp(Now) -> - N2T = fun(N) -> calendar:now_to_local_time(N) end, - format_timestamp(Now, N2T, true). +%% format_timestamp(Now) -> +%% N2T = fun(N) -> calendar:now_to_local_time(N) end, +%% format_timestamp(Now, N2T, true). -format_timestamp({_N1, _N2, N3} = N, N2T, true) -> - FormatExtra = ".~.2.0w", - ArgsExtra = [N3 div 10000], - format_timestamp(N, N2T, FormatExtra, ArgsExtra); -format_timestamp({_N1, _N2, _N3} = N, N2T, false) -> - FormatExtra = "", - ArgsExtra = [], - format_timestamp(N, N2T, FormatExtra, ArgsExtra). +%% format_timestamp({_N1, _N2, N3} = N, N2T, true) -> +%% FormatExtra = ".~.2.0w", +%% ArgsExtra = [N3 div 10000], +%% format_timestamp(N, N2T, FormatExtra, ArgsExtra); +%% format_timestamp({_N1, _N2, _N3} = N, N2T, false) -> +%% FormatExtra = "", +%% ArgsExtra = [], +%% format_timestamp(N, N2T, FormatExtra, ArgsExtra). -format_timestamp(N, N2T, FormatExtra, ArgsExtra) -> - {Date, Time} = N2T(N), - {YYYY,MM,DD} = Date, - {Hour,Min,Sec} = Time, - FormatDate = - io_lib:format("~.4w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w" ++ FormatExtra, - [YYYY, MM, DD, Hour, Min, Sec] ++ ArgsExtra), - lists:flatten(FormatDate). +%% format_timestamp(N, N2T, FormatExtra, ArgsExtra) -> +%% {Date, Time} = N2T(N), +%% {YYYY,MM,DD} = Date, +%% {Hour,Min,Sec} = Time, +%% FormatDate = +%% io_lib:format("~.4w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w" ++ FormatExtra, +%% [YYYY, MM, DD, Hour, Min, Sec] ++ ArgsExtra), +%% lists:flatten(FormatDate). %% --- e(F, A) -> - p("<ERROR> " ++ F, A). + ?LIB:e(F, A). i(F) -> - i(F, []). + ?LIB:i(F). + i(F, A) -> - p("*** " ++ F, A). - -p(F, A) -> - io:format("[client,~p][~s] " ++ F ++ "~n", [self(),formated_timestamp()|A]). + ?LIB:i(F, A). diff --git a/lib/kernel/test/socket_lib.erl b/lib/kernel/test/socket_lib.erl new file mode 100644 index 0000000000..0eed81d61a --- /dev/null +++ b/lib/kernel/test/socket_lib.erl @@ -0,0 +1,129 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2018-2018. 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(socket_lib). + +-export([ + sleep/1, + enc_req_msg/2, enc_rep_msg/2, + enc_msg/3, dec_msg/1, + request/3, reply/4, + f/2, + i/1, i/2, + e/2 + ]). + + +-define(REQ, 0). +-define(REP, 1). + + +%% --- + +sleep(T) -> + receive after T -> ok end. + + +%% --- + +enc_req_msg(N, Data) -> + enc_msg(?REQ, N, Data). + +enc_rep_msg(N, Data) -> + enc_msg(?REP, N, Data). + +enc_msg(Type, N, Data) when is_list(Data) -> + enc_msg(Type, N, list_to_binary(Data)); +enc_msg(Type, N, Data) + when is_integer(Type) andalso is_integer(N) andalso is_binary(Data) -> + <<Type:32/integer, N:32/integer, Data/binary>>. + +dec_msg(<<?REQ:32/integer, N:32/integer, Data/binary>>) -> + {request, N, Data}; +dec_msg(<<?REP:32/integer, N:32/integer, Data/binary>>) -> + {reply, N, Data}. + + +%% --- + +request(Tag, Pid, Request) -> + Ref = make_ref(), + Pid ! {Tag, self(), Ref, Request}, + receive + {Tag, Pid, Ref, Reply} -> + Reply + end. + +reply(Tag, Pid, Ref, Reply) -> + Pid ! {Tag, self(), Ref, Reply}. + + +%% --- + +f(F, A) -> + lists:flatten(io_lib:format(F, A)). + + +%% --- + +e(F, A) -> + p("<ERROR> " ++ F, A). + +i(F) -> + i(F, []). +i(F, A) -> + p("*** " ++ F, A). + +p(F, A) -> + p(get(sname), F, A). + +p(SName, F, A) -> + io:format("[~s,~p][~s] " ++ F ++ "~n", + [SName,self(),formated_timestamp()|A]). + + +%% --- + +formated_timestamp() -> + format_timestamp(os:timestamp()). + +format_timestamp(Now) -> + N2T = fun(N) -> calendar:now_to_local_time(N) end, + format_timestamp(Now, N2T, true). + +format_timestamp({_N1, _N2, N3} = N, N2T, true) -> + FormatExtra = ".~.2.0w", + ArgsExtra = [N3 div 10000], + format_timestamp(N, N2T, FormatExtra, ArgsExtra); +format_timestamp({_N1, _N2, _N3} = N, N2T, false) -> + FormatExtra = "", + ArgsExtra = [], + format_timestamp(N, N2T, FormatExtra, ArgsExtra). + +format_timestamp(N, N2T, FormatExtra, ArgsExtra) -> + {Date, Time} = N2T(N), + {YYYY,MM,DD} = Date, + {Hour,Min,Sec} = Time, + FormatDate = + io_lib:format("~.4w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w" ++ FormatExtra, + [YYYY, MM, DD, Hour, Min, Sec] ++ ArgsExtra), + lists:flatten(FormatDate). + + diff --git a/lib/kernel/test/socket_server.erl b/lib/kernel/test/socket_server.erl index dde605b624..702f040434 100644 --- a/lib/kernel/test/socket_server.erl +++ b/lib/kernel/test/socket_server.erl @@ -1,21 +1,34 @@ -%%%------------------------------------------------------------------- -%%% @author Micael Karlberg <[email protected]> -%%% @copyright (C) 2018, Micael Karlberg -%%% @doc -%%% -%%% @end -%%% Created : 27 Jun 2018 by Micael Karlberg <[email protected]> -%%%------------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2018-2018. 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(socket_server). --export([start/0]). +-export([start/0, + start_tcp/0, + start_udp/0]). --define(REQ, 0). --define(REP, 1). +-define(LIB, socket_lib). --record(manager, {acceptor, handler_id, handlers}). +-record(manager, {acceptor, handler_id, handlers}). -record(acceptor, {socket, manager}). --record(handler, {socket, manager}). +-record(handler, {socket, type, manager}). start() -> start_tcp(). @@ -23,6 +36,9 @@ start() -> start_tcp() -> start(inet, stream, tcp). +start_udp() -> + start(inet, dgram, udp). + start(Domain, Type, Proto) -> put(sname, "starter"), i("try start manager"), @@ -51,13 +67,13 @@ manager_stop(Pid, Reason) -> manager_request(Pid, {stop, Reason}). manager_request(Pid, Request) -> - request(manager, Pid, Request). + ?LIB:request(manager, Pid, Request). manager_reply(Pid, Ref, Reply) -> - reply(manager, Pid, Ref, Reply). + ?LIB:reply(manager, Pid, Ref, Reply). -manager_init(Domain, Type, Proto) -> +manager_init(Domain, stream = Type, Proto) -> put(sname, "manager"), i("try start acceptor"), case acceptor_start(Domain, Type, Proto) of @@ -68,8 +84,44 @@ manager_init(Domain, Type, Proto) -> handlers = []}); {error, Reason} -> exit({failed_starting_acceptor, Reason}) + end; +manager_init(Domain, dgram = Type, Proto) -> + put(sname, "manager"), + i("try open socket"), + case socket:open(Domain, Type, Proto) of + {ok, Sock} -> + Addr = which_addr(Domain), + SA = #{family => Domain, + addr => Addr}, + case socket:bind(Sock, SA) of + {ok, _P} -> + ok; + {error, BReason} -> + throw({bind, BReason}) + end, + i("try start handler for" + "~n ~p", [case socket:sockname(Sock) of + {ok, Name} -> Name; + {error, _} = E -> E + end]), + case handler_start(1, Sock) of + {ok, {Pid, MRef}} -> + i("handler (~p) started", [Pid]), + handler_continue(Pid), + manager_loop(#manager{handler_id = 2, % Just in case + handlers = [{Pid, MRef, 1}]}); + {error, SReason} -> + e("Failed starting handler: " + "~n ~p", [SReason]), + exit({failed_start_handler, SReason}) + end; + {error, OReason} -> + e("Failed open socket: " + "~n ~p", [OReason]), + exit({failed_open_socket, OReason}) end. + manager_loop(M) -> receive {'DOWN', MRef, process, Pid, Reason} -> @@ -262,7 +314,11 @@ acceptor_loop(#acceptor{socket = LSock} = A) -> end. acceptor_handle_accept_success(#acceptor{manager = Manager}, Sock) -> - i("try start handler"), + i("try start handler for peer" + "~n ~p", [case socket:peername(Sock) of + {ok, Peer} -> Peer; + {error, _} = E -> E + end]), case manager_start_handler(Manager, Sock) of {ok, Pid} -> i("handler (~p) started - now change 'ownership'", [Pid]), @@ -309,10 +365,10 @@ handler_continue(Pid) -> handler_request(Pid, continue). handler_request(Pid, Request) -> - request(handler, Pid, Request). + ?LIB:request(handler, Pid, Request). handler_reply(Pid, Ref, Reply) -> - reply(handler, Pid, Ref, Reply). + ?LIB:reply(handler, Pid, Ref, Reply). handler_init(Manager, ID, Sock) -> @@ -321,23 +377,30 @@ handler_init(Manager, ID, Sock) -> Manager ! {handler, self(), ok}, receive {handler, Pid, Ref, continue} -> - i("continue"), + i("got continue"), handler_reply(Pid, Ref, ok), + {ok, Type} = socket:getopt(Sock, socket, type), %% socket:setopt(Socket, otp, debug, true), handler_loop(#handler{manager = Manager, + type = Type, socket = Sock}) end. -handler_loop(#handler{socket = Socket} = H) -> - case socket:recv(Socket) of - {ok, Msg} -> - i("received ~w bytes of data", [size(Msg)]), - case dec_msg(Msg) of +handler_loop(H) -> + i("try read message"), + case recv(H) of + {ok, {Source, Msg}} -> + i("received ~w bytes of data~s", + [size(Msg), case Source of + undefined -> ""; + _ -> f(" from:~n ~p", [Source]) + end]), + case ?LIB:dec_msg(Msg) of {request, N, Req} -> i("received request ~w: " "~n ~p", [N, Req]), - Reply = enc_rep_msg(N, "hoppsan"), - case socket:send(Socket, Reply) of + Reply = ?LIB:enc_rep_msg(N, "hoppsan"), + case send(H, Reply, Source) of ok -> i("successfully sent reply ~w", [N]), handler_loop(H); @@ -360,87 +423,99 @@ handler_loop(#handler{socket = Socket} = H) -> end. +recv(#handler{socket = Sock, type = stream}) -> + case socket:recv(Sock) of + {ok, Msg} -> + {ok, {undefined, Msg}}; + {error, _} = ERROR -> + ERROR + end; +recv(#handler{socket = Sock, type = dgram}) -> + %% ok = socket:setopt(Sock, otp, debug, true), + socket:recvfrom(Sock). + + +send(#handler{socket = Sock, type = stream}, Msg, _) -> + socket:send(Sock, Msg); +send(#handler{socket = Sock, type = dgram}, Msg, Dest) -> + socket:sendto(Sock, Msg, Dest). + + %% ========================================================================= -enc_req_msg(N, Data) -> - enc_msg(?REQ, N, Data). +%% enc_req_msg(N, Data) -> +%% enc_msg(?REQ, N, Data). -enc_rep_msg(N, Data) -> - enc_msg(?REP, N, Data). +%% enc_rep_msg(N, Data) -> +%% enc_msg(?REP, N, Data). -enc_msg(Type, N, Data) when is_list(Data) -> - enc_msg(Type, N, list_to_binary(Data)); -enc_msg(Type, N, Data) - when is_integer(Type) andalso is_integer(N) andalso is_binary(Data) -> - <<Type:32/integer, N:32/integer, Data/binary>>. +%% enc_msg(Type, N, Data) when is_list(Data) -> +%% enc_msg(Type, N, list_to_binary(Data)); +%% enc_msg(Type, N, Data) +%% when is_integer(Type) andalso is_integer(N) andalso is_binary(Data) -> +%% <<Type:32/integer, N:32/integer, Data/binary>>. -dec_msg(<<?REQ:32/integer, N:32/integer, Data/binary>>) -> - {request, N, Data}; -dec_msg(<<?REP:32/integer, N:32/integer, Data/binary>>) -> - {reply, N, Data}. +%% dec_msg(<<?REQ:32/integer, N:32/integer, Data/binary>>) -> +%% {request, N, Data}; +%% dec_msg(<<?REP:32/integer, N:32/integer, Data/binary>>) -> +%% {reply, N, Data}. %% --- -request(Tag, Pid, Request) -> - Ref = make_ref(), - Pid ! {Tag, self(), Ref, Request}, - receive - {Tag, Pid, Ref, Reply} -> - Reply - end. +%% request(Tag, Pid, Request) -> +%% Ref = make_ref(), +%% Pid ! {Tag, self(), Ref, Request}, +%% receive +%% {Tag, Pid, Ref, Reply} -> +%% Reply +%% end. -reply(Tag, Pid, Ref, Reply) -> - Pid ! {Tag, self(), Ref, Reply}. +%% reply(Tag, Pid, Ref, Reply) -> +%% Pid ! {Tag, self(), Ref, Reply}. %% --- -formated_timestamp() -> - format_timestamp(os:timestamp()). +%% formated_timestamp() -> +%% format_timestamp(os:timestamp()). -format_timestamp(Now) -> - N2T = fun(N) -> calendar:now_to_local_time(N) end, - format_timestamp(Now, N2T, true). +%% format_timestamp(Now) -> +%% N2T = fun(N) -> calendar:now_to_local_time(N) end, +%% format_timestamp(Now, N2T, true). -format_timestamp({_N1, _N2, N3} = N, N2T, true) -> - FormatExtra = ".~.2.0w", - ArgsExtra = [N3 div 10000], - format_timestamp(N, N2T, FormatExtra, ArgsExtra); -format_timestamp({_N1, _N2, _N3} = N, N2T, false) -> - FormatExtra = "", - ArgsExtra = [], - format_timestamp(N, N2T, FormatExtra, ArgsExtra). +%% format_timestamp({_N1, _N2, N3} = N, N2T, true) -> +%% FormatExtra = ".~.2.0w", +%% ArgsExtra = [N3 div 10000], +%% format_timestamp(N, N2T, FormatExtra, ArgsExtra); +%% format_timestamp({_N1, _N2, _N3} = N, N2T, false) -> +%% FormatExtra = "", +%% ArgsExtra = [], +%% format_timestamp(N, N2T, FormatExtra, ArgsExtra). -format_timestamp(N, N2T, FormatExtra, ArgsExtra) -> - {Date, Time} = N2T(N), - {YYYY,MM,DD} = Date, - {Hour,Min,Sec} = Time, - FormatDate = - io_lib:format("~.4w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w" ++ FormatExtra, - [YYYY, MM, DD, Hour, Min, Sec] ++ ArgsExtra), - lists:flatten(FormatDate). +%% format_timestamp(N, N2T, FormatExtra, ArgsExtra) -> +%% {Date, Time} = N2T(N), +%% {YYYY,MM,DD} = Date, +%% {Hour,Min,Sec} = Time, +%% FormatDate = +%% io_lib:format("~.4w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w" ++ FormatExtra, +%% [YYYY, MM, DD, Hour, Min, Sec] ++ ArgsExtra), +%% lists:flatten(FormatDate). %% --- f(F, A) -> - lists:flatten(io_lib:format(F, A)). + ?LIB:f(F, A). e(F, A) -> - p("<ERROR> " ++ F, A). + ?LIB:e(F, A). i(F) -> - i(F, []). -i(F, A) -> - p("*** " ++ F, A). + ?LIB:i(F). -p(F, A) -> - p(get(sname), F, A). +i(F, A) -> + ?LIB:i(F, A). -p(SName, F, A) -> - io:format("[~s,~p][~s] " ++ F ++ "~n", - [SName,self(),formated_timestamp()|A]). - |