1 8a7ec697 2015-10-26 adrien package p9pnew
7 8a7ec697 2015-10-26 adrien "golang.org/x/net/context"
12 8a7ec697 2015-10-26 adrien type client struct {
13 fb37ce2a 2015-10-30 stephen.d version string
14 fb37ce2a 2015-10-30 stephen.d msize uint32
15 e6bcde66 2015-10-29 stephen.d ctx context.Context
16 e6bcde66 2015-10-29 stephen.d transport roundTripper
19 5f1e8105 2015-10-28 stephen.d // NewSession returns a session using the connection. The Context ctx provides
20 5f1e8105 2015-10-28 stephen.d // a context for out of bad messages, such as flushes, that may be sent by the
21 5f1e8105 2015-10-28 stephen.d // session. The session can effectively shutdown with this context.
22 5f1e8105 2015-10-28 stephen.d func NewSession(ctx context.Context, conn net.Conn) (Session, error) {
23 fb37ce2a 2015-10-30 stephen.d const msize = 64 << 10
24 fb37ce2a 2015-10-30 stephen.d const vers = "9P2000"
26 fb37ce2a 2015-10-30 stephen.d ch := newChannel(conn, codec9p{}, msize) // sets msize, effectively.
28 fb37ce2a 2015-10-30 stephen.d // negotiate the protocol version
29 3bf22e58 2015-11-04 stephen.d _, err := clientnegotiate(ctx, ch, vers)
30 fb37ce2a 2015-10-30 stephen.d if err != nil {
31 fb37ce2a 2015-10-30 stephen.d return nil, err
34 8a7ec697 2015-10-26 adrien return &client{
35 fb37ce2a 2015-10-30 stephen.d version: vers,
36 fb37ce2a 2015-10-30 stephen.d msize: msize,
37 e6bcde66 2015-10-29 stephen.d ctx: ctx,
38 fb37ce2a 2015-10-30 stephen.d transport: newTransport(ctx, ch),
42 8a7ec697 2015-10-26 adrien var _ Session = &client{}
44 fb37ce2a 2015-10-30 stephen.d func (c *client) Version() (uint32, string) {
45 fb37ce2a 2015-10-30 stephen.d return c.msize, c.version
48 8a7ec697 2015-10-26 adrien func (c *client) Auth(ctx context.Context, afid Fid, uname, aname string) (Qid, error) {
49 8a7ec697 2015-10-26 adrien panic("not implemented")
52 8a7ec697 2015-10-26 adrien func (c *client) Attach(ctx context.Context, fid, afid Fid, uname, aname string) (Qid, error) {
53 e6bcde66 2015-10-29 stephen.d log.Println("client attach", fid, aname)
54 5f1e8105 2015-10-28 stephen.d fcall := &Fcall{
55 5f1e8105 2015-10-28 stephen.d Type: Tattach,
56 5f1e8105 2015-10-28 stephen.d Message: &MessageTattach{
57 5f1e8105 2015-10-28 stephen.d Fid: fid,
58 5f1e8105 2015-10-28 stephen.d Afid: afid,
59 5f1e8105 2015-10-28 stephen.d Uname: uname,
60 5f1e8105 2015-10-28 stephen.d Aname: aname,
64 e6bcde66 2015-10-29 stephen.d resp, err := c.transport.send(ctx, fcall)
65 5f1e8105 2015-10-28 stephen.d if err != nil {
66 5f1e8105 2015-10-28 stephen.d return Qid{}, err
69 5f1e8105 2015-10-28 stephen.d mrr, ok := resp.Message.(*MessageRattach)
70 5f1e8105 2015-10-28 stephen.d if !ok {
71 5f1e8105 2015-10-28 stephen.d return Qid{}, fmt.Errorf("invalid rpc response for attach message: %v", resp)
74 5f1e8105 2015-10-28 stephen.d return mrr.Qid, nil
77 8a7ec697 2015-10-26 adrien func (c *client) Clunk(ctx context.Context, fid Fid) error {
78 e6bcde66 2015-10-29 stephen.d fcall := newFcall(&MessageTclunk{
79 e6bcde66 2015-10-29 stephen.d Fid: fid,
82 e6bcde66 2015-10-29 stephen.d resp, err := c.transport.send(ctx, fcall)
83 e6bcde66 2015-10-29 stephen.d if err != nil {
84 e6bcde66 2015-10-29 stephen.d return err
87 e6bcde66 2015-10-29 stephen.d if resp.Type != Rclunk {
88 e6bcde66 2015-10-29 stephen.d return fmt.Errorf("incorrect response type: %v", resp)
91 e6bcde66 2015-10-29 stephen.d return nil
94 8a7ec697 2015-10-26 adrien func (c *client) Remove(ctx context.Context, fid Fid) error {
95 8a7ec697 2015-10-26 adrien panic("not implemented")
98 8a7ec697 2015-10-26 adrien func (c *client) Walk(ctx context.Context, fid Fid, newfid Fid, names ...string) ([]Qid, error) {
99 5f1e8105 2015-10-28 stephen.d if len(names) > 16 {
100 e6bcde66 2015-10-29 stephen.d return nil, fmt.Errorf("too many elements in wname")
103 5f1e8105 2015-10-28 stephen.d fcall := &Fcall{
104 5f1e8105 2015-10-28 stephen.d Type: Twalk,
105 5f1e8105 2015-10-28 stephen.d Message: &MessageTwalk{
106 5f1e8105 2015-10-28 stephen.d Fid: fid,
107 5f1e8105 2015-10-28 stephen.d Newfid: newfid,
108 e6bcde66 2015-10-29 stephen.d Wnames: names,
112 e6bcde66 2015-10-29 stephen.d resp, err := c.transport.send(ctx, fcall)
113 5f1e8105 2015-10-28 stephen.d if err != nil {
114 5f1e8105 2015-10-28 stephen.d return nil, err
117 5f1e8105 2015-10-28 stephen.d mrr, ok := resp.Message.(*MessageRwalk)
118 5f1e8105 2015-10-28 stephen.d if !ok {
119 5f1e8105 2015-10-28 stephen.d return nil, fmt.Errorf("invalid rpc response for walk message: %v", resp)
122 5f1e8105 2015-10-28 stephen.d return mrr.Qids, nil
125 8a7ec697 2015-10-26 adrien func (c *client) Read(ctx context.Context, fid Fid, p []byte, offset int64) (n int, err error) {
126 5f1e8105 2015-10-28 stephen.d // TODO(stevvooe): Split up reads into multiple messages based on iounit.
127 5f1e8105 2015-10-28 stephen.d // For now, we just support full blast. I mean, why not?
128 5f1e8105 2015-10-28 stephen.d fcall := &Fcall{
129 5f1e8105 2015-10-28 stephen.d Type: Tread,
130 5f1e8105 2015-10-28 stephen.d Message: &MessageTread{
131 5f1e8105 2015-10-28 stephen.d Fid: fid,
132 5f1e8105 2015-10-28 stephen.d Offset: uint64(offset),
133 5f1e8105 2015-10-28 stephen.d Count: uint32(len(p)),
137 e6bcde66 2015-10-29 stephen.d resp, err := c.transport.send(ctx, fcall)
138 5f1e8105 2015-10-28 stephen.d if err != nil {
139 5f1e8105 2015-10-28 stephen.d return 0, err
142 5f1e8105 2015-10-28 stephen.d mrr, ok := resp.Message.(*MessageRread)
143 5f1e8105 2015-10-28 stephen.d if !ok {
144 5f1e8105 2015-10-28 stephen.d return 0, fmt.Errorf("invalid rpc response for read message: %v", resp)
147 5f1e8105 2015-10-28 stephen.d return copy(p, mrr.Data), nil
150 8a7ec697 2015-10-26 adrien func (c *client) Write(ctx context.Context, fid Fid, p []byte, offset int64) (n int, err error) {
151 5f1e8105 2015-10-28 stephen.d // TODO(stevvooe): Split up writes into multiple messages based on iounit.
152 5f1e8105 2015-10-28 stephen.d // For now, we just support full blast. I mean, why not?
153 5f1e8105 2015-10-28 stephen.d fcall := &Fcall{
154 5f1e8105 2015-10-28 stephen.d Type: Twrite,
155 5f1e8105 2015-10-28 stephen.d Message: &MessageTwrite{
156 5f1e8105 2015-10-28 stephen.d Fid: fid,
157 5f1e8105 2015-10-28 stephen.d Offset: uint64(offset),
158 5f1e8105 2015-10-28 stephen.d Data: p,
162 e6bcde66 2015-10-29 stephen.d resp, err := c.transport.send(ctx, fcall)
163 5f1e8105 2015-10-28 stephen.d if err != nil {
164 5f1e8105 2015-10-28 stephen.d return 0, err
167 97423e8b 2015-10-29 stephen.d mrr, ok := resp.Message.(*MessageRwrite)
168 5f1e8105 2015-10-28 stephen.d if !ok {
169 e6bcde66 2015-10-29 stephen.d return 0, fmt.Errorf("invalid rpc response for write message: %v", resp)
172 5f1e8105 2015-10-28 stephen.d return int(mrr.Count), nil
175 e6bcde66 2015-10-29 stephen.d func (c *client) Open(ctx context.Context, fid Fid, mode uint8) (Qid, uint32, error) {
176 e6bcde66 2015-10-29 stephen.d fcall := newFcall(&MessageTopen{
177 e6bcde66 2015-10-29 stephen.d Fid: fid,
178 e6bcde66 2015-10-29 stephen.d Mode: mode,
181 e6bcde66 2015-10-29 stephen.d resp, err := c.transport.send(ctx, fcall)
182 e6bcde66 2015-10-29 stephen.d if err != nil {
183 e6bcde66 2015-10-29 stephen.d return Qid{}, 0, err
186 97423e8b 2015-10-29 stephen.d respmsg, ok := resp.Message.(*MessageRopen)
187 e6bcde66 2015-10-29 stephen.d if !ok {
188 e6bcde66 2015-10-29 stephen.d return Qid{}, 0, fmt.Errorf("invalid rpc response for open message: %v", resp)
191 fb37ce2a 2015-10-30 stephen.d return respmsg.Qid, respmsg.IOUnit, nil
194 fb37ce2a 2015-10-30 stephen.d func (c *client) Create(ctx context.Context, parent Fid, name string, perm uint32, mode uint32) (Qid, uint32, error) {
195 8a7ec697 2015-10-26 adrien panic("not implemented")
198 74ec7ac9 2015-10-30 stephen.d func (c *client) Stat(ctx context.Context, fid Fid) (Dir, error) {
199 74ec7ac9 2015-10-30 stephen.d fcall := newFcall(MessageTstat{Fid: fid})
201 74ec7ac9 2015-10-30 stephen.d resp, err := c.transport.send(ctx, fcall)
202 74ec7ac9 2015-10-30 stephen.d if err != nil {
203 74ec7ac9 2015-10-30 stephen.d return Dir{}, err
206 74ec7ac9 2015-10-30 stephen.d respmsg, ok := resp.Message.(*MessageRstat)
207 74ec7ac9 2015-10-30 stephen.d if !ok {
208 74ec7ac9 2015-10-30 stephen.d return Dir{}, fmt.Errorf("invalid rpc response for stat message: %v", resp)
211 74ec7ac9 2015-10-30 stephen.d return respmsg.Stat, nil
214 8a7ec697 2015-10-26 adrien func (c *client) WStat(context.Context, Fid, Dir) error {
215 8a7ec697 2015-10-26 adrien panic("not implemented")
218 fb37ce2a 2015-10-30 stephen.d func (c *client) flush(ctx context.Context, tag Tag) error {
219 fb37ce2a 2015-10-30 stephen.d // TODO(stevvooe): We need to fire and forget flush messages when a call
220 fb37ce2a 2015-10-30 stephen.d // context gets cancelled.
222 fb37ce2a 2015-10-30 stephen.d panic("not implemented")