-module(p11p_server_sup). -behaviour(supervisor). -export([start_link/0, start_server/1]). -export([init/1, cleanup/0]). start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []). init([]) -> ok = start_servers(p11p_config:nameof(p11p_config:tokens())), {ok, {{simple_one_for_one, 1, 5}, [{sock_server, {p11p_server, start_link, []}, temporary, 1000, worker, [p11p_server]} ]}}. start_server(Args) -> {ok, Pid} = supervisor:start_child(?MODULE, [Args]), Pid. cleanup() -> cleanup(p11p_config:nameof(p11p_config:tokens())). %% Private functions. start_servers([]) -> ok; start_servers([Name|T]) -> Path = socket_path(mkdir_socket_basepath(), Name), file:delete(Path), % TODO: consider flow control through {active, once}, don't forget activating after read! {ok, Socket} = gen_tcp:listen(0, [{ifaddr, {local, Path}}, binary]), spawn_link(?MODULE, start_server, [[Name, Path, Socket]]), start_servers(T). cleanup([]) -> ok; cleanup([Token|Tail]) -> file:delete(socket_path(mkdir_socket_basepath(), Token)), cleanup(Tail). mkdir_socket_basepath() -> %%"/run/user/$UNIXUID/p11p/$TokenCfg-$UNIXPID" EUID = "1000", % FIXME: get euid Path = "/run/user/" ++ EUID ++ "/p11p/", ok = case file:make_dir(Path) of ok -> ok; {error, eexist} -> ok; Err -> lager:error("~s: unable to create directory: ~p", [Path, Err]), err end, Path. -spec socket_path(string(), string()) -> string(). socket_path(BasePath, Name) -> BasePath ++ Name ++ "-" ++ os:getpid().