From 6f5b1dbee7a9bb75a4443c6e3c32e3c8ed1e5a1d Mon Sep 17 00:00:00 2001 From: Lomanic Date: Thu, 5 Sep 2019 18:35:16 +0200 Subject: [PATCH] [darwin][process] Add cgo implementation of Exe() from PR #243 Original from ppanyukov https://github.com/shirou/gopsutil/commit/447301409866fd5ca98a70339fbdcdbbdb3c280c --- process/process_darwin.go | 22 ---------------------- process/process_darwin_cgo.go | 30 ++++++++++++++++++++++++++++++ process/process_darwin_nocgo.go | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 22 deletions(-) create mode 100644 process/process_darwin_cgo.go create mode 100644 process/process_darwin_nocgo.go diff --git a/process/process_darwin.go b/process/process_darwin.go index 98a5566..480c236 100644 --- a/process/process_darwin.go +++ b/process/process_darwin.go @@ -99,28 +99,6 @@ func (p *Process) Exe() (string, error) { return p.ExeWithContext(context.Background()) } -func (p *Process) ExeWithContext(ctx context.Context) (string, error) { - lsof_bin, err := exec.LookPath("lsof") - if err != nil { - return "", err - } - out, err := invoke.CommandWithContext(ctx, lsof_bin, "-p", strconv.Itoa(int(p.Pid)), "-Fpfn") - if err != nil { - return "", fmt.Errorf("bad call to lsof: %s", err) - } - txtFound := 0 - lines := strings.Split(string(out), "\n") - for i := 1; i < len(lines); i += 2 { - if lines[i] == "ftxt" { - txtFound++ - if txtFound == 2 { - return lines[i-1][1:], nil - } - } - } - return "", fmt.Errorf("missing txt data returned by lsof") -} - // Cmdline returns the command line arguments of the process as a string with // each argument separated by 0x20 ascii character. func (p *Process) Cmdline() (string, error) { diff --git a/process/process_darwin_cgo.go b/process/process_darwin_cgo.go new file mode 100644 index 0000000..a808177 --- /dev/null +++ b/process/process_darwin_cgo.go @@ -0,0 +1,30 @@ +// +build darwin +// +build cgo + +package process + +// #include +// #include +import "C" +import ( + "context" + "fmt" + "unsafe" +) + +func (p *Process) ExeWithContext(ctx context.Context) (string, error) { + var c C.char // need a var for unsafe.Sizeof need a var + const bufsize = C.PROC_PIDPATHINFO_MAXSIZE * unsafe.Sizeof(c) + buffer := (*C.char)(C.malloc(C.size_t(bufsize))) + defer C.free(unsafe.Pointer(buffer)) + + ret, err := C.proc_pidpath(C.int(p.Pid), unsafe.Pointer(buffer), C.uint32_t(bufsize)) + if err != nil { + return "", err + } + if ret <= 0 { + return "", fmt.Errorf("unknown error: proc_pidpath returned %d", ret) + } + + return C.GoString(buffer), nil +} diff --git a/process/process_darwin_nocgo.go b/process/process_darwin_nocgo.go new file mode 100644 index 0000000..86466fd --- /dev/null +++ b/process/process_darwin_nocgo.go @@ -0,0 +1,34 @@ +// +build darwin +// +build !cgo + +package process + +import ( + "context" + "fmt" + "os/exec" + "strconv" + "strings" +) + +func (p *Process) ExeWithContext(ctx context.Context) (string, error) { + lsof_bin, err := exec.LookPath("lsof") + if err != nil { + return "", err + } + out, err := invoke.CommandWithContext(ctx, lsof_bin, "-p", strconv.Itoa(int(p.Pid)), "-Fpfn") + if err != nil { + return "", fmt.Errorf("bad call to lsof: %s", err) + } + txtFound := 0 + lines := strings.Split(string(out), "\n") + for i := 1; i < len(lines); i += 2 { + if lines[i] == "ftxt" { + txtFound++ + if txtFound == 2 { + return lines[i-1][1:], nil + } + } + } + return "", fmt.Errorf("missing txt data returned by lsof") +}