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  }