commit 96ad2b22c286a0147125e76a113442a1121d7d0d from: Stephen J Day date: Wed Oct 28 22:41:07 2015 UTC fs/p9p/new: add server stubs and various implementation notes Signed-off-by: Stephen J Day commit - c979b5e1f8a799f06a75c3affd19126f5d57d020 commit + 96ad2b22c286a0147125e76a113442a1121d7d0d blob - c33ca277646297a1dd3badf83aca03b187eb9c7a blob + 45ec913cb709375259ca68b89724efe2da533146 --- encoding.go +++ encoding.go @@ -4,9 +4,25 @@ import ( "encoding/binary" "fmt" "io" + "log" "reflect" "time" ) + +// EncodeDir is just a helper for encoding directories until we export the +// encoder and decoder. +func EncodeDir(wr io.Writer, d *Dir) error { + enc := &encoder{wr} + + return enc.encode(d) +} + +// DecodeDir is just a helper for decoding directories until we export the +// encoder and decoder. +func DecodeDir(rd io.Reader, d *Dir) error { + dec := &decoder{rd} + return dec.decode(d) +} // NOTE(stevvooe): This file covers 9p encoding and decoding (despite just // being called encoding). @@ -58,6 +74,11 @@ func (e *encoder) encode(vs ...interface{}) error { return err } case Message, *Qid, *Dir: + // BUG(stevvooe): The encoding for Dir is incorrect. Under certain + // cases, we need to include size field and in other cases, such + // as Twstat, we need the size twice. See bugs in + // http://man.cat-v.org/plan_9/5/stat to make sense of this. + elements, err := fields9p(v) if err != nil { return err @@ -129,6 +150,7 @@ func (d *decoder) decode(vs ...interface{}) error { n, err := io.ReadFull(d.rd, b) if err != nil { + log.Println("readfull failed:", err) return err } blob - 9a676b70dc7a2076e7b7b306bda3332a1794a936 blob + 1467c5bfd69e08e5dabbf2b195dd87d531b47ee3 --- encoding_test.go +++ encoding_test.go @@ -129,6 +129,7 @@ func TestEncodeDecode(t *testing.T) { marshaled: []byte{ 0x47, 0x0, 0x0, 0x0, 0x7d, 0xb4, 0x15, + // 0x40, 0x0, // TODO(stevvooe): Include Dir size. Not straightforward. 0xff, 0xff, // type 0xff, 0xff, 0xff, 0xff, // dev 0x80, 0xff, 0xff, 0xff, 0xff, // qid.type, qid.version blob - 1074f83dc94bc6e9447cf920226f37465cd3d61c blob + 19ec9f4039516b5fcebf2abc647d96a425cc374f --- server.go +++ server.go @@ -1,8 +1,54 @@ +// +build ignore + package p9pnew -import "net" +import ( + "log" + "net" + "time" + "golang.org/x/net/context" +) + // Serve the 9p session over the provided network connection. -func Serve(conn net.Conn, session Session) error { +func Serve(ctx context.Context, conn net.Conn, session Session) error { panic("not implemented") } + +type server struct { + ctx context.Context + session Session + conn net.Conn +} + +func (s *server) run() { + dec := decoder{s.conn} + + fcall := new(Fcall) + if err := dec.decode(fcall); err != nil { + log.Println(err) + } + +} + +// handle responds to an fcall using the session. An error is only returned if +// the handler cannot proceed. All session errors are returned as Rerror. +func (s *server) handle(f *Fcall) (*Fcall, error) { + const timeout = 30 * time.Second // TODO(stevvooe): Allow this to be configured. + ctx, cancel = context.WithTimeout(s.ctx, timeout) + defer cancel() + + switch fcall.Type { + case Tattach: + atc, ok := fcall.Message.(*MessageTattach) + if ok { + log.Println("bad message") + continue + } + + qid, err := s.session.Attach(s.ctx, atc.Fid, atc.Afid, atc.Uname, atc.Aname) + if err != nil { + return + } + } +}