func kernProcargs()

in sigar_common_darwin.go [365:441]


func kernProcargs(pid int,
	exe func(string),
	argv func(string),
	env func(string, string)) error {

	mib := []C.int{C.CTL_KERN, C.KERN_PROCARGS2, C.int(pid)}
	argmax := uintptr(C.ARG_MAX)
	buf := make([]byte, argmax)
	err := sysctl(mib, &buf[0], &argmax, nil, 0)
	if err != nil {
		return nil
	}

	bbuf := bytes.NewBuffer(buf)
	bbuf.Truncate(int(argmax))

	var argc int32
	binary.Read(bbuf, binary.LittleEndian, &argc)

	path, err := bbuf.ReadBytes(0)
	if err != nil {
		return fmt.Errorf("Error reading the argv[0]: %v", err)
	}
	if exe != nil {
		exe(string(chop(path)))
	}

	// skip trailing \0's
	for {
		c, err := bbuf.ReadByte()
		if err != nil {
			return fmt.Errorf("Error skipping nils: %v", err)
		}
		if c != 0 {
			bbuf.UnreadByte()
			break // start of argv[0]
		}
	}

	for i := 0; i < int(argc); i++ {
		arg, err := bbuf.ReadBytes(0)
		if err == io.EOF {
			break
		}
		if err != nil {
			return fmt.Errorf("Error reading args: %v", err)
		}
		if argv != nil {
			argv(string(chop(arg)))
		}
	}

	if env == nil {
		return nil
	}

	delim := []byte{61} // "="

	for {
		line, err := bbuf.ReadBytes(0)
		if err == io.EOF || line[0] == 0 {
			break
		}
		if err != nil {
			return fmt.Errorf("Error reading args: %v", err)
		}
		pair := bytes.SplitN(chop(line), delim, 2)

		if len(pair) != 2 {
			return fmt.Errorf("Error reading process information for PID: %d", pid)
		}

		env(string(pair[0]), string(pair[1]))
	}

	return nil
}