Ejemplo n.º 1
0
func (fid *Fid) Stat() (*plan9.Dir, error) {
	checkSeq(nil, fid)
	tx := &plan9.Fcall{Type: plan9.Tstat, Fid: fid.fid}
	rx, err := fid.c.rpc(tx)
	if err != nil {
		return nil, err
	}
	return plan9.UnmarshalDir(rx.Stat)
}
Ejemplo n.º 2
0
func (sq *seq9p) fcall2result(rxc <-chan *plan9.Fcall, resultc chan<- seq.Result) {
	defer func() {
		sq.replyEOF = true
		sq.putfids()
		close(resultc)
		sq.c.w.Unlock()
	}()
	for {
		rx := <-rxc
		sq.c.w.Lock()
		if rx == nil {
			sq.err = sq.c.getErr()
			return
		}
		rq := sq.q.Get()
		if rx.Type != rq.tx.Type+1 && rx.Type != plan9.Rerror {
			// TODO what do we do here
			panic(fmt.Sprintf("mismatched replies; sent %v; got %v", rq.tx, rx))
		}
		var result seq.Result
		switch rx.Type {
		case plan9.Rbegin:
		case plan9.Rend:
			return
		case plan9.Rerror:
			switch op := rq.op.(type) {
			case seq.CloneReq:
				newfid := (*Fid)(op.F.(*file9p))
				newfid.flags &^= fPending
				newfid.seq = nil
				sq.putfid(newfid)
				newfid.Close()
			}
			sq.err = errors.New(rx.Ename)
			return
		case plan9.Rwalk:
			switch len(rx.Wqid) {
			case 0:
				nfid := (*Fid)(rq.op.(seq.CloneReq).F.(*file9p))
				nfid.qid = rq.fid.qid
				nfid.mode = rq.fid.mode
				nfid.flags |= fAlloc
				nfid.flags &^= fPending
				nfid.offset = rq.fid.offset
				result = seq.CloneResult{}
			case 1:
				rq.fid.qid = rx.Wqid[0]
				result = seq.WalkResult{rx.Wqid[0]}
			default:
				panic("unexpected Rwalk qid count")
			}
		case plan9.Ropen:
			rq.fid.mode = rq.op.(seq.OpenReq).Mode
			rq.fid.flags |= fOpen
			rq.fid.qid = rx.Qid
			result = seq.OpenResult{rx.Qid}
		case plan9.Rnonseq:
			sq.putfid(rq.fid)
			result = seq.NonseqResult{}
		case plan9.Rcreate:
			rq.fid.mode = rq.op.(seq.CreateReq).Mode
			rq.fid.flags |= fOpen
			rq.fid.qid = rx.Qid
			result = seq.CreateResult{rx.Qid}
		case plan9.Rwrite:
			result = seq.WriteResult{int(rx.Count)} // TODO: check overflow?
		case plan9.Rread:
			data := rq.op.(seq.ReadReq).Data
			copy(data, rx.Data)
			result = seq.ReadResult{len(rx.Data)}
		case plan9.Rstat:
			d, err := plan9.UnmarshalDir(rx.Stat)
			if err != nil {
				// TODO try to recover here
				panic("bad dir structure from server")
			}
			result = seq.StatResult{*d}
		case plan9.Rwstat:
			result = seq.WstatResult{}
		case plan9.Rremove:
			rq.fid.flags &^= fAlloc
			sq.putfid(rq.fid)
			rq.fid.Close()
			result = seq.RemoveResult{}
		case plan9.Rclunk:
			rq.fid.flags &^= fAlloc
			sq.putfid(rq.fid)
			rq.fid.Close()
			result = seq.ClunkResult{}
		default:
			// TODO ensure sanity checked before it gets here.
			panic(fmt.Sprintf("unexpected rmessage: %v", rx))
		}
		//log.Printf("fcall2result %#v (rq %#v)\n", result, rq)
		sq.c.w.Unlock()
		if result != nil {
			resultc <- result
		}
	}

}