1
2 #ifndef _GNU_SOURCE
3 #define _GNU_SOURCE 1
4 #endif
5
6 #include <assert.h>
7 #include <errno.h>
8 #include <stdbool.h>
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <utmpx.h>
12 #include <sys/sysctl.h>
13 #include <sys/vmmeter.h>
14 #include <libproc.h>
15 #include <sys/proc_info.h>
16 #include <netinet/tcp_fsm.h>
17 #include <arpa/inet.h>
18 #include <net/if_dl.h>
19 #include <pwd.h>
20
21 #include <mach/mach.h>
22 #include <mach/task.h>
23 #include <mach/mach_init.h>
24 #include <mach/host_info.h>
25 #include <mach/mach_host.h>
26 #include <mach/mach_traps.h>
27 #include <mach/mach_vm.h>
28 #include <mach/shared_region.h>
29
30 #include <mach-o/loader.h>
31
32 #include <CoreFoundation/CoreFoundation.h>
33 #include <IOKit/IOKitLib.h>
34 #include <IOKit/storage/IOBlockStorageDriver.h>
35 #include <IOKit/storage/IOMedia.h>
36 #include <IOKit/IOBSD.h>
37 #include <IOKit/ps/IOPowerSources.h>
38 #include <IOKit/ps/IOPSKeys.h>
39
40 #include "common.h"
41 #include "posix.h"
42 #include "arch/macos/process_info.h"
43
44
45 #define PS__TV2DOUBLE(t) ((t).tv_sec + (t).tv_usec / 1000000.0)
46
47 /*
48 * Return an integer vector of all the PIDs running on the system.
49 */
ps__pids()50 SEXP ps__pids() {
51 kinfo_proc *proclist = NULL;
52 kinfo_proc *orig_address = NULL;
53 size_t num_processes;
54 size_t idx;
55 SEXP retlist = R_NilValue;
56
57 if (ps__get_proc_list(&proclist, &num_processes) != 0) {
58 if (errno != 0) {
59 ps__set_error_from_errno();
60 } else {
61 ps__set_error("failed to retrieve process list");
62 }
63 goto error;
64 }
65
66 retlist = PROTECT(allocVector(INTSXP, num_processes));
67
68 if (num_processes > 0) {
69 // save the address of proclist so we can free it later
70 orig_address = proclist;
71 for (idx = 0; idx < num_processes; idx++) {
72 INTEGER(retlist)[idx] = proclist->kp_proc.p_pid;
73 proclist++;
74 }
75 free(orig_address);
76 }
77
78 UNPROTECT(1);
79 return retlist;
80
81 error:
82 if (orig_address != NULL) free(orig_address);
83 ps__throw_error();
84 return R_NilValue;
85 }
86
ps__define_tcp_statuses()87 SEXP ps__define_tcp_statuses() {
88 SEXP result, names;
89
90 PROTECT(result = allocVector(INTSXP, 12));
91 PROTECT(names = allocVector(STRSXP, 12));
92
93 INTEGER(result)[0] = TCPS_CLOSED;
94 SET_STRING_ELT(names, 0, mkChar("CONN_CLOSE"));
95 INTEGER(result)[1] = TCPS_CLOSING;
96 SET_STRING_ELT(names, 1, mkChar("CONN_CLOSING"));
97 INTEGER(result)[2] = TCPS_CLOSE_WAIT;
98 SET_STRING_ELT(names, 2, mkChar("CONN_CLOSE_WAIT"));
99 INTEGER(result)[3] = TCPS_LISTEN;
100 SET_STRING_ELT(names, 3, mkChar("CONN_LISTEN"));
101 INTEGER(result)[4] = TCPS_ESTABLISHED;
102 SET_STRING_ELT(names, 4, mkChar("CONN_ESTABLISHED"));
103 INTEGER(result)[5] = TCPS_SYN_SENT;
104 SET_STRING_ELT(names, 5, mkChar("CONN_SYN_SENT"));
105 INTEGER(result)[6] = TCPS_SYN_RECEIVED;
106 SET_STRING_ELT(names, 6, mkChar("CONN_SYN_RECV"));
107 INTEGER(result)[7] = TCPS_FIN_WAIT_1;
108 SET_STRING_ELT(names, 7, mkChar("CONN_FIN_WAIT_1"));
109 INTEGER(result)[8] = TCPS_FIN_WAIT_2;
110 SET_STRING_ELT(names, 8, mkChar("CONN_FIN_WAIT_2"));
111 INTEGER(result)[9] = TCPS_LAST_ACK;
112 SET_STRING_ELT(names, 9, mkChar("CONN_LAST_ACK"));
113 INTEGER(result)[10] = TCPS_TIME_WAIT;
114 SET_STRING_ELT(names, 10, mkChar("CONN_TIME_WAIT"));
115 INTEGER(result)[11] = PS__CONN_NONE;
116 SET_STRING_ELT(names, 11, mkChar("PS__CONN_NONE"));
117
118 setAttrib(result, R_NamesSymbol, names);
119 UNPROTECT(2);
120 return result;
121 }
122
ps__init(SEXP psenv,SEXP constenv)123 SEXP ps__init(SEXP psenv, SEXP constenv) {
124
125 /* Signals */
126 defineVar(install("signals"), ps__define_signals(), constenv);
127
128 /* errno values */
129 defineVar(install("errno"), ps__define_errno(), constenv);
130
131 /* Connection statuses */
132 defineVar(install("tcp_statuses"), ps__define_tcp_statuses(), constenv);
133
134 /* Socket address families */
135 defineVar(install("address_families"),
136 ps__define_socket_address_families(), constenv);
137
138 /* Socket address families */
139 defineVar(install("socket_types"), ps__define_socket_types(), constenv);
140
141 return R_NilValue;
142 }
143