func FillPidMetrics()

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
}