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