Blame


1 4b33cdd0 2015-11-30 stephen.d package p9p
2 4b33cdd0 2015-11-30 stephen.d
3 529e2b2e 2016-11-14 noreply import "context"
4 4b33cdd0 2015-11-30 stephen.d
5 4b33cdd0 2015-11-30 stephen.d // Handler defines an interface for 9p message handlers. A handler
6 4b33cdd0 2015-11-30 stephen.d // implementation could be used to intercept calls of all types before sending
7 4b33cdd0 2015-11-30 stephen.d // them to the next handler.
8 4b33cdd0 2015-11-30 stephen.d type Handler interface {
9 4b33cdd0 2015-11-30 stephen.d Handle(ctx context.Context, msg Message) (Message, error)
10 4b33cdd0 2015-11-30 stephen.d
11 4b33cdd0 2015-11-30 stephen.d // TODO(stevvooe): Right now, this interface is functianally identical to
12 4b33cdd0 2015-11-30 stephen.d // roundtripper. If we find that this is sufficient on the server-side, we
13 4b33cdd0 2015-11-30 stephen.d // may unify the types. For now, we leave them separated to differentiate
14 4b33cdd0 2015-11-30 stephen.d // between them.
15 4b33cdd0 2015-11-30 stephen.d }
16 4b33cdd0 2015-11-30 stephen.d
17 4b33cdd0 2015-11-30 stephen.d // HandlerFunc is a convenience type for defining inline handlers.
18 4b33cdd0 2015-11-30 stephen.d type HandlerFunc func(ctx context.Context, msg Message) (Message, error)
19 4b33cdd0 2015-11-30 stephen.d
20 a0568195 2016-05-23 stevvooe // Handle implements the requirements for the Handler interface.
21 4b33cdd0 2015-11-30 stephen.d func (fn HandlerFunc) Handle(ctx context.Context, msg Message) (Message, error) {
22 4b33cdd0 2015-11-30 stephen.d return fn(ctx, msg)
23 4b33cdd0 2015-11-30 stephen.d }
24 4b33cdd0 2015-11-30 stephen.d
25 4b33cdd0 2015-11-30 stephen.d // Dispatch returns a handler that dispatches messages to the target session.
26 4b33cdd0 2015-11-30 stephen.d // No concurrency is managed by the returned handler. It simply turns messages
27 4b33cdd0 2015-11-30 stephen.d // into function calls on the session.
28 4b33cdd0 2015-11-30 stephen.d func Dispatch(session Session) Handler {
29 4b33cdd0 2015-11-30 stephen.d return HandlerFunc(func(ctx context.Context, msg Message) (Message, error) {
30 4b33cdd0 2015-11-30 stephen.d switch msg := msg.(type) {
31 4b33cdd0 2015-11-30 stephen.d case MessageTauth:
32 4b33cdd0 2015-11-30 stephen.d qid, err := session.Auth(ctx, msg.Afid, msg.Uname, msg.Aname)
33 4b33cdd0 2015-11-30 stephen.d if err != nil {
34 4b33cdd0 2015-11-30 stephen.d return nil, err
35 4b33cdd0 2015-11-30 stephen.d }
36 4b33cdd0 2015-11-30 stephen.d
37 4b33cdd0 2015-11-30 stephen.d return MessageRauth{Qid: qid}, nil
38 4b33cdd0 2015-11-30 stephen.d case MessageTattach:
39 4b33cdd0 2015-11-30 stephen.d qid, err := session.Attach(ctx, msg.Fid, msg.Afid, msg.Uname, msg.Aname)
40 4b33cdd0 2015-11-30 stephen.d if err != nil {
41 4b33cdd0 2015-11-30 stephen.d return nil, err
42 4b33cdd0 2015-11-30 stephen.d }
43 4b33cdd0 2015-11-30 stephen.d
44 4b33cdd0 2015-11-30 stephen.d return MessageRattach{
45 4b33cdd0 2015-11-30 stephen.d Qid: qid,
46 4b33cdd0 2015-11-30 stephen.d }, nil
47 4b33cdd0 2015-11-30 stephen.d case MessageTwalk:
48 4b33cdd0 2015-11-30 stephen.d // TODO(stevvooe): This is one of the places where we need to manage
49 4b33cdd0 2015-11-30 stephen.d // fid allocation lifecycle. We need to reserve the fid, then, if this
50 4b33cdd0 2015-11-30 stephen.d // call succeeds, we should alloc the fid for future uses. Also need
51 4b33cdd0 2015-11-30 stephen.d // to interact correctly with concurrent clunk and the flush of this
52 4b33cdd0 2015-11-30 stephen.d // walk message.
53 4b33cdd0 2015-11-30 stephen.d qids, err := session.Walk(ctx, msg.Fid, msg.Newfid, msg.Wnames...)
54 4b33cdd0 2015-11-30 stephen.d if err != nil {
55 4b33cdd0 2015-11-30 stephen.d return nil, err
56 4b33cdd0 2015-11-30 stephen.d }
57 4b33cdd0 2015-11-30 stephen.d
58 4b33cdd0 2015-11-30 stephen.d return MessageRwalk{
59 4b33cdd0 2015-11-30 stephen.d Qids: qids,
60 4b33cdd0 2015-11-30 stephen.d }, nil
61 4b33cdd0 2015-11-30 stephen.d case MessageTopen:
62 4b33cdd0 2015-11-30 stephen.d qid, iounit, err := session.Open(ctx, msg.Fid, msg.Mode)
63 4b33cdd0 2015-11-30 stephen.d if err != nil {
64 4b33cdd0 2015-11-30 stephen.d return nil, err
65 4b33cdd0 2015-11-30 stephen.d }
66 4b33cdd0 2015-11-30 stephen.d
67 4b33cdd0 2015-11-30 stephen.d return MessageRopen{
68 4b33cdd0 2015-11-30 stephen.d Qid: qid,
69 4b33cdd0 2015-11-30 stephen.d IOUnit: iounit,
70 4b33cdd0 2015-11-30 stephen.d }, nil
71 4b33cdd0 2015-11-30 stephen.d case MessageTcreate:
72 4b33cdd0 2015-11-30 stephen.d qid, iounit, err := session.Create(ctx, msg.Fid, msg.Name, msg.Perm, msg.Mode)
73 4b33cdd0 2015-11-30 stephen.d if err != nil {
74 4b33cdd0 2015-11-30 stephen.d return nil, err
75 4b33cdd0 2015-11-30 stephen.d }
76 4b33cdd0 2015-11-30 stephen.d
77 4b33cdd0 2015-11-30 stephen.d return MessageRcreate{
78 4b33cdd0 2015-11-30 stephen.d Qid: qid,
79 4b33cdd0 2015-11-30 stephen.d IOUnit: iounit,
80 4b33cdd0 2015-11-30 stephen.d }, nil
81 4b33cdd0 2015-11-30 stephen.d case MessageTread:
82 4b33cdd0 2015-11-30 stephen.d p := make([]byte, int(msg.Count))
83 4b33cdd0 2015-11-30 stephen.d n, err := session.Read(ctx, msg.Fid, p, int64(msg.Offset))
84 4b33cdd0 2015-11-30 stephen.d if err != nil {
85 4b33cdd0 2015-11-30 stephen.d return nil, err
86 4b33cdd0 2015-11-30 stephen.d }
87 4b33cdd0 2015-11-30 stephen.d
88 4b33cdd0 2015-11-30 stephen.d return MessageRread{
89 4b33cdd0 2015-11-30 stephen.d Data: p[:n],
90 4b33cdd0 2015-11-30 stephen.d }, nil
91 4b33cdd0 2015-11-30 stephen.d case MessageTwrite:
92 4b33cdd0 2015-11-30 stephen.d n, err := session.Write(ctx, msg.Fid, msg.Data, int64(msg.Offset))
93 4b33cdd0 2015-11-30 stephen.d if err != nil {
94 4b33cdd0 2015-11-30 stephen.d return nil, err
95 4b33cdd0 2015-11-30 stephen.d }
96 4b33cdd0 2015-11-30 stephen.d
97 4b33cdd0 2015-11-30 stephen.d return MessageRwrite{
98 4b33cdd0 2015-11-30 stephen.d Count: uint32(n),
99 4b33cdd0 2015-11-30 stephen.d }, nil
100 4b33cdd0 2015-11-30 stephen.d case MessageTclunk:
101 4b33cdd0 2015-11-30 stephen.d // TODO(stevvooe): Manage the clunking of file descriptors based on
102 4b33cdd0 2015-11-30 stephen.d // walk and attach call progression.
103 4b33cdd0 2015-11-30 stephen.d if err := session.Clunk(ctx, msg.Fid); err != nil {
104 4b33cdd0 2015-11-30 stephen.d return nil, err
105 4b33cdd0 2015-11-30 stephen.d }
106 4b33cdd0 2015-11-30 stephen.d
107 4b33cdd0 2015-11-30 stephen.d return MessageRclunk{}, nil
108 4b33cdd0 2015-11-30 stephen.d case MessageTremove:
109 4b33cdd0 2015-11-30 stephen.d if err := session.Remove(ctx, msg.Fid); err != nil {
110 4b33cdd0 2015-11-30 stephen.d return nil, err
111 4b33cdd0 2015-11-30 stephen.d }
112 4b33cdd0 2015-11-30 stephen.d
113 4b33cdd0 2015-11-30 stephen.d return MessageRremove{}, nil
114 4b33cdd0 2015-11-30 stephen.d case MessageTstat:
115 4b33cdd0 2015-11-30 stephen.d dir, err := session.Stat(ctx, msg.Fid)
116 4b33cdd0 2015-11-30 stephen.d if err != nil {
117 4b33cdd0 2015-11-30 stephen.d return nil, err
118 4b33cdd0 2015-11-30 stephen.d }
119 4b33cdd0 2015-11-30 stephen.d
120 4b33cdd0 2015-11-30 stephen.d return MessageRstat{
121 4b33cdd0 2015-11-30 stephen.d Stat: dir,
122 4b33cdd0 2015-11-30 stephen.d }, nil
123 4b33cdd0 2015-11-30 stephen.d case MessageTwstat:
124 4b33cdd0 2015-11-30 stephen.d if err := session.WStat(ctx, msg.Fid, msg.Stat); err != nil {
125 4b33cdd0 2015-11-30 stephen.d return nil, err
126 4b33cdd0 2015-11-30 stephen.d }
127 4b33cdd0 2015-11-30 stephen.d
128 4b33cdd0 2015-11-30 stephen.d return MessageRwstat{}, nil
129 4b33cdd0 2015-11-30 stephen.d default:
130 4b33cdd0 2015-11-30 stephen.d return nil, ErrUnknownMsg
131 4b33cdd0 2015-11-30 stephen.d }
132 4b33cdd0 2015-11-30 stephen.d })
133 4b33cdd0 2015-11-30 stephen.d }