system_info_darwin.go
1 package tools 2 3 import ( 4 "fmt" 5 "os/exec" 6 "strconv" 7 "strings" 8 "syscall" 9 ) 10 11 func getMemoryInfo() string { 12 // macOS: use sysctl for total memory 13 out, err := exec.Command("sysctl", "-n", "hw.memsize").CombinedOutput() 14 if err != nil { 15 return "" 16 } 17 totalBytes, err := strconv.ParseUint(strings.TrimSpace(string(out)), 10, 64) 18 if err != nil { 19 return "" 20 } 21 22 // Get page size and free pages from vm_stat 23 pageSize := uint64(syscall.Getpagesize()) 24 vmOut, err := exec.Command("vm_stat").CombinedOutput() 25 if err != nil { 26 return fmt.Sprintf("Memory Total: %s\n", formatBytes(totalBytes)) 27 } 28 29 freePages := uint64(0) 30 for _, line := range strings.Split(string(vmOut), "\n") { 31 if strings.HasPrefix(line, "Pages free:") { 32 val := strings.TrimSpace(strings.TrimSuffix(strings.TrimPrefix(line, "Pages free:"), ".")) 33 if n, err := strconv.ParseUint(val, 10, 64); err == nil { 34 freePages = n 35 } 36 } 37 } 38 freeBytes := freePages * pageSize 39 40 return fmt.Sprintf("Memory Total: %s\nMemory Free: %s\n", formatBytes(totalBytes), formatBytes(freeBytes)) 41 } 42 43 func getDiskInfo() string { 44 var stat syscall.Statfs_t 45 if err := syscall.Statfs("/", &stat); err != nil { 46 return "" 47 } 48 total := stat.Blocks * uint64(stat.Bsize) 49 free := stat.Bavail * uint64(stat.Bsize) 50 return fmt.Sprintf("Disk Total: %s\nDisk Free: %s\n", formatBytes(total), formatBytes(free)) 51 } 52 53 func formatBytes(b uint64) string { 54 const ( 55 MB = 1024 * 1024 56 GB = 1024 * MB 57 ) 58 if b >= GB { 59 return fmt.Sprintf("%.1f GB", float64(b)/float64(GB)) 60 } 61 return fmt.Sprintf("%.1f MB", float64(b)/float64(MB)) 62 }