1*333d2b36SAndroid Build Coastguard Workerpackage proc 2*333d2b36SAndroid Build Coastguard Worker 3*333d2b36SAndroid Build Coastguard Workerimport ( 4*333d2b36SAndroid Build Coastguard Worker "io/ioutil" 5*333d2b36SAndroid Build Coastguard Worker "path/filepath" 6*333d2b36SAndroid Build Coastguard Worker "strconv" 7*333d2b36SAndroid Build Coastguard Worker "strings" 8*333d2b36SAndroid Build Coastguard Worker 9*333d2b36SAndroid Build Coastguard Worker "android/soong/finder/fs" 10*333d2b36SAndroid Build Coastguard Worker) 11*333d2b36SAndroid Build Coastguard Worker 12*333d2b36SAndroid Build Coastguard Worker// NewProcStatus returns an instance of the ProcStatus that contains memory 13*333d2b36SAndroid Build Coastguard Worker// information of the process. The memory information is extracted from the 14*333d2b36SAndroid Build Coastguard Worker// "/proc/<pid>/status" text file. This is only available for Linux 15*333d2b36SAndroid Build Coastguard Worker// distribution that supports /proc. 16*333d2b36SAndroid Build Coastguard Workerfunc NewProcStatus(pid int, fileSystem fs.FileSystem) (*ProcStatus, error) { 17*333d2b36SAndroid Build Coastguard Worker statusFname := filepath.Join("/proc", strconv.Itoa(pid), "status") 18*333d2b36SAndroid Build Coastguard Worker r, err := fileSystem.Open(statusFname) 19*333d2b36SAndroid Build Coastguard Worker if err != nil { 20*333d2b36SAndroid Build Coastguard Worker return &ProcStatus{}, err 21*333d2b36SAndroid Build Coastguard Worker } 22*333d2b36SAndroid Build Coastguard Worker defer r.Close() 23*333d2b36SAndroid Build Coastguard Worker 24*333d2b36SAndroid Build Coastguard Worker data, err := ioutil.ReadAll(r) 25*333d2b36SAndroid Build Coastguard Worker if err != nil { 26*333d2b36SAndroid Build Coastguard Worker return &ProcStatus{}, err 27*333d2b36SAndroid Build Coastguard Worker } 28*333d2b36SAndroid Build Coastguard Worker 29*333d2b36SAndroid Build Coastguard Worker s := &ProcStatus{ 30*333d2b36SAndroid Build Coastguard Worker pid: pid, 31*333d2b36SAndroid Build Coastguard Worker } 32*333d2b36SAndroid Build Coastguard Worker 33*333d2b36SAndroid Build Coastguard Worker for _, l := range strings.Split(string(data), "\n") { 34*333d2b36SAndroid Build Coastguard Worker // If the status file does not contain "key: values", just skip the line 35*333d2b36SAndroid Build Coastguard Worker // as the information we are looking for is not needed. 36*333d2b36SAndroid Build Coastguard Worker if !strings.Contains(l, ":") { 37*333d2b36SAndroid Build Coastguard Worker continue 38*333d2b36SAndroid Build Coastguard Worker } 39*333d2b36SAndroid Build Coastguard Worker 40*333d2b36SAndroid Build Coastguard Worker // At this point, we're only considering entries that has key, single value pairs. 41*333d2b36SAndroid Build Coastguard Worker kv := strings.SplitN(l, ":", 2) 42*333d2b36SAndroid Build Coastguard Worker fillProcStatus(s, strings.TrimSpace(kv[0]), strings.TrimSpace(kv[1])) 43*333d2b36SAndroid Build Coastguard Worker } 44*333d2b36SAndroid Build Coastguard Worker 45*333d2b36SAndroid Build Coastguard Worker return s, nil 46*333d2b36SAndroid Build Coastguard Worker} 47