package proc import ( "bytes" "os" "path" "strconv" "strings" "github.com/coroot/coroot-node-agent/cgroup" ) var root = "/proc" func Path(pid uint32, subpath ...string) string { return path.Join(append([]string{root, strconv.Itoa(int(pid))}, subpath...)...) } func HostPath(p string) string { return Path(1, "root", p) } func GetCmdline(pid uint32) []byte { cmdline, err := os.ReadFile(Path(pid, "cmdline")) if err != nil { return nil } return bytes.TrimSuffix(cmdline, []byte{0}) } func GetNsPid(pid uint32) uint32 { data, err := os.ReadFile(Path(pid, "status")) if err != nil { return pid } for _, line := range strings.Split(string(data), "\n") { fields := strings.Fields(line) if len(fields) < 2 { continue } if fields[0] == "NSpid:" { if len(fields) == 3 { if nsPid, err := strconv.ParseUint(fields[2], 10, 32); err == nil { return uint32(nsPid) } } return pid } } return pid } func ReadCgroup(pid uint32) (*cgroup.Cgroup, error) { return cgroup.NewFromProcessCgroupFile(Path(pid, "cgroup")) } func ListPids() ([]uint32, error) { root, err := os.Open(root) if err != nil { return nil, err } defer root.Close() dirs, err := root.Readdirnames(0) if err != nil { return nil, err } res := make([]uint32, 0, len(dirs)) for _, dir := range dirs { pid64, err := strconv.ParseUint(dir, 10, 32) if err != nil { continue } res = append(res, uint32(pid64)) } return res, nil } func GetProcName(pid uint32) string { comm, err := os.ReadFile(Path(pid, "comm")) if err != nil { return "" } return string(bytes.TrimRight(comm, "\n")) }