Pure Erlang implementation of 9p2000 protocol
filesystem fs 9p2000 erlang 9p

Use record for storing state of the server

hauleth.dev d81e5d5c 4ad25702

verified
+32 -15
+32 -15
src/e9p_server.erl
··· 11 11 -export([start_link/2, 12 12 setup_acceptor/3, 13 13 accept_loop/2, 14 - loop/3 14 + loop/1 15 15 ]). 16 16 17 + -record(state, { 18 + socket, 19 + % trans_mod = gen_tcp, 20 + % ver, 21 + fids = #{}, 22 + handler 23 + }). 24 + 25 + -record(fid, {qid, path, state}). 26 + 17 27 start_link(Port, Handler) -> 18 28 proc_lib:start_link(?MODULE, setup_acceptor, [self(), Port, Handler]). 19 29 20 30 setup_acceptor(Parent, Port, Handler0) -> 21 - {ok, LSock} = gen_tcp:listen(Port, [binary, {active, false}]), 22 - {ok, Handler} = e9p_fs:init(Handler0), 31 + maybe 32 + {ok, LSock} ?= gen_tcp:listen(Port, [binary, {active, false}]), 33 + {ok, Handler} ?= e9p_fs:init(Handler0), 23 34 24 - proc_lib:init_ack(Parent, {ok, self()}), 35 + proc_lib:init_ack(Parent, {ok, self()}), 25 36 26 - ?MODULE:accept_loop(LSock, Handler). 37 + ?MODULE:accept_loop(LSock, Handler) 38 + else 39 + {error, _} = Error -> 40 + proc_lib:init_fail(Parent, Error) 41 + end. 27 42 28 43 accept_loop(LSock, Handler) -> 29 44 case gen_tcp:accept(LSock, 5000) of 30 45 {ok, Sock} -> 31 46 % TODO: Handle connected clients in separate process 32 - ok = ?MODULE:loop(Sock, #{}, Handler), 47 + 48 + State = #state{ 49 + socket = Sock, 50 + handler = Handler 51 + }, 52 + ok = ?MODULE:loop(State), 33 53 ?MODULE:accept_loop(LSock, Handler); 34 54 {error, timeout} -> 35 55 ?MODULE:accept_loop(LSock, Handler); ··· 37 57 ok 38 58 end. 39 59 40 - loop(Sock, FIDs, Handler) -> 60 + loop(#state{socket = Sock} = State) -> 41 61 case e9p_transport:read(Sock) of 42 62 {ok, Tag, Data} -> 43 63 ?LOG_DEBUG(#{msg => Data}), 44 - try handle_message(Data, FIDs, Handler) of 45 - {ok, Reply, RFIDs, RHandler} -> 64 + try handle_message(Data, State#state.fids, State#state.handler) of 65 + {ok, Reply, FIDs, Handler} -> 46 66 e9p_transport:send(Sock, Tag, Reply), 47 - ?MODULE:loop(Sock, RFIDs, RHandler); 67 + ?MODULE:loop(State#state{fids = FIDs, handler = Handler}); 48 68 {error, Err, RHandler} -> 49 - e9p_transport:send(Sock, Tag, error_msg(Err)), 50 - ?MODULE:loop(Sock, FIDs, RHandler) 69 + e9p_transport:send(Sock, Tag, #rerror{msg = Err}), 70 + ?MODULE:loop(State#state{handler = RHandler}) 51 71 catch 52 72 C:E:S -> 53 73 e9p_transport:send(Sock, Tag, #rerror{msg = io_lib:format("Caught ~p: ~p", [C, E])}), ··· 145 165 #{FID := QID} -> {ok, QID}; 146 166 _ -> {error, io_lib:fwrite(~"Unknown FID: ~B", [FID])} 147 167 end. 148 - 149 - error_msg(Data) -> 150 - #rerror{msg = io_lib:fwrite(~"~p", [Data])}.