summaryrefslogtreecommitdiff
path: root/vendor/github.com/keybase/go-ps/darwincgo/process_darwin.go
blob: ab9edf417a3550e4a9816c882b481fc692cc7506 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// +build darwin

package darwincgo

/*
#include <stdio.h>
#include <errno.h>
#include <libproc.h>
extern int darwinProcesses();
extern void darwinProcessPaths();
*/
import "C"

import (
	"path/filepath"
	"sync"
)

// This lock is what verifies that C calling back into Go is only
// modifying data once at a time.
var darwinLock sync.Mutex
var darwinProcsByPID map[int]*DarwinProcess

// DarwinProcess is process definition for OS X
type DarwinProcess struct {
	pid  int
	ppid int
	path string
}

// Pid returns process id
func (p *DarwinProcess) Pid() int {
	return p.pid
}

// PPid returns parent process id
func (p *DarwinProcess) PPid() int {
	return p.ppid
}

// Executable returns process executable name
func (p *DarwinProcess) Executable() string {
	path, _ := p.Path()
	return filepath.Base(path)
}

// Path returns path to process executable
func (p *DarwinProcess) Path() (string, error) {
	return p.path, nil
}

//export goDarwinAppendProc
func goDarwinAppendProc(pid C.pid_t, ppid C.pid_t, comm *C.char) {
	proc := &DarwinProcess{
		pid:  int(pid),
		ppid: int(ppid),
	}
	darwinProcsByPID[proc.pid] = proc
}

//export goDarwinSetPath
func goDarwinSetPath(pid C.pid_t, comm *C.char) {
	if proc, ok := darwinProcsByPID[int(pid)]; ok && proc != nil {
		proc.path = C.GoString(comm)
	}
}

// ProcessMap returns a map of processes for the main library package.
func ProcessMap() (map[int]*DarwinProcess, error) {
	darwinLock.Lock()
	defer darwinLock.Unlock()
	darwinProcsByPID = make(map[int]*DarwinProcess)

	// To ignore deadcode warnings for exported functions
	_ = goDarwinAppendProc
	_ = goDarwinSetPath

	// TODO: Investigate why darwinProcesses returns error even if process list
	// succeeds
	C.darwinProcesses()
	C.darwinProcessPaths()

	return darwinProcsByPID, nil
}