Pure Erlang implementation of 9p2000 protocol
filesystem
fs
9p2000
erlang
9p
1% SPDX-FileCopyrightText: 2025 Łukasz Niemier <~@hauleth.dev>
2%
3% SPDX-License-Identifier: Apache-2.0
4
5-module(e9p_transport).
6
7-include("e9p_internal.hrl").
8
9% -include_lib("kernel/include/logger.hrl").
10
11-export([send/3, read/1, read_stream/1]).
12
13send(Socket, Tag, Message) ->
14 Encoded = e9p_msg:encode(Tag, Message),
15 Size = iolist_size(Encoded) + 4,
16 gen_tcp:send(Socket, [<<Size:4/?int>>, Encoded]).
17
18read(Socket) ->
19 maybe
20 {ok, <<Size:4/?int>>} ?= gen_tcp:recv(Socket, 4),
21 {ok, Data} ?= gen_tcp:recv(Socket, Size - 4),
22 true = is_binary(Data),
23 {ok, Tag, Msg} ?= e9p_msg:parse(Data),
24 {ok, Tag, Msg}
25 else
26 {error, _} = Error -> Error
27 end.
28
29read_stream(<<Size:4/?int, Data:(Size - 4)/binary, Rest/binary>> = Input) ->
30 case e9p_msg:parse(Data) of
31 {ok, Tag, Msg} ->
32 {ok, Tag, Msg, Rest};
33 {error, Error} ->
34 {error, Error, Input}
35 end;
36read_stream(Input) ->
37 {more, Input}.