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
}
|