package main import ( "os" "strconv" "strings" ) // Process contains an alias that will be returned when queries, and a process // name to look for. type Process struct { Alias string `json:"alias"` Process string `json:"process"` } // ProcessesState is a map of processes' aliases and its statuses. type ProcessesState map[string]bool func GetProcessesState(procs *[]Process) (ps ProcessesState) { ps = make(ProcessesState) for _, proc := range *procs { pids, err := GetProcessPIDs(proc.Process) ps[proc.Alias] = err == nil && len(pids) > 0 } return } // GetProcessPIDs returns a list of PIDs found for a process. func GetProcessPIDs(name string) (pids []int, err error) { dir, err := os.ReadDir("/proc/") if err != nil { return nil, err } for _, entry := range dir { // This line demands a little clarification. Here we are making sure // that the first character of a directory name is numeric. In ASCII // all numerals are laying within 0x30-0x39 range. if entry.IsDir() && entry.Name()[0]>>0x4&0xf == 0x3 { cmdline, err := os.ReadFile("/proc/" + entry.Name() + "/cmdline") if err != nil { return nil, err } if strings.Contains(string(cmdline), name) { pid, err := strconv.Atoi(entry.Name()) if err != nil { continue } pids = append(pids, pid) } } } return pids, nil }