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:
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