7 "golang.org/x/net/context"
16 transport roundTripper
19 // NewSession returns a session using the connection. The Context ctx provides
20 // a context for out of bad messages, such as flushes, that may be sent by the
21 // session. The session can effectively shutdown with this context.
22 func NewSession(ctx context.Context, conn net.Conn) (Session, error) {
23 const msize = 64 << 10
26 ch := newChannel(conn, codec9p{}, msize) // sets msize, effectively.
28 // negotiate the protocol version
29 _, err := clientnegotiate(ctx, ch, vers)
38 transport: newTransport(ctx, ch),
42 var _ Session = &client{}
44 func (c *client) Version() (uint32, string) {
45 return c.msize, c.version
48 func (c *client) Auth(ctx context.Context, afid Fid, uname, aname string) (Qid, error) {
49 panic("not implemented")
52 func (c *client) Attach(ctx context.Context, fid, afid Fid, uname, aname string) (Qid, error) {
53 log.Println("client attach", fid, aname)
56 Message: &MessageTattach{
64 resp, err := c.transport.send(ctx, fcall)
69 mrr, ok := resp.Message.(*MessageRattach)
71 return Qid{}, fmt.Errorf("invalid rpc response for attach message: %v", resp)
77 func (c *client) Clunk(ctx context.Context, fid Fid) error {
78 fcall := newFcall(&MessageTclunk{
82 resp, err := c.transport.send(ctx, fcall)
87 if resp.Type != Rclunk {
88 return fmt.Errorf("incorrect response type: %v", resp)
94 func (c *client) Remove(ctx context.Context, fid Fid) error {
95 panic("not implemented")
98 func (c *client) Walk(ctx context.Context, fid Fid, newfid Fid, names ...string) ([]Qid, error) {
100 return nil, fmt.Errorf("too many elements in wname")
105 Message: &MessageTwalk{
112 resp, err := c.transport.send(ctx, fcall)
117 mrr, ok := resp.Message.(*MessageRwalk)
119 return nil, fmt.Errorf("invalid rpc response for walk message: %v", resp)
125 func (c *client) Read(ctx context.Context, fid Fid, p []byte, offset int64) (n int, err error) {
126 // TODO(stevvooe): Split up reads into multiple messages based on iounit.
127 // For now, we just support full blast. I mean, why not?
130 Message: &MessageTread{
132 Offset: uint64(offset),
133 Count: uint32(len(p)),
137 resp, err := c.transport.send(ctx, fcall)
142 mrr, ok := resp.Message.(*MessageRread)
144 return 0, fmt.Errorf("invalid rpc response for read message: %v", resp)
147 return copy(p, mrr.Data), nil
150 func (c *client) Write(ctx context.Context, fid Fid, p []byte, offset int64) (n int, err error) {
151 // TODO(stevvooe): Split up writes into multiple messages based on iounit.
152 // For now, we just support full blast. I mean, why not?
155 Message: &MessageTwrite{
157 Offset: uint64(offset),
162 resp, err := c.transport.send(ctx, fcall)
167 mrr, ok := resp.Message.(*MessageRwrite)
169 return 0, fmt.Errorf("invalid rpc response for write message: %v", resp)
172 return int(mrr.Count), nil
175 func (c *client) Open(ctx context.Context, fid Fid, mode uint8) (Qid, uint32, error) {
176 fcall := newFcall(&MessageTopen{
181 resp, err := c.transport.send(ctx, fcall)
186 respmsg, ok := resp.Message.(*MessageRopen)
188 return Qid{}, 0, fmt.Errorf("invalid rpc response for open message: %v", resp)
191 return respmsg.Qid, respmsg.IOUnit, nil
194 func (c *client) Create(ctx context.Context, parent Fid, name string, perm uint32, mode uint32) (Qid, uint32, error) {
195 panic("not implemented")
198 func (c *client) Stat(ctx context.Context, fid Fid) (Dir, error) {
199 fcall := newFcall(MessageTstat{Fid: fid})
201 resp, err := c.transport.send(ctx, fcall)
206 respmsg, ok := resp.Message.(*MessageRstat)
208 return Dir{}, fmt.Errorf("invalid rpc response for stat message: %v", resp)
211 return respmsg.Stat, nil
214 func (c *client) WStat(context.Context, Fid, Dir) error {
215 panic("not implemented")
218 func (c *client) flush(ctx context.Context, tag Tag) error {
219 // TODO(stevvooe): We need to fire and forget flush messages when a call
220 // context gets cancelled.
222 panic("not implemented")