in metric/system/process/process_aix.go [115:199]
func FillPidMetrics(_ resolve.Resolver, pid int, state ProcState, filter func(string) bool) (ProcState, error) {
pagesize := uint64(os.Getpagesize())
info := C.struct_procsinfo64{}
cpid := C.pid_t(pid)
num, err := C.getprocs(unsafe.Pointer(&info), C.sizeof_struct_procsinfo64, nil, 0, &cpid, 1)
if err != nil {
return state, fmt.Errorf("error in getprocs: %w", err)
}
if num != 1 {
return state, syscall.ESRCH
}
state.Memory.Size = opt.UintWith(uint64(info.pi_size) * pagesize)
state.Memory.Share = opt.UintWith(uint64(info.pi_sdsize) * pagesize)
state.Memory.Rss.Bytes = opt.UintWith(uint64(info.pi_drss+info.pi_trss) * pagesize)
state.CPU.StartTime = unixTimeMsToTime(uint64(info.pi_start) * 1000)
state.CPU.User.Ticks = opt.UintWith(uint64(info.pi_utime) * 1000)
state.CPU.System.Ticks = opt.UintWith(uint64(info.pi_stime) * 1000)
state.CPU.Total.Ticks = opt.UintWith(opt.SumOptUint(state.CPU.User.Ticks, state.CPU.System.Ticks))
// Get Proc Args
/* If buffer is not large enough, args are truncated */
buf := make([]byte, 8192)
info.pi_pid = C.pid_t(pid)
if _, err := C.getargs(unsafe.Pointer(&info), C.sizeof_struct_procsinfo64, (*C.char)(&buf[0]), 8192); err != nil {
return state, fmt.Errorf("error in getargs: %w", err)
}
bbuf := bytes.NewBuffer(buf)
var args []string
for {
arg, err := bbuf.ReadBytes(0)
if err == io.EOF || arg[0] == 0 {
break
}
if err != nil {
return state, fmt.Errorf("error reading args buffer: %w", err)
}
args = append(args, stripNullByte(arg))
}
state.Args = args
state.Exe = args[0]
// get env vars
buf = make([]byte, 8192)
if _, err := C.getevars(unsafe.Pointer(&info), C.sizeof_struct_procsinfo64, (*C.char)(&buf[0]), 8192); err != nil {
return state, fmt.Errorf("error in getevars: %w", err)
}
if state.Env != nil {
return state, nil
}
bbuf = bytes.NewBuffer(buf)
delim := []byte{61} // "="
vars := mapstr.M{}
for {
line, err := bbuf.ReadBytes(0)
if errors.Is(err, io.EOF) || line[0] == 0 {
break
}
if err != nil {
return state, fmt.Errorf("error: %w", err)
}
pair := bytes.SplitN(stripNullByteRaw(line), delim, 2)
if len(pair) != 2 {
return state, fmt.Errorf("error reading environment: %w", err)
}
eKey := string(pair[0])
if filter == nil || filter(eKey) {
vars[string(pair[0])] = string(pair[1])
}
}
state.Env = vars
return state, nil
}