github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/runc/libcontainer/utils/utils.go (about) 1 package utils 2 3 import ( 4 "crypto/rand" 5 "encoding/hex" 6 "encoding/json" 7 "io" 8 "os" 9 "path/filepath" 10 "strings" 11 "syscall" 12 "unsafe" 13 ) 14 15 const ( 16 exitSignalOffset = 128 17 ) 18 19 // GenerateRandomName returns a new name joined with a prefix. This size 20 // specified is used to truncate the randomly generated value 21 func GenerateRandomName(prefix string, size int) (string, error) { 22 id := make([]byte, 32) 23 if _, err := io.ReadFull(rand.Reader, id); err != nil { 24 return "", err 25 } 26 if size > 64 { 27 size = 64 28 } 29 return prefix + hex.EncodeToString(id)[:size], nil 30 } 31 32 // ResolveRootfs ensures that the current working directory is 33 // not a symlink and returns the absolute path to the rootfs 34 func ResolveRootfs(uncleanRootfs string) (string, error) { 35 rootfs, err := filepath.Abs(uncleanRootfs) 36 if err != nil { 37 return "", err 38 } 39 return filepath.EvalSymlinks(rootfs) 40 } 41 42 // ExitStatus returns the correct exit status for a process based on if it 43 // was signaled or exited cleanly 44 func ExitStatus(status syscall.WaitStatus) int { 45 if status.Signaled() { 46 return exitSignalOffset + int(status.Signal()) 47 } 48 return status.ExitStatus() 49 } 50 51 // WriteJSON writes the provided struct v to w using standard json marshaling 52 func WriteJSON(w io.Writer, v interface{}) error { 53 data, err := json.Marshal(v) 54 if err != nil { 55 return err 56 } 57 _, err = w.Write(data) 58 return err 59 } 60 61 // CleanPath makes a path safe for use with filepath.Join. This is done by not 62 // only cleaning the path, but also (if the path is relative) adding a leading 63 // '/' and cleaning it (then removing the leading '/'). This ensures that a 64 // path resulting from prepending another path will always resolve to lexically 65 // be a subdirectory of the prefixed path. This is all done lexically, so paths 66 // that include symlinks won't be safe as a result of using CleanPath. 67 func CleanPath(path string) string { 68 // Deal with empty strings nicely. 69 if path == "" { 70 return "" 71 } 72 73 // Ensure that all paths are cleaned (especially problematic ones like 74 // "/../../../../../" which can cause lots of issues). 75 path = filepath.Clean(path) 76 77 // If the path isn't absolute, we need to do more processing to fix paths 78 // such as "../../../../<etc>/some/path". We also shouldn't convert absolute 79 // paths to relative ones. 80 if !filepath.IsAbs(path) { 81 path = filepath.Clean(string(os.PathSeparator) + path) 82 // This can't fail, as (by definition) all paths are relative to root. 83 path, _ = filepath.Rel(string(os.PathSeparator), path) 84 } 85 86 // Clean the path again for good measure. 87 return filepath.Clean(path) 88 } 89 90 // SearchLabels searches a list of key-value pairs for the provided key and 91 // returns the corresponding value. The pairs must be separated with '='. 92 func SearchLabels(labels []string, query string) string { 93 for _, l := range labels { 94 parts := strings.SplitN(l, "=", 2) 95 if len(parts) < 2 { 96 continue 97 } 98 if parts[0] == query { 99 return parts[1] 100 } 101 } 102 return "" 103 } 104 105 // Annotations returns the bundle path and user defined annotations from the 106 // libcontainer state. We need to remove the bundle because that is a label 107 // added by libcontainer. 108 func Annotations(labels []string) (bundle string, userAnnotations map[string]string) { 109 userAnnotations = make(map[string]string) 110 for _, l := range labels { 111 parts := strings.SplitN(l, "=", 2) 112 if len(parts) < 2 { 113 continue 114 } 115 if parts[0] == "bundle" { 116 bundle = parts[1] 117 } else { 118 userAnnotations[parts[0]] = parts[1] 119 } 120 } 121 return 122 } 123 124 func GetIntSize() int { 125 return int(unsafe.Sizeof(1)) 126 }