github.com/songzhibin97/gkit@v1.2.13/sys/cpu/util.go (about) 1 package cpu 2 3 import ( 4 "bufio" 5 "io/ioutil" 6 "os" 7 "strconv" 8 "strings" 9 10 "github.com/pkg/errors" 11 ) 12 13 // readFile 读取文件返回对应string 14 func readFile(path string) (string, error) { 15 contents, err := ioutil.ReadFile(path) 16 if err != nil { 17 return "", errors.Wrapf(err, "os/stat: read file(%s) failed!", path) 18 } 19 return strings.TrimSpace(string(contents)), nil 20 } 21 22 // parseUint 解析 Uint 23 func parseUint(s string) (uint64, error) { 24 v, err := strconv.ParseUint(s, 10, 64) 25 if err != nil { 26 intValue, intErr := strconv.ParseInt(s, 10, 64) 27 // 处理 28 // 1. Handle negative values greater than MinInt64 (and) 29 // 2. Handle negative values lesser than MinInt64 30 if intErr == nil && intValue < 0 { 31 return 0, nil 32 } else if intErr != nil && 33 intErr.(*strconv.NumError).Err == strconv.ErrRange && 34 intValue < 0 { 35 return 0, nil 36 } 37 return 0, errors.Wrapf(err, "os/stat: parseUint(%s) failed!", s) 38 } 39 return v, nil 40 } 41 42 // ParseUintList parses and validates the specified string as the value 43 // found in some cgroup file (e.g. cpuset.cpus, cpuset.mems), which could be 44 // one of the formats below. Note that duplicates are actually allowed in the 45 // input string. It returns a map[int]bool with available elements from val 46 // set to true. 47 // Supported formats: 48 // 7 49 // 1-6 50 // 0,3-4,7,8-10 51 // 0-0,0,1-7 52 // 03,1-3 <- this is gonna get parsed as [1,2,3] 53 // 3,2,1 54 // 0-2,3,1 55 func ParseUintList(val string) (map[int]bool, error) { 56 if val == "" { 57 return map[int]bool{}, nil 58 } 59 60 availableInts := make(map[int]bool) 61 split := strings.Split(val, ",") 62 errInvalidFormat := errors.Errorf("os/stat: invalid format: %s", val) 63 for _, r := range split { 64 if !strings.Contains(r, "-") { 65 v, err := strconv.Atoi(r) 66 if err != nil { 67 return nil, errInvalidFormat 68 } 69 availableInts[v] = true 70 } else { 71 split := strings.SplitN(r, "-", 2) 72 min, err := strconv.Atoi(split[0]) 73 if err != nil { 74 return nil, errInvalidFormat 75 } 76 max, err := strconv.Atoi(split[1]) 77 if err != nil { 78 return nil, errInvalidFormat 79 } 80 if max < min { 81 return nil, errInvalidFormat 82 } 83 for i := min; i <= max; i++ { 84 availableInts[i] = true 85 } 86 } 87 } 88 return availableInts, nil 89 } 90 91 // readLines 读取首行 92 func readLines(filename string) ([]string, error) { 93 return readLinesOffsetN(filename, 0, -1) 94 } 95 96 // readLinesOffsetN 读取行数据 97 // n >= 0: at most n lines 98 // n < 0: whole file 99 func readLinesOffsetN(filename string, offset uint, n int) ([]string, error) { 100 f, err := os.Open(filename) 101 if err != nil { 102 return []string{""}, err 103 } 104 defer f.Close() 105 106 var ret []string 107 108 r := bufio.NewReader(f) 109 for i := 0; i < n+int(offset) || n < 0; i++ { 110 line, err := r.ReadString('\n') 111 if err != nil { 112 break 113 } 114 if i < int(offset) { 115 continue 116 } 117 ret = append(ret, strings.Trim(line, "\n")) 118 } 119 120 return ret, nil 121 }