lib9p

Go 9P library.
Log | Files | Refs | LICENSE

qid_windows.go (2617B)


      1 //go:build windows
      2 
      3 package diskfs
      4 
      5 import (
      6 	"fmt"
      7 	"io/fs"
      8 	"os"
      9 	"path/filepath"
     10 	"time"
     11 
     12 	"git.mtkn.jp/lib9p"
     13 )
     14 
     15 // fileID is the identifier of a windows file.
     16 // It is used to assosiate the file with Qid.
     17 type fileID string
     18 
     19 // qidReq is used to update the Qid.Vers by checking the file's
     20 // modified time.
     21 type qidRec struct {
     22 	qid   *lib9p.Qid
     23 	mtime time.Time
     24 }
     25 
     26 // QidPool is the list of Qids in the file system.
     27 type QidPool struct {
     28 	m       map[fileID]*qidRec
     29 	nextQid uint64
     30 }
     31 
     32 // id derives the fileID from the file.
     33 func (f *File) id() (fileID, error) {
     34 	return fileID(f.path), nil
     35 }
     36 
     37 // idFromInfo derives the fileID from the fs.FileInfo.
     38 func idFromInfo(path string, info fs.FileInfo) fileID {
     39 	return fileID(path)
     40 }
     41 
     42 // newQidPool allocates a QidPool.
     43 func newQidPool() *QidPool {
     44 	return &QidPool{
     45 		m: make(map[fileID]*qidRec),
     46 	}
     47 }
     48 
     49 // lookup looks up the file in the QidPool.
     50 // If found, it returns the corresponding Qid and true.
     51 // If not found, it returns nil and false.
     52 func (pool *QidPool) lookup(f *File) (lib9p.Qid, bool) {
     53 	id, err := f.id()
     54 	if err != nil {
     55 		return lib9p.Qid{}, false
     56 	}
     57 	ospath := filepath.Join(f.fs.rootPath, f.path)
     58 	fsfi, err := os.Stat(ospath)
     59 	if err != nil {
     60 		return lib9p.Qid{}, false
     61 	}
     62 	return pool.lookupID(id, fsfi.ModTime())
     63 }
     64 
     65 // lookupID looksup the file in the QidPool by fileID.
     66 // It also checks if the file is modified after the last access by
     67 // comparing the qidReq.mtime and mtime, and update Qid.Vers if needed.
     68 func (pool *QidPool) lookupID(id fileID, mtime time.Time) (lib9p.Qid, bool) {
     69 	qrec, ok := pool.m[id]
     70 	if !ok {
     71 		return lib9p.Qid{}, false
     72 	}
     73 	if qrec.mtime.Before(mtime) {
     74 		qrec.qid.Vers++
     75 		qrec.mtime = mtime
     76 	}
     77 	return *qrec.qid, ok
     78 }
     79 
     80 // add adds the file's Qid to the QidPool and returns the newly added Qid.
     81 func (pool *QidPool) add(f *File) (lib9p.Qid, error) {
     82 	id, err := f.id()
     83 	if err != nil {
     84 		return lib9p.Qid{}, fmt.Errorf("get id: %v", err)
     85 	}
     86 	ospath := filepath.Join(f.fs.rootPath, f.path)
     87 	fi, err := os.Stat(ospath)
     88 	if err != nil {
     89 		return lib9p.Qid{}, fmt.Errorf("stat %v: %v", f, err)
     90 	}
     91 	return pool.addID(id, fi)
     92 }
     93 
     94 // addID does the same as add, but by fileID.
     95 func (pool *QidPool) addID(id fileID, info fs.FileInfo) (lib9p.Qid, error) {
     96 	qtype := lib9p.FSModeToQidType(info.Mode())
     97 	qid := &lib9p.Qid{
     98 		Path: pool.nextQid,
     99 		Type: qtype,
    100 	}
    101 	pool.m[id] = &qidRec{qid: qid, mtime: info.ModTime()}
    102 	pool.nextQid++
    103 	return *qid, nil
    104 }
    105 
    106 // delete deletes Qid associated with f from the QidPool.
    107 func (pool *QidPool) delete(f *File) {
    108 	id, err := f.id()
    109 	if err != nil {
    110 		return
    111 	}
    112 	delete(pool.m, id)
    113 }