summaryrefslogtreecommitdiff
path: root/p11p-daemon/src/p11p_server.erl
diff options
context:
space:
mode:
authorLinus Nordberg <linus@sunet.se>2019-06-24 16:04:53 +0200
committerLinus Nordberg <linus@sunet.se>2019-06-24 16:04:53 +0200
commit5ce12907073082be03c25707e2d6fc0703db9f1f (patch)
treef4990c0d09688d06b68fb947c1e9148b38ae1735 /p11p-daemon/src/p11p_server.erl
parent6e90bceab4a3a6e4b9d4496b810324867d533ce1 (diff)
start one sock_server per token; give servers a chance to clean up
still not rm'ing the socket file though. wonder where that should happen.
Diffstat (limited to 'p11p-daemon/src/p11p_server.erl')
-rw-r--r--p11p-daemon/src/p11p_server.erl62
1 files changed, 44 insertions, 18 deletions
diff --git a/p11p-daemon/src/p11p_server.erl b/p11p-daemon/src/p11p_server.erl
index 726e97b..c2422dc 100644
--- a/p11p-daemon/src/p11p_server.erl
+++ b/p11p-daemon/src/p11p_server.erl
@@ -1,7 +1,5 @@
%% Create an AF_UNIX socket and accept connections. On connect, spawn
-%% a p11p_server process.
-
-%% FIXME: Run _one_ socket per instance of this server!
+%% another p11p_server process.
-module(p11p_server).
-behaviour(gen_server).
@@ -15,41 +13,69 @@
%% Records and types.
-include("p11p_defs.hrl").
--record(state, {socket :: gen_tcp:socket()}).
+-record(state, {
+ sockpath :: string(), % FIXME: filename(3erl)
+ socket :: gen_tcp:socket()
+ }).
%% API.
-spec start_link(gen_tcp:socket()) -> {ok, pid()} | {error, term()}.
-start_link(Socket) ->
- gen_server:start_link(?MODULE, Socket, []).
+start_link(Args) ->
+ lager:debug("~p: p11p_server:start_link enter", [self()]),
+ gen_server:start_link(?MODULE, Args, []).
%% Genserver callbacks.
-init(Socket) ->
+init([SocketPath, Socket]) ->
+ lager:debug("~p: p11p_server:init: ~s", [self(), SocketPath]),
+ process_flag(trap_exit, true), % We want terminate().
gen_server:cast(self(), accept), % Perform accept in gen-server loop.
- {ok, #state{socket = Socket}}.
+ {ok, #state{sockpath = SocketPath, socket = Socket}}.
handle_call(Request, _From, State) ->
lager:debug("Unhandled call: ~p~n", [Request]),
{reply, unhandled, State}.
-handle_cast(accept, State = #state{socket = ListenSocket}) ->
- {ok, Sock} = gen_tcp:accept(ListenSocket),
- %% TODO: authz
- lager:debug("new connection accepted: ~p", [Sock]),
- p11p_server_sup:start_server(), % New acceptor.
- {noreply, State#state{socket = Sock}};
+handle_cast(accept, State = #state{sockpath = SocketPath, socket = ListenSocket}) ->
+ %% Blocking until client connects or timeout fires. Without a
+ %% timeout our supervisor cannot terminate us.
+ case gen_tcp:accept(ListenSocket, 900) of
+ {ok, Sock} ->
+ %% TODO: authz
+ lager:debug("~p: ~p: new connection accepted", [self(), Sock]),
+ p11p_server_sup:start_server([SocketPath, ListenSocket]), % Start a new acceptor.
+ {noreply, State#state{socket = Sock}}; % Use the new socket.
+ {error, timeout} ->
+ gen_server:cast(self(), accept), % Try again.
+ {noreply, State};
+ {error, closed} ->
+ lager:debug("~p: listening socket closed", [self()]),
+ {stop, normal, State}
+ end;
handle_cast(Request, State) ->
lager:debug("Unhandled cast: ~p~n", [Request]),
{noreply, State}.
-handle_info({tcp, _Socket, Data}, State) ->
+handle_info({tcp, Port, Data}, State) ->
lager:debug("~p: received: ~s", [self(), Data]),
- {noreply, State};
+ case Data of
+ <<"q\n">> ->
+ gen_tcp:send(Port, "ok, bye\n"), %DEBUG
+ {stop, {shutdown, quit_by_client}, State};
+ _ ->
+ gen_tcp:send(Port, "ok, thanks: " ++ Data), %DEBUG
+ {noreply, State}
+ end;
+handle_info({tcp_closed, Port}, State) ->
+ lager:debug("~p: ~p: closed", [self(), Port]),
+ {stop, {shutdown, close_by_client}, State};
handle_info(Info, State) ->
lager:debug("Unhandled info: ~p~n", [Info]),
{noreply, State}.
-terminate(_Reason, #state{socket = Socket}) ->
- gen_tcp:close(Socket), % FIXME: correct?
+terminate(_Reason, #state{sockpath = _SocketPath, socket = Socket}) ->
+ lager:debug("~p: ~p: terminated", [self(), Socket]),
+ gen_tcp:close(Socket),
+ %%FIXME: clean up socket file where? file:delete(SocketPath),
ok.
code_change(_OldVersion, State, _Extra) ->