-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathprocess_darwin.h
73 lines (60 loc) · 1.98 KB
/
process_darwin.h
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
// +build darwin
#ifndef _GO_PROCESSDARWIN_H_INCLUDED
#define _GO_PROCESSDARWIN_H_INCLUDED
#include <errno.h>
#include <stdlib.h>
#include <sys/sysctl.h>
// This is declared in process_darwin.go
extern void go_darwin_append_proc4(pid_t, pid_t, char *, long, int);
// Loads the process table and calls the exported Go function to insert
// the data back into the Go space.
//
// This function is implemented in C because while it would technically
// be possible to do this all in Go, I didn't want to go spelunking through
// header files to get all the structures properly. It is much easier to just
// call it in C and be done with it.
static inline int darwinProcesses() {
int err = 0;
int i = 0;
static const int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
size_t length = 0;
struct kinfo_proc *result = NULL;
size_t resultCount = 0;
// Get the length first
err = sysctl((int*)name, (sizeof(name) / sizeof(*name)) - 1,
NULL, &length, NULL, 0);
if (err != 0) {
goto ERREXIT;
}
// Allocate the appropriate sized buffer to read the process list
result = malloc(length);
// Call sysctl again with our buffer to fill it with the process list
err = sysctl((int*)name, (sizeof(name) / sizeof(*name)) - 1,
result, &length,
NULL, 0);
if (err != 0) {
goto ERREXIT;
}
resultCount = length / sizeof(struct kinfo_proc);
for (i = 0; i < resultCount; i++) {
struct kinfo_proc *single = &result[i];
int isZombie = 0;
if (single->kp_proc.p_stat == SZOMB) { isZombie = 1; }
go_darwin_append_proc4(
single->kp_proc.p_pid,
single->kp_eproc.e_ppid,
single->kp_proc.p_comm,
single->kp_proc.p_un.__p_starttime.tv_sec,
isZombie
);
}
ERREXIT:
if (result != NULL) {
free(result);
}
if (err != 0) {
return errno;
}
return 0;
}
#endif