lib9p

Go 9P library.
Log | Files | Refs

commit ba9d2e2f6b0ab6ae793ed9581b80bdb11ed35f6e
parent 63a5ee93dc615a79111b2bb97129de2a6ed8736a
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Sun, 15 Oct 2023 08:10:49 +0900

implement ClientFile.Stat() and .Open()

Diffstat:
Mclient2.go | 2+-
Mfid.go | 16+++++++++++++++-
Mfile.go | 19+++++++++++++++++--
3 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/client2.go b/client2.go @@ -30,7 +30,7 @@ func Mount(r io.Reader, w io.Writer, uname, aname string) (fs *Client, err error } // TODO: auth - fid, err := c.fPool.add(0) + fid, err := c.fPool.add() if err != nil { return nil, fmt.Errorf("add fid: %v", err) } diff --git a/fid.go b/fid.go @@ -137,10 +137,24 @@ func (pool *clientFidPool) lookup(fid uint32) (*clientFid, bool) { return f, ok } -func (pool *clientFidPool) add(fid uint32) (*clientFid, error) { +func (pool *clientFidPool) nextFid() (uint32, error) { pool.lock.Lock() defer pool.lock.Unlock() + for i := uint32(0); i < i + 1; i++ { + if _, ok := pool.m[i]; !ok { + return i, nil + } + } + return 0, fmt.Errorf("run out of fid") +} +func (pool *clientFidPool) add() (*clientFid, error) { + fid, err := pool.nextFid() + if err != nil { + return nil, err + } + pool.lock.Lock() + defer pool.lock.Unlock() if _, ok := pool.m[fid]; ok { return nil, fmt.Errorf("fid already in use.") } diff --git a/file.go b/file.go @@ -139,6 +139,12 @@ func (cf *ClientFile) Child() ([]File, error) { } func (cf *ClientFile) Stat() (*FileInfo, error) { + if cf.fid == nil { + if err := cf.Open(OREAD); err != nil { + return nil, fmt.Errorf("open: %v", err) + } + } + defer cf.Close() st, err := cf.client.Stat(context.TODO(), cf.fid.fid) if err != nil { return nil, err @@ -152,11 +158,20 @@ func (cf *ClientFile) Qid() Qid { func (cf *ClientFile) Open(mode OpenMode) error { if cf.fid == nil { - panic("TODO: Walk to the file") + fid, err := cf.client.fPool.add() + if err != nil { + return fmt.Errorf("add fid: %v", err) + } + wname := strings.Split(cf.path, "/") + _, err = cf.client.Walk(context.TODO(), cf.client.root.fid.fid, fid.fid, wname) + if err != nil { + return fmt.Errorf("walk: %v", err) + } + cf.fid = fid } qid, iounit, err := cf.client.Open(context.TODO(), cf.fid.fid, mode) if err != nil { - return err + return fmt.Errorf("open: %v", err) } cf.qid = qid cf.iounit = iounit