-
Notifications
You must be signed in to change notification settings - Fork 0
/
pathindex.go
63 lines (57 loc) · 1.2 KB
/
pathindex.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package rpz
import (
"os"
"strings"
"syscall"
)
var (
nextPathIndex = int64(1)
indexForPathInode map[uint64]int64
)
func init() {
indexForPathInode = make(map[uint64]int64)
}
func PathIndex(path string) (pathIndex int64, ok bool) {
inodeNum, ok := inode(path)
if !ok {
return 0, false
}
pathIndex, ok = indexForPathInode[inodeNum]
if !ok {
pathIndex = nextPathIndex
indexForPathInode[inodeNum] = pathIndex
nextPathIndex++
}
return pathIndex, true
}
func TrimWorkingDirPrefix(absolutePath string) string {
prefix := absolutePath
prefixLength := len(absolutePath)
for {
prefixPathIndex, ok := PathIndex(prefix)
if !ok {
return absolutePath
}
if prefixPathIndex == WorkingDirPathIndex {
return "." + absolutePath[prefixLength:]
}
prefixLength = strings.LastIndex(prefix, "/")
if prefixLength == -1 {
break
}
prefix = prefix[:prefixLength]
}
return absolutePath
}
// Inode returns the inode number for the given absolute path
func inode(path string) (uint64, bool) {
fileinfo, err := os.Stat(path)
if err != nil {
return 0, false
}
stat, ok := fileinfo.Sys().(*syscall.Stat_t)
if !ok {
panic("Error casting file information to Stat_t")
}
return stat.Ino, true
}