sophuwu.site > quickstat   
              235
            
             package main

import (
	"os"
	"time"
)

var (
	cpuLoad,
	cpuMHz,
	cpuTemp int
	totalMem,
	usedMem,
	takenMem,
	freeMem,
	availMem,
	prctMem,
	prctBuff,
	prctFree float64
)

func errCheck(err error, errFunc func() string) bool {
	if err == nil {
		return false
	}
	print("  An error occurred: " + errFunc())
	if len(os.Args) > 1 && os.Args[1] == "-d" {
		print(err.Error() + "\n")
	}
	return true
}

func numFromLine(i int, b []byte, n *float64) int {
	for ; i < len(b); i++ {
		if b[i] == 10 {
			return i + 1
		}
		if b[i] >= 48 && b[i] <= 57 {
			*n = *n*10 + float64(b[i]) - 48
		}
	}
	return i
}

func getMem() {
	errFunc := func() string {
		prctMem = -1
		prctBuff = -1
		prctFree = -1
		return "Unable to read memory.\n"
	}

	b := make([]byte, 84)
	f, err := os.Open("/proc/meminfo")
	if errCheck(err, errFunc) {
		return
	}
	_, err = f.Read(b)
	if errCheck(err, errFunc) {
		return
	}
	f.Close()

	i := numFromLine(0, b, &totalMem)
	totalMem /= 1000
	i = numFromLine(i, b, &freeMem)
	freeMem /= 1000
	_ = numFromLine(i, b, &availMem)
	availMem /= 1000

	usedMem = totalMem - freeMem
	takenMem = totalMem - availMem
	prctMem = takenMem * 100 / totalMem
	prctBuff = (usedMem - takenMem) * 100 / totalMem
	prctFree = freeMem * 100 / totalMem
}

func findCPUTypeNo(path string, fileName string, comp string) (string, error) {
	var b = make([]byte, 100)
	var i int = 0
	if fileName == "_label" {
		i = 1
	}
	var err error = nil
	for ; err == nil && string(b[:len(comp)]) != comp; i++ {
		b, err = os.ReadFile(path + string(i+48) + fileName)
	}
	if err != nil {
		return "", err
	}
	return string(i + 48 - 1), nil
}

func getCPUTemp() {
	errFunc := func() string {
		cpuTemp = -1
		return "Unable to read CPU temperature.\n"
	}
	var (
		b         = make([]byte, 2)
		thrmPath  = "/sys/class/thermal/thermal_zone"
		hwMonPath = "/sys/class/hwmon/hwmon"
	)
	nStr, err := findCPUTypeNo(thrmPath, "/type", "x86_pkg_temp")
	if err != nil {
		nStr, err = findCPUTypeNo(hwMonPath, "/name", "k10temp")
		if errCheck(err, errFunc) {
			return
		}
		nStrHW := nStr
		nStr, err = findCPUTypeNo(hwMonPath+nStrHW+"/temp", "_label", "Tdie")
		if errCheck(err, errFunc) {
			return
		}
		b, err = os.ReadFile(hwMonPath + nStrHW + "/temp" + nStr + "_input")
	} else {
		b, err = os.ReadFile(thrmPath + nStr + "/temp")
	}
	if errCheck(err, errFunc) {
		return
	}
	cpuTemp = (int(b[0])-48)*10 + int(b[1]) - 48
}

func getCPU() {
	readStat := func(n *[4]float64) bool {
		errFunc := func() string {
			cpuLoad = -1
			return "Unable to read cpu load.\n"
		}

		b := make([]byte, 100)
		f, err := os.Open("/proc/stat")
		if errCheck(err, errFunc) {
			return true
		}
		_, err = f.Read(b)
		if errCheck(err, errFunc) {
			return true
		}
		f.Close()
		for i, j := 6, 0; j < 4; i++ {
			if b[i] >= 48 && b[i] <= 57 {
				n[j] = n[j]*10 + float64(b[i]) - 48
			} else if b[i] == ' ' {
				j++
			}
		}
		return false
	}
	var a, b [4]float64
	if readStat(&a) {
		return
	}
	time.Sleep(1 * time.Second)
	if readStat(&b) {
		return
	}
	cpuLoad = int(100 * ((b[0] + b[1] + b[2]) - (a[0] + a[1] + a[2])) / ((b[0] + b[1] + b[2] + b[3]) - (a[0] + a[1] + a[2] + a[3])))
}

func getMHz() {
	b, err := os.ReadFile("/proc/cpuinfo")

	if errCheck(err, func() string {
		cpuMHz = -1
		return "Unable to read cpu MHz.\n"
	}) {
		return
	}

	var tmp, j int
	cpuMHz = 0
	for i := 0; i < len(b); i++ {
		if string(b[i:i+7]) == "cpu MHz" {
			tmp = 0
			for ; i < len(b) && b[i] != 10 && b[i] != '.'; i++ {
				if b[i] >= 48 && b[i] <= 57 {
					tmp = tmp*10 + int(b[i]) - 48
				}
			}
			cpuMHz += tmp
			j++
		}
	}
	cpuMHz /= j
}

func round(f float64) string {
	var n int = int(f*1000) % 1000
	var s string = ""

	if n != 0 {
		for i := 0; i < 3; i++ {
			if n%10 >= 5 {
				n += 10
			}
			n /= 10
		}
	}

	n = int(f) + n
	for n > 0 {
		s = string(n%10+48) + s
		n /= 10
	}

	return s
}

func printNWithErr(in interface{}) string {
	var n float64
	switch v := in.(type) {
	case int:
		n = float64(v)
		break
	case float64:
		n = v
		break
	default:
		return "Err"
	}
	if n < 0 {
		return "Err"
	}
	return round(n)
}

func main() {
	go getMem()
	go getCPUTemp()
	go getMHz()
	getCPU()
	println("   Mem:  ", printNWithErr(prctMem), "% USED  ", printNWithErr(prctBuff), "% BUFF  ", printNWithErr(prctFree), "% FREE   CPU:  ", printNWithErr(cpuLoad), "%  ", printNWithErr(cpuTemp), "C  ", printNWithErr(cpuMHz), "MHz")
}