]> Cypherpunks.ru repositories - goredo.git/commitdiff
Stat most files without opening them
authorSergey Matveev <stargrave@stargrave.org>
Sun, 28 Aug 2022 14:07:28 +0000 (17:07 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Sun, 28 Aug 2022 14:07:28 +0000 (17:07 +0300)
dep.go
depfix.go
inode.go
ood.go
run.go

diff --git a/dep.go b/dep.go
index 0e4f24fb0a1ef8872145d2715271f8eb5cff8adc..d819440a18b57909e05e387941030fc84482aa95 100644 (file)
--- a/dep.go
+++ b/dep.go
@@ -100,7 +100,7 @@ func depWrite(fdDep *os.File, cwd, tgt, hsh string) error {
        if fi.IsDir() {
                return nil
        }
-       inode, err := inodeFromFile(fd)
+       inode, err := inodeFromFileByFd(fd)
        if err != nil {
                return err
        }
index 3cd45bbed3f652d20ad3609b8a7bbd06284190e5..a7174be0a77748d5c25c46026368d365da2d5dc2 100644 (file)
--- a/depfix.go
+++ b/depfix.go
@@ -121,7 +121,7 @@ func depFix(root string) error {
                                        }
                                        return err
                                }
-                               inode, err := inodeFromFile(fd)
+                               inode, err := inodeFromFileByFd(fd)
                                if err != nil {
                                        fd.Close()
                                        return err
index 82b61984ab0f37e05c14dd0e2034410ec0dfe4d2..22aa14237377dfe4c8a5bf8f189b9c3dbbb6922f 100644 (file)
--- a/inode.go
+++ b/inode.go
@@ -84,8 +84,19 @@ func (inode *Inode) RecfileFields() []recfile.Field {
        }
 }
 
-func inodeFromFile(fd *os.File) (*Inode, error) {
-       var fi os.FileInfo
+func inodeFromFileStat(fi os.FileInfo, stat unix.Stat_t) *Inode {
+       ctimeSec, ctimeNsec := stat.Ctim.Unix()
+       mtimeSec := fi.ModTime().Unix()
+       mtimeNsec := fi.ModTime().UnixNano()
+       return &Inode{
+               Size:     fi.Size(),
+               InodeNum: uint64(stat.Ino),
+               CtimeSec: ctimeSec, CtimeNsec: ctimeNsec,
+               MtimeSec: mtimeSec, MtimeNsec: mtimeNsec,
+       }
+}
+
+func inodeFromFileByFd(fd *os.File) (*Inode, error) {
        fi, err := fd.Stat()
        if err != nil {
                return nil, err
@@ -95,15 +106,20 @@ func inodeFromFile(fd *os.File) (*Inode, error) {
        if err != nil {
                return nil, err
        }
-       ctimeSec, ctimeNsec := stat.Ctim.Unix()
-       mtimeSec := fi.ModTime().Unix()
-       mtimeNsec := fi.ModTime().UnixNano()
-       return &Inode{
-               Size:     fi.Size(),
-               InodeNum: uint64(stat.Ino),
-               CtimeSec: ctimeSec, CtimeNsec: ctimeNsec,
-               MtimeSec: mtimeSec, MtimeNsec: mtimeNsec,
-       }, nil
+       return inodeFromFileStat(fi, stat), nil
+}
+
+func inodeFromFileByPath(p string) (*Inode, error) {
+       fi, err := os.Stat(p)
+       if err != nil {
+               return nil, err
+       }
+       var stat unix.Stat_t
+       err = unix.Stat(p, &stat)
+       if err != nil {
+               return nil, err
+       }
+       return inodeFromFileStat(fi, stat), nil
 }
 
 func inodeFromRec(m map[string]string) (*Inode, error) {
diff --git a/ood.go b/ood.go
index 40e6da8b3c17f535d7f03ab4d9cbe2fa3da897ca..7a315734287268d3f37c68fe1b82d0a91bc2579e 100644 (file)
--- a/ood.go
+++ b/ood.go
@@ -153,7 +153,7 @@ func isOOD(cwd, tgtOrig string, level int, seen map[string]struct{}) (bool, erro
                theirHsh := m["Hash"]
                tracef(CDebug, "ood: %s%s -> %s: checking", indent, tgtOrig, dep)
 
-               fd, err := os.Open(path.Join(cwd, dep))
+               inode, err := inodeFromFileByPath(path.Join(cwd, dep))
                if err != nil {
                        if os.IsNotExist(err) {
                                tracef(CDebug, "ood: %s%s -> %s: not exists", indent, tgtOrig, dep)
@@ -162,12 +162,7 @@ func isOOD(cwd, tgtOrig string, level int, seen map[string]struct{}) (bool, erro
                        }
                        return ood, TgtError{tgtOrig, err}
                }
-               defer fd.Close()
 
-               inode, err := inodeFromFile(fd)
-               if err != nil {
-                       return ood, TgtError{tgtOrig, err}
-               }
                if inode.Size != theirInode.Size {
                        tracef(CDebug, "ood: %s%s -> %s: size differs", indent, tgtOrig, dep)
                        ood = true
@@ -177,7 +172,12 @@ func isOOD(cwd, tgtOrig string, level int, seen map[string]struct{}) (bool, erro
                        tracef(CDebug, "ood: %s%s -> %s: same inode", indent, tgtOrig, dep)
                } else {
                        tracef(CDebug, "ood: %s%s -> %s: inode differs", indent, tgtOrig, dep)
+                       fd, err := os.Open(path.Join(cwd, dep))
+                       if err != nil {
+                               return ood, TgtError{tgtOrig, err}
+                       }
                        hsh, err := fileHash(fd)
+                       fd.Close()
                        if err != nil {
                                return ood, TgtError{tgtOrig, err}
                        }
@@ -188,7 +188,6 @@ func isOOD(cwd, tgtOrig string, level int, seen map[string]struct{}) (bool, erro
                        }
                        tracef(CDebug, "ood: %s%s -> %s: same hash", indent, tgtOrig, dep)
                }
-               fd.Close()
 
                if dep == tgt {
                        tracef(CDebug, "ood: %s%s -> %s: same target", indent, tgtOrig, dep)
diff --git a/run.go b/run.go
index 8cb6017d7d5ee3547a9bb0fd59d8a180135fa0c8..5e67c41c37ac0107e3a816d7b48a5258f7db4e7b 100644 (file)
--- a/run.go
+++ b/run.go
@@ -156,18 +156,13 @@ func isModified(cwd, redoDir, tgt string) (bool, *Inode, string, error) {
                if m["Type"] != DepTypeIfchange || m["Target"] != tgt {
                        continue
                }
-               fd, err := os.Open(path.Join(cwd, tgt))
+               ourInode, err = inodeFromFileByPath(path.Join(cwd, tgt))
                if err != nil {
                        if os.IsNotExist(err) {
                                return false, nil, "", nil
                        }
                        return false, nil, "", err
                }
-               ourInode, err = inodeFromFile(fd)
-               fd.Close()
-               if err != nil {
-                       return false, nil, "", err
-               }
                theirInode, err := inodeFromRec(m)
                if err != nil {
                        return false, nil, "", err
@@ -655,15 +650,12 @@ func runScript(tgtOrig string, errs chan error, traced bool) error {
                }
 
                // Was $1 touched?
-               if fd, err := os.Open(path.Join(cwdOrig, tgt)); err == nil {
+               if inode, err := inodeFromFileByPath(path.Join(cwdOrig, tgt)); err == nil {
                        if inodePrev == nil {
-                               fd.Close()
                                runErr.Err = Err1WasTouched
                                errs <- runErr
                                return
                        }
-                       inode, err := inodeFromFile(fd)
-                       fd.Close()
                        if err != nil {
                                runErr.Err = err
                                errs <- runErr
@@ -677,10 +669,8 @@ func runScript(tgtOrig string, errs chan error, traced bool) error {
                }
 
                if inodePrev != nil {
-                       if fd, err := os.Open(path.Join(cwdOrig, tgt)); err == nil {
-                               inode, err := inodeFromFile(fd)
-                               fd.Close()
-                               if err == nil && !inode.Equals(inodePrev) {
+                       if inode, err := inodeFromFileByPath(path.Join(cwdOrig, tgt)); err == nil {
+                               if !inode.Equals(inodePrev) {
                                        runErr.Err = Err1WasTouched
                                        errs <- runErr
                                        return