commit b1dc634e18ea7d53f3aa47c15ce925a4464296c3
parent c2354fbcab452d3371d2679e272e721ae1bdc2a8
Author: Matsuda Kenji <info@mtkn.jp>
Date: Sat, 28 Oct 2023 07:17:53 +0900
export fields of Req
Diffstat:
| M | req.go | | | 20 | ++++++++++---------- |
| M | server.go | | | 222 | ++++++++++++++++++++++++++++++++++++++++---------------------------------------- |
| M | server_test.go | | | 21 | ++++++++++++--------- |
| D | test_fs.go | | | 197 | ------------------------------------------------------------------------------- |
4 files changed, 133 insertions(+), 327 deletions(-)
diff --git a/req.go b/req.go
@@ -7,23 +7,23 @@ import (
// Req represents each requests.
type Req struct {
- tag uint16
- srv *Server
- ifcall Msg
- ofcall Msg
- fid *Fid
- afid *Fid
- oldReq *Req
+ Tag uint16
+ Srv *Server
+ Ifcall Msg
+ Ofcall Msg
+ Fid *Fid
+ Afid *Fid
+ Oldreq *Req
pool *ReqPool
- cancel context.CancelFunc
+ Cancel context.CancelFunc
}
// flush cancels the Req by calling r.cancel.
func (r *Req) flush() {
// TODO: need mutex?
// BUG: cancel() can be nil.
- r.cancel()
- r.pool.delete(r.tag)
+ r.Cancel()
+ r.pool.delete(r.Tag)
}
// ReqPool is the pool of Reqs the server is dealing with.
diff --git a/server.go b/server.go
@@ -23,7 +23,7 @@ var (
)
func setError(r *Req, err error) {
- r.ofcall = &RError{
+ r.Ofcall = &RError{
Ename: err,
}
}
@@ -137,7 +137,7 @@ func (s *Server) runSpeaker(w io.Writer) (chan<- *Req, <-chan error) {
defer close(ec)
for {
r := <-rc
- _, err := w.Write(r.ofcall.marshal())
+ _, err := w.Write(r.Ofcall.marshal())
if err != nil {
ec <- err
}
@@ -161,21 +161,21 @@ func getReq(r io.Reader, s *Server) (*Req, error) {
if err != nil {
// duplicate tag: cons up a fake Req
req := new(Req)
- req.srv = s
- req.ifcall = ifcall
+ req.Srv = s
+ req.Ifcall = ifcall
if s.chatty9P {
- fmt.Fprintf(os.Stderr, "<-- %v\n", req.ifcall)
+ fmt.Fprintf(os.Stderr, "<-- %v\n", req.Ifcall)
}
return req, ErrDupTag
}
- req.srv = s
- req.tag = ifcall.GetTag()
- req.ifcall = ifcall
- if ifcall, ok := req.ifcall.(*TFlush); ok {
- req.oldReq, _ = req.srv.rPool.lookup(ifcall.Oldtag)
+ req.Srv = s
+ req.Tag = ifcall.GetTag()
+ req.Ifcall = ifcall
+ if ifcall, ok := req.Ifcall.(*TFlush); ok {
+ req.Oldreq, _ = req.Srv.rPool.lookup(ifcall.Oldtag)
}
if s.chatty9P {
- fmt.Fprintf(os.Stderr, "<-- %v\n", req.ifcall)
+ fmt.Fprintf(os.Stderr, "<-- %v\n", req.Ifcall)
}
return req, nil
}
@@ -189,7 +189,7 @@ func getReq(r io.Reader, s *Server) (*Req, error) {
// TODO: abort all outstanding I/O on the same connection before
// serving new Tversion.
func sVersion(ctx context.Context, s *Server, r *Req) {
- ifcall := r.ifcall.(*TVersion)
+ ifcall := r.Ifcall.(*TVersion)
version := ifcall.Version
if ok := strings.HasPrefix(version, "9P2000"); !ok {
version = "unknown"
@@ -200,7 +200,7 @@ func sVersion(ctx context.Context, s *Server, r *Req) {
if msize > s.mSize() {
msize = s.mSize()
}
- r.ofcall = &RVersion{
+ r.Ofcall = &RVersion{
Msize: msize,
Version: version,
}
@@ -213,14 +213,14 @@ func rVersion(r *Req, err error) {
if err != nil {
panic(fmt.Errorf("rVersion err: %w", err))
}
- r.srv.setMSize(r.ofcall.(*RVersion).Msize)
+ r.Srv.setMSize(r.Ofcall.(*RVersion).Msize)
}
// sAuth serves Tauth message.
func sAuth(ctx context.Context, s *Server, r *Req) {
- ifcall := r.ifcall.(*TAuth)
+ ifcall := r.Ifcall.(*TAuth)
var err error
- r.afid, err = s.fPool.add(ifcall.Afid)
+ r.Afid, err = s.fPool.add(ifcall.Afid)
if err != nil {
respond(ctx, r, ErrDupFid)
}
@@ -236,13 +236,13 @@ func sAuth(ctx context.Context, s *Server, r *Req) {
// allocated fid from fPool.
func rAuth(r *Req, err error) {
if err != nil {
- r.srv.fPool.delete(r.ifcall.(*TAuth).Afid)
+ r.Srv.fPool.delete(r.Ifcall.(*TAuth).Afid)
setError(r, err)
}
}
func sAttach(ctx context.Context, s *Server, r *Req) {
- ifcall := r.ifcall.(*TAttach)
+ ifcall := r.Ifcall.(*TAttach)
fid, err := s.fPool.add(ifcall.Fid)
if err != nil {
respond(ctx, r, ErrDupFid)
@@ -284,7 +284,7 @@ func sAttach(ctx context.Context, s *Server, r *Req) {
respond(ctx, r, fmt.Errorf("stat root: %v", err))
return
}
- r.ofcall = &RAttach{
+ r.Ofcall = &RAttach{
Qid: st.Sys().(*Stat).Qid,
}
respond(ctx, r, nil)
@@ -292,7 +292,7 @@ func sAttach(ctx context.Context, s *Server, r *Req) {
func rAttach(r *Req, err error) {
if err != nil {
- r.srv.fPool.delete(r.ifcall.(*TAttach).Fid)
+ r.Srv.fPool.delete(r.Ifcall.(*TAttach).Fid)
setError(r, err)
}
}
@@ -305,14 +305,14 @@ func rFlush(r *Req, err error) {
if err != nil {
panic(fmt.Errorf("err in flush: %v", err))
}
- if r.oldReq != nil {
- r.oldReq.flush()
+ if r.Oldreq != nil {
+ r.Oldreq.flush()
}
- r.ofcall = &RFlush{}
+ r.Ofcall = &RFlush{}
}
func sWalk(ctx context.Context, s *Server, r *Req) {
- ifcall := r.ifcall.(*TWalk)
+ ifcall := r.Ifcall.(*TWalk)
oldFid, ok := s.fPool.lookup(ifcall.Fid)
if !ok {
respond(ctx, r, ErrUnknownFid)
@@ -366,18 +366,18 @@ func sWalk(ctx context.Context, s *Server, r *Req) {
newFid.File = cwdf
newFid.Uid = oldFid.Uid
newFid.path = cwdp
- r.ofcall = &RWalk{
+ r.Ofcall = &RWalk{
Qids: wqids[:n],
}
respond(ctx, r, nil)
}
func rWalk(r *Req, err error) {
- ifcall := r.ifcall.(*TWalk)
- ofcall := r.ofcall.(*RWalk)
+ ifcall := r.Ifcall.(*TWalk)
+ ofcall := r.Ofcall.(*RWalk)
if err != nil || len(ofcall.Qids) < len(ifcall.Wnames) {
if ifcall.Fid != ifcall.Newfid {
- r.srv.fPool.delete(ifcall.Newfid)
+ r.Srv.fPool.delete(ifcall.Newfid)
}
if len(ofcall.Qids) == 0 {
if err == nil && len(ifcall.Wnames) != 0 {
@@ -389,14 +389,14 @@ func rWalk(r *Req, err error) {
}
func sOpen(ctx context.Context, s *Server, r *Req) {
- ifcall := r.ifcall.(*TOpen)
+ ifcall := r.Ifcall.(*TOpen)
var ok bool
- r.fid, ok = s.fPool.lookup(ifcall.Fid)
+ r.Fid, ok = s.fPool.lookup(ifcall.Fid)
if !ok {
respond(ctx, r, ErrUnknownFid)
return
}
- if r.fid.OMode != -1 {
+ if r.Fid.OMode != -1 {
respond(ctx, r, ErrBotch)
return
}
@@ -404,7 +404,7 @@ func sOpen(ctx context.Context, s *Server, r *Req) {
// See open(5).
// In plan9 implementation, ifcall.Mode() is ANDed with ^ORCLOSE,
// but ORCLOSE is also prohibitted by the protocol...
- st, err := r.fid.File.Stat()
+ st, err := r.Fid.File.Stat()
if err != nil {
respond(ctx, r, fmt.Errorf("stat: %v", err))
return
@@ -434,24 +434,24 @@ func sOpen(ctx context.Context, s *Server, r *Req) {
respond(ctx, r, ErrPerm)
return
}
- if !hasPerm(r.fid.File, r.fid.Uid, p) {
+ if !hasPerm(r.Fid.File, r.Fid.Uid, p) {
respond(ctx, r, ErrPerm)
return
}
if ifcall.Mode&ORCLOSE != 0 {
- parentPath := path.Dir(r.fid.path)
+ parentPath := path.Dir(r.Fid.path)
parent, err := s.fs.OpenFile(parentPath, OREAD, 0)
defer parent.Close()
if err != nil {
respond(ctx, r, fmt.Errorf("open parent"))
return
}
- if !hasPerm(parent, r.fid.Uid, AWRITE) {
+ if !hasPerm(parent, r.Fid.Uid, AWRITE) {
respond(ctx, r, ErrPerm)
return
}
}
- r.ofcall = &ROpen{
+ r.Ofcall = &ROpen{
Qid: qid,
Iounit: s.mSize() - IOHDRSZ,
}
@@ -463,24 +463,24 @@ func rOpen(r *Req, err error) {
setError(r, err)
return
}
- r.fid.OMode = r.ifcall.(*TOpen).Mode
- f, err := r.srv.fs.OpenFile(r.fid.path, r.fid.OMode, 0)
+ r.Fid.OMode = r.Ifcall.(*TOpen).Mode
+ f, err := r.Srv.fs.OpenFile(r.Fid.path, r.Fid.OMode, 0)
if err != nil {
setError(r, err)
return
}
- r.fid.File = f
+ r.Fid.File = f
}
func sCreate(ctx context.Context, s *Server, r *Req) {
- ifcall := r.ifcall.(*TCreate)
+ ifcall := r.Ifcall.(*TCreate)
var ok bool
- r.fid, ok = s.fPool.lookup(ifcall.Fid)
+ r.Fid, ok = s.fPool.lookup(ifcall.Fid)
if !ok {
respond(ctx, r, ErrUnknownFid)
return
}
- dir := r.fid.File
+ dir := r.Fid.File
dirstat, err := dir.Stat()
if err != nil {
respond(ctx, r, fmt.Errorf("stat: %v", err))
@@ -490,11 +490,11 @@ func sCreate(ctx context.Context, s *Server, r *Req) {
respond(ctx, r, fmt.Errorf("create in non-dir"))
return
}
- if !hasPerm(dir, r.fid.Uid, AWRITE) {
+ if !hasPerm(dir, r.Fid.Uid, AWRITE) {
respond(ctx, r, ErrPerm)
return
}
- cfdir, ok := r.fid.File.(CreaterFile)
+ cfdir, ok := r.Fid.File.(CreaterFile)
if !ok {
respond(ctx, r, ErrOperation)
return
@@ -506,23 +506,23 @@ func sCreate(ctx context.Context, s *Server, r *Req) {
} else {
perm &= ^FileMode(0777) | (dirperm & FileMode(0777))
}
- file, err := cfdir.Create(ifcall.Name, r.fid.Uid, ifcall.Mode, perm)
+ file, err := cfdir.Create(ifcall.Name, r.Fid.Uid, ifcall.Mode, perm)
if err != nil {
respond(ctx, r, fmt.Errorf("create: %v", err))
return
}
- if err := r.fid.File.Close(); err != nil {
+ if err := r.Fid.File.Close(); err != nil {
respond(ctx, r, fmt.Errorf("close: %v", err))
return
}
- r.fid.File = file
- r.fid.path = path.Join(r.fid.path, ifcall.Name)
- st, err := r.fid.File.Stat()
+ r.Fid.File = file
+ r.Fid.path = path.Join(r.Fid.path, ifcall.Name)
+ st, err := r.Fid.File.Stat()
if err != nil {
respond(ctx, r, fmt.Errorf("stat: %v", err))
return
}
- r.ofcall = &RCreate{
+ r.Ofcall = &RCreate{
Qid: st.Sys().(*Stat).Qid,
Iounit: s.mSize() - IOHDRSZ,
}
@@ -533,29 +533,29 @@ func rCreate(r *Req, err error) {
setError(r, err)
return
}
- r.fid.OMode = r.ifcall.(*TCreate).Mode
+ r.Fid.OMode = r.Ifcall.(*TCreate).Mode
// TODO: pass OCREATE with non 0 perm.
- f, err := r.srv.fs.OpenFile(r.fid.path, r.fid.OMode, 0)
+ f, err := r.Srv.fs.OpenFile(r.Fid.path, r.Fid.OMode, 0)
if err != nil {
setError(r, err)
return
}
- r.fid.File = f
+ r.Fid.File = f
}
func sRead(ctx context.Context, s *Server, r *Req) {
- ifcall := r.ifcall.(*TRead)
+ ifcall := r.Ifcall.(*TRead)
var ok bool
- r.fid, ok = s.fPool.lookup(ifcall.Fid)
+ r.Fid, ok = s.fPool.lookup(ifcall.Fid)
if !ok {
respond(ctx, r, ErrUnknownFid)
return
}
- if r.fid.OMode == -1 {
+ if r.Fid.OMode == -1 {
respond(ctx, r, fmt.Errorf("not open"))
return
}
- if r.fid.OMode != OREAD && r.fid.OMode != ORDWR && r.fid.OMode != OEXEC {
+ if r.Fid.OMode != OREAD && r.Fid.OMode != ORDWR && r.Fid.OMode != OEXEC {
respond(ctx, r, ErrPerm)
return
}
@@ -566,7 +566,7 @@ func sRead(ctx context.Context, s *Server, r *Req) {
err error
wg sync.WaitGroup
)
- fi, err := r.fid.File.Stat()
+ fi, err := r.Fid.File.Stat()
if err != nil {
log.Printf("Stat: %v", err)
respond(ctx, r, fmt.Errorf("internal error"))
@@ -580,20 +580,20 @@ func sRead(ctx context.Context, s *Server, r *Req) {
}()
defer wg.Done()
if fi.IsDir() {
- children, err := getChildren(s.fs, r.fid.path)
+ children, err := getChildren(s.fs, r.Fid.path)
if err != nil {
log.Printf("get children: %v", err)
}
- if ifcall.Offset != 0 && ifcall.Offset != r.fid.dirOffset {
+ if ifcall.Offset != 0 && ifcall.Offset != r.Fid.dirOffset {
respond(ctx, r, fmt.Errorf("invalid dir offset"))
return
}
if ifcall.Offset == 0 {
- r.fid.dirIndex = 0
- r.fid.dirOffset = 0
+ r.Fid.dirIndex = 0
+ r.Fid.dirOffset = 0
}
- k := r.fid.dirIndex
+ k := r.Fid.dirIndex
for ; k < len(children); k++ {
if children[k] == nil {
continue
@@ -613,13 +613,13 @@ func sRead(ctx context.Context, s *Server, r *Req) {
}
n += len(buf)
}
- r.fid.dirOffset += uint64(n)
- r.fid.dirIndex = k
+ r.Fid.dirOffset += uint64(n)
+ r.Fid.dirIndex = k
} else {
- if reader, ok := r.fid.File.(io.ReaderAt); ok {
+ if reader, ok := r.Fid.File.(io.ReaderAt); ok {
n, err = reader.ReadAt(data, int64(ifcall.Offset))
} else {
- n, err = r.fid.File.Read(data)
+ n, err = r.Fid.File.Read(data)
}
if err != io.EOF && err != nil {
log.Printf("sRead: %v\n", err)
@@ -632,7 +632,7 @@ func sRead(ctx context.Context, s *Server, r *Req) {
case <-done:
case <-ctx.Done():
}
- r.ofcall = &RRead{
+ r.Ofcall = &RRead{
Count: uint32(n),
Data: data[:n],
}
@@ -645,9 +645,9 @@ func rRead(r *Req, err error) {
}
func sWrite(ctx context.Context, s *Server, r *Req) {
- ifcall := r.ifcall.(*TWrite)
+ ifcall := r.Ifcall.(*TWrite)
var ok bool
- r.fid, ok = s.fPool.lookup(ifcall.Fid)
+ r.Fid, ok = s.fPool.lookup(ifcall.Fid)
if !ok {
respond(ctx, r, ErrUnknownFid)
return
@@ -655,13 +655,13 @@ func sWrite(ctx context.Context, s *Server, r *Req) {
if ifcall.Count > s.mSize()-IOHDRSZ {
ifcall.Count = s.mSize() - IOHDRSZ
}
- if !hasPerm(r.fid.File, r.fid.Uid, AWRITE) {
+ if !hasPerm(r.Fid.File, r.Fid.Uid, AWRITE) {
respond(ctx, r, ErrPerm)
return
}
- omode := r.fid.OMode & 3
+ omode := r.Fid.OMode & 3
if omode != OWRITE && omode != ORDWR {
- respond(ctx, r, fmt.Errorf("write on fid with open mode 0x%x", r.fid.OMode))
+ respond(ctx, r, fmt.Errorf("write on fid with open mode 0x%x", r.Fid.OMode))
return
}
ofcall := new(RWrite)
@@ -673,7 +673,7 @@ func sWrite(ctx context.Context, s *Server, r *Req) {
wg.Wait()
close(done)
}()
- switch file := r.fid.File.(type) {
+ switch file := r.Fid.File.(type) {
case io.WriterAt:
n, err := file.WriteAt(ifcall.Data, int64(ifcall.Offset))
if err != nil {
@@ -698,7 +698,7 @@ func sWrite(ctx context.Context, s *Server, r *Req) {
case <-done:
case <-ctx.Done():
}
- r.ofcall = ofcall
+ r.Ofcall = ofcall
respond(ctx, r, nil)
}
@@ -711,14 +711,14 @@ func rWrite(r *Req, err error) {
}
func sClunk(ctx context.Context, s *Server, r *Req) {
- ifcall := r.ifcall.(*TClunk)
+ ifcall := r.Ifcall.(*TClunk)
_, ok := s.fPool.lookup(ifcall.Fid)
if !ok {
respond(ctx, r, ErrUnknownFid)
return
}
s.fPool.delete(ifcall.Fid)
- r.ofcall = &RClunk{}
+ r.Ofcall = &RClunk{}
respond(ctx, r, nil)
}
@@ -729,26 +729,26 @@ func rClunk(r *Req, err error) {
}
func sRemove(ctx context.Context, s *Server, r *Req) {
- ifcall := r.ifcall.(*TRemove)
+ ifcall := r.Ifcall.(*TRemove)
var ok bool
- r.fid, ok = s.fPool.lookup(ifcall.Fid)
+ r.Fid, ok = s.fPool.lookup(ifcall.Fid)
if !ok {
respond(ctx, r, ErrUnknownFid)
return
}
defer s.fPool.delete(ifcall.Fid)
- parentPath := path.Dir(r.fid.path)
+ parentPath := path.Dir(r.Fid.path)
parent, err := s.fs.OpenFile(parentPath, OREAD, 0)
if err != nil {
respond(ctx, r, fmt.Errorf("open parent: %v", err))
return
}
defer parent.Close()
- if !hasPerm(parent, r.fid.Uid, AWRITE) {
+ if !hasPerm(parent, r.Fid.Uid, AWRITE) {
respond(ctx, r, ErrPerm)
return
}
- rfile, ok := r.fid.File.(RemoverFile)
+ rfile, ok := r.Fid.File.(RemoverFile)
if !ok {
respond(ctx, r, ErrOperation)
return
@@ -757,7 +757,7 @@ func sRemove(ctx context.Context, s *Server, r *Req) {
respond(ctx, r, fmt.Errorf("remove: %v", err))
return
}
- r.ofcall = &RRemove{}
+ r.Ofcall = &RRemove{}
respond(ctx, r, nil)
}
func rRemove(r *Req, err error) {
@@ -767,20 +767,20 @@ func rRemove(r *Req, err error) {
}
func sStat(ctx context.Context, s *Server, r *Req) {
- ifcall := r.ifcall.(*TStat)
+ ifcall := r.Ifcall.(*TStat)
var ok bool
- r.fid, ok = s.fPool.lookup(ifcall.Fid)
+ r.Fid, ok = s.fPool.lookup(ifcall.Fid)
if !ok {
respond(ctx, r, ErrUnknownFid)
return
}
- fileInfo, err := r.fid.File.Stat()
+ fileInfo, err := r.Fid.File.Stat()
if err != nil {
- log.Printf("stat %v: %v", r.fid.File, err)
+ log.Printf("stat %v: %v", r.Fid.File, err)
respond(ctx, r, fmt.Errorf("internal error"))
return
}
- r.ofcall = &RStat{
+ r.Ofcall = &RStat{
Stat: fileInfo.Sys().(*Stat),
}
respond(ctx, r, nil)
@@ -793,20 +793,20 @@ func rStat(r *Req, err error) {
}
func sWStat(ctx context.Context, s *Server, r *Req) {
- ifcall := r.ifcall.(*TWStat)
+ ifcall := r.Ifcall.(*TWStat)
var ok bool
- r.fid, ok = s.fPool.lookup(ifcall.Fid)
+ r.Fid, ok = s.fPool.lookup(ifcall.Fid)
if !ok {
respond(ctx, r, ErrUnknownFid)
return
}
- wsfile, ok := r.fid.File.(WriterStatFile)
+ wsfile, ok := r.Fid.File.(WriterStatFile)
if !ok {
respond(ctx, r, ErrOperation)
return
}
wstat := ifcall.Stat
- fi, err := r.fid.File.Stat()
+ fi, err := r.Fid.File.Stat()
if err != nil {
respond(ctx, r, fmt.Errorf("stat: %v", err))
return
@@ -820,13 +820,13 @@ func sWStat(ctx context.Context, s *Server, r *Req) {
return
}
if wstat.Name != "" {
- parentPath := path.Dir(r.fid.path)
+ parentPath := path.Dir(r.Fid.path)
parent, err := s.fs.OpenFile(parentPath, OREAD, 0)
if err != nil {
respond(ctx, r, fmt.Errorf("get parent: %v", err))
return
}
- if !hasPerm(parent, r.fid.Uid, AWRITE) {
+ if !hasPerm(parent, r.Fid.Uid, AWRITE) {
respond(ctx, r, ErrPerm)
return
}
@@ -849,7 +849,7 @@ func sWStat(ctx context.Context, s *Server, r *Req) {
newStat.Name = wstat.Name
}
if wstat.Length != ^int64(0) {
- if fi.IsDir() || !hasPerm(r.fid.File, r.fid.Uid, AWRITE) {
+ if fi.IsDir() || !hasPerm(r.Fid.File, r.Fid.Uid, AWRITE) {
respond(ctx, r, ErrPerm)
return
}
@@ -857,7 +857,7 @@ func sWStat(ctx context.Context, s *Server, r *Req) {
}
if wstat.Mode != FileMode(^uint32(0)) {
// the owner of the file or the group leader of the file's group.
- if r.fid.Uid != newStat.Uid && r.fid.Uid != newStat.Gid {
+ if r.Fid.Uid != newStat.Uid && r.Fid.Uid != newStat.Gid {
respond(ctx, r, ErrPerm)
return
}
@@ -869,7 +869,7 @@ func sWStat(ctx context.Context, s *Server, r *Req) {
}
if wstat.Mtime != ^uint32(0) {
// the owner of the file or the group leader of the file's group.
- if r.fid.Uid != newStat.Uid && r.fid.Uid != newStat.Gid {
+ if r.Fid.Uid != newStat.Uid && r.Fid.Uid != newStat.Gid {
respond(ctx, r, ErrPerm)
return
}
@@ -885,7 +885,7 @@ func sWStat(ctx context.Context, s *Server, r *Req) {
respond(ctx, r, fmt.Errorf("wstat: %v", err))
return
}
- r.ofcall = &RWStat{}
+ r.Ofcall = &RWStat{}
respond(ctx, r, nil)
}
@@ -912,11 +912,11 @@ L:
continue L
case r := <-s.listenChan:
ctx1, cancel := context.WithCancel(ctx)
- r.cancel = cancel
+ r.Cancel = cancel
go func() {
- switch r.ifcall.(type) {
+ switch r.Ifcall.(type) {
default:
- respond(ctx1, r, fmt.Errorf("unknown message type: %d", r.ifcall.Type()))
+ respond(ctx1, r, fmt.Errorf("unknown message type: %d", r.Ifcall.Type()))
case *TVersion:
sVersion(ctx1, s, r)
case *TAuth:
@@ -952,13 +952,13 @@ L:
}
}
-// Respond responds to the request r with the message r.ofcall if err is nil,
+// Respond responds to the request r with the message r.Ofcall if err is nil,
// or if err is not nil, with the Rerror with the error message.
-// If r is nil, or both r.ofcall and err are nil it panics.
+// If r is nil, or both r.Ofcall and err are nil it panics.
func respond(ctx context.Context, r *Req, err error) {
- switch r.ifcall.(type) {
+ switch r.Ifcall.(type) {
default:
- panic(fmt.Errorf("bug: r.ifcall: %v", r.ifcall))
+ panic(fmt.Errorf("bug: r.Ifcall: %v", r.Ifcall))
case *TVersion:
rVersion(r, err)
case *TAuth:
@@ -986,20 +986,20 @@ func respond(ctx context.Context, r *Req, err error) {
case *TWStat:
rWStat(r, err)
}
- r.ofcall.SetTag(r.tag)
+ r.Ofcall.SetTag(r.Tag)
// free tag.
if r.pool == nil && err != ErrDupTag {
panic("ReqPool is nil but err is not EDupTag")
}
if r.pool != nil {
- r.pool.delete(r.tag)
+ r.pool.delete(r.Tag)
}
select {
- case r.srv.speakChan <- r:
- if r.srv.chatty9P {
- fmt.Fprintf(os.Stderr, "--> %s\n", r.ofcall)
+ case r.Srv.speakChan <- r:
+ if r.Srv.chatty9P {
+ fmt.Fprintf(os.Stderr, "--> %s\n", r.Ofcall)
}
case <-ctx.Done():
- log.Printf("req flush: %v", r.ifcall)
+ log.Printf("req flush: %v", r.Ifcall)
}
}
diff --git a/server_test.go b/server_test.go
@@ -1,4 +1,4 @@
-package lib9p
+package lib9p_test
import (
"context"
@@ -6,12 +6,15 @@ import (
"io"
"path/filepath"
"testing"
+
+ "git.mtkn.jp/lib9p"
+ "git.mtkn.jp/lib9p/testfs"
)
-func newReq(s *Server, msg Msg) (*Req, error) {
- r, err := s.rPool.add(msg.GetTag())
+func newReq(s *lib9p.Server, msg lib9p.Msg) (*lib9p.Req, error) {
+ r, err := s.RPool().Add(msg.GetTag())
if err != nil {
- return nil, fmt.Errorf("ReqPool.add(%d): %w", msg.GetTag(), err)
+ return nil, fmt.Errorf("lib9p.ReqPool.add(%d): %w", msg.GetTag(), err)
}
r.srv = s
r.tag = msg.GetTag()
@@ -19,7 +22,7 @@ func newReq(s *Server, msg Msg) (*Req, error) {
return r, nil
}
-func handleReq(ctx context.Context, s *Server, r *Req) {
+func handleReq(ctx context.Context, s *lib9p.Server, r *lib9p.Req) {
switch r.ifcall.(type) {
default:
respond(ctx, r, fmt.Errorf("unknown message type: %d", r.ifcall.Type()))
@@ -51,7 +54,7 @@ func handleReq(ctx context.Context, s *Server, r *Req) {
}
// This function does the actual work for TestWalk().
-func testWalk(t *testing.T, fs *TestFS, path string, file *TestFile) {
+func testWalk(t *testing.T, fs *testfs.TestFS, path string, file *testfs.TestFile) {
t.Logf("walk %s", path)
f, err := fs.walk(split9path(path))
if err != nil {
@@ -80,7 +83,7 @@ func TestServer(t *testing.T) {
cr, sw := io.Pipe()
defer cr.Close()
defer sw.Close()
- msg := []Msg{
+ msg := []lib9p.Msg{
&TVersion{
Tag: NOTAG,
Msize: 1024,
@@ -163,9 +166,9 @@ func TestServer(t *testing.T) {
if err != nil {
t.Fatalf("read: %v", err)
}
- t.Logf("--> %v\n", bufMsg(buf))
+ t.Logf("--> %v\n", buflib9p.Msg(buf))
- if bufMsg(buf).Type() == Rread {
+ if buflib9p.Msg(buf).Type() == Rread {
rread := newRRead(buf)
data := rread.Data
fid, ok := s.fPool.lookup(m.(*TRead).Fid)
diff --git a/test_fs.go b/test_fs.go
@@ -1,197 +0,0 @@
-package lib9p
-
-import (
- "bytes"
- "fmt"
- "io/fs"
- "path"
- "strings"
- "time"
-)
-
-const sleepTime = 1 * time.Second
-
-type TestFile struct {
- Fsys *TestFS
- Parent *TestFile
- Children []*TestFile
- Content []byte
- Reader *bytes.Reader
-
- St Stat
-}
-
-func (f *TestFile) Stat() (*FileInfo, error) {
- return &FileInfo{Stat: f.St}, nil
-}
-func (f *TestFile) Close() error {
- f.Reader = nil
- return nil
-}
-
-func (f *TestFile) Read(b []byte) (int, error) {
- if f.Fsys.Slow {
- time.Sleep(sleepTime)
- }
- return f.Reader.Read(b)
-}
-
-func (f *TestFile) ReadAt(b []byte, off int64) (n int, err error) {
- if f.Fsys.Slow {
- time.Sleep(sleepTime)
- }
- return f.Reader.ReadAt(b, off)
-}
-
-func (f *TestFile) ReadDir(n int) ([]*DirEntry, error) {
- de := make([]*DirEntry, len(f.Children))
- for i, c := range f.Children {
- de[i], _ = c.Stat()
- }
- return de, nil
-}
-
-func (f *TestFile) WriteAt(p []byte, off int64) (int, error) {
- if f.Fsys.Slow {
- time.Sleep(sleepTime)
- }
- if f.Reader == nil {
- return 0, fmt.Errorf("not open")
- }
- if off < 0 || off > int64(len(f.Content)) {
- return 0, fmt.Errorf("bad offset")
- }
-
- if off+int64(len(p)) > int64(len(f.Content)) {
- newcon := make([]byte, off+int64(len(p)))
- copy(newcon, f.Content)
- f.Content = newcon
- }
- copy(f.Content[off:], p)
- f.Reader.Reset(f.Content)
- return len(p), nil
-}
-
-type TestFS struct {
- Root *TestFile
- Slow bool
-}
-
-func (fs *TestFS) OpenFile(path string, omode OpenMode, perm fs.FileMode) (File, error) {
- path = clean9path(path)
- wnames := split9path(path)
- f, err := fs.walk(wnames)
- if err != nil {
- return nil, fmt.Errorf("walk: %v", err)
- }
- f.Reader = bytes.NewReader(f.Content)
- return f, nil
-}
-
-func (fs *TestFS) walk(wnames []string) (*TestFile, error) {
- cwd := fs.Root
-L:
- for i, name := range wnames {
- for _, child := range cwd.Children {
- if child.St.Name == name {
- cwd = child
- continue L
- }
- }
- return nil, fmt.Errorf("%s not found", strings.Join(wnames[:i+1], "/"))
- }
- return cwd, nil
-}
-
-func clean9path(name string) string {
- // TODO: eliminate leading ".."
- name = path.Clean(name)
- return name
-}
-
-func split9path(path string) []string {
- if path == "." || path == "/" {
- return []string{}
- }
- return strings.Split(path, "/")
-}
-
-var fsys *TestFS
-
-func init() {
- fsys = &TestFS{
- Root: &TestFile{
- St: Stat{
- Qid: Qid{Path: 0, Type: QTDIR},
- Mode: FileMode(fs.ModeDir | 0755),
- Name: "root",
- Uid: "glenda",
- Gid: "glenda",
- Muid: "glenda",
- },
- Children: []*TestFile{
- &TestFile{
- Content: []byte("a\n"),
- St: Stat{
- Qid: Qid{Path: 1, Type: QTFILE},
- Mode: FileMode(0644),
- Name: "a",
- Uid: "glenda",
- Gid: "glenda",
- Muid: "glenda",
- },
- },
- &TestFile{
- Content: []byte("b\n"),
- St: Stat{
- Qid: Qid{Path: 2, Type: QTFILE},
- Mode: FileMode(0400),
- Name: "b",
- Uid: "ken",
- Gid: "ken",
- Muid: "ken",
- },
- },
- &TestFile{
- St: Stat{
- Qid: Qid{Path: 3, Type: QTDIR},
- Mode: FileMode(fs.ModeDir | 0755),
- Name: "dir",
- Uid: "rob",
- Gid: "rob",
- Muid: "rob",
- },
- Children: []*TestFile{
- &TestFile{
- Content: []byte("unko\n"),
- St: Stat{
- Qid: Qid{Path: 4, Type: QTFILE},
- Mode: FileMode(0666),
- Name: "file",
- Uid: "brian",
- Gid: "brian",
- Muid: "dennis",
- },
- },
- },
- },
- },
- },
- }
- SetFsysAndParent(fsys, nil)
-}
-
-// SetFsysAndParent sets file.fsys and file.parent for every file in the fsys.
-// Pass nil as file to setup entire file system.
-func SetFsysAndParent(fsys *TestFS, file *TestFile) {
- if file == nil {
- file = fsys.Root
- file.Parent = fsys.Root
- file.Fsys = fsys
- }
- for _, child := range file.Children {
- child.Parent = file
- child.Fsys = fsys
- SetFsysAndParent(fsys, child)
- }
-}