in providers/aix/process_aix_ppc64.go [105:192]
func (p *process) Info() (types.ProcessInfo, error) {
if p.info != nil {
return *p.info, nil
}
p.info = &types.ProcessInfo{
PID: p.pid,
}
// Retrieve PPID and StartTime
info := C.struct_procsinfo64{}
cpid := C.pid_t(p.pid)
num, err := C.getprocs(unsafe.Pointer(&info), C.sizeof_struct_procsinfo64, nil, 0, &cpid, 1)
if num != 1 {
err = syscall.ESRCH
}
if err != nil {
return types.ProcessInfo{}, fmt.Errorf("error while calling getprocs: %w", err)
}
p.info.PPID = int(info.pi_ppid)
// pi_start is the time in second since the process have started.
p.info.StartTime = time.Unix(0, int64(uint64(info.pi_start)*1000*uint64(time.Millisecond)))
// Retrieve arguments and executable name
// If buffer is not large enough, args are truncated
buf := make([]byte, 8192)
var args []string
if _, err := C.getargs(unsafe.Pointer(&info), C.sizeof_struct_procsinfo64, (*C.char)(&buf[0]), 8192); err != nil {
return types.ProcessInfo{}, fmt.Errorf("error while calling getargs: %w", err)
}
bbuf := bytes.NewBuffer(buf)
for {
arg, err := bbuf.ReadBytes(0)
if err == io.EOF || arg[0] == 0 {
break
}
if err != nil {
return types.ProcessInfo{}, fmt.Errorf("error while reading arguments: %w", err)
}
args = append(args, string(chop(arg)))
}
// For some special programs, getargs might return an empty buffer.
if len(args) == 0 {
args = append(args, "")
}
// The first element of the arguments list is the executable path.
// There are some exceptions which don't have an executable path
// but rather a special name directly in args[0].
if strings.Contains(args[0], "sshd: ") {
// ssh connections can be named "sshd: root@pts/11".
// If we are using filepath.Base, the result will only
// be 11 because of the last "/".
p.info.Name = args[0]
} else {
p.info.Name = filepath.Base(args[0])
}
// The process was launched using its absolute path, so we can retrieve
// the executable path from its "name".
if filepath.IsAbs(args[0]) {
p.info.Exe = filepath.Clean(args[0])
} else {
// TODO: improve this case. The executable full path can still
// be retrieve in some cases. Look at os/executable_path.go
// in the stdlib.
// For the moment, let's "exe" be the same as "name"
p.info.Exe = p.info.Name
}
p.info.Args = args
// Get CWD
cwd, err := os.Readlink("/proc/" + strconv.Itoa(p.pid) + "/cwd")
if err != nil {
if !os.IsNotExist(err) {
return types.ProcessInfo{}, fmt.Errorf("error while reading /proc/%s/cwd: %w", strconv.Itoa(p.pid), err)
}
}
p.info.CWD = strings.TrimSuffix(cwd, "/")
return *p.info, nil
}