xref: /xnu-11417.101.15/tests/proc_info.c (revision e3723e1f17661b24996789d8afc084c0c3303b26)
1*e3723e1fSApple OSS Distributions #define PRIVATE
2*e3723e1fSApple OSS Distributions #include <System/sys/kdebug.h>
3*e3723e1fSApple OSS Distributions #include <darwintest.h>
4*e3723e1fSApple OSS Distributions #include <darwintest_utils.h>
5*e3723e1fSApple OSS Distributions #include <dispatch/dispatch.h>
6*e3723e1fSApple OSS Distributions #include <fcntl.h>
7*e3723e1fSApple OSS Distributions #include <inttypes.h>
8*e3723e1fSApple OSS Distributions #include <libproc.h>
9*e3723e1fSApple OSS Distributions #include <libgen.h>
10*e3723e1fSApple OSS Distributions #include <limits.h>
11*e3723e1fSApple OSS Distributions #include <mach/mach.h>
12*e3723e1fSApple OSS Distributions #include <mach/policy.h>
13*e3723e1fSApple OSS Distributions #include <mach/vm_param.h>
14*e3723e1fSApple OSS Distributions #include <os/assumes.h>
15*e3723e1fSApple OSS Distributions #include <os/overflow.h>
16*e3723e1fSApple OSS Distributions #include <pthread.h>
17*e3723e1fSApple OSS Distributions #include <pthread/qos_private.h>
18*e3723e1fSApple OSS Distributions #include <signal.h>
19*e3723e1fSApple OSS Distributions #include <stdint.h>
20*e3723e1fSApple OSS Distributions #include <stdio.h>
21*e3723e1fSApple OSS Distributions #include <stdlib.h>
22*e3723e1fSApple OSS Distributions #include <string.h>
23*e3723e1fSApple OSS Distributions #include <sys/event.h>
24*e3723e1fSApple OSS Distributions #include <sys/mman.h>
25*e3723e1fSApple OSS Distributions #include <sys/proc_info.h>
26*e3723e1fSApple OSS Distributions #include <sys/stat.h>
27*e3723e1fSApple OSS Distributions #include <sys/sysctl.h>
28*e3723e1fSApple OSS Distributions #include <sys/vnode.h>
29*e3723e1fSApple OSS Distributions #include <unistd.h>
30*e3723e1fSApple OSS Distributions #undef PRIVATE
31*e3723e1fSApple OSS Distributions 
32*e3723e1fSApple OSS Distributions #include "recount/recount_test_utils.h"
33*e3723e1fSApple OSS Distributions 
34*e3723e1fSApple OSS Distributions T_GLOBAL_META(T_META_RUN_CONCURRENTLY(true));
35*e3723e1fSApple OSS Distributions 
36*e3723e1fSApple OSS Distributions #define ACT_CHANGE_UID 1
37*e3723e1fSApple OSS Distributions #define ACT_CHANGE_RUID 2
38*e3723e1fSApple OSS Distributions #define ACT_EXIT 127
39*e3723e1fSApple OSS Distributions 
40*e3723e1fSApple OSS Distributions #define ACT_PHASE2 2
41*e3723e1fSApple OSS Distributions #define ACT_PHASE3 3
42*e3723e1fSApple OSS Distributions #define ACT_PHASE4 4
43*e3723e1fSApple OSS Distributions #define ACT_PHASE5 5
44*e3723e1fSApple OSS Distributions 
45*e3723e1fSApple OSS Distributions #define PIPE_IN 0
46*e3723e1fSApple OSS Distributions #define PIPE_OUT 1
47*e3723e1fSApple OSS Distributions 
48*e3723e1fSApple OSS Distributions #define CONF_THREAD_NAME "test_child_thread"
49*e3723e1fSApple OSS Distributions #define CONF_CMD_NAME getprogname()
50*e3723e1fSApple OSS Distributions #define CONF_PROC_COUNT 20
51*e3723e1fSApple OSS Distributions #define CONF_BLK_SIZE 4096
52*e3723e1fSApple OSS Distributions #define CONF_UID_VAL 999U
53*e3723e1fSApple OSS Distributions #define CONF_RUID_VAL 998U
54*e3723e1fSApple OSS Distributions #define CONF_GID_VAL 997U
55*e3723e1fSApple OSS Distributions #define CONF_NICE_VAL 5
56*e3723e1fSApple OSS Distributions #define CONF_NUM_THREADS 2
57*e3723e1fSApple OSS Distributions 
58*e3723e1fSApple OSS Distributions #define BASEPRI_DEFAULT 31
59*e3723e1fSApple OSS Distributions #define MAXPRI_USER 63
60*e3723e1fSApple OSS Distributions 
61*e3723e1fSApple OSS Distributions #define CONF_OPN_FILE_COUNT 3
62*e3723e1fSApple OSS Distributions #define CONF_TMP_FILE_PFX   "/tmp/xnu.tests.proc_info."
63*e3723e1fSApple OSS Distributions static int
CONF_TMP_FILE_OPEN(char path[PATH_MAX])64*e3723e1fSApple OSS Distributions CONF_TMP_FILE_OPEN(char path[PATH_MAX])
65*e3723e1fSApple OSS Distributions {
66*e3723e1fSApple OSS Distributions 	static char stmp_path[PATH_MAX] = {};
67*e3723e1fSApple OSS Distributions 	char *nm;
68*e3723e1fSApple OSS Distributions 	if (path) {
69*e3723e1fSApple OSS Distributions 		nm = path;
70*e3723e1fSApple OSS Distributions 	} else {
71*e3723e1fSApple OSS Distributions 		nm = stmp_path;
72*e3723e1fSApple OSS Distributions 	}
73*e3723e1fSApple OSS Distributions 	strlcpy(nm, CONF_TMP_FILE_PFX "XXXXXXXXXX", PATH_MAX);
74*e3723e1fSApple OSS Distributions 	int fd = mkstemp(nm);
75*e3723e1fSApple OSS Distributions 	T_QUIET;
76*e3723e1fSApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(fd, "mkstemp(" CONF_TMP_FILE_PFX "XXXXXXXXXX)");
77*e3723e1fSApple OSS Distributions 	return fd;
78*e3723e1fSApple OSS Distributions }
79*e3723e1fSApple OSS Distributions 
80*e3723e1fSApple OSS Distributions uint32_t get_tty_dev(void);
81*e3723e1fSApple OSS Distributions 
82*e3723e1fSApple OSS Distributions #define WAIT_FOR_CHILDREN(pipefd, action, child_count)                           \
83*e3723e1fSApple OSS Distributions 	do {                                                                         \
84*e3723e1fSApple OSS Distributions 	        long ret;                                                                \
85*e3723e1fSApple OSS Distributions 	        if (child_count == 1) {                                                  \
86*e3723e1fSApple OSS Distributions 	                int child_ret_action = 999;                                          \
87*e3723e1fSApple OSS Distributions 	                while (child_ret_action != action) {                                 \
88*e3723e1fSApple OSS Distributions 	                        ret = read(pipefd, &child_ret_action, sizeof(child_ret_action)); \
89*e3723e1fSApple OSS Distributions 	                }                                                                    \
90*e3723e1fSApple OSS Distributions 	        } else {                                                                 \
91*e3723e1fSApple OSS Distributions 	                int child_ready_count = child_count * (int)sizeof(action);           \
92*e3723e1fSApple OSS Distributions                                                                                  \
93*e3723e1fSApple OSS Distributions 	                action = 0;                                                          \
94*e3723e1fSApple OSS Distributions 	                while (child_ready_count) {                                          \
95*e3723e1fSApple OSS Distributions 	                        ret = read(pipefd, &action, (int)sizeof(action));                \
96*e3723e1fSApple OSS Distributions 	                        if (ret != -1) {                                                 \
97*e3723e1fSApple OSS Distributions 	                                child_ready_count -= ret;                                    \
98*e3723e1fSApple OSS Distributions 	                        } else {                                                         \
99*e3723e1fSApple OSS Distributions 	                                T_FAIL("ERROR: Could not read from pipe() : %d", errno);     \
100*e3723e1fSApple OSS Distributions 	                        }                                                                \
101*e3723e1fSApple OSS Distributions 	                        if (action) {                                                    \
102*e3723e1fSApple OSS Distributions 	                                T_FAIL("ERROR: Child action failed with error %d", action);  \
103*e3723e1fSApple OSS Distributions 	                        }                                                                \
104*e3723e1fSApple OSS Distributions 	                }                                                                    \
105*e3723e1fSApple OSS Distributions 	        }                                                                        \
106*e3723e1fSApple OSS Distributions 	} while (0)
107*e3723e1fSApple OSS Distributions 
108*e3723e1fSApple OSS Distributions #define PROC_INFO_CALL(struct_name, pid, flavor, proc_arg)                                                     \
109*e3723e1fSApple OSS Distributions 	do {                                                                                                       \
110*e3723e1fSApple OSS Distributions 	        struct struct_name * struct_var = malloc(sizeof(struct struct_name));                                  \
111*e3723e1fSApple OSS Distributions 	        T_QUIET;                                                                                               \
112*e3723e1fSApple OSS Distributions 	        T_ASSERT_NOTNULL(struct_var, "malloc() for " #flavor);                                                 \
113*e3723e1fSApple OSS Distributions 	        retval = __proc_info(PROC_INFO_CALL_PIDINFO, pid, flavor, (uint64_t)proc_arg, (user_addr_t)struct_var, \
114*e3723e1fSApple OSS Distributions 	                             (uint32_t)sizeof(struct struct_name));                                            \
115*e3723e1fSApple OSS Distributions                                                                                                                \
116*e3723e1fSApple OSS Distributions 	        T_QUIET;                                                                                               \
117*e3723e1fSApple OSS Distributions 	        T_EXPECT_POSIX_SUCCESS(retval, "__proc_info call for " #flavor);                                       \
118*e3723e1fSApple OSS Distributions 	        T_ASSERT_EQ_INT(retval, (int)sizeof(struct struct_name), "__proc_info call for " #flavor);             \
119*e3723e1fSApple OSS Distributions 	        ret_structs[i] = (void *)struct_var;                                                                   \
120*e3723e1fSApple OSS Distributions 	        i++;                                                                                                   \
121*e3723e1fSApple OSS Distributions 	} while (0)
122*e3723e1fSApple OSS Distributions 
123*e3723e1fSApple OSS Distributions uint32_t
get_tty_dev()124*e3723e1fSApple OSS Distributions get_tty_dev()
125*e3723e1fSApple OSS Distributions {
126*e3723e1fSApple OSS Distributions 	struct stat buf;
127*e3723e1fSApple OSS Distributions 	stat(ttyname(1), &buf);
128*e3723e1fSApple OSS Distributions 	return (uint32_t)buf.st_rdev;
129*e3723e1fSApple OSS Distributions }
130*e3723e1fSApple OSS Distributions 
131*e3723e1fSApple OSS Distributions /*
132*e3723e1fSApple OSS Distributions  * Defined in libsyscall/wrappers/libproc/libproc.c
133*e3723e1fSApple OSS Distributions  * For API test only. For normal use, please use the libproc API instead.
134*e3723e1fSApple OSS Distributions  * DO NOT COPY
135*e3723e1fSApple OSS Distributions  */
136*e3723e1fSApple OSS Distributions extern int __proc_info(int32_t callnum, int32_t pid, uint32_t flavor, uint64_t arg, user_addr_t buffer, int32_t buffersize);
137*e3723e1fSApple OSS Distributions struct proc_config_s {
138*e3723e1fSApple OSS Distributions 	int parent_pipe[2];
139*e3723e1fSApple OSS Distributions 	int child_count;
140*e3723e1fSApple OSS Distributions 	pid_t proc_grp_id;
141*e3723e1fSApple OSS Distributions 	int child_pipe[CONF_PROC_COUNT][2];
142*e3723e1fSApple OSS Distributions 	int child_pids[CONF_PROC_COUNT];
143*e3723e1fSApple OSS Distributions 	void * cow_map; /* memory for cow test */
144*e3723e1fSApple OSS Distributions };
145*e3723e1fSApple OSS Distributions typedef struct proc_config_s * proc_config_t;
146*e3723e1fSApple OSS Distributions 
147*e3723e1fSApple OSS Distributions typedef void (^child_action_handler_t)(proc_config_t proc_config, int child_id);
148*e3723e1fSApple OSS Distributions 
149*e3723e1fSApple OSS Distributions enum proc_info_opt {
150*e3723e1fSApple OSS Distributions 	P_UNIQIDINFO    = 0x01,
151*e3723e1fSApple OSS Distributions 	C_UNIQIDINFO    = 0x02,
152*e3723e1fSApple OSS Distributions 	PBSD_OLD        = 0x04,
153*e3723e1fSApple OSS Distributions 	PBSD            = 0x08,
154*e3723e1fSApple OSS Distributions 	PBSD_SHORT      = 0x10,
155*e3723e1fSApple OSS Distributions 	PBSD_UNIQID     = 0x20,
156*e3723e1fSApple OSS Distributions 	P_TASK_INFO     = 0x40,
157*e3723e1fSApple OSS Distributions 	P_TASK_INFO_NEW = 0x80,
158*e3723e1fSApple OSS Distributions 	PALL            = 0x100,
159*e3723e1fSApple OSS Distributions 	THREAD_ADDR     = 0x200,
160*e3723e1fSApple OSS Distributions 	PTHINFO_OLD     = 0x400,
161*e3723e1fSApple OSS Distributions 	PTHINFO         = 0x800,
162*e3723e1fSApple OSS Distributions 	PTHINFO_64      = 0x1000,
163*e3723e1fSApple OSS Distributions 	PINFO_PATH      = 0x2000,
164*e3723e1fSApple OSS Distributions 	PAI             = 0x4000,
165*e3723e1fSApple OSS Distributions 	PREGINFO        = 0x8000,
166*e3723e1fSApple OSS Distributions 	PREGINFO_PATH   = 0x10000,
167*e3723e1fSApple OSS Distributions 	PREGINFO_PATH_2 = 0x20000,
168*e3723e1fSApple OSS Distributions 	PREGINFO_PATH_3 = 0x40000,
169*e3723e1fSApple OSS Distributions 	PVNINFO         = 0x80000
170*e3723e1fSApple OSS Distributions };
171*e3723e1fSApple OSS Distributions 
172*e3723e1fSApple OSS Distributions static int tmp_fd = -1;
173*e3723e1fSApple OSS Distributions 
174*e3723e1fSApple OSS Distributions static child_action_handler_t proc_info_listpids_handler = ^void (proc_config_t proc_config, int child_id) {
175*e3723e1fSApple OSS Distributions 	close(proc_config->parent_pipe[PIPE_IN]);
176*e3723e1fSApple OSS Distributions 	close(proc_config->child_pipe[child_id][PIPE_OUT]);
177*e3723e1fSApple OSS Distributions 	long retval      = 0;
178*e3723e1fSApple OSS Distributions 	int child_action = 0;
179*e3723e1fSApple OSS Distributions 	retval           = write(proc_config->parent_pipe[PIPE_OUT], &child_action, sizeof(child_action));
180*e3723e1fSApple OSS Distributions 	if (retval != -1) {
181*e3723e1fSApple OSS Distributions 		while (child_action != ACT_EXIT) {
182*e3723e1fSApple OSS Distributions 			retval = read(proc_config->child_pipe[child_id][PIPE_IN], &child_action, sizeof(child_action));
183*e3723e1fSApple OSS Distributions 			if (retval == 0 || (retval == -1 && errno == EAGAIN)) {
184*e3723e1fSApple OSS Distributions 				continue;
185*e3723e1fSApple OSS Distributions 			}
186*e3723e1fSApple OSS Distributions 			if (retval != -1) {
187*e3723e1fSApple OSS Distributions 				switch (child_action) {
188*e3723e1fSApple OSS Distributions 				case ACT_CHANGE_UID:
189*e3723e1fSApple OSS Distributions 					/*
190*e3723e1fSApple OSS Distributions 					 * Change uid
191*e3723e1fSApple OSS Distributions 					 */
192*e3723e1fSApple OSS Distributions 					retval = setuid(CONF_UID_VAL);
193*e3723e1fSApple OSS Distributions 					break;
194*e3723e1fSApple OSS Distributions 				case ACT_CHANGE_RUID:
195*e3723e1fSApple OSS Distributions 					/*
196*e3723e1fSApple OSS Distributions 					 * Change ruid
197*e3723e1fSApple OSS Distributions 					 */
198*e3723e1fSApple OSS Distributions 					retval = setreuid(CONF_RUID_VAL, (uid_t)-1);
199*e3723e1fSApple OSS Distributions 					break;
200*e3723e1fSApple OSS Distributions 				case ACT_EXIT:
201*e3723e1fSApple OSS Distributions 					/*
202*e3723e1fSApple OSS Distributions 					 * Exit
203*e3723e1fSApple OSS Distributions 					 */
204*e3723e1fSApple OSS Distributions 					break;
205*e3723e1fSApple OSS Distributions 				}
206*e3723e1fSApple OSS Distributions 			}
207*e3723e1fSApple OSS Distributions 			if (child_action != ACT_EXIT) {
208*e3723e1fSApple OSS Distributions 				retval = write(proc_config->parent_pipe[PIPE_OUT], &retval, sizeof(retval));
209*e3723e1fSApple OSS Distributions 				if (retval == -1) {
210*e3723e1fSApple OSS Distributions 					break;
211*e3723e1fSApple OSS Distributions 				}
212*e3723e1fSApple OSS Distributions 			}
213*e3723e1fSApple OSS Distributions 		}
214*e3723e1fSApple OSS Distributions 	}
215*e3723e1fSApple OSS Distributions 	close(proc_config->parent_pipe[PIPE_OUT]);
216*e3723e1fSApple OSS Distributions 	close(proc_config->child_pipe[child_id][PIPE_IN]);
217*e3723e1fSApple OSS Distributions 	exit(0);
218*e3723e1fSApple OSS Distributions };
219*e3723e1fSApple OSS Distributions 
220*e3723e1fSApple OSS Distributions static child_action_handler_t proc_info_call_pidinfo_handler = ^void (proc_config_t proc_config, int child_id) {
221*e3723e1fSApple OSS Distributions 	close(proc_config->parent_pipe[PIPE_IN]);
222*e3723e1fSApple OSS Distributions 	close(proc_config->child_pipe[child_id][PIPE_OUT]);
223*e3723e1fSApple OSS Distributions 	int action  = 0;
224*e3723e1fSApple OSS Distributions 	long retval = 0;
225*e3723e1fSApple OSS Distributions 	int i;
226*e3723e1fSApple OSS Distributions 	void * tmp_map           = NULL;
227*e3723e1fSApple OSS Distributions 	dispatch_queue_t q       = NULL;
228*e3723e1fSApple OSS Distributions 	dispatch_semaphore_t sem = NULL;
229*e3723e1fSApple OSS Distributions 	/*
230*e3723e1fSApple OSS Distributions 	 * PHASE 1: Child ready and waits for parent to send next action
231*e3723e1fSApple OSS Distributions 	 */
232*e3723e1fSApple OSS Distributions 	T_LOG("Child ready to accept action from parent");
233*e3723e1fSApple OSS Distributions 	retval = write(proc_config->parent_pipe[PIPE_OUT], &action, sizeof(action));
234*e3723e1fSApple OSS Distributions 	if (retval != -1) {
235*e3723e1fSApple OSS Distributions 		while (action != ACT_EXIT) {
236*e3723e1fSApple OSS Distributions 			retval = read(proc_config->child_pipe[child_id][PIPE_IN], &action, sizeof(action));
237*e3723e1fSApple OSS Distributions 
238*e3723e1fSApple OSS Distributions 			if (retval != -1) {
239*e3723e1fSApple OSS Distributions 				retval = 0;
240*e3723e1fSApple OSS Distributions 				switch (action) {
241*e3723e1fSApple OSS Distributions 				case ACT_PHASE2: {
242*e3723e1fSApple OSS Distributions 					/*
243*e3723e1fSApple OSS Distributions 					 * Change uid, euid, guid, rgid, nice value
244*e3723e1fSApple OSS Distributions 					 * Also change the svuid and svgid
245*e3723e1fSApple OSS Distributions 					 */
246*e3723e1fSApple OSS Distributions 					T_LOG("Child changing uid, euid, rguid, svuid, svgid and nice value");
247*e3723e1fSApple OSS Distributions 					retval = nice(CONF_NICE_VAL);
248*e3723e1fSApple OSS Distributions 					if (retval == -1) {
249*e3723e1fSApple OSS Distributions 						T_LOG("(child) ERROR: nice() failed");
250*e3723e1fSApple OSS Distributions 						break;
251*e3723e1fSApple OSS Distributions 					}
252*e3723e1fSApple OSS Distributions 					retval = setgid(CONF_GID_VAL);
253*e3723e1fSApple OSS Distributions 					if (retval == -1) {
254*e3723e1fSApple OSS Distributions 						T_LOG("(child) ERROR: setgid() failed");
255*e3723e1fSApple OSS Distributions 						break;
256*e3723e1fSApple OSS Distributions 					}
257*e3723e1fSApple OSS Distributions 					retval = setreuid((uid_t)-1, CONF_RUID_VAL);
258*e3723e1fSApple OSS Distributions 					if (retval == -1) {
259*e3723e1fSApple OSS Distributions 						T_LOG("(child) ERROR: setreuid() failed");
260*e3723e1fSApple OSS Distributions 						break;
261*e3723e1fSApple OSS Distributions 					}
262*e3723e1fSApple OSS Distributions 					break;
263*e3723e1fSApple OSS Distributions 				}
264*e3723e1fSApple OSS Distributions 				case ACT_PHASE3: {
265*e3723e1fSApple OSS Distributions 					/*
266*e3723e1fSApple OSS Distributions 					 * Allocate a page of memory
267*e3723e1fSApple OSS Distributions 					 * Copy on write shared memory
268*e3723e1fSApple OSS Distributions 					 *
269*e3723e1fSApple OSS Distributions 					 * WARNING
270*e3723e1fSApple OSS Distributions 					 * Don't add calls to T_LOG here as they can end up generating unwanted
271*e3723e1fSApple OSS Distributions 					 * calls to mach_msg_send(). If curtask->messages_sent gets incremented
272*e3723e1fSApple OSS Distributions 					 * at this point it will interfere with testing pti_messages_sent.
273*e3723e1fSApple OSS Distributions 					 */
274*e3723e1fSApple OSS Distributions 					retval  = 0;
275*e3723e1fSApple OSS Distributions 					tmp_map = mmap(0, PAGE_SIZE, PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
276*e3723e1fSApple OSS Distributions 					if (tmp_map == MAP_FAILED) {
277*e3723e1fSApple OSS Distributions 						T_LOG("(child) ERROR: mmap() failed");
278*e3723e1fSApple OSS Distributions 						retval = 1;
279*e3723e1fSApple OSS Distributions 						break;
280*e3723e1fSApple OSS Distributions 					}
281*e3723e1fSApple OSS Distributions 					/*
282*e3723e1fSApple OSS Distributions 					 * Get the page allocated
283*e3723e1fSApple OSS Distributions 					 */
284*e3723e1fSApple OSS Distributions 					int * map_ptr = (int *)tmp_map;
285*e3723e1fSApple OSS Distributions 					for (i = 0; i < (int)(PAGE_SIZE / sizeof(int)); i++) {
286*e3723e1fSApple OSS Distributions 						*map_ptr++ = i;
287*e3723e1fSApple OSS Distributions 					}
288*e3723e1fSApple OSS Distributions 					/*
289*e3723e1fSApple OSS Distributions 					 * Cause copy on write to the page
290*e3723e1fSApple OSS Distributions 					 */
291*e3723e1fSApple OSS Distributions 					*((int *)(proc_config->cow_map)) = 20;
292*e3723e1fSApple OSS Distributions 
293*e3723e1fSApple OSS Distributions 					break;
294*e3723e1fSApple OSS Distributions 				}
295*e3723e1fSApple OSS Distributions 				case ACT_PHASE4: {
296*e3723e1fSApple OSS Distributions 					T_LOG("Child spending CPU cycles and changing thread name");
297*e3723e1fSApple OSS Distributions 					retval                       = 0;
298*e3723e1fSApple OSS Distributions 					int number                   = 1000;
299*e3723e1fSApple OSS Distributions 					unsigned long long factorial = 1;
300*e3723e1fSApple OSS Distributions 					int j;
301*e3723e1fSApple OSS Distributions 					for (j = 1; j <= number; j++) {
302*e3723e1fSApple OSS Distributions 						factorial *= (unsigned long long)j;
303*e3723e1fSApple OSS Distributions 					}
304*e3723e1fSApple OSS Distributions 					sysctlbyname("kern.threadname", NULL, 0, CONF_THREAD_NAME, strlen(CONF_THREAD_NAME));
305*e3723e1fSApple OSS Distributions 					break;
306*e3723e1fSApple OSS Distributions 				}
307*e3723e1fSApple OSS Distributions 				case ACT_PHASE5: {
308*e3723e1fSApple OSS Distributions 					/*
309*e3723e1fSApple OSS Distributions 					 * Dispatch for Workq test
310*e3723e1fSApple OSS Distributions 					 */
311*e3723e1fSApple OSS Distributions 					T_LOG("Child creating a dispatch queue, and dispatching blocks on it");
312*e3723e1fSApple OSS Distributions 					q = dispatch_queue_create("com.apple.test_proc_info.workqtest",
313*e3723e1fSApple OSS Distributions 					    DISPATCH_QUEUE_CONCURRENT);                     // dispatch_get_global_queue(0, 0);
314*e3723e1fSApple OSS Distributions 					sem = dispatch_semaphore_create(0);
315*e3723e1fSApple OSS Distributions 
316*e3723e1fSApple OSS Distributions 					for (i = 0; i < CONF_NUM_THREADS; i++) {
317*e3723e1fSApple OSS Distributions 						dispatch_async(q, ^{
318*e3723e1fSApple OSS Distributions 								/*
319*e3723e1fSApple OSS Distributions 								 * Block the thread, do nothing
320*e3723e1fSApple OSS Distributions 								 */
321*e3723e1fSApple OSS Distributions 								dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
322*e3723e1fSApple OSS Distributions 							});
323*e3723e1fSApple OSS Distributions 					}
324*e3723e1fSApple OSS Distributions 					break;
325*e3723e1fSApple OSS Distributions 				}
326*e3723e1fSApple OSS Distributions 				case ACT_EXIT: {
327*e3723e1fSApple OSS Distributions 					/*
328*e3723e1fSApple OSS Distributions 					 * Exit
329*e3723e1fSApple OSS Distributions 					 */
330*e3723e1fSApple OSS Distributions 					if (sem) {
331*e3723e1fSApple OSS Distributions 						for (i = 0; i < CONF_NUM_THREADS; i++) {
332*e3723e1fSApple OSS Distributions 							dispatch_semaphore_signal(sem);
333*e3723e1fSApple OSS Distributions 						}
334*e3723e1fSApple OSS Distributions 					}
335*e3723e1fSApple OSS Distributions 
336*e3723e1fSApple OSS Distributions 					if (tmp_map) {
337*e3723e1fSApple OSS Distributions 						munmap(tmp_map, PAGE_SIZE);
338*e3723e1fSApple OSS Distributions 					}
339*e3723e1fSApple OSS Distributions 
340*e3723e1fSApple OSS Distributions 					if (proc_config->cow_map) {
341*e3723e1fSApple OSS Distributions 						munmap(proc_config->cow_map, PAGE_SIZE);
342*e3723e1fSApple OSS Distributions 					}
343*e3723e1fSApple OSS Distributions 
344*e3723e1fSApple OSS Distributions 					break;
345*e3723e1fSApple OSS Distributions 				}
346*e3723e1fSApple OSS Distributions 				}
347*e3723e1fSApple OSS Distributions 			}
348*e3723e1fSApple OSS Distributions 			if (action != ACT_EXIT) {
349*e3723e1fSApple OSS Distributions 				retval = write(proc_config->parent_pipe[PIPE_OUT], &action, sizeof(action));
350*e3723e1fSApple OSS Distributions 				if (retval == -1) {
351*e3723e1fSApple OSS Distributions 					break;
352*e3723e1fSApple OSS Distributions 				}
353*e3723e1fSApple OSS Distributions 			}
354*e3723e1fSApple OSS Distributions 		}
355*e3723e1fSApple OSS Distributions 		close(proc_config->parent_pipe[PIPE_OUT]);
356*e3723e1fSApple OSS Distributions 		close(proc_config->child_pipe[child_id][PIPE_IN]);
357*e3723e1fSApple OSS Distributions 		exit(0);
358*e3723e1fSApple OSS Distributions 	}
359*e3723e1fSApple OSS Distributions };
360*e3723e1fSApple OSS Distributions 
361*e3723e1fSApple OSS Distributions static void
free_proc_config(proc_config_t proc_config)362*e3723e1fSApple OSS Distributions free_proc_config(proc_config_t proc_config)
363*e3723e1fSApple OSS Distributions {
364*e3723e1fSApple OSS Distributions 	free(proc_config);
365*e3723e1fSApple OSS Distributions }
366*e3723e1fSApple OSS Distributions 
367*e3723e1fSApple OSS Distributions static void
send_action_to_child_processes(proc_config_t proc_config,int action)368*e3723e1fSApple OSS Distributions send_action_to_child_processes(proc_config_t proc_config, int action)
369*e3723e1fSApple OSS Distributions {
370*e3723e1fSApple OSS Distributions 	long err;
371*e3723e1fSApple OSS Distributions 	for (int i = 0; i < proc_config->child_count; i++) {
372*e3723e1fSApple OSS Distributions 		err = write(proc_config->child_pipe[i][PIPE_OUT], &action, sizeof(action));
373*e3723e1fSApple OSS Distributions 		T_QUIET;
374*e3723e1fSApple OSS Distributions 		T_ASSERT_POSIX_SUCCESS(err, "write() to child in send_action");
375*e3723e1fSApple OSS Distributions 	}
376*e3723e1fSApple OSS Distributions 	if (action != ACT_EXIT) {
377*e3723e1fSApple OSS Distributions 		WAIT_FOR_CHILDREN(proc_config->parent_pipe[PIPE_IN], action, proc_config->child_count);
378*e3723e1fSApple OSS Distributions 	}
379*e3723e1fSApple OSS Distributions }
380*e3723e1fSApple OSS Distributions 
381*e3723e1fSApple OSS Distributions static void
kill_child_processes(proc_config_t proc_config)382*e3723e1fSApple OSS Distributions kill_child_processes(proc_config_t proc_config)
383*e3723e1fSApple OSS Distributions {
384*e3723e1fSApple OSS Distributions 	int ret = 0;
385*e3723e1fSApple OSS Distributions 	T_LOG("Killing child processes");
386*e3723e1fSApple OSS Distributions 	send_action_to_child_processes(proc_config, ACT_EXIT);
387*e3723e1fSApple OSS Distributions 	for (int child_id = 0; child_id < proc_config->child_count; child_id++) {
388*e3723e1fSApple OSS Distributions 		close(proc_config->child_pipe[child_id][PIPE_OUT]);
389*e3723e1fSApple OSS Distributions 		dt_waitpid(proc_config->child_pids[child_id], NULL, NULL, 5);
390*e3723e1fSApple OSS Distributions 		T_QUIET;
391*e3723e1fSApple OSS Distributions 		T_ASSERT_POSIX_SUCCESS(ret, "killed child %d", child_id);
392*e3723e1fSApple OSS Distributions 	}
393*e3723e1fSApple OSS Distributions 	close(proc_config->parent_pipe[PIPE_IN]);
394*e3723e1fSApple OSS Distributions 	munmap(proc_config->cow_map, PAGE_SIZE);
395*e3723e1fSApple OSS Distributions 	T_LOG("Killed child processes");
396*e3723e1fSApple OSS Distributions }
397*e3723e1fSApple OSS Distributions 
398*e3723e1fSApple OSS Distributions static proc_config_t
spawn_child_processes(int child_count,child_action_handler_t child_handler)399*e3723e1fSApple OSS Distributions spawn_child_processes(int child_count, child_action_handler_t child_handler)
400*e3723e1fSApple OSS Distributions {
401*e3723e1fSApple OSS Distributions 	/*
402*e3723e1fSApple OSS Distributions 	 * Spawn procs for Tests 1.2 and 1.3
403*e3723e1fSApple OSS Distributions 	 */
404*e3723e1fSApple OSS Distributions 	T_LOG("Spawning child processes...");
405*e3723e1fSApple OSS Distributions 	proc_config_t proc_config = malloc(sizeof(*proc_config));
406*e3723e1fSApple OSS Distributions 	int action                = 0;
407*e3723e1fSApple OSS Distributions 	int err;
408*e3723e1fSApple OSS Distributions 
409*e3723e1fSApple OSS Distributions 	setpgid(0, 0);
410*e3723e1fSApple OSS Distributions 	proc_config->proc_grp_id = getpgid(0);
411*e3723e1fSApple OSS Distributions 
412*e3723e1fSApple OSS Distributions 	proc_config->child_count = child_count;
413*e3723e1fSApple OSS Distributions 
414*e3723e1fSApple OSS Distributions 	err = pipe(proc_config->parent_pipe);
415*e3723e1fSApple OSS Distributions 	T_QUIET;
416*e3723e1fSApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(err, "pipe() call");
417*e3723e1fSApple OSS Distributions 
418*e3723e1fSApple OSS Distributions 	/*
419*e3723e1fSApple OSS Distributions 	 * Needed for ACT_PHASE3 tests
420*e3723e1fSApple OSS Distributions 	 */
421*e3723e1fSApple OSS Distributions 	proc_config->cow_map = mmap(0, PAGE_SIZE, PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
422*e3723e1fSApple OSS Distributions 	T_QUIET;
423*e3723e1fSApple OSS Distributions 	T_ASSERT_NE_PTR(proc_config->cow_map, MAP_FAILED, "cow_map mmap()");
424*e3723e1fSApple OSS Distributions 	*((int *)(proc_config->cow_map)) = 10;
425*e3723e1fSApple OSS Distributions 
426*e3723e1fSApple OSS Distributions 	pid_t child_pid;
427*e3723e1fSApple OSS Distributions 	int i;
428*e3723e1fSApple OSS Distributions 	int child_id;
429*e3723e1fSApple OSS Distributions 	for (i = 0; i < child_count; i++) {
430*e3723e1fSApple OSS Distributions 		err = pipe(proc_config->child_pipe[i]);
431*e3723e1fSApple OSS Distributions 		T_QUIET;
432*e3723e1fSApple OSS Distributions 		T_ASSERT_POSIX_SUCCESS(err, "pipe() call");
433*e3723e1fSApple OSS Distributions 
434*e3723e1fSApple OSS Distributions 		child_pid = fork();
435*e3723e1fSApple OSS Distributions 		child_id  = i;
436*e3723e1fSApple OSS Distributions 		T_QUIET;
437*e3723e1fSApple OSS Distributions 		T_ASSERT_POSIX_SUCCESS(child_pid, "fork() in parent process for child %d", child_id);
438*e3723e1fSApple OSS Distributions 
439*e3723e1fSApple OSS Distributions 		if (child_pid == 0) {
440*e3723e1fSApple OSS Distributions 			child_handler(proc_config, child_id);
441*e3723e1fSApple OSS Distributions 		} else {
442*e3723e1fSApple OSS Distributions 			proc_config->child_pids[child_id] = child_pid;
443*e3723e1fSApple OSS Distributions 		}
444*e3723e1fSApple OSS Distributions 		close(proc_config->child_pipe[child_id][PIPE_IN]);
445*e3723e1fSApple OSS Distributions 	}
446*e3723e1fSApple OSS Distributions 	/*
447*e3723e1fSApple OSS Distributions 	 * Wait for the children processes to spawn
448*e3723e1fSApple OSS Distributions 	 */
449*e3723e1fSApple OSS Distributions 	close(proc_config->parent_pipe[PIPE_OUT]);
450*e3723e1fSApple OSS Distributions 	WAIT_FOR_CHILDREN(proc_config->parent_pipe[PIPE_IN], action, child_count);
451*e3723e1fSApple OSS Distributions 
452*e3723e1fSApple OSS Distributions 	return proc_config;
453*e3723e1fSApple OSS Distributions }
454*e3723e1fSApple OSS Distributions 
455*e3723e1fSApple OSS Distributions /*
456*e3723e1fSApple OSS Distributions  *  All PROC_INFO_CALL_PIDINFO __proc_info calls fire from this function.
457*e3723e1fSApple OSS Distributions  *  T_DECLs require different combinations of structs and different actions
458*e3723e1fSApple OSS Distributions  *  must occur in the child to get the data.  Instead of performing the setup
459*e3723e1fSApple OSS Distributions  *  in each T_DECL, this function accepts a bitmap and performs the necessary setup
460*e3723e1fSApple OSS Distributions  *  and cleanup work
461*e3723e1fSApple OSS Distributions  */
462*e3723e1fSApple OSS Distributions 
463*e3723e1fSApple OSS Distributions static void
proc_info_caller(int proc_info_opts,void ** ret_structs,int * ret_child_pid)464*e3723e1fSApple OSS Distributions proc_info_caller(int proc_info_opts, void ** ret_structs, int * ret_child_pid)
465*e3723e1fSApple OSS Distributions {
466*e3723e1fSApple OSS Distributions 	int retval, i = 0;
467*e3723e1fSApple OSS Distributions 	uint64_t * thread_addr = NULL;
468*e3723e1fSApple OSS Distributions 	void * map_tmp         = NULL;
469*e3723e1fSApple OSS Distributions 	static char tmp_path[PATH_MAX] = {};
470*e3723e1fSApple OSS Distributions 
471*e3723e1fSApple OSS Distributions 	proc_config_t proc_config = spawn_child_processes(1, proc_info_call_pidinfo_handler);
472*e3723e1fSApple OSS Distributions 	int child_pid             = proc_config->child_pids[0];
473*e3723e1fSApple OSS Distributions 	/*
474*e3723e1fSApple OSS Distributions 	 * These tests only require one child.
475*e3723e1fSApple OSS Distributions 	 * Some DECLs need to know the child pid, so we pass that back if applicable
476*e3723e1fSApple OSS Distributions 	 */
477*e3723e1fSApple OSS Distributions 	if (ret_child_pid != NULL) {
478*e3723e1fSApple OSS Distributions 		*ret_child_pid = child_pid;
479*e3723e1fSApple OSS Distributions 	}
480*e3723e1fSApple OSS Distributions 
481*e3723e1fSApple OSS Distributions 	if (proc_info_opts & P_UNIQIDINFO) {
482*e3723e1fSApple OSS Distributions 		PROC_INFO_CALL(proc_uniqidentifierinfo, getpid(), PROC_PIDUNIQIDENTIFIERINFO, 0);
483*e3723e1fSApple OSS Distributions 	}
484*e3723e1fSApple OSS Distributions 	if (proc_info_opts & C_UNIQIDINFO) {
485*e3723e1fSApple OSS Distributions 		PROC_INFO_CALL(proc_uniqidentifierinfo, child_pid, PROC_PIDUNIQIDENTIFIERINFO, 0);
486*e3723e1fSApple OSS Distributions 	}
487*e3723e1fSApple OSS Distributions 	if (proc_info_opts & PBSD_OLD) {
488*e3723e1fSApple OSS Distributions 		PROC_INFO_CALL(proc_bsdinfo, child_pid, PROC_PIDTBSDINFO, 0);
489*e3723e1fSApple OSS Distributions 	}
490*e3723e1fSApple OSS Distributions 
491*e3723e1fSApple OSS Distributions 	/*
492*e3723e1fSApple OSS Distributions 	 * Child Phase 2 Fires if opts require it
493*e3723e1fSApple OSS Distributions 	 * Small nap after call to give child time to receive and execute the action
494*e3723e1fSApple OSS Distributions 	 */
495*e3723e1fSApple OSS Distributions 
496*e3723e1fSApple OSS Distributions 	if (proc_info_opts >= PBSD) {
497*e3723e1fSApple OSS Distributions 		send_action_to_child_processes(proc_config, ACT_PHASE2);
498*e3723e1fSApple OSS Distributions 	}
499*e3723e1fSApple OSS Distributions 
500*e3723e1fSApple OSS Distributions 	if (proc_info_opts & PBSD) {
501*e3723e1fSApple OSS Distributions 		PROC_INFO_CALL(proc_bsdinfo, child_pid, PROC_PIDTBSDINFO, 0);
502*e3723e1fSApple OSS Distributions 	}
503*e3723e1fSApple OSS Distributions 
504*e3723e1fSApple OSS Distributions 	if (proc_info_opts & PBSD_SHORT) {
505*e3723e1fSApple OSS Distributions 		PROC_INFO_CALL(proc_bsdshortinfo, child_pid, PROC_PIDT_SHORTBSDINFO, 0);
506*e3723e1fSApple OSS Distributions 	}
507*e3723e1fSApple OSS Distributions 
508*e3723e1fSApple OSS Distributions 	if (proc_info_opts & PBSD_UNIQID) {
509*e3723e1fSApple OSS Distributions 		PROC_INFO_CALL(proc_bsdinfowithuniqid, child_pid, PROC_PIDT_BSDINFOWITHUNIQID, 0);
510*e3723e1fSApple OSS Distributions 	}
511*e3723e1fSApple OSS Distributions 	if (proc_info_opts & P_TASK_INFO) {
512*e3723e1fSApple OSS Distributions 		PROC_INFO_CALL(proc_taskinfo, child_pid, PROC_PIDTASKINFO, 0);
513*e3723e1fSApple OSS Distributions 	}
514*e3723e1fSApple OSS Distributions 
515*e3723e1fSApple OSS Distributions 	/*
516*e3723e1fSApple OSS Distributions 	 * Child Phase 3 Fires
517*e3723e1fSApple OSS Distributions 	 */
518*e3723e1fSApple OSS Distributions 	if (proc_info_opts >= P_TASK_INFO_NEW) {
519*e3723e1fSApple OSS Distributions 		send_action_to_child_processes(proc_config, ACT_PHASE3);
520*e3723e1fSApple OSS Distributions 	}
521*e3723e1fSApple OSS Distributions 
522*e3723e1fSApple OSS Distributions 	if (proc_info_opts & P_TASK_INFO_NEW) {
523*e3723e1fSApple OSS Distributions 		PROC_INFO_CALL(proc_taskinfo, child_pid, PROC_PIDTASKINFO, 0);
524*e3723e1fSApple OSS Distributions 	}
525*e3723e1fSApple OSS Distributions 
526*e3723e1fSApple OSS Distributions 	if (proc_info_opts & PALL) {
527*e3723e1fSApple OSS Distributions 		PROC_INFO_CALL(proc_taskallinfo, child_pid, PROC_PIDTASKALLINFO, 0);
528*e3723e1fSApple OSS Distributions 	}
529*e3723e1fSApple OSS Distributions 	/*
530*e3723e1fSApple OSS Distributions 	 * This case breaks the pattern in that its proc_info call requires PALL,
531*e3723e1fSApple OSS Distributions 	 * its value is required in some other proc_info calls
532*e3723e1fSApple OSS Distributions 	 * and we never put the retval into our ret_structs
533*e3723e1fSApple OSS Distributions 	 */
534*e3723e1fSApple OSS Distributions 	if (proc_info_opts & THREAD_ADDR || proc_info_opts & PTHINFO_OLD || proc_info_opts & PTHINFO || proc_info_opts & PINFO_PATH) {
535*e3723e1fSApple OSS Distributions 		struct proc_taskallinfo * pall = malloc(sizeof(struct proc_taskallinfo));
536*e3723e1fSApple OSS Distributions 		T_QUIET;
537*e3723e1fSApple OSS Distributions 		T_ASSERT_NOTNULL(pall, "malloc() for PROC_TASKALLINFO");
538*e3723e1fSApple OSS Distributions 
539*e3723e1fSApple OSS Distributions 		retval = __proc_info(PROC_INFO_CALL_PIDINFO, child_pid, PROC_PIDTASKALLINFO, (uint32_t)0, (user_addr_t)pall,
540*e3723e1fSApple OSS Distributions 		    (uint32_t)sizeof(struct proc_taskallinfo));
541*e3723e1fSApple OSS Distributions 		T_QUIET;
542*e3723e1fSApple OSS Distributions 		T_ASSERT_EQ_INT(retval, (int)sizeof(struct proc_taskallinfo), "__proc_info call for PROC_PIDTASKALLINFO in THREAD_ADDR");
543*e3723e1fSApple OSS Distributions 
544*e3723e1fSApple OSS Distributions 		thread_addr = malloc(sizeof(uint64_t) * (unsigned long)(pall->ptinfo.pti_threadnum + 1));
545*e3723e1fSApple OSS Distributions 		memset(thread_addr, 0, sizeof(uint64_t) * (unsigned long)(pall->ptinfo.pti_threadnum + 1));
546*e3723e1fSApple OSS Distributions 		T_QUIET;
547*e3723e1fSApple OSS Distributions 		T_ASSERT_NOTNULL(thread_addr, "malloc() for PROC_PIDLISTTHREADS");
548*e3723e1fSApple OSS Distributions 
549*e3723e1fSApple OSS Distributions 		retval = __proc_info(PROC_INFO_CALL_PIDINFO, child_pid, PROC_PIDLISTTHREADS, (uint32_t)0, (user_addr_t)thread_addr,
550*e3723e1fSApple OSS Distributions 		    (int32_t)(sizeof(uint64_t) * (unsigned long)(pall->ptinfo.pti_threadnum + 1)));
551*e3723e1fSApple OSS Distributions 		T_LOG("(int)((unsigned long)retval / PROC_PIDLISTTHREADS_SIZE: %d",
552*e3723e1fSApple OSS Distributions 		    (int)((unsigned long)retval / PROC_PIDLISTTHREADS_SIZE));
553*e3723e1fSApple OSS Distributions 		T_ASSERT_GE_INT((int)((unsigned long)retval / PROC_PIDLISTTHREADS_SIZE), pall->ptinfo.pti_threadnum,
554*e3723e1fSApple OSS Distributions 		    "__proc_info call for PROC_PIDLISTTHREADS");
555*e3723e1fSApple OSS Distributions 
556*e3723e1fSApple OSS Distributions 		free(pall);
557*e3723e1fSApple OSS Distributions 	}
558*e3723e1fSApple OSS Distributions 	if (proc_info_opts & PTHINFO_OLD) {
559*e3723e1fSApple OSS Distributions 		PROC_INFO_CALL(proc_threadinfo, child_pid, PROC_PIDTHREADINFO, thread_addr[0]);
560*e3723e1fSApple OSS Distributions 	}
561*e3723e1fSApple OSS Distributions 
562*e3723e1fSApple OSS Distributions 	/*
563*e3723e1fSApple OSS Distributions 	 * Child Phase 4 Fires
564*e3723e1fSApple OSS Distributions 	 */
565*e3723e1fSApple OSS Distributions 	if (proc_info_opts >= PTHINFO) {
566*e3723e1fSApple OSS Distributions 		send_action_to_child_processes(proc_config, ACT_PHASE4);
567*e3723e1fSApple OSS Distributions 	}
568*e3723e1fSApple OSS Distributions 
569*e3723e1fSApple OSS Distributions 	if (proc_info_opts & PTHINFO) {
570*e3723e1fSApple OSS Distributions 		PROC_INFO_CALL(proc_threadinfo, child_pid, PROC_PIDTHREADINFO, thread_addr[0]);
571*e3723e1fSApple OSS Distributions 	}
572*e3723e1fSApple OSS Distributions 	if (proc_info_opts & PTHINFO_64) {
573*e3723e1fSApple OSS Distributions 		mach_port_name_t child_task  = MACH_PORT_NULL;
574*e3723e1fSApple OSS Distributions 		thread_array_t child_threads = NULL;
575*e3723e1fSApple OSS Distributions 		mach_msg_type_number_t child_thread_count;
576*e3723e1fSApple OSS Distributions 		thread_identifier_info_data_t child_thread_threadinfo;
577*e3723e1fSApple OSS Distributions 		mach_msg_type_number_t thread_info_count = THREAD_IDENTIFIER_INFO_COUNT;
578*e3723e1fSApple OSS Distributions 		struct proc_threadinfo * pthinfo_64      = malloc(sizeof(struct proc_threadinfo));
579*e3723e1fSApple OSS Distributions 		T_QUIET;
580*e3723e1fSApple OSS Distributions 		T_ASSERT_NOTNULL(pthinfo_64, "malloc() for PROC_THREADINFO");
581*e3723e1fSApple OSS Distributions 
582*e3723e1fSApple OSS Distributions 		retval = task_for_pid(mach_task_self(), child_pid, &child_task);
583*e3723e1fSApple OSS Distributions 		T_ASSERT_EQ_INT(retval, 0, "task_for_pid for PROC_PIDTHREADID64INFO");
584*e3723e1fSApple OSS Distributions 
585*e3723e1fSApple OSS Distributions 		retval = task_threads(child_task, &child_threads, &child_thread_count);
586*e3723e1fSApple OSS Distributions 		T_ASSERT_MACH_SUCCESS(retval, "task_threads() call for PROC_PIDTHREADID64INFO");
587*e3723e1fSApple OSS Distributions 
588*e3723e1fSApple OSS Distributions 		retval = thread_info(child_threads[0], THREAD_IDENTIFIER_INFO, (thread_info_t)&child_thread_threadinfo, &thread_info_count);
589*e3723e1fSApple OSS Distributions 		T_ASSERT_MACH_SUCCESS(retval, "thread_info call for PROC_PIDTHREADID64INFO");
590*e3723e1fSApple OSS Distributions 
591*e3723e1fSApple OSS Distributions 		retval = __proc_info(PROC_INFO_CALL_PIDINFO, child_pid, PROC_PIDTHREADID64INFO, (uint64_t)child_thread_threadinfo.thread_id,
592*e3723e1fSApple OSS Distributions 		    (user_addr_t)pthinfo_64, (uint32_t)sizeof(struct proc_threadinfo));
593*e3723e1fSApple OSS Distributions 		T_ASSERT_EQ_INT(retval, (int)sizeof(struct proc_threadinfo), "__proc_info call for PROC_PIDTHREADID64INFO");
594*e3723e1fSApple OSS Distributions 
595*e3723e1fSApple OSS Distributions 		ret_structs[i] = (void *)pthinfo_64;
596*e3723e1fSApple OSS Distributions 		i++;
597*e3723e1fSApple OSS Distributions 
598*e3723e1fSApple OSS Distributions 		mach_port_deallocate(mach_task_self(), child_task);
599*e3723e1fSApple OSS Distributions 		mach_port_deallocate(mach_task_self(), child_threads[0]);
600*e3723e1fSApple OSS Distributions 		child_threads[0] = MACH_PORT_NULL;
601*e3723e1fSApple OSS Distributions 		child_task       = MACH_PORT_NULL;
602*e3723e1fSApple OSS Distributions 	}
603*e3723e1fSApple OSS Distributions 	if (proc_info_opts & PINFO_PATH) {
604*e3723e1fSApple OSS Distributions 		PROC_INFO_CALL(proc_threadwithpathinfo, child_pid, PROC_PIDTHREADPATHINFO, thread_addr[0]);
605*e3723e1fSApple OSS Distributions 	}
606*e3723e1fSApple OSS Distributions 
607*e3723e1fSApple OSS Distributions 	if (proc_info_opts & PAI) {
608*e3723e1fSApple OSS Distributions 		PROC_INFO_CALL(proc_archinfo, getpid(), PROC_PIDARCHINFO, 0);
609*e3723e1fSApple OSS Distributions 	}
610*e3723e1fSApple OSS Distributions 
611*e3723e1fSApple OSS Distributions 	vm_map_size_t map_tmp_sz = 0;
612*e3723e1fSApple OSS Distributions 	if ((proc_info_opts & PREGINFO) | (proc_info_opts & PREGINFO_PATH) | (proc_info_opts & PREGINFO_PATH_2) |
613*e3723e1fSApple OSS Distributions 	    (proc_info_opts & PREGINFO_PATH_3)) {
614*e3723e1fSApple OSS Distributions 		tmp_fd = CONF_TMP_FILE_OPEN(tmp_path);
615*e3723e1fSApple OSS Distributions 
616*e3723e1fSApple OSS Distributions 		/*
617*e3723e1fSApple OSS Distributions 		 * subsequent checks assume that this data does *not* stay
618*e3723e1fSApple OSS Distributions 		 * resident in the buffer cache, so set F_NOCACHE for direct
619*e3723e1fSApple OSS Distributions 		 * to storage writing. NOTE: this works if the writes are
620*e3723e1fSApple OSS Distributions 		 * page-aligned and > 2 pages in length.
621*e3723e1fSApple OSS Distributions 		 */
622*e3723e1fSApple OSS Distributions 		retval = fcntl(tmp_fd, F_NOCACHE, 1);
623*e3723e1fSApple OSS Distributions 		T_QUIET;
624*e3723e1fSApple OSS Distributions 		T_ASSERT_POSIX_SUCCESS(retval, "fcntl(%d, F_NOCACHE) failed", tmp_fd);
625*e3723e1fSApple OSS Distributions 
626*e3723e1fSApple OSS Distributions 		int npages_to_write = 10;
627*e3723e1fSApple OSS Distributions 		map_tmp_sz = (vm_map_size_t)npages_to_write * (vm_map_size_t)PAGE_SIZE;
628*e3723e1fSApple OSS Distributions 
629*e3723e1fSApple OSS Distributions 		/*
630*e3723e1fSApple OSS Distributions 		 * To make sure we don't go through the cached write paths in
631*e3723e1fSApple OSS Distributions 		 * the VM, we allocate a PAGE-aligned buffer that is > 2
632*e3723e1fSApple OSS Distributions 		 * pages, and perform a write of the entire buffer (not in
633*e3723e1fSApple OSS Distributions 		 * small page-aligned chunks).
634*e3723e1fSApple OSS Distributions 		 */
635*e3723e1fSApple OSS Distributions 		char *buf = valloc((size_t)map_tmp_sz);
636*e3723e1fSApple OSS Distributions 		T_QUIET;
637*e3723e1fSApple OSS Distributions 		T_ASSERT_NOTNULL(buf, "valloc(%d) failed", (int)map_tmp_sz);
638*e3723e1fSApple OSS Distributions 
639*e3723e1fSApple OSS Distributions 		memset(buf, 0x5, map_tmp_sz);
640*e3723e1fSApple OSS Distributions 		ssize_t bw = write(tmp_fd, buf, (size_t)map_tmp_sz);
641*e3723e1fSApple OSS Distributions 		T_QUIET;
642*e3723e1fSApple OSS Distributions 		T_ASSERT_GT_INT((int)bw, 0, "write(%d, buf, %d) failed", tmp_fd, (int)map_tmp_sz);
643*e3723e1fSApple OSS Distributions 
644*e3723e1fSApple OSS Distributions 		free(buf);
645*e3723e1fSApple OSS Distributions 
646*e3723e1fSApple OSS Distributions 		map_tmp_sz -= PAGE_SIZE;
647*e3723e1fSApple OSS Distributions 		map_tmp = mmap(0, (size_t)map_tmp_sz, PROT_WRITE, MAP_PRIVATE, tmp_fd, (off_t)PAGE_SIZE);
648*e3723e1fSApple OSS Distributions 		T_ASSERT_NE_PTR(map_tmp, MAP_FAILED, "mmap() for PROC_PIDREGIONINFO");
649*e3723e1fSApple OSS Distributions 
650*e3723e1fSApple OSS Distributions 		T_LOG("file: %s is opened as fd %d and mapped at %llx with size %lu", tmp_path, tmp_fd, (uint64_t)map_tmp,
651*e3723e1fSApple OSS Distributions 		    (unsigned long)PAGE_SIZE);
652*e3723e1fSApple OSS Distributions 
653*e3723e1fSApple OSS Distributions 		/*
654*e3723e1fSApple OSS Distributions 		 * unlink() the file to be nice, but do it _after_ we've
655*e3723e1fSApple OSS Distributions 		 * already flushed and mapped the file. This will ensure that
656*e3723e1fSApple OSS Distributions 		 * we don't end up writing to the buffer cache because the
657*e3723e1fSApple OSS Distributions 		 * file is unlinked.
658*e3723e1fSApple OSS Distributions 		 */
659*e3723e1fSApple OSS Distributions 		if (!(proc_info_opts & PREGINFO_PATH_3)) {
660*e3723e1fSApple OSS Distributions 			retval = unlink(tmp_path);
661*e3723e1fSApple OSS Distributions 			T_QUIET;
662*e3723e1fSApple OSS Distributions 			T_ASSERT_POSIX_SUCCESS(retval, "unlink(%s) failed", tmp_path);
663*e3723e1fSApple OSS Distributions 		}
664*e3723e1fSApple OSS Distributions 	}
665*e3723e1fSApple OSS Distributions 
666*e3723e1fSApple OSS Distributions 	if (proc_info_opts & PREGINFO) {
667*e3723e1fSApple OSS Distributions 		PROC_INFO_CALL(proc_regioninfo, getpid(), PROC_PIDREGIONINFO, map_tmp);
668*e3723e1fSApple OSS Distributions 		ret_structs[i] = map_tmp;
669*e3723e1fSApple OSS Distributions 		i++;
670*e3723e1fSApple OSS Distributions 		ret_structs[i] = (void *)(uintptr_t)map_tmp_sz;
671*e3723e1fSApple OSS Distributions 		i++;
672*e3723e1fSApple OSS Distributions 	}
673*e3723e1fSApple OSS Distributions 	if (proc_info_opts & PREGINFO_PATH) {
674*e3723e1fSApple OSS Distributions 		PROC_INFO_CALL(proc_regionwithpathinfo, getpid(), PROC_PIDREGIONPATHINFO, map_tmp);
675*e3723e1fSApple OSS Distributions 		ret_structs[i] = map_tmp;
676*e3723e1fSApple OSS Distributions 		i++;
677*e3723e1fSApple OSS Distributions 		ret_structs[i] = (void *)(uintptr_t)map_tmp_sz;
678*e3723e1fSApple OSS Distributions 		i++;
679*e3723e1fSApple OSS Distributions 	}
680*e3723e1fSApple OSS Distributions 	if (proc_info_opts & PREGINFO_PATH_2) {
681*e3723e1fSApple OSS Distributions 		PROC_INFO_CALL(proc_regionwithpathinfo, getpid(), PROC_PIDREGIONPATHINFO2, map_tmp);
682*e3723e1fSApple OSS Distributions 		ret_structs[i] = map_tmp;
683*e3723e1fSApple OSS Distributions 		i++;
684*e3723e1fSApple OSS Distributions 		ret_structs[i] = (void *)(uintptr_t)map_tmp_sz;
685*e3723e1fSApple OSS Distributions 		i++;
686*e3723e1fSApple OSS Distributions 	}
687*e3723e1fSApple OSS Distributions 
688*e3723e1fSApple OSS Distributions 	if (proc_info_opts & PREGINFO_PATH_3) {
689*e3723e1fSApple OSS Distributions 		struct proc_regionwithpathinfo * preginfo_path = malloc(sizeof(struct proc_regionwithpathinfo));
690*e3723e1fSApple OSS Distributions 
691*e3723e1fSApple OSS Distributions 		retval = __proc_info(PROC_INFO_CALL_PIDINFO, getpid(), PROC_PIDREGIONPATHINFO2, (uint64_t)map_tmp,
692*e3723e1fSApple OSS Distributions 		    (user_addr_t)preginfo_path, (uint32_t)sizeof(struct proc_regionwithpathinfo));
693*e3723e1fSApple OSS Distributions 
694*e3723e1fSApple OSS Distributions 		T_ASSERT_EQ_INT(retval, (int)sizeof(struct proc_regionwithpathinfo), "__proc_info call for PROC_PIDREGIONPATHINFO2");
695*e3723e1fSApple OSS Distributions 
696*e3723e1fSApple OSS Distributions 		T_LOG("preginfo_path.prp_vip.vip_vi.vi_fsid.val 0: %d", preginfo_path->prp_vip.vip_vi.vi_fsid.val[0]);
697*e3723e1fSApple OSS Distributions 		T_LOG("preginfo_path.prp_vip.vip_vi.vi_fsid.val 1: %d", preginfo_path->prp_vip.vip_vi.vi_fsid.val[1]);
698*e3723e1fSApple OSS Distributions 		ret_structs[3] = (void *)(uintptr_t)preginfo_path->prp_vip.vip_vi.vi_fsid.val[0];
699*e3723e1fSApple OSS Distributions 		ret_structs[4] = (void *)(uintptr_t)preginfo_path->prp_vip.vip_vi.vi_fsid.val[1];
700*e3723e1fSApple OSS Distributions 
701*e3723e1fSApple OSS Distributions 		retval = __proc_info(PROC_INFO_CALL_PIDINFO, getpid(), PROC_PIDREGIONPATHINFO3,
702*e3723e1fSApple OSS Distributions 		    (uint64_t)preginfo_path->prp_vip.vip_vi.vi_fsid.val[0] +
703*e3723e1fSApple OSS Distributions 		    ((uint64_t)preginfo_path->prp_vip.vip_vi.vi_fsid.val[1] << 32),
704*e3723e1fSApple OSS Distributions 		    (user_addr_t)preginfo_path,
705*e3723e1fSApple OSS Distributions 		    (uint32_t)sizeof(struct proc_regionwithpathinfo));
706*e3723e1fSApple OSS Distributions 		T_ASSERT_EQ_INT(retval, (int)sizeof(struct proc_regionwithpathinfo), "__proc_info call for PROC_PIDREGIONPATHWITHINFO3");
707*e3723e1fSApple OSS Distributions 		ret_structs[0] = (void *)preginfo_path;
708*e3723e1fSApple OSS Distributions 		ret_structs[1] = (void *)map_tmp;
709*e3723e1fSApple OSS Distributions 		ret_structs[2] = (void *)(uintptr_t)map_tmp_sz;
710*e3723e1fSApple OSS Distributions 
711*e3723e1fSApple OSS Distributions 		retval = unlink(tmp_path);
712*e3723e1fSApple OSS Distributions 		T_QUIET;
713*e3723e1fSApple OSS Distributions 		T_ASSERT_POSIX_SUCCESS(retval, "unlink(%s) failed", preginfo_path->prp_vip.vip_path);
714*e3723e1fSApple OSS Distributions 	}
715*e3723e1fSApple OSS Distributions 
716*e3723e1fSApple OSS Distributions 	if (proc_info_opts & PVNINFO) {
717*e3723e1fSApple OSS Distributions 		PROC_INFO_CALL(proc_vnodepathinfo, getpid(), PROC_PIDVNODEPATHINFO, 0);
718*e3723e1fSApple OSS Distributions 	}
719*e3723e1fSApple OSS Distributions 
720*e3723e1fSApple OSS Distributions 	kill_child_processes(proc_config);
721*e3723e1fSApple OSS Distributions 	free_proc_config(proc_config);
722*e3723e1fSApple OSS Distributions 	free(thread_addr);
723*e3723e1fSApple OSS Distributions 	thread_addr = NULL;
724*e3723e1fSApple OSS Distributions 	close(tmp_fd);
725*e3723e1fSApple OSS Distributions 	tmp_fd = -1;
726*e3723e1fSApple OSS Distributions }
727*e3723e1fSApple OSS Distributions 
728*e3723e1fSApple OSS Distributions static void
free_proc_info(void ** proc_info,int num)729*e3723e1fSApple OSS Distributions free_proc_info(void ** proc_info, int num)
730*e3723e1fSApple OSS Distributions {
731*e3723e1fSApple OSS Distributions 	for (int i = 0; i < num; i++) {
732*e3723e1fSApple OSS Distributions 		free(proc_info[i]);
733*e3723e1fSApple OSS Distributions 	}
734*e3723e1fSApple OSS Distributions 
735*e3723e1fSApple OSS Distributions 	return;
736*e3723e1fSApple OSS Distributions }
737*e3723e1fSApple OSS Distributions 
738*e3723e1fSApple OSS Distributions /*
739*e3723e1fSApple OSS Distributions  *	Start DECLs
740*e3723e1fSApple OSS Distributions  */
741*e3723e1fSApple OSS Distributions 
742*e3723e1fSApple OSS Distributions T_DECL(proc_info_listpids_all_pids,
743*e3723e1fSApple OSS Distributions     "proc_info API test to verify PROC_INFO_CALL_LISTPIDS",
744*e3723e1fSApple OSS Distributions     T_META_ASROOT(true), T_META_TAG_VM_PREFERRED)
745*e3723e1fSApple OSS Distributions {
746*e3723e1fSApple OSS Distributions 	/*
747*e3723e1fSApple OSS Distributions 	 * Get the value of nprocs with no buffer sent in
748*e3723e1fSApple OSS Distributions 	 */
749*e3723e1fSApple OSS Distributions 	int num_procs;
750*e3723e1fSApple OSS Distributions 	num_procs = __proc_info(PROC_INFO_CALL_LISTPIDS, PROC_ALL_PIDS, (uint32_t)getpid(), (uint32_t)0, (user_addr_t)0, (uint32_t)0);
751*e3723e1fSApple OSS Distributions 	T_ASSERT_GE_INT(num_procs, 1, "verify valid value for nprocs: %d", num_procs);
752*e3723e1fSApple OSS Distributions 
753*e3723e1fSApple OSS Distributions 	proc_config_t proc_config = spawn_child_processes(CONF_PROC_COUNT, proc_info_listpids_handler);
754*e3723e1fSApple OSS Distributions 
755*e3723e1fSApple OSS Distributions 	num_procs = __proc_info(PROC_INFO_CALL_LISTPIDS, PROC_ALL_PIDS, (uint32_t)getpid(), (uint32_t)0, (user_addr_t)0, (uint32_t)0);
756*e3723e1fSApple OSS Distributions 
757*e3723e1fSApple OSS Distributions 	int proc_count     = num_procs / (int)sizeof(pid_t);
758*e3723e1fSApple OSS Distributions 	int proc_count_all = num_procs / (int)sizeof(pid_t);
759*e3723e1fSApple OSS Distributions 	if (proc_count > (CONF_PROC_COUNT + 1)) {
760*e3723e1fSApple OSS Distributions 		proc_count = CONF_PROC_COUNT + 1;
761*e3723e1fSApple OSS Distributions 	}
762*e3723e1fSApple OSS Distributions 	pid_t * proc_ids = malloc(sizeof(pid_t) * (unsigned long)proc_count);
763*e3723e1fSApple OSS Distributions 	num_procs        = __proc_info(PROC_INFO_CALL_LISTPIDS, PROC_ALL_PIDS, (uint32_t)getpid(), (uint32_t)0, (user_addr_t)proc_ids,
764*e3723e1fSApple OSS Distributions 	    (int32_t)(proc_count * (int)sizeof(pid_t)));
765*e3723e1fSApple OSS Distributions 	num_procs = num_procs / (int)sizeof(pid_t);
766*e3723e1fSApple OSS Distributions 	T_ASSERT_GE_INT(num_procs, proc_count, "Valid number of pids obtained for PROC_ALL_PIDS.");
767*e3723e1fSApple OSS Distributions 
768*e3723e1fSApple OSS Distributions 	free(proc_ids);
769*e3723e1fSApple OSS Distributions 
770*e3723e1fSApple OSS Distributions 	/*
771*e3723e1fSApple OSS Distributions 	 * Grab list of all procs and make sure our spawned children are in the list.
772*e3723e1fSApple OSS Distributions 	 */
773*e3723e1fSApple OSS Distributions 
774*e3723e1fSApple OSS Distributions 	proc_ids  = malloc(sizeof(pid_t) * (unsigned long)proc_count_all);
775*e3723e1fSApple OSS Distributions 	num_procs = __proc_info(PROC_INFO_CALL_LISTPIDS, PROC_ALL_PIDS, (uint32_t)getpid(), (uint32_t)0, (user_addr_t)proc_ids,
776*e3723e1fSApple OSS Distributions 	    (int32_t)(proc_count_all * (int)sizeof(pid_t)));
777*e3723e1fSApple OSS Distributions 	num_procs = num_procs / (int)sizeof(pid_t);
778*e3723e1fSApple OSS Distributions 
779*e3723e1fSApple OSS Distributions 	int pid_match = 1;
780*e3723e1fSApple OSS Distributions 
781*e3723e1fSApple OSS Distributions 	for (int i = 0; i < (CONF_PROC_COUNT - 1); i++) {
782*e3723e1fSApple OSS Distributions 		for (int j = 0; j < num_procs; j++) {
783*e3723e1fSApple OSS Distributions 			if (proc_ids[j] == proc_config->child_pids[i]) {
784*e3723e1fSApple OSS Distributions 				break;
785*e3723e1fSApple OSS Distributions 			} else if (j == (num_procs - 1)) {
786*e3723e1fSApple OSS Distributions 				pid_match = 0;
787*e3723e1fSApple OSS Distributions 				break;
788*e3723e1fSApple OSS Distributions 			}
789*e3723e1fSApple OSS Distributions 		}
790*e3723e1fSApple OSS Distributions 
791*e3723e1fSApple OSS Distributions 		if (!pid_match) {
792*e3723e1fSApple OSS Distributions 			break;
793*e3723e1fSApple OSS Distributions 		}
794*e3723e1fSApple OSS Distributions 	}
795*e3723e1fSApple OSS Distributions 
796*e3723e1fSApple OSS Distributions 	T_ASSERT_EQ(pid_match, 1, "PROC_INFO_CALL_LISTPIDS contains our spawned children's pids");
797*e3723e1fSApple OSS Distributions 
798*e3723e1fSApple OSS Distributions 	free(proc_ids);
799*e3723e1fSApple OSS Distributions 
800*e3723e1fSApple OSS Distributions 	kill_child_processes(proc_config);
801*e3723e1fSApple OSS Distributions 	free_proc_config(proc_config);
802*e3723e1fSApple OSS Distributions 
803*e3723e1fSApple OSS Distributions 	errno     = 0;
804*e3723e1fSApple OSS Distributions 	num_procs = __proc_info(PROC_INFO_CALL_LISTPIDS, PROC_ALL_PIDS, (uint32_t)getpid(), (uint32_t)0, (user_addr_t)proc_ids,
805*e3723e1fSApple OSS Distributions 	    (uint32_t)(sizeof(pid_t) - 1));
806*e3723e1fSApple OSS Distributions 	T_EXPECT_POSIX_ERROR(errno, ENOMEM, "Valid proc_info behavior when bufsize < sizeof(pid_t).");
807*e3723e1fSApple OSS Distributions }
808*e3723e1fSApple OSS Distributions 
809*e3723e1fSApple OSS Distributions T_DECL(proc_info_listpids_pgrp_only,
810*e3723e1fSApple OSS Distributions     "proc_info API test to verify PROC_INFO_CALL_LISTPIDS",
811*e3723e1fSApple OSS Distributions     T_META_ASROOT(true), T_META_TAG_VM_PREFERRED)
812*e3723e1fSApple OSS Distributions {
813*e3723e1fSApple OSS Distributions 	proc_config_t proc_config = spawn_child_processes(CONF_PROC_COUNT, proc_info_listpids_handler);
814*e3723e1fSApple OSS Distributions 	T_LOG("Test to verify PROC_PGRP_ONLY returns correct value");
815*e3723e1fSApple OSS Distributions 	/*
816*e3723e1fSApple OSS Distributions 	 * The number of obtained pids depends on size of buffer.
817*e3723e1fSApple OSS Distributions 	 * count = childCount + 1(parent)
818*e3723e1fSApple OSS Distributions 	 * So, we set it to one more than expected to capture any error.
819*e3723e1fSApple OSS Distributions 	 */
820*e3723e1fSApple OSS Distributions 	int proc_count   = CONF_PROC_COUNT + 2;
821*e3723e1fSApple OSS Distributions 	pid_t * proc_ids = malloc(sizeof(*proc_ids) * (unsigned long)proc_count);
822*e3723e1fSApple OSS Distributions 	int num_procs    = __proc_info(PROC_INFO_CALL_LISTPIDS, PROC_PGRP_ONLY, (uint32_t)proc_config->proc_grp_id, (uint32_t)0,
823*e3723e1fSApple OSS Distributions 	    (user_addr_t)proc_ids, (int32_t)(proc_count * (int)sizeof(*proc_ids)));
824*e3723e1fSApple OSS Distributions 	num_procs = num_procs / (int)sizeof(pid_t);
825*e3723e1fSApple OSS Distributions 	T_ASSERT_EQ_INT(num_procs, CONF_PROC_COUNT + 1, "Valid number of pids obtained for PROC_PGRP_ONLY.");
826*e3723e1fSApple OSS Distributions 	kill_child_processes(proc_config);
827*e3723e1fSApple OSS Distributions 	free_proc_config(proc_config);
828*e3723e1fSApple OSS Distributions 	free(proc_ids);
829*e3723e1fSApple OSS Distributions }
830*e3723e1fSApple OSS Distributions 
831*e3723e1fSApple OSS Distributions T_DECL(proc_info_listpids_ppid_only,
832*e3723e1fSApple OSS Distributions     "proc_info API test to verify PROC_INFO_CALL_LISTPIDS",
833*e3723e1fSApple OSS Distributions     T_META_ASROOT(true), T_META_TAG_VM_PREFERRED)
834*e3723e1fSApple OSS Distributions {
835*e3723e1fSApple OSS Distributions 	proc_config_t proc_config = spawn_child_processes(CONF_PROC_COUNT, proc_info_listpids_handler);
836*e3723e1fSApple OSS Distributions 	T_LOG("Test to verify PROC_PPID_ONLY returns correct value");
837*e3723e1fSApple OSS Distributions 	/*
838*e3723e1fSApple OSS Distributions 	 * Pass in the same (bigger) buffer but expect only the pids where ppid is pid of current proc.
839*e3723e1fSApple OSS Distributions 	 */
840*e3723e1fSApple OSS Distributions 	int proc_count   = CONF_PROC_COUNT + 2;
841*e3723e1fSApple OSS Distributions 	pid_t * proc_ids = malloc(sizeof(*proc_ids) * (unsigned long)proc_count);
842*e3723e1fSApple OSS Distributions 	int num_procs    = __proc_info(PROC_INFO_CALL_LISTPIDS, PROC_PPID_ONLY, (uint32_t)getpid(), (uint32_t)0, (user_addr_t)proc_ids,
843*e3723e1fSApple OSS Distributions 	    (int32_t)(proc_count * (int)sizeof(*proc_ids)));
844*e3723e1fSApple OSS Distributions 	num_procs = num_procs / (int)sizeof(pid_t);
845*e3723e1fSApple OSS Distributions 	T_ASSERT_EQ_INT(num_procs, CONF_PROC_COUNT, "Valid number of pids obtained for PROC_PPID_ONLY.");
846*e3723e1fSApple OSS Distributions 	kill_child_processes(proc_config);
847*e3723e1fSApple OSS Distributions 	free_proc_config(proc_config);
848*e3723e1fSApple OSS Distributions 	free(proc_ids);
849*e3723e1fSApple OSS Distributions }
850*e3723e1fSApple OSS Distributions 
851*e3723e1fSApple OSS Distributions T_DECL(proc_info_listpids_uid_only,
852*e3723e1fSApple OSS Distributions     "proc_info API test to verify PROC_INFO_CALL_LISTPIDS",
853*e3723e1fSApple OSS Distributions     T_META_ASROOT(true), T_META_TAG_VM_PREFERRED)
854*e3723e1fSApple OSS Distributions {
855*e3723e1fSApple OSS Distributions 	proc_config_t proc_config = spawn_child_processes(CONF_PROC_COUNT, proc_info_listpids_handler);
856*e3723e1fSApple OSS Distributions 	T_LOG("Test to verify PROC_UID_ONLY returns correct value");
857*e3723e1fSApple OSS Distributions 	int proc_count   = CONF_PROC_COUNT + 2;
858*e3723e1fSApple OSS Distributions 	pid_t * proc_ids = malloc(sizeof(*proc_ids) * (unsigned long)proc_count);
859*e3723e1fSApple OSS Distributions 	send_action_to_child_processes(proc_config, ACT_CHANGE_UID);
860*e3723e1fSApple OSS Distributions 	usleep(10000);
861*e3723e1fSApple OSS Distributions 	int num_procs = __proc_info(PROC_INFO_CALL_LISTPIDS, PROC_UID_ONLY, CONF_UID_VAL, (uint32_t)0, (user_addr_t)proc_ids,
862*e3723e1fSApple OSS Distributions 	    (int32_t)(proc_count * (int)sizeof(*proc_ids)));
863*e3723e1fSApple OSS Distributions 	T_ASSERT_GE_ULONG((unsigned long)num_procs / sizeof(pid_t), (unsigned long)CONF_PROC_COUNT,
864*e3723e1fSApple OSS Distributions 	    "Valid number of pids obtained for PROC_UID_ONLY.");
865*e3723e1fSApple OSS Distributions 	kill_child_processes(proc_config);
866*e3723e1fSApple OSS Distributions 	free_proc_config(proc_config);
867*e3723e1fSApple OSS Distributions 	free(proc_ids);
868*e3723e1fSApple OSS Distributions }
869*e3723e1fSApple OSS Distributions 
870*e3723e1fSApple OSS Distributions T_DECL(proc_info_listpids_ruid_only,
871*e3723e1fSApple OSS Distributions     "proc_info API test to verify PROC_INFO_CALL_LISTPIDS",
872*e3723e1fSApple OSS Distributions     T_META_ASROOT(true), T_META_TAG_VM_PREFERRED)
873*e3723e1fSApple OSS Distributions {
874*e3723e1fSApple OSS Distributions 	proc_config_t proc_config = spawn_child_processes(CONF_PROC_COUNT, proc_info_listpids_handler);
875*e3723e1fSApple OSS Distributions 	T_LOG("Test to verify PROC_RUID_ONLY returns correct value");
876*e3723e1fSApple OSS Distributions 	int proc_count   = CONF_PROC_COUNT + 2;
877*e3723e1fSApple OSS Distributions 	pid_t * proc_ids = malloc(sizeof(*proc_ids) * (unsigned long)proc_count);
878*e3723e1fSApple OSS Distributions 	send_action_to_child_processes(proc_config, ACT_CHANGE_RUID);
879*e3723e1fSApple OSS Distributions 	usleep(10000);
880*e3723e1fSApple OSS Distributions 	int num_procs = __proc_info(PROC_INFO_CALL_LISTPIDS, PROC_RUID_ONLY, CONF_RUID_VAL, (uint32_t)0, (user_addr_t)proc_ids,
881*e3723e1fSApple OSS Distributions 	    (int32_t)(proc_count * (int)sizeof(*proc_ids)));
882*e3723e1fSApple OSS Distributions 	T_ASSERT_GE_ULONG((unsigned long)num_procs / sizeof(pid_t), (unsigned long)CONF_PROC_COUNT,
883*e3723e1fSApple OSS Distributions 	    "Valid number of pids obtained for PROC_RUID_ONLY.");
884*e3723e1fSApple OSS Distributions 	kill_child_processes(proc_config);
885*e3723e1fSApple OSS Distributions 	free_proc_config(proc_config);
886*e3723e1fSApple OSS Distributions 	free(proc_ids);
887*e3723e1fSApple OSS Distributions }
888*e3723e1fSApple OSS Distributions 
889*e3723e1fSApple OSS Distributions T_DECL(proc_info_listpids_tty_only,
890*e3723e1fSApple OSS Distributions     "proc_info API test to verify PROC_INFO_CALL_LISTPIDS",
891*e3723e1fSApple OSS Distributions     T_META_ASROOT(true), T_META_TAG_VM_PREFERRED)
892*e3723e1fSApple OSS Distributions {
893*e3723e1fSApple OSS Distributions 	int ret = isatty(STDOUT_FILENO);
894*e3723e1fSApple OSS Distributions 	if (ret != 1) {
895*e3723e1fSApple OSS Distributions 		T_SKIP("Not connected to tty...skipping test");
896*e3723e1fSApple OSS Distributions 	}
897*e3723e1fSApple OSS Distributions 
898*e3723e1fSApple OSS Distributions 	proc_config_t proc_config = spawn_child_processes(CONF_PROC_COUNT, proc_info_listpids_handler);
899*e3723e1fSApple OSS Distributions 
900*e3723e1fSApple OSS Distributions 	T_LOG("Test to verify PROC_TTY_ONLY returns correct value");
901*e3723e1fSApple OSS Distributions 	int proc_count   = CONF_PROC_COUNT + 2;
902*e3723e1fSApple OSS Distributions 	pid_t * proc_ids = malloc(sizeof(*proc_ids) * (unsigned long)proc_count);
903*e3723e1fSApple OSS Distributions 	int num_procs    = __proc_info(PROC_INFO_CALL_LISTPIDS, PROC_TTY_ONLY, get_tty_dev(), (uint32_t)0, (user_addr_t)proc_ids,
904*e3723e1fSApple OSS Distributions 	    (int32_t)(proc_count * (int)sizeof(*proc_ids)));
905*e3723e1fSApple OSS Distributions 	num_procs = num_procs / (int)sizeof(pid_t);
906*e3723e1fSApple OSS Distributions 	T_ASSERT_GE_INT(num_procs, 0, "Valid number of pids returned by PROC_TTY_ONLY.");
907*e3723e1fSApple OSS Distributions 	kill_child_processes(proc_config);
908*e3723e1fSApple OSS Distributions 	free_proc_config(proc_config);
909*e3723e1fSApple OSS Distributions 	free(proc_ids);
910*e3723e1fSApple OSS Distributions }
911*e3723e1fSApple OSS Distributions 
912*e3723e1fSApple OSS Distributions /*
913*e3723e1fSApple OSS Distributions  * Most of the following PROC_INFO_CALL_PIDINFO tests rely on a helper function (proc_info_caller) to make the necessary proc_info
914*e3723e1fSApple OSS Distributions  * calls on their behalf
915*e3723e1fSApple OSS Distributions  * In a previous iteration, these tests were all in one giant T_DECL and the helper function handles inter-DECL dependencies such as
916*e3723e1fSApple OSS Distributions  * a proc_info call relying on the results of a previous proc_info call or an assumed state that a child should be in.
917*e3723e1fSApple OSS Distributions  */
918*e3723e1fSApple OSS Distributions 
919*e3723e1fSApple OSS Distributions T_DECL(proc_info_pidinfo_proc_piduniqidentifierinfo,
920*e3723e1fSApple OSS Distributions     "Test to identify PROC_PIDUNIQIDENTIFIERINFO returns correct unique identifiers for process",
921*e3723e1fSApple OSS Distributions     T_META_ASROOT(true), T_META_TAG_VM_PREFERRED)
922*e3723e1fSApple OSS Distributions {
923*e3723e1fSApple OSS Distributions 	void * proc_info[2];
924*e3723e1fSApple OSS Distributions 	proc_info_caller(P_UNIQIDINFO | C_UNIQIDINFO, proc_info, NULL);
925*e3723e1fSApple OSS Distributions 	struct proc_uniqidentifierinfo * p_uniqidinfo = (struct proc_uniqidentifierinfo *)proc_info[0];
926*e3723e1fSApple OSS Distributions 	struct proc_uniqidentifierinfo * c_uniqidinfo = (struct proc_uniqidentifierinfo *)proc_info[1];
927*e3723e1fSApple OSS Distributions 
928*e3723e1fSApple OSS Distributions 	T_EXPECT_NE_ULLONG(c_uniqidinfo->p_uniqueid, p_uniqidinfo->p_uniqueid, "p_uniqueid not unique for the process");
929*e3723e1fSApple OSS Distributions 
930*e3723e1fSApple OSS Distributions 	for (size_t i = 0; i < 16; i++) {
931*e3723e1fSApple OSS Distributions 		T_EXPECT_EQ_UCHAR(c_uniqidinfo->p_uuid[i], p_uniqidinfo->p_uuid[i], "p_uuid should be the same unique id");
932*e3723e1fSApple OSS Distributions 	}
933*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_ULLONG(c_uniqidinfo->p_puniqueid, p_uniqidinfo->p_uniqueid,
934*e3723e1fSApple OSS Distributions 	    "p_puniqueid of child should be same as p_uniqueid for parent");
935*e3723e1fSApple OSS Distributions 
936*e3723e1fSApple OSS Distributions 	// The child's p_orig_ppidversion should be set to the p_idversion of the parent.
937*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(c_uniqidinfo->p_orig_ppidversion, p_uniqidinfo->p_idversion,
938*e3723e1fSApple OSS Distributions 	    "child->p_pidversion == parent->p_idversion");
939*e3723e1fSApple OSS Distributions 
940*e3723e1fSApple OSS Distributions 	free_proc_info(proc_info, 2);
941*e3723e1fSApple OSS Distributions }
942*e3723e1fSApple OSS Distributions 
943*e3723e1fSApple OSS Distributions T_DECL(ensure_ppidversion_is_not_updated,
944*e3723e1fSApple OSS Distributions     "A process's parent's idversion field should not be updated when the parent re-execs",
945*e3723e1fSApple OSS Distributions     T_META_ASROOT(true), T_META_TAG_VM_PREFERRED)
946*e3723e1fSApple OSS Distributions {
947*e3723e1fSApple OSS Distributions 	// Given a process (the test runner) which forks to create a child
948*e3723e1fSApple OSS Distributions 	pid_t original_pid = getpid();
949*e3723e1fSApple OSS Distributions 	if (!fork()) {
950*e3723e1fSApple OSS Distributions 		// And the child process waits for the parent to re-exec...
951*e3723e1fSApple OSS Distributions 		// (To get rid of this, we could exec something controlled that signals a semaphore.)
952*e3723e1fSApple OSS Distributions 		sleep(1);
953*e3723e1fSApple OSS Distributions 
954*e3723e1fSApple OSS Distributions 		// When the child inspects the parent's current idversion
955*e3723e1fSApple OSS Distributions 		struct proc_uniqidentifierinfo parent_info;
956*e3723e1fSApple OSS Distributions 		int ret = proc_pidinfo(original_pid, PROC_PIDUNIQIDENTIFIERINFO, 0, &parent_info, sizeof(parent_info));
957*e3723e1fSApple OSS Distributions 		T_ASSERT_EQ((unsigned long)ret, sizeof(parent_info), "PROC_PIDUNIQIDENTIFIERINFO - parent");
958*e3723e1fSApple OSS Distributions 
959*e3723e1fSApple OSS Distributions 		// And compares it to the child's stored idversion
960*e3723e1fSApple OSS Distributions 		struct proc_uniqidentifierinfo child_info;
961*e3723e1fSApple OSS Distributions 		ret = proc_pidinfo(getpid(), PROC_PIDUNIQIDENTIFIERINFO, 0, &child_info, sizeof(child_info));
962*e3723e1fSApple OSS Distributions 		T_ASSERT_EQ((unsigned long)ret, sizeof(child_info), "PROC_PIDUNIQIDENTIFIERINFO - child");
963*e3723e1fSApple OSS Distributions 
964*e3723e1fSApple OSS Distributions 		// Then the child can see that the parent's idversion has changed from what was stored.
965*e3723e1fSApple OSS Distributions 		T_EXPECT_NE_INT(child_info.p_orig_ppidversion, parent_info.p_idversion,
966*e3723e1fSApple OSS Distributions 		    "child->p_orig_ppidversion != parent->p_idversion after parent exec");
967*e3723e1fSApple OSS Distributions 	} else {
968*e3723e1fSApple OSS Distributions 		// And we (the parent process) re-exec into something else
969*e3723e1fSApple OSS Distributions 		const char* exec_cmd[] = { "sleep", "2", NULL };
970*e3723e1fSApple OSS Distributions 		execvp(exec_cmd[0], exec_cmd);
971*e3723e1fSApple OSS Distributions 		T_FAIL("execvp() failed");
972*e3723e1fSApple OSS Distributions 	}
973*e3723e1fSApple OSS Distributions }
974*e3723e1fSApple OSS Distributions 
975*e3723e1fSApple OSS Distributions T_DECL(ensure_ppidversion_is_not_updated_after_exec,
976*e3723e1fSApple OSS Distributions     "A child's parent pidversion field should not be updated when the child re-execs",
977*e3723e1fSApple OSS Distributions     T_META_ASROOT(true), T_META_TAG_VM_PREFERRED)
978*e3723e1fSApple OSS Distributions {
979*e3723e1fSApple OSS Distributions 	// Given a child
980*e3723e1fSApple OSS Distributions 	pid_t child_pid = fork();
981*e3723e1fSApple OSS Distributions 	if (!child_pid) {
982*e3723e1fSApple OSS Distributions 		// Give the parent a moment to record our initial p_orig_ppidversion
983*e3723e1fSApple OSS Distributions 		sleep(1);
984*e3723e1fSApple OSS Distributions 
985*e3723e1fSApple OSS Distributions 		// When the child execs into something else
986*e3723e1fSApple OSS Distributions 		const char* exec_cmd[] = { "sleep", "2", NULL };
987*e3723e1fSApple OSS Distributions 		execvp(exec_cmd[0], exec_cmd);
988*e3723e1fSApple OSS Distributions 		T_FAIL("execvp() failed");
989*e3723e1fSApple OSS Distributions 	} else {
990*e3723e1fSApple OSS Distributions 		// And we save the child's original p_orig_ppidversion
991*e3723e1fSApple OSS Distributions 		struct proc_uniqidentifierinfo child_parent_info;
992*e3723e1fSApple OSS Distributions 		int ret = proc_pidinfo(child_pid, PROC_PIDUNIQIDENTIFIERINFO, 0, &child_parent_info, sizeof(child_parent_info));
993*e3723e1fSApple OSS Distributions 		T_ASSERT_EQ((unsigned long)ret, sizeof(child_parent_info), "PROC_PIDUNIQIDENTIFIERINFO - child");
994*e3723e1fSApple OSS Distributions 		int first_ppidversion = child_parent_info.p_orig_ppidversion;
995*e3723e1fSApple OSS Distributions 
996*e3723e1fSApple OSS Distributions 		// And we give the child a moment to re-exec into something else
997*e3723e1fSApple OSS Distributions 		sleep(2);
998*e3723e1fSApple OSS Distributions 
999*e3723e1fSApple OSS Distributions 		// And we inspect the child's p_orig_ppidversion again
1000*e3723e1fSApple OSS Distributions 		ret = proc_pidinfo(child_pid, PROC_PIDUNIQIDENTIFIERINFO, 0, &child_parent_info, sizeof(child_parent_info));
1001*e3723e1fSApple OSS Distributions 		T_ASSERT_EQ((unsigned long)ret, sizeof(child_parent_info), "PROC_PIDUNIQIDENTIFIERINFO - child");
1002*e3723e1fSApple OSS Distributions 		int second_ppidversion = child_parent_info.p_orig_ppidversion;
1003*e3723e1fSApple OSS Distributions 
1004*e3723e1fSApple OSS Distributions 		// Then the child's p_orig_ppidversion has not changed due to exec()
1005*e3723e1fSApple OSS Distributions 		T_ASSERT_EQ(first_ppidversion, second_ppidversion, "p_orig_ppidversion should not change after exec()");
1006*e3723e1fSApple OSS Distributions 	}
1007*e3723e1fSApple OSS Distributions }
1008*e3723e1fSApple OSS Distributions 
1009*e3723e1fSApple OSS Distributions T_DECL(proc_info_pidinfo_proc_pidtbsdinfo,
1010*e3723e1fSApple OSS Distributions     "Test to verify PROC_PIDTBSDINFO returns valid information about the process",
1011*e3723e1fSApple OSS Distributions     T_META_ASROOT(true), T_META_TAG_VM_PREFERRED)
1012*e3723e1fSApple OSS Distributions {
1013*e3723e1fSApple OSS Distributions 	void * proc_info[2];
1014*e3723e1fSApple OSS Distributions 	int child_pid = 0;
1015*e3723e1fSApple OSS Distributions 	proc_info_caller(PBSD_OLD | PBSD, proc_info, &child_pid);
1016*e3723e1fSApple OSS Distributions 	struct proc_bsdinfo * pbsd_old = (struct proc_bsdinfo *)proc_info[0];
1017*e3723e1fSApple OSS Distributions 	struct proc_bsdinfo * pbsd     = (struct proc_bsdinfo *)proc_info[1];
1018*e3723e1fSApple OSS Distributions 
1019*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT((unsigned int)SRUN, pbsd->pbi_status, "PROC_PIDTBSDINFO shows Correct status");
1020*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(0U, pbsd->pbi_xstatus, "PROC_PIDTBSDINFO show Correct xstatus (exit status)");
1021*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd->pbi_pid, (unsigned int)child_pid, "PROC_PIDTBSDINFO returns valid pid");
1022*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd->pbi_ppid, (unsigned int)getpid(), "PROC_PIDTBSDINFO returns valid ppid");
1023*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd->pbi_uid, CONF_RUID_VAL, "PROC_PIDTBSDINFO returns valid uid");
1024*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd->pbi_gid, CONF_GID_VAL, "PROC_PIDTBSDINFO returns valid gid");
1025*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd->pbi_ruid, 0U, "PROC_PIDTBSDINFO returns valid ruid");
1026*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd->pbi_rgid, CONF_GID_VAL, "PROC_PIDTBSDINFO returns valid rgid");
1027*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd->pbi_svuid, CONF_RUID_VAL, "PROC_PIDTBSDINFO returns valid svuid");
1028*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd->pbi_svgid, CONF_GID_VAL, "PROC_PIDTBSDINFO returns valid svgid");
1029*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd->pbi_nice, CONF_NICE_VAL, "PROC_PIDTBSDINFO returns valid nice value");
1030*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_STR(pbsd->pbi_comm, CONF_CMD_NAME, "PROC_PIDTBSDINFO returns valid p_comm name");
1031*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_STR(pbsd->pbi_name, CONF_CMD_NAME, "PROC_PIDTBSDINFO returns valid p_name name");
1032*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd->pbi_flags, (pbsd_old->pbi_flags | PROC_FLAG_PSUGID), "PROC_PIDTBSDINFO returns valid flags");
1033*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd->pbi_nfiles, pbsd_old->pbi_nfiles, "PROC_PIDTBSDINFO returned valid pbi_nfiles");
1034*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd->pbi_pgid, (uint32_t)getpgid(getpid()), "PROC_PIDTBSDINFO returned valid pbi_pgid");
1035*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd->pbi_pjobc, pbsd->pbi_pjobc, "PROC_PIDTBSDINFO returned valid pbi_pjobc");
1036*e3723e1fSApple OSS Distributions 	T_EXPECT_NE_UINT(pbsd->e_tdev, 0U, "PROC_PIDTBSDINFO returned valid e_tdev");
1037*e3723e1fSApple OSS Distributions 
1038*e3723e1fSApple OSS Distributions 	free_proc_info(proc_info, 2);
1039*e3723e1fSApple OSS Distributions }
1040*e3723e1fSApple OSS Distributions 
1041*e3723e1fSApple OSS Distributions T_DECL(proc_info_pidt_shortbsdinfo,
1042*e3723e1fSApple OSS Distributions     "Test to verify PROC_PIDT_SHORTBSDINFO returns valid information about the process",
1043*e3723e1fSApple OSS Distributions     T_META_ASROOT(true), T_META_TAG_VM_PREFERRED)
1044*e3723e1fSApple OSS Distributions {
1045*e3723e1fSApple OSS Distributions 	void * proc_info[2];
1046*e3723e1fSApple OSS Distributions 	int child_pid = 0;
1047*e3723e1fSApple OSS Distributions 	proc_info_caller(PBSD | PBSD_SHORT, proc_info, &child_pid);
1048*e3723e1fSApple OSS Distributions 	struct proc_bsdinfo * pbsd            = (struct proc_bsdinfo *)proc_info[0];
1049*e3723e1fSApple OSS Distributions 	struct proc_bsdshortinfo * pbsd_short = (struct proc_bsdshortinfo *)proc_info[1];
1050*e3723e1fSApple OSS Distributions 
1051*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd_short->pbsi_pid, (unsigned int)child_pid, "PROC_PIDT_SHORTBSDINFO returns valid pid");
1052*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd_short->pbsi_ppid, (unsigned int)getpid(), "PROC_PIDT_SHORTBSDINFO returns valid ppid");
1053*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd_short->pbsi_pgid, (uint32_t)getpgid(getpid()), "PROC_PIDT_SHORTBSDINFO returned valid pbi_pgid");
1054*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT((unsigned int)SRUN, pbsd_short->pbsi_status, "PROC_PIDT_SHORTBSDINFO shows Correct status");
1055*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_STR(pbsd_short->pbsi_comm, CONF_CMD_NAME, "PROC_PIDT_SHORTBSDINFO returns valid p_comm name");
1056*e3723e1fSApple OSS Distributions 	/*
1057*e3723e1fSApple OSS Distributions 	 * The short variant returns all flags except session flags, hence ignoring them here.
1058*e3723e1fSApple OSS Distributions 	 */
1059*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd_short->pbsi_flags, (pbsd->pbi_flags & (unsigned int)(~PROC_FLAG_CTTY)),
1060*e3723e1fSApple OSS Distributions 	    "PROC_PIDT_SHORTBSDINFO returns valid flags");
1061*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd_short->pbsi_uid, CONF_RUID_VAL, "PROC_PIDT_SHORTBSDINFO returns valid uid");
1062*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd_short->pbsi_gid, CONF_GID_VAL, "PROC_PIDT_SHORTBSDINFO returns valid gid");
1063*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd_short->pbsi_ruid, 0U, "PROC_PIDT_SHORTBSDINFO returns valid ruid");
1064*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd_short->pbsi_svuid, CONF_RUID_VAL, "PROC_PIDT_SHORTBSDINFO returns valid svuid");
1065*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd_short->pbsi_svgid, CONF_GID_VAL, "PROC_PIDT_SHORTBSDINFO returns valid svgid");
1066*e3723e1fSApple OSS Distributions 
1067*e3723e1fSApple OSS Distributions 	free_proc_info(proc_info, 2);
1068*e3723e1fSApple OSS Distributions }
1069*e3723e1fSApple OSS Distributions 
1070*e3723e1fSApple OSS Distributions T_DECL(proc_info_pidt_bsdinfowithuniqid,
1071*e3723e1fSApple OSS Distributions     "Test to verify PROC_PIDT_BSDINFOWITHUNIQID returns valid information about the process",
1072*e3723e1fSApple OSS Distributions     T_META_ASROOT(true), T_META_TAG_VM_PREFERRED)
1073*e3723e1fSApple OSS Distributions {
1074*e3723e1fSApple OSS Distributions 	void * proc_info[4];
1075*e3723e1fSApple OSS Distributions 	int child_pid = 0;
1076*e3723e1fSApple OSS Distributions 	proc_info_caller(P_UNIQIDINFO | PBSD_OLD | PBSD | PBSD_UNIQID, proc_info, &child_pid);
1077*e3723e1fSApple OSS Distributions 	struct proc_uniqidentifierinfo * p_uniqidinfo = (struct proc_uniqidentifierinfo *)proc_info[0];
1078*e3723e1fSApple OSS Distributions 	struct proc_bsdinfo * pbsd_old                = (struct proc_bsdinfo *)proc_info[1];
1079*e3723e1fSApple OSS Distributions 	struct proc_bsdinfo * pbsd                    = (struct proc_bsdinfo *)proc_info[2];
1080*e3723e1fSApple OSS Distributions 	struct proc_bsdinfowithuniqid * pbsd_uniqid   = (struct proc_bsdinfowithuniqid *)proc_info[3];
1081*e3723e1fSApple OSS Distributions 
1082*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT((unsigned int)SRUN, pbsd->pbi_status, "PROC_PIDT_BSDINFOWITHUNIQID shows Correct status");
1083*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(0U, pbsd->pbi_xstatus, "PROC_PIDT_BSDINFOWITHUNIQID show Correct xstatus");
1084*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd_uniqid->pbsd.pbi_pid, (unsigned int)child_pid, "PROC_PIDT_BSDINFOWITHUNIQID returns valid pid");
1085*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd_uniqid->pbsd.pbi_ppid, (unsigned int)getpid(), "PROC_PIDT_BSDINFOWITHUNIQID returns valid ppid");
1086*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd_uniqid->pbsd.pbi_uid, CONF_RUID_VAL, "PROC_PIDT_BSDINFOWITHUNIQID returns valid uid");
1087*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd_uniqid->pbsd.pbi_gid, CONF_GID_VAL, "PROC_PIDT_BSDINFOWITHUNIQID returns valid gid");
1088*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd_uniqid->pbsd.pbi_ruid, 0U, "PROC_PIDT_BSDINFOWITHUNIQID returns valid ruid");
1089*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd_uniqid->pbsd.pbi_rgid, CONF_GID_VAL, "PROC_PIDT_BSDINFOWITHUNIQID returns valid rgid");
1090*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd_uniqid->pbsd.pbi_svuid, CONF_RUID_VAL, "PROC_PIDT_BSDINFOWITHUNIQID returns valid svuid");
1091*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd_uniqid->pbsd.pbi_svgid, CONF_GID_VAL, "PROC_PIDT_BSDINFOWITHUNIQID returns valid svgid");
1092*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd_uniqid->pbsd.pbi_nice, CONF_NICE_VAL, "PROC_PIDT_BSDINFOWITHUNIQID returns valid nice value");
1093*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_STR(pbsd_uniqid->pbsd.pbi_comm, CONF_CMD_NAME, "PROC_PIDT_BSDINFOWITHUNIQID returns valid p_comm name");
1094*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_STR(pbsd_uniqid->pbsd.pbi_name, CONF_CMD_NAME, "PROC_PIDT_BSDINFOWITHUNIQID returns valid p_name name");
1095*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd_uniqid->pbsd.pbi_flags, (pbsd_old->pbi_flags | PROC_FLAG_PSUGID),
1096*e3723e1fSApple OSS Distributions 	    "PROC_PIDT_BSDINFOWITHUNIQID returns valid flags");
1097*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd_uniqid->pbsd.pbi_nfiles, pbsd_old->pbi_nfiles, "PROC_PIDT_BSDINFOWITHUNIQID returned valid pbi_nfiles");
1098*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd_uniqid->pbsd.pbi_pgid, (uint32_t)getpgid(getpid()),
1099*e3723e1fSApple OSS Distributions 	    "PROC_PIDT_BSDINFOWITHUNIQID returned valid pbi_pgid");
1100*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pbsd_uniqid->pbsd.pbi_pjobc, pbsd->pbi_pjobc, "PROC_PIDT_BSDINFOWITHUNIQID returned valid pbi_pjobc");
1101*e3723e1fSApple OSS Distributions 	T_EXPECT_NE_UINT(pbsd_uniqid->pbsd.e_tdev, 0U, "PROC_PIDT_BSDINFOWITHUNIQID returned valid e_tdev");
1102*e3723e1fSApple OSS Distributions 	T_EXPECT_NE_ULLONG(pbsd_uniqid->p_uniqidentifier.p_uniqueid, p_uniqidinfo->p_uniqueid,
1103*e3723e1fSApple OSS Distributions 	    "PROC_PIDT_BSDINFOWITHUNIQID returned valid p_uniqueid");
1104*e3723e1fSApple OSS Distributions 	for (int i = 0; i < 16; i++) {
1105*e3723e1fSApple OSS Distributions 		T_EXPECT_EQ_UCHAR(pbsd_uniqid->p_uniqidentifier.p_uuid[i], p_uniqidinfo->p_uuid[i],
1106*e3723e1fSApple OSS Distributions 		    "PROC_PIDT_BSDINFOWITHUNIQID reported valid p_uniqueid");
1107*e3723e1fSApple OSS Distributions 	}
1108*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_ULLONG(pbsd_uniqid->p_uniqidentifier.p_puniqueid, p_uniqidinfo->p_uniqueid,
1109*e3723e1fSApple OSS Distributions 	    "p_puniqueid of child should be same as p_uniqueid for parent");
1110*e3723e1fSApple OSS Distributions 
1111*e3723e1fSApple OSS Distributions 	free_proc_info(proc_info, 4);
1112*e3723e1fSApple OSS Distributions }
1113*e3723e1fSApple OSS Distributions 
1114*e3723e1fSApple OSS Distributions static void
_expect_increasing_taskinfo_times(const char * name,struct proc_taskinfo * early,struct proc_taskinfo * late)1115*e3723e1fSApple OSS Distributions _expect_increasing_taskinfo_times(const char *name, struct proc_taskinfo *early,
1116*e3723e1fSApple OSS Distributions     struct proc_taskinfo *late)
1117*e3723e1fSApple OSS Distributions {
1118*e3723e1fSApple OSS Distributions 	if (has_user_system_times()) {
1119*e3723e1fSApple OSS Distributions 		T_EXPECT_GT(late->pti_total_system, early->pti_total_system,
1120*e3723e1fSApple OSS Distributions 		    "%s returned increasing pti_total_system time", name);
1121*e3723e1fSApple OSS Distributions 		T_EXPECT_GT(late->pti_threads_system, early->pti_threads_system,
1122*e3723e1fSApple OSS Distributions 		    "%s returned increasing pti_threads_system time", name);
1123*e3723e1fSApple OSS Distributions 	}
1124*e3723e1fSApple OSS Distributions 
1125*e3723e1fSApple OSS Distributions 	T_EXPECT_GT(late->pti_threads_user, early->pti_threads_user,
1126*e3723e1fSApple OSS Distributions 	    "%s returned increasing pti_threads_user time", name);
1127*e3723e1fSApple OSS Distributions 	T_EXPECT_GT(late->pti_total_user, early->pti_total_user,
1128*e3723e1fSApple OSS Distributions 	    "%s returned increasing pti_total_user time", name);
1129*e3723e1fSApple OSS Distributions }
1130*e3723e1fSApple OSS Distributions 
1131*e3723e1fSApple OSS Distributions T_DECL(proc_info_proc_pidtask_info,
1132*e3723e1fSApple OSS Distributions     "Test to verify PROC_PIDTASKINFO returns valid information about the process",
1133*e3723e1fSApple OSS Distributions     T_META_ASROOT(true), T_META_TAG_VM_PREFERRED)
1134*e3723e1fSApple OSS Distributions {
1135*e3723e1fSApple OSS Distributions 	void * proc_info[2];
1136*e3723e1fSApple OSS Distributions 	proc_info_caller(P_TASK_INFO | P_TASK_INFO_NEW, proc_info, NULL);
1137*e3723e1fSApple OSS Distributions 	struct proc_taskinfo * p_task_info     = (struct proc_taskinfo *)proc_info[0];
1138*e3723e1fSApple OSS Distributions 	struct proc_taskinfo * p_task_info_new = (struct proc_taskinfo *)proc_info[1];
1139*e3723e1fSApple OSS Distributions 
1140*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_ULLONG((p_task_info_new->pti_virtual_size - p_task_info->pti_virtual_size), (unsigned long long)PAGE_SIZE,
1141*e3723e1fSApple OSS Distributions 	    "PROC_PIDTASKINFO returned valid value for pti_virtual_size");
1142*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_ULLONG((p_task_info_new->pti_resident_size - p_task_info->pti_resident_size), (unsigned long long)PAGE_SIZE,
1143*e3723e1fSApple OSS Distributions 	    "PROC_PIDTASKINFO returned valid value for pti_resident_size");
1144*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(p_task_info_new->pti_policy, POLICY_TIMESHARE, "PROC_PIDTASKINFO returned valid value for pti_policy");
1145*e3723e1fSApple OSS Distributions 	_expect_increasing_taskinfo_times("PROC_PIDTASKINFO", p_task_info, p_task_info_new);
1146*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_INT((p_task_info_new->pti_faults - p_task_info->pti_faults), 1,
1147*e3723e1fSApple OSS Distributions 	    "PROC_PIDTASKINFO returned valid value for pti_faults");
1148*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_INT((p_task_info_new->pti_cow_faults - p_task_info->pti_cow_faults), 1,
1149*e3723e1fSApple OSS Distributions 	    "PROC_PIDTASKINFO returned valid value for pti_cow_faults");
1150*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_INT((p_task_info_new->pti_syscalls_mach - p_task_info->pti_syscalls_mach), 0,
1151*e3723e1fSApple OSS Distributions 	    "PROC_PIDTASKINFO returned valid value for pti_syscalls_mach");
1152*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_INT((p_task_info_new->pti_syscalls_unix - p_task_info->pti_syscalls_unix), 2,
1153*e3723e1fSApple OSS Distributions 	    "PROC_PIDTASKINFO returned valid value for pti_syscalls_unix");
1154*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT((p_task_info_new->pti_messages_sent - p_task_info->pti_messages_sent), 0,
1155*e3723e1fSApple OSS Distributions 	    "PROC_PIDTASKINFO returned valid value for pti_messages_sent");
1156*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT((p_task_info_new->pti_messages_received - p_task_info->pti_messages_received), 0,
1157*e3723e1fSApple OSS Distributions 	    "PROC_PIDTASKINFO returned valid value for pti_messages_received");
1158*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(p_task_info_new->pti_priority, p_task_info->pti_priority,
1159*e3723e1fSApple OSS Distributions 	    "PROC_PIDTASKINFO returned valid value for pti_priority");
1160*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_INT(p_task_info_new->pti_threadnum, 1, "PROC_PIDTASKINFO returned valid value for pti_threadnum");
1161*e3723e1fSApple OSS Distributions 
1162*e3723e1fSApple OSS Distributions 	if (p_task_info_new->pti_threadnum > 1) {
1163*e3723e1fSApple OSS Distributions 		T_LOG("WARN: PROC_PIDTASKINFO returned threadnum greater than 1");
1164*e3723e1fSApple OSS Distributions 	}
1165*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_INT(p_task_info_new->pti_numrunning, 0, "PROC_PIDTASKINFO returned valid value for pti_numrunning");
1166*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_INT(p_task_info_new->pti_pageins, 0, "PROC_PIDTASKINFO returned valid value for pti_pageins");
1167*e3723e1fSApple OSS Distributions 
1168*e3723e1fSApple OSS Distributions 	if (p_task_info_new->pti_pageins > 0) {
1169*e3723e1fSApple OSS Distributions 		T_LOG("WARN: PROC_PIDTASKINFO returned pageins greater than 0");
1170*e3723e1fSApple OSS Distributions 	}
1171*e3723e1fSApple OSS Distributions 
1172*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_INT(p_task_info_new->pti_csw, p_task_info->pti_csw, "PROC_PIDTASKINFO returned valid value for pti_csw");
1173*e3723e1fSApple OSS Distributions 
1174*e3723e1fSApple OSS Distributions 	free_proc_info(proc_info, 2);
1175*e3723e1fSApple OSS Distributions }
1176*e3723e1fSApple OSS Distributions 
1177*e3723e1fSApple OSS Distributions T_DECL(proc_info_proc_pidtaskallinfo,
1178*e3723e1fSApple OSS Distributions     "Test to verify PROC_PIDTASKALLINFO returns valid information about the process",
1179*e3723e1fSApple OSS Distributions     T_META_ASROOT(true), T_META_TAG_VM_PREFERRED)
1180*e3723e1fSApple OSS Distributions {
1181*e3723e1fSApple OSS Distributions 	void * proc_info[4];
1182*e3723e1fSApple OSS Distributions 	int child_pid = 0;
1183*e3723e1fSApple OSS Distributions 	proc_info_caller(PBSD | PBSD_OLD | P_TASK_INFO | PALL, proc_info, &child_pid);
1184*e3723e1fSApple OSS Distributions 	struct proc_bsdinfo * pbsd         = (struct proc_bsdinfo *)proc_info[0];
1185*e3723e1fSApple OSS Distributions 	struct proc_bsdinfo * pbsd_old     = (struct proc_bsdinfo *)proc_info[1];
1186*e3723e1fSApple OSS Distributions 	struct proc_taskinfo * p_task_info = (struct proc_taskinfo *)proc_info[2];
1187*e3723e1fSApple OSS Distributions 	struct proc_taskallinfo * pall     = (struct proc_taskallinfo *)proc_info[3];
1188*e3723e1fSApple OSS Distributions 
1189*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT((unsigned int)SRUN, pbsd->pbi_status, "PROC_PIDTASKALLINFO shows Correct status");
1190*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(0U, pbsd->pbi_xstatus, "PROC_PIDTASKALLINFO show Correct xstatus");
1191*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pall->pbsd.pbi_pid, (unsigned int)child_pid, "PROC_PIDTASKALLINFO returns valid pid");
1192*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pall->pbsd.pbi_ppid, (unsigned int)getpid(), "PROC_PIDTASKALLINFO returns valid ppid");
1193*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pall->pbsd.pbi_uid, CONF_RUID_VAL, "PROC_PIDTASKALLINFO returns valid uid");
1194*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pall->pbsd.pbi_gid, CONF_GID_VAL, "PROC_PIDTASKALLINFO returns valid gid");
1195*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pall->pbsd.pbi_ruid, 0U, "PROC_PIDTASKALLINFO returns valid ruid");
1196*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pall->pbsd.pbi_rgid, CONF_GID_VAL, "PROC_PIDTASKALLINFO returns valid rgid");
1197*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pall->pbsd.pbi_svuid, CONF_RUID_VAL, "PROC_PIDTASKALLINFO returns valid svuid");
1198*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pall->pbsd.pbi_svgid, CONF_GID_VAL, "PROC_PIDTASKALLINFO returns valid svgid");
1199*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(pall->pbsd.pbi_nice, CONF_NICE_VAL, "PROC_PIDTASKALLINFO returns valid nice value");
1200*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_STR(pall->pbsd.pbi_comm, CONF_CMD_NAME, "PROC_PIDTASKALLINFO returns valid p_comm name");
1201*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_STR(pall->pbsd.pbi_name, CONF_CMD_NAME, "PROC_PIDTASKALLINFO returns valid p_name name");
1202*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pall->pbsd.pbi_flags, (pbsd_old->pbi_flags | PROC_FLAG_PSUGID), "PROC_PIDTASKALLINFO returns valid flags");
1203*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pall->pbsd.pbi_nfiles, pbsd_old->pbi_nfiles, "PROC_PIDTASKALLINFO returned valid pbi_nfiles");
1204*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pall->pbsd.pbi_pgid, (uint32_t)getpgid(getpid()), "PROC_PIDTASKALLINFO returned valid pbi_pgid");
1205*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pall->pbsd.pbi_pjobc, pbsd->pbi_pjobc, "PROC_PIDTASKALLINFO returned valid pbi_pjobc");
1206*e3723e1fSApple OSS Distributions 	T_EXPECT_NE_UINT(pall->pbsd.e_tdev, 0U, "PROC_PIDTASKALLINFO returned valid e_tdev");
1207*e3723e1fSApple OSS Distributions 
1208*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_ULLONG((pall->ptinfo.pti_virtual_size - p_task_info->pti_virtual_size), (unsigned long long)PAGE_SIZE,
1209*e3723e1fSApple OSS Distributions 	    "PROC_PIDTASKALLINFO returned valid value for pti_virtual_size");
1210*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_ULLONG((pall->ptinfo.pti_resident_size - p_task_info->pti_resident_size), (unsigned long long)PAGE_SIZE,
1211*e3723e1fSApple OSS Distributions 	    "PROC_PIDTASKALLINFO returned valid value for pti_resident_size");
1212*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(pall->ptinfo.pti_policy, POLICY_TIMESHARE, "PROC_PIDTASKALLINFO returned valid value for pti_policy");
1213*e3723e1fSApple OSS Distributions 	_expect_increasing_taskinfo_times("PROC_PIDTASKALLLINFO", p_task_info, &pall->ptinfo);
1214*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_INT((pall->ptinfo.pti_faults - p_task_info->pti_faults), 1,
1215*e3723e1fSApple OSS Distributions 	    "PROC_PIDTASKALLINFO returned valid value for pti_faults");
1216*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_INT((pall->ptinfo.pti_cow_faults - p_task_info->pti_cow_faults), 1,
1217*e3723e1fSApple OSS Distributions 	    "PROC_PIDTASKALLINFO returned valid value for pti_cow_faults");
1218*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_INT((pall->ptinfo.pti_syscalls_mach - p_task_info->pti_syscalls_mach), 0,
1219*e3723e1fSApple OSS Distributions 	    "PROC_PIDTASKALLINFO returned valid value for pti_syscalls_mach");
1220*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_INT((pall->ptinfo.pti_syscalls_unix - p_task_info->pti_syscalls_unix), 2,
1221*e3723e1fSApple OSS Distributions 	    "PROC_PIDTASKALLINFO returned valid value for pti_syscalls_unix");
1222*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT((pall->ptinfo.pti_messages_sent - p_task_info->pti_messages_sent), 0,
1223*e3723e1fSApple OSS Distributions 	    "PROC_PIDTASKALLINFO returned valid value for pti_messages_sent");
1224*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT((pall->ptinfo.pti_messages_received - p_task_info->pti_messages_received), 0,
1225*e3723e1fSApple OSS Distributions 	    "PROC_PIDTASKALLINFO returned valid value for pti_messages_received");
1226*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(pall->ptinfo.pti_priority, p_task_info->pti_priority,
1227*e3723e1fSApple OSS Distributions 	    "PROC_PIDTASKALLINFO returned valid value for pti_priority");
1228*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_INT(pall->ptinfo.pti_threadnum, 1, "PROC_PIDTASKALLINFO returned valid value for pti_threadnum");
1229*e3723e1fSApple OSS Distributions 	if (pall->ptinfo.pti_threadnum > 1) {
1230*e3723e1fSApple OSS Distributions 		T_LOG("WARN: PROC_PIDTASKALLINFO returned threadnum greater than 1");
1231*e3723e1fSApple OSS Distributions 	}
1232*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_INT(pall->ptinfo.pti_numrunning, 0, "PROC_PIDTASKALLINFO returned valid value for pti_numrunning");
1233*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_INT(pall->ptinfo.pti_pageins, 0, "PROC_PIDTASKALLINFO returned valid value for pti_pageins");
1234*e3723e1fSApple OSS Distributions 	if (pall->ptinfo.pti_pageins > 0) {
1235*e3723e1fSApple OSS Distributions 		T_LOG("WARN: PROC_PIDTASKALLINFO returned pageins greater than 0");
1236*e3723e1fSApple OSS Distributions 	}
1237*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_INT(pall->ptinfo.pti_csw, p_task_info->pti_csw, "PROC_PIDTASKALLINFO returned valid value for pti_csw");
1238*e3723e1fSApple OSS Distributions 
1239*e3723e1fSApple OSS Distributions 	free_proc_info(proc_info, 4);
1240*e3723e1fSApple OSS Distributions }
1241*e3723e1fSApple OSS Distributions 
1242*e3723e1fSApple OSS Distributions T_DECL(proc_info_proc_pidlistthreads,
1243*e3723e1fSApple OSS Distributions     "Test to verify PROC_PIDLISTTHREADS returns valid information about process",
1244*e3723e1fSApple OSS Distributions     T_META_ASROOT(true), T_META_TAG_VM_PREFERRED)
1245*e3723e1fSApple OSS Distributions {
1246*e3723e1fSApple OSS Distributions 	void * proc_info[1];
1247*e3723e1fSApple OSS Distributions 	proc_info_caller(THREAD_ADDR, proc_info, NULL);
1248*e3723e1fSApple OSS Distributions }
1249*e3723e1fSApple OSS Distributions 
1250*e3723e1fSApple OSS Distributions T_DECL(proc_info_proc_pidthreadinfo,
1251*e3723e1fSApple OSS Distributions     "Test to verify PROC_PIDTHREADINFO returns valid information about the process",
1252*e3723e1fSApple OSS Distributions     T_META_ASROOT(true), T_META_TAG_VM_PREFERRED)
1253*e3723e1fSApple OSS Distributions {
1254*e3723e1fSApple OSS Distributions 	void * proc_info[2];
1255*e3723e1fSApple OSS Distributions 	int child_pid = 0;
1256*e3723e1fSApple OSS Distributions 	proc_info_caller(PTHINFO_OLD | PTHINFO, proc_info, &child_pid);
1257*e3723e1fSApple OSS Distributions 	struct proc_threadinfo * pthinfo_old = (struct proc_threadinfo *)proc_info[0];
1258*e3723e1fSApple OSS Distributions 	struct proc_threadinfo * pthinfo     = (struct proc_threadinfo *)proc_info[1];
1259*e3723e1fSApple OSS Distributions 
1260*e3723e1fSApple OSS Distributions 	T_EXPECT_GT_ULLONG((pthinfo->pth_user_time - pthinfo_old->pth_user_time), 0ULL,
1261*e3723e1fSApple OSS Distributions 	    "PROC_PIDTHREADINFO returns valid value for pth_user_time");
1262*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_ULLONG((pthinfo->pth_system_time - pthinfo_old->pth_system_time), 0ULL,
1263*e3723e1fSApple OSS Distributions 	    "PROC_PIDTHREADINFO returns valid value for pth_system_time");
1264*e3723e1fSApple OSS Distributions 	/*
1265*e3723e1fSApple OSS Distributions 	 * This is the scaled cpu usage percentage, since we are not
1266*e3723e1fSApple OSS Distributions 	 * doing a really long CPU bound task, it is (nearly) zero
1267*e3723e1fSApple OSS Distributions 	 */
1268*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_INT(pthinfo->pth_cpu_usage, 0, "PROC_PIDTHREADINFO returns valid value for pth_cpu_usage");
1269*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(pthinfo->pth_policy, POLICY_TIMESHARE, "PROC_PIDTHREADINFO returns valid value for pth_policy");
1270*e3723e1fSApple OSS Distributions 	if (!(pthinfo->pth_run_state == TH_STATE_WAITING) && !(pthinfo->pth_run_state == TH_STATE_RUNNING)) {
1271*e3723e1fSApple OSS Distributions 		T_EXPECT_EQ_INT(pthinfo->pth_run_state, -1, "PROC_PIDTHREADINFO returns valid value for pth_run_state");
1272*e3723e1fSApple OSS Distributions 	}
1273*e3723e1fSApple OSS Distributions 	/*
1274*e3723e1fSApple OSS Distributions 	 * This value is hardcoded to 0 in the source, hence it will always
1275*e3723e1fSApple OSS Distributions 	 * unconditionally return 0
1276*e3723e1fSApple OSS Distributions 	 */
1277*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(pthinfo->pth_sleep_time, 0, "PROC_PIDTHREADINFO returns valid value for pth_sleep_time");
1278*e3723e1fSApple OSS Distributions 	T_EXPECT_LE_INT(pthinfo->pth_curpri, (BASEPRI_DEFAULT - CONF_NICE_VAL),
1279*e3723e1fSApple OSS Distributions 	    "PROC_PIDTHREADINFO returns valid value for pth_curpri");
1280*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(pthinfo->pth_priority, (BASEPRI_DEFAULT - CONF_NICE_VAL),
1281*e3723e1fSApple OSS Distributions 	    "PROC_PIDTHREADINFO returns valid value for pth_priority");
1282*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(pthinfo->pth_maxpriority, MAXPRI_USER, "PROC_PIDTHREADINFO returns valid value for pth_maxpriority");
1283*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_STR(pthinfo->pth_name, CONF_THREAD_NAME, "PROC_PIDTHREADINFO returns valid value for pth_name");
1284*e3723e1fSApple OSS Distributions 
1285*e3723e1fSApple OSS Distributions 	free_proc_info(proc_info, 2);
1286*e3723e1fSApple OSS Distributions }
1287*e3723e1fSApple OSS Distributions 
1288*e3723e1fSApple OSS Distributions T_DECL(proc_info_proc_threadid64info,
1289*e3723e1fSApple OSS Distributions     "Test to verify PROC_PIDTHREADID64INFO returns valid information about the process",
1290*e3723e1fSApple OSS Distributions     T_META_ASROOT(true), T_META_TAG_VM_PREFERRED)
1291*e3723e1fSApple OSS Distributions {
1292*e3723e1fSApple OSS Distributions 	void * proc_info[2];
1293*e3723e1fSApple OSS Distributions 	proc_info_caller(PTHINFO | PTHINFO_64, proc_info, NULL);
1294*e3723e1fSApple OSS Distributions 	struct proc_threadinfo pthinfo    = *((struct proc_threadinfo *)proc_info[0]);
1295*e3723e1fSApple OSS Distributions 	struct proc_threadinfo pthinfo_64 = *((struct proc_threadinfo *)proc_info[1]);
1296*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_ULLONG(pthinfo_64.pth_user_time, pthinfo.pth_user_time,
1297*e3723e1fSApple OSS Distributions 	    "PROC_PIDTHREADID64INFO returns valid value for pth_user_time");
1298*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_ULLONG(pthinfo_64.pth_system_time, pthinfo.pth_system_time,
1299*e3723e1fSApple OSS Distributions 	    "PROC_PIDTHREADID64INFO returns valid value for pth_system_time");
1300*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_INT(pthinfo_64.pth_cpu_usage, pthinfo.pth_cpu_usage,
1301*e3723e1fSApple OSS Distributions 	    "PROC_PIDTHREADID64INFO returns valid value for pth_cpu_usage");
1302*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(pthinfo_64.pth_policy, POLICY_TIMESHARE, "PROC_PIDTHREADID64INFO returns valid value for pth_policy");
1303*e3723e1fSApple OSS Distributions 	if (!(pthinfo_64.pth_run_state == TH_STATE_WAITING) && !(pthinfo_64.pth_run_state == TH_STATE_RUNNING)) {
1304*e3723e1fSApple OSS Distributions 		T_EXPECT_EQ_INT(pthinfo_64.pth_run_state, -1, "PROC_PIDTHREADID64INFO returns valid value for pth_run_state");
1305*e3723e1fSApple OSS Distributions 	}
1306*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(pthinfo_64.pth_sleep_time, 0, "PROC_PIDTHREADID64INFO returns valid value for pth_sleep_time");
1307*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(pthinfo_64.pth_curpri, pthinfo.pth_curpri, "PROC_PIDTHREADID64INFO returns valid value for pth_curpri");
1308*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(pthinfo_64.pth_priority, pthinfo.pth_priority, "PROC_PIDTHREADID64INFO returns valid value for pth_priority");
1309*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(pthinfo_64.pth_maxpriority, pthinfo.pth_maxpriority,
1310*e3723e1fSApple OSS Distributions 	    "PROC_PIDTHREADID64INFO returns valid value for pth_maxpriority");
1311*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_STR(pthinfo_64.pth_name, CONF_THREAD_NAME, "PROC_PIDTHREADID64INFO returns valid value for pth_name");
1312*e3723e1fSApple OSS Distributions 
1313*e3723e1fSApple OSS Distributions 	free_proc_info(proc_info, 2);
1314*e3723e1fSApple OSS Distributions }
1315*e3723e1fSApple OSS Distributions 
1316*e3723e1fSApple OSS Distributions T_DECL(proc_info_proc_pidthreadpathinfo,
1317*e3723e1fSApple OSS Distributions     "Test to verify PROC_PIDTHREADPATHINFO returns valid information about the process",
1318*e3723e1fSApple OSS Distributions     T_META_ASROOT(true), T_META_TAG_VM_PREFERRED)
1319*e3723e1fSApple OSS Distributions {
1320*e3723e1fSApple OSS Distributions 	void * proc_info[2];
1321*e3723e1fSApple OSS Distributions 	proc_info_caller(PTHINFO | PINFO_PATH, proc_info, NULL);
1322*e3723e1fSApple OSS Distributions 	struct proc_threadinfo pthinfo            = *((struct proc_threadinfo *)proc_info[0]);
1323*e3723e1fSApple OSS Distributions 	struct proc_threadwithpathinfo pinfo_path = *((struct proc_threadwithpathinfo *)proc_info[1]);
1324*e3723e1fSApple OSS Distributions 
1325*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_ULLONG(pinfo_path.pt.pth_user_time, pthinfo.pth_user_time,
1326*e3723e1fSApple OSS Distributions 	    "PROC_PIDTHREADPATHINFO returns valid value for pth_user_time");
1327*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_ULLONG(pinfo_path.pt.pth_system_time, pthinfo.pth_system_time,
1328*e3723e1fSApple OSS Distributions 	    "PROC_PIDTHREADPATHINFO returns valid value for pth_system_time");
1329*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_INT(pinfo_path.pt.pth_cpu_usage, pthinfo.pth_cpu_usage,
1330*e3723e1fSApple OSS Distributions 	    "PROC_PIDTHREADPATHINFO returns valid value for pth_cpu_usage");
1331*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(pinfo_path.pt.pth_policy, POLICY_TIMESHARE, "PROC_PIDTHREADPATHINFO returns valid value for pth_policy");
1332*e3723e1fSApple OSS Distributions 	if (!(pinfo_path.pt.pth_run_state == TH_STATE_WAITING) && !(pinfo_path.pt.pth_run_state == TH_STATE_RUNNING)) {
1333*e3723e1fSApple OSS Distributions 		T_EXPECT_EQ_INT(pinfo_path.pt.pth_run_state, -1, "PROC_PIDTHREADPATHINFO returns valid value for pth_run_state");
1334*e3723e1fSApple OSS Distributions 	}
1335*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(pinfo_path.pt.pth_sleep_time, 0, "PROC_PIDTHREADPATHINFO returns valid value for pth_sleep_time");
1336*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(pinfo_path.pt.pth_curpri, pthinfo.pth_curpri, "PROC_PIDTHREADPATHINFO returns valid value for pth_curpri");
1337*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(pinfo_path.pt.pth_priority, pthinfo.pth_priority,
1338*e3723e1fSApple OSS Distributions 	    "PROC_PIDTHREADPATHINFO returns valid value for pth_priority");
1339*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(pinfo_path.pt.pth_maxpriority, pthinfo.pth_maxpriority,
1340*e3723e1fSApple OSS Distributions 	    "PROC_PIDTHREADPATHINFO returns valid value for pth_maxpriority");
1341*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_STR(pinfo_path.pt.pth_name, CONF_THREAD_NAME, "PROC_PIDTHREADPATHINFO returns valid value for pth_name");
1342*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(pinfo_path.pvip.vip_vi.vi_type, VNON, "PROC_PIDTHREADPATHINFO valid vnode information");
1343*e3723e1fSApple OSS Distributions 
1344*e3723e1fSApple OSS Distributions 	free_proc_info(proc_info, 2);
1345*e3723e1fSApple OSS Distributions }
1346*e3723e1fSApple OSS Distributions 
1347*e3723e1fSApple OSS Distributions T_DECL(proc_info_proc_pidarchinfo,
1348*e3723e1fSApple OSS Distributions     "Test to verify PROC_PIDARCHINFO returns valid information about the process",
1349*e3723e1fSApple OSS Distributions     T_META_ASROOT(true), T_META_TAG_VM_PREFERRED)
1350*e3723e1fSApple OSS Distributions {
1351*e3723e1fSApple OSS Distributions 	void * proc_info[1];
1352*e3723e1fSApple OSS Distributions 	proc_info_caller(PAI, proc_info, NULL);
1353*e3723e1fSApple OSS Distributions 	struct proc_archinfo pai = *((struct proc_archinfo *)proc_info[0]);
1354*e3723e1fSApple OSS Distributions 
1355*e3723e1fSApple OSS Distributions #if defined(__arm64__)
1356*e3723e1fSApple OSS Distributions 	if (!((pai.p_cputype & CPU_TYPE_ARM) == CPU_TYPE_ARM) && !((pai.p_cputype & CPU_TYPE_ARM64) == CPU_TYPE_ARM64)) {
1357*e3723e1fSApple OSS Distributions 		T_EXPECT_EQ_INT(pai.p_cputype, CPU_TYPE_ARM, "PROC_PIDARCHINFO returned valid value for p_cputype");
1358*e3723e1fSApple OSS Distributions 	}
1359*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT((pai.p_cpusubtype & CPU_SUBTYPE_ARM_ALL), CPU_SUBTYPE_ARM_ALL,
1360*e3723e1fSApple OSS Distributions 	    "PROC_PIDARCHINFO returned valid value for p_cpusubtype");
1361*e3723e1fSApple OSS Distributions #else
1362*e3723e1fSApple OSS Distributions 	if (!((pai.p_cputype & CPU_TYPE_X86) == CPU_TYPE_X86) && !((pai.p_cputype & CPU_TYPE_X86_64) == CPU_TYPE_X86_64)) {
1363*e3723e1fSApple OSS Distributions 		T_EXPECT_EQ_INT(pai.p_cputype, CPU_TYPE_X86, "PROC_PIDARCHINFO returned valid value for p_cputype");
1364*e3723e1fSApple OSS Distributions 	}
1365*e3723e1fSApple OSS Distributions #endif
1366*e3723e1fSApple OSS Distributions 	free_proc_info(proc_info, 1);
1367*e3723e1fSApple OSS Distributions }
1368*e3723e1fSApple OSS Distributions 
1369*e3723e1fSApple OSS Distributions T_DECL(proc_info_proc_pidregioninfo,
1370*e3723e1fSApple OSS Distributions     "Test to verify PROC_PIDREGIONINFO returns valid information about the process",
1371*e3723e1fSApple OSS Distributions     T_META_ASROOT(true), T_META_TAG_VM_PREFERRED)
1372*e3723e1fSApple OSS Distributions {
1373*e3723e1fSApple OSS Distributions 	void * proc_info[3];
1374*e3723e1fSApple OSS Distributions 	proc_info_caller(PREGINFO, proc_info, NULL);
1375*e3723e1fSApple OSS Distributions 
1376*e3723e1fSApple OSS Distributions 	struct proc_regioninfo preginfo = *((struct proc_regioninfo *)proc_info[0]);
1377*e3723e1fSApple OSS Distributions 	/*
1378*e3723e1fSApple OSS Distributions 	 *	map_tmp isn't a struct like the rest of our ret_structs, but we sneak it back because we need it
1379*e3723e1fSApple OSS Distributions 	 */
1380*e3723e1fSApple OSS Distributions 	void *map_tmp = proc_info[1];
1381*e3723e1fSApple OSS Distributions 	vm_map_size_t map_tmp_sz = (vm_map_size_t)(uintptr_t)proc_info[2];
1382*e3723e1fSApple OSS Distributions 
1383*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_ULLONG(preginfo.pri_offset, (unsigned long long)PAGE_SIZE, "PROC_PIDREGIONINFO returns valid value for pri_offset");
1384*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT((preginfo.pri_protection ^ (VM_PROT_READ | VM_PROT_WRITE)), 0U,
1385*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONINFO returns valid value for pri_protection, expected read/write only");
1386*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT((preginfo.pri_max_protection & (VM_PROT_READ | VM_PROT_WRITE)), (unsigned int)(VM_PROT_READ | VM_PROT_WRITE),
1387*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONINFO returns valid value for pri_max_protection");
1388*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT((preginfo.pri_inheritance ^ VM_INHERIT_COPY), 0U,
1389*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONINFO returns valid value for pri_inheritance");
1390*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT((preginfo.pri_behavior ^ VM_BEHAVIOR_DEFAULT), 0U, "PROC_PIDREGIONINFO returns valid value for pri_behavior");
1391*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo.pri_user_wired_count, 0U, "PROC_PIDREGIONINFO returns valid value for pri_user_wired_count");
1392*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo.pri_user_tag, 0U, "PROC_PIDREGIONINFO returns valid value for pri_user_tag");
1393*e3723e1fSApple OSS Distributions 	T_EXPECT_NE_UINT((preginfo.pri_flags ^ (PROC_REGION_SUBMAP | PROC_REGION_SHARED)), 0U,
1394*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONINFO returns valid value for pri_flags");
1395*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo.pri_pages_resident, 0U, "PROC_PIDREGIONINFO returns valid value for pri_pages_resident");
1396*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo.pri_pages_shared_now_private, 0U,
1397*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONINFO returns valid value for pri_pages_shared_now_private");
1398*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo.pri_pages_swapped_out, 0U, "PROC_PIDREGIONINFO returns valid value for pri_pages_swapped_out");
1399*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo.pri_pages_dirtied, 0U, "PROC_PIDREGIONINFO returns valid value for pri_pages_dirtied");
1400*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo.pri_ref_count, 2U, "PROC_PIDREGIONINFO returns valid value for pri_ref_count");
1401*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo.pri_shadow_depth, 1U, "PROC_PIDREGIONINFO returns valid value for pri_shadow_depth");
1402*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo.pri_share_mode, (unsigned int)SM_COW, "PROC_PIDREGIONINFO returns valid value for pri_share_mode");
1403*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo.pri_private_pages_resident, 0U,
1404*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONINFO returns valid value for pri_private_pages_resident");
1405*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_UINT(preginfo.pri_shared_pages_resident, 0U,
1406*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONINFO returns valid value for pri_shared_pages_resident");
1407*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_ULLONG(preginfo.pri_address, (uint64_t)map_tmp, "PROC_PIDREGIONINFO returns valid value for pri_addr");
1408*e3723e1fSApple OSS Distributions 	T_EXPECT_NE_UINT(preginfo.pri_obj_id, 0U, "PROC_PIDREGIONINFO returns valid value for pri_obj_id");
1409*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_ULLONG(preginfo.pri_size, (unsigned long long)map_tmp_sz, "PROC_PIDREGIONINFO returns valid value for pri_size");
1410*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo.pri_depth, 0U, "PROC_PIDREGIONINFO returns valid value for pri_depth");
1411*e3723e1fSApple OSS Distributions 
1412*e3723e1fSApple OSS Distributions 	int ret = 0;
1413*e3723e1fSApple OSS Distributions 	ret     = munmap(map_tmp, (size_t)map_tmp_sz);
1414*e3723e1fSApple OSS Distributions 	T_QUIET;
1415*e3723e1fSApple OSS Distributions 	T_EXPECT_POSIX_SUCCESS(ret, "munmap of map_tmp");
1416*e3723e1fSApple OSS Distributions 	free_proc_info(proc_info, 1);
1417*e3723e1fSApple OSS Distributions }
1418*e3723e1fSApple OSS Distributions 
1419*e3723e1fSApple OSS Distributions T_DECL(proc_info_proc_pidregionpathinfo,
1420*e3723e1fSApple OSS Distributions     "Test to verify PROC_PIDREGIONPATHINFO returns valid information about the process",
1421*e3723e1fSApple OSS Distributions     T_META_ASROOT(true), T_META_TAG_VM_PREFERRED)
1422*e3723e1fSApple OSS Distributions {
1423*e3723e1fSApple OSS Distributions 	void * proc_info[3];
1424*e3723e1fSApple OSS Distributions 	proc_info_caller(PREGINFO_PATH, proc_info, NULL);
1425*e3723e1fSApple OSS Distributions 
1426*e3723e1fSApple OSS Distributions 	struct proc_regionwithpathinfo preginfo_path = *((struct proc_regionwithpathinfo *)proc_info[0]);
1427*e3723e1fSApple OSS Distributions 	/*
1428*e3723e1fSApple OSS Distributions 	 *	map_tmp isn't a struct like the rest of our ret_structs, but we sneak it back because we need it
1429*e3723e1fSApple OSS Distributions 	 */
1430*e3723e1fSApple OSS Distributions 	void *map_tmp = proc_info[1];
1431*e3723e1fSApple OSS Distributions 	vm_map_size_t map_tmp_sz = (vm_map_size_t)(uintptr_t)proc_info[2];
1432*e3723e1fSApple OSS Distributions 
1433*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_ULLONG(preginfo_path.prp_prinfo.pri_offset, (uint64_t)PAGE_SIZE,
1434*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO returns valid value for pri_offset");
1435*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT((preginfo_path.prp_prinfo.pri_protection ^ (VM_PROT_READ | VM_PROT_WRITE)), 0U,
1436*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO returns valid value for pri_protection, expected read/write only");
1437*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT((preginfo_path.prp_prinfo.pri_max_protection & (VM_PROT_READ | VM_PROT_WRITE)),
1438*e3723e1fSApple OSS Distributions 	    (unsigned int)(VM_PROT_READ | VM_PROT_WRITE),
1439*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO returns valid value for pri_max_protection");
1440*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT((preginfo_path.prp_prinfo.pri_inheritance ^ VM_INHERIT_COPY), 0U,
1441*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO returns valid value for pri_inheritance");
1442*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT((preginfo_path.prp_prinfo.pri_behavior ^ VM_BEHAVIOR_DEFAULT), 0U,
1443*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO returns valid value for pri_behavior");
1444*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_user_wired_count, 0U,
1445*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO returns valid value for pri_user_wired_count");
1446*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_user_tag, 0U, "PROC_PIDREGIONPATHINFO returns valid value for pri_user_tag");
1447*e3723e1fSApple OSS Distributions 	T_EXPECT_NE_UINT((preginfo_path.prp_prinfo.pri_flags ^ (PROC_REGION_SUBMAP | PROC_REGION_SHARED)), 0U,
1448*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO returns valid value for pri_flags");
1449*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_pages_resident, 0U,
1450*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO returns valid value for pri_pages_resident");
1451*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_pages_shared_now_private, 0U,
1452*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO returns valid value for pri_pages_shared_now_private");
1453*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_pages_swapped_out, 0U,
1454*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO returns valid value for pri_pages_swapped_out");
1455*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_pages_dirtied, 0U,
1456*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO returns valid value for pri_pages_dirtied");
1457*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_ref_count, 2U, "PROC_PIDREGIONPATHINFO returns valid value for pri_ref_count");
1458*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_shadow_depth, 1U,
1459*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO returns valid value for pri_shadow_depth");
1460*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_share_mode, (unsigned int)SM_COW,
1461*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO returns valid value for pri_share_mode");
1462*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_private_pages_resident, 0U,
1463*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO returns valid value for pri_private_pages_resident");
1464*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_UINT(preginfo_path.prp_prinfo.pri_shared_pages_resident, 0U,
1465*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO returns valid value for pri_shared_pages_resident");
1466*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_ULLONG(preginfo_path.prp_prinfo.pri_address, (uint64_t)map_tmp,
1467*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO returns valid value for pri_addr");
1468*e3723e1fSApple OSS Distributions 	T_EXPECT_NE_UINT(preginfo_path.prp_prinfo.pri_obj_id, 0U, "PROC_PIDREGIONPATHINFO returns valid value for pri_obj_id");
1469*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_ULLONG(preginfo_path.prp_prinfo.pri_size, (uint64_t)map_tmp_sz,
1470*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO returns valid value for pri_size");
1471*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_depth, 0U, "PROC_PIDREGIONPATHINFO returns valid value for pri_depth");
1472*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(preginfo_path.prp_vip.vip_vi.vi_type, VREG, "PROC_PIDREGIONPATHINFO returns valid value for vi_type");
1473*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(preginfo_path.prp_vip.vip_vi.vi_pad, 0, "PROC_PIDREGIONPATHINFO returns valid value for vi_pad");
1474*e3723e1fSApple OSS Distributions 	T_EXPECT_NE_INT(preginfo_path.prp_vip.vip_vi.vi_fsid.val[0], 0,
1475*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO returns valid value for vi_fsid.val[0]");
1476*e3723e1fSApple OSS Distributions 	T_EXPECT_NE_INT(preginfo_path.prp_vip.vip_vi.vi_fsid.val[1], 0,
1477*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO returns valid value for vi_fsid.val[1]");
1478*e3723e1fSApple OSS Distributions 	T_EXPECT_NE_PTR((void *)(strcasestr(preginfo_path.prp_vip.vip_path, CONF_TMP_FILE_PFX)), NULL,
1479*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO returns valid value for vi_path");
1480*e3723e1fSApple OSS Distributions 	/*
1481*e3723e1fSApple OSS Distributions 	 * Basic sanity checks for vnode stat returned by the API
1482*e3723e1fSApple OSS Distributions 	 */
1483*e3723e1fSApple OSS Distributions 	T_EXPECT_NE_UINT(preginfo_path.prp_vip.vip_vi.vi_stat.vst_dev, 0U, "PROC_PIDREGIONPATHINFO returns valid value for vst_dev");
1484*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(((preginfo_path.prp_vip.vip_vi.vi_stat.vst_mode & S_IFMT) ^ S_IFREG), 0,
1485*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO returns valid value for vst_mode");
1486*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_USHORT(preginfo_path.prp_vip.vip_vi.vi_stat.vst_nlink, (unsigned short)0, /* the file was unlink()'d! */
1487*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO returns valid value for vst_nlink");
1488*e3723e1fSApple OSS Distributions 	T_EXPECT_NE_ULLONG(preginfo_path.prp_vip.vip_vi.vi_stat.vst_ino, 0ULL,
1489*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO returns valid value for vst_ino");
1490*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo_path.prp_vip.vip_vi.vi_stat.vst_uid, 0U, "PROC_PIDREGIONPATHINFO returns valid value for vst_uid");
1491*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo_path.prp_vip.vip_vi.vi_stat.vst_gid, 0U, "PROC_PIDREGIONPATHINFO returns valid value for vst_gid");
1492*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_LLONG(preginfo_path.prp_vip.vip_vi.vi_stat.vst_size, (off_t)CONF_BLK_SIZE,
1493*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO returns valid value for vst_size");
1494*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_LLONG(preginfo_path.prp_vip.vip_vi.vi_stat.vst_blocks, 1LL,
1495*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO returns valid value for vst_blocks");
1496*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_INT(preginfo_path.prp_vip.vip_vi.vi_stat.vst_blksize, CONF_BLK_SIZE,
1497*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO returns valid value for vst_blksize");
1498*e3723e1fSApple OSS Distributions 
1499*e3723e1fSApple OSS Distributions 	int ret = 0;
1500*e3723e1fSApple OSS Distributions 	ret     = munmap(map_tmp, (size_t)map_tmp_sz);
1501*e3723e1fSApple OSS Distributions 	T_QUIET;
1502*e3723e1fSApple OSS Distributions 	T_EXPECT_POSIX_SUCCESS(ret, "munmap of map_tmp");
1503*e3723e1fSApple OSS Distributions 	free_proc_info(proc_info, 1);
1504*e3723e1fSApple OSS Distributions }
1505*e3723e1fSApple OSS Distributions 
1506*e3723e1fSApple OSS Distributions T_DECL(proc_info_proc_pidregionpathinfo2,
1507*e3723e1fSApple OSS Distributions     "Test to verify PROC_PIDREGIONPATHINFO2 returns valid information about the process",
1508*e3723e1fSApple OSS Distributions     T_META_ASROOT(true), T_META_TAG_VM_PREFERRED)
1509*e3723e1fSApple OSS Distributions {
1510*e3723e1fSApple OSS Distributions 	void * proc_info[3];
1511*e3723e1fSApple OSS Distributions 	proc_info_caller(PREGINFO_PATH_2, proc_info, NULL);
1512*e3723e1fSApple OSS Distributions 
1513*e3723e1fSApple OSS Distributions 	struct proc_regionwithpathinfo preginfo_path = *((struct proc_regionwithpathinfo *)proc_info[0]);
1514*e3723e1fSApple OSS Distributions 	/*
1515*e3723e1fSApple OSS Distributions 	 *	map_tmp isn't a struct like the rest of our ret_structs, but we sneak it back because we need it
1516*e3723e1fSApple OSS Distributions 	 */
1517*e3723e1fSApple OSS Distributions 	void *map_tmp = proc_info[1];
1518*e3723e1fSApple OSS Distributions 	vm_map_size_t map_tmp_sz = (vm_map_size_t)(uintptr_t)proc_info[2];
1519*e3723e1fSApple OSS Distributions 
1520*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_ULLONG(preginfo_path.prp_prinfo.pri_offset, (uint64_t)PAGE_SIZE,
1521*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO2 returns valid value for pri_offset");
1522*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT((preginfo_path.prp_prinfo.pri_protection ^ (VM_PROT_READ | VM_PROT_WRITE)), 0U,
1523*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO2 returns valid value for pri_protection, expected read/write only");
1524*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT((preginfo_path.prp_prinfo.pri_max_protection & (VM_PROT_READ | VM_PROT_WRITE)),
1525*e3723e1fSApple OSS Distributions 	    (unsigned int)(VM_PROT_READ | VM_PROT_WRITE),
1526*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO2 returns valid value for pri_max_protection");
1527*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT((preginfo_path.prp_prinfo.pri_inheritance ^ VM_INHERIT_COPY), 0U,
1528*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO2 returns valid value for pri_inheritance");
1529*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT((preginfo_path.prp_prinfo.pri_behavior ^ VM_BEHAVIOR_DEFAULT), 0U,
1530*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO2 returns valid value for pri_behavior");
1531*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_user_wired_count, 0U,
1532*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO2 returns valid value for pri_user_wired_count");
1533*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_user_tag, 0U, "PROC_PIDREGIONPATHINFO2 returns valid value for pri_user_tag");
1534*e3723e1fSApple OSS Distributions 	T_EXPECT_NE_UINT((preginfo_path.prp_prinfo.pri_flags ^ (PROC_REGION_SUBMAP | PROC_REGION_SHARED)), 0U,
1535*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO2 returns valid value for pri_flags");
1536*e3723e1fSApple OSS Distributions 	/*
1537*e3723e1fSApple OSS Distributions 	 * Following values are hard-coded to be zero in source
1538*e3723e1fSApple OSS Distributions 	 */
1539*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_pages_resident, 0U,
1540*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO2 returns valid value for pri_pages_resident");
1541*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_pages_shared_now_private, 0U,
1542*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO2 returns valid value for pri_pages_shared_now_private");
1543*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_pages_swapped_out, 0U,
1544*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO2 returns valid value for pri_pages_swapped_out");
1545*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_pages_dirtied, 0U,
1546*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO2 returns valid value for pri_pages_dirtied");
1547*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_ref_count, 0U, "PROC_PIDREGIONPATHINFO2 returns valid value for pri_ref_count");
1548*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_shadow_depth, 0U,
1549*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO2 returns valid value for pri_shadow_depth");
1550*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_share_mode, 0U, "PROC_PIDREGIONPATHINFO2 returns valid value for pri_share_mode");
1551*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_private_pages_resident, 0U,
1552*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO2 returns valid value for pri_private_pages_resident");
1553*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_shared_pages_resident, 0U,
1554*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO2 returns valid value for pri_shared_pages_resident");
1555*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_ULLONG(preginfo_path.prp_prinfo.pri_address, (uint64_t)map_tmp,
1556*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO2 returns valid value for pri_addr");
1557*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_obj_id, 0U, "PROC_PIDREGIONPATHINFO2 returns valid value for pri_obj_id");
1558*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_ULLONG(preginfo_path.prp_prinfo.pri_size, (unsigned long long)map_tmp_sz,
1559*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO2 returns valid value for pri_size");
1560*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo_path.prp_prinfo.pri_depth, 0U, "PROC_PIDREGIONPATHINFO2 returns valid value for pri_depth");
1561*e3723e1fSApple OSS Distributions 
1562*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(preginfo_path.prp_vip.vip_vi.vi_type, VREG, "PROC_PIDREGIONPATHINFO2 returns valid value for vi_type");
1563*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(preginfo_path.prp_vip.vip_vi.vi_pad, 0, "PROC_PIDREGIONPATHINFO2 returns valid value for vi_pad");
1564*e3723e1fSApple OSS Distributions 	T_EXPECT_NE_INT(preginfo_path.prp_vip.vip_vi.vi_fsid.val[0], 0,
1565*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO2 returns valid value for vi_fsid.val[0]:%d",
1566*e3723e1fSApple OSS Distributions 	    preginfo_path.prp_vip.vip_vi.vi_fsid.val[0]);
1567*e3723e1fSApple OSS Distributions 	T_EXPECT_NE_INT(preginfo_path.prp_vip.vip_vi.vi_fsid.val[1], 0,
1568*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO2 returns valid value for vi_fsid.val[1]:%d",
1569*e3723e1fSApple OSS Distributions 	    preginfo_path.prp_vip.vip_vi.vi_fsid.val[1]);
1570*e3723e1fSApple OSS Distributions 	T_EXPECT_NE_PTR((void *)(strcasestr(preginfo_path.prp_vip.vip_path, CONF_TMP_FILE_PFX)), NULL,
1571*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO2 returns valid value for vi_path");
1572*e3723e1fSApple OSS Distributions 	/*
1573*e3723e1fSApple OSS Distributions 	 * Basic sanity checks for vnode stat returned by the API
1574*e3723e1fSApple OSS Distributions 	 */
1575*e3723e1fSApple OSS Distributions 	T_EXPECT_NE_UINT(preginfo_path.prp_vip.vip_vi.vi_stat.vst_dev, 0U, "PROC_PIDREGIONPATHINFO2 returns valid value for vst_dev");
1576*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(((preginfo_path.prp_vip.vip_vi.vi_stat.vst_mode & S_IFMT) ^ S_IFREG), 0,
1577*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO2 returns valid value for vst_mode");
1578*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_USHORT(preginfo_path.prp_vip.vip_vi.vi_stat.vst_nlink, (unsigned short)0, /* the file was unlink()'d! */
1579*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO2 returns valid value for vst_nlink");
1580*e3723e1fSApple OSS Distributions 	T_EXPECT_NE_ULLONG(preginfo_path.prp_vip.vip_vi.vi_stat.vst_ino, 0ULL,
1581*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO2 returns valid value for vst_ino");
1582*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo_path.prp_vip.vip_vi.vi_stat.vst_uid, 0U, "PROC_PIDREGIONPATHINFO2 returns valid value for vst_uid");
1583*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(preginfo_path.prp_vip.vip_vi.vi_stat.vst_gid, 0U, "PROC_PIDREGIONPATHINFO2 returns valid value for vst_gid");
1584*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_LLONG(preginfo_path.prp_vip.vip_vi.vi_stat.vst_size, (off_t)CONF_BLK_SIZE,
1585*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO2 returns valid value for vst_size");
1586*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_LLONG(preginfo_path.prp_vip.vip_vi.vi_stat.vst_blocks, 1LL,
1587*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO2 returns valid value for vst_blocks");
1588*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_UINT(preginfo_path.prp_vip.vip_vi.vi_stat.vst_blksize, CONF_BLK_SIZE,
1589*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO2 returns valid value for vst_blksize");
1590*e3723e1fSApple OSS Distributions 
1591*e3723e1fSApple OSS Distributions 	int ret = 0;
1592*e3723e1fSApple OSS Distributions 	ret     = munmap(map_tmp, (size_t)map_tmp_sz);
1593*e3723e1fSApple OSS Distributions 	T_QUIET;
1594*e3723e1fSApple OSS Distributions 	T_EXPECT_POSIX_SUCCESS(ret, "munmap of map_tmp");
1595*e3723e1fSApple OSS Distributions 	free_proc_info(proc_info, 1);
1596*e3723e1fSApple OSS Distributions }
1597*e3723e1fSApple OSS Distributions 
1598*e3723e1fSApple OSS Distributions T_DECL(proc_info_proc_pidregionpathinfo3,
1599*e3723e1fSApple OSS Distributions     "Test to verify PROC_PIDREGIONPATHINFO3 returns valid information about the process",
1600*e3723e1fSApple OSS Distributions     T_META_ASROOT(true), T_META_TAG_VM_PREFERRED)
1601*e3723e1fSApple OSS Distributions {
1602*e3723e1fSApple OSS Distributions 	void * proc_info[5];
1603*e3723e1fSApple OSS Distributions 	proc_info_caller(PREGINFO_PATH_3, proc_info, NULL);
1604*e3723e1fSApple OSS Distributions 
1605*e3723e1fSApple OSS Distributions 	struct proc_regionwithpathinfo preginfo_path = *((struct proc_regionwithpathinfo *)proc_info[0]);
1606*e3723e1fSApple OSS Distributions 	void *map_tmp = proc_info[1];
1607*e3723e1fSApple OSS Distributions 	vm_map_size_t map_tmp_sz = (vm_map_size_t)(uintptr_t)proc_info[2];
1608*e3723e1fSApple OSS Distributions 
1609*e3723e1fSApple OSS Distributions 	/* The *info3 version of this call returns any open file that lives on the same file system */
1610*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(preginfo_path.prp_vip.vip_vi.vi_fsid.val[0], (int)(uintptr_t)proc_info[3],
1611*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO3 returns valid value for vi_fsid.val[0]");
1612*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(preginfo_path.prp_vip.vip_vi.vi_fsid.val[1], (int)(uintptr_t)proc_info[4],
1613*e3723e1fSApple OSS Distributions 	    "PROC_PIDREGIONPATHINFO3 returns valid value for vi_fsid.val[1]");
1614*e3723e1fSApple OSS Distributions 
1615*e3723e1fSApple OSS Distributions 	int ret = 0;
1616*e3723e1fSApple OSS Distributions 	ret     = munmap(map_tmp, (size_t)map_tmp_sz);
1617*e3723e1fSApple OSS Distributions 	T_QUIET;
1618*e3723e1fSApple OSS Distributions 	T_EXPECT_POSIX_SUCCESS(ret, "munmap of map_tmp");
1619*e3723e1fSApple OSS Distributions 	free_proc_info(proc_info, 1);
1620*e3723e1fSApple OSS Distributions }
1621*e3723e1fSApple OSS Distributions 
1622*e3723e1fSApple OSS Distributions T_DECL(proc_info_proc_pidvnodepathinfo,
1623*e3723e1fSApple OSS Distributions     "Test to verify PROC_PIDVNODEPATHINFO returns valid information about the process",
1624*e3723e1fSApple OSS Distributions     T_META_ASROOT(true), T_META_TAG_VM_PREFERRED)
1625*e3723e1fSApple OSS Distributions {
1626*e3723e1fSApple OSS Distributions 	void * proc_info[1];
1627*e3723e1fSApple OSS Distributions 	proc_info_caller(PVNINFO, proc_info, NULL);
1628*e3723e1fSApple OSS Distributions 	struct proc_vnodepathinfo pvninfo = *((struct proc_vnodepathinfo *)proc_info[0]);
1629*e3723e1fSApple OSS Distributions 
1630*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(pvninfo.pvi_cdir.vip_vi.vi_type, VDIR, "PROC_PIDVNODEPATHINFO returns valid value for vi_type");
1631*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(pvninfo.pvi_cdir.vip_vi.vi_pad, 0, "PROC_PIDVNODEPATHINFO returns valid value for vi_pad");
1632*e3723e1fSApple OSS Distributions 	T_EXPECT_NE_INT(pvninfo.pvi_cdir.vip_vi.vi_fsid.val[0], 0, "PROC_PIDVNODEPATHINFO returns valid value for vi_fsid.val[0]");
1633*e3723e1fSApple OSS Distributions 	T_EXPECT_NE_INT(pvninfo.pvi_cdir.vip_vi.vi_fsid.val[1], 0, "PROC_PIDVNODEPATHINFO returns valid value for vi_fsid.val[1]");
1634*e3723e1fSApple OSS Distributions 	/*
1635*e3723e1fSApple OSS Distributions 	 * Basic sanity checks for vnode stat returned by the API
1636*e3723e1fSApple OSS Distributions 	 */
1637*e3723e1fSApple OSS Distributions 	T_EXPECT_NE_UINT(pvninfo.pvi_cdir.vip_vi.vi_stat.vst_dev, 0U, "PROC_PIDVNODEPATHINFO returns valid value for vst_dev");
1638*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(((pvninfo.pvi_cdir.vip_vi.vi_stat.vst_mode & S_IFMT) ^ S_IFDIR), 0,
1639*e3723e1fSApple OSS Distributions 	    "PROC_PIDVNODEPATHINFO returns valid value for vst_mode");
1640*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_USHORT(pvninfo.pvi_cdir.vip_vi.vi_stat.vst_nlink, (unsigned short)2,
1641*e3723e1fSApple OSS Distributions 	    "PROC_PIDVNODEPATHINFO returns valid value for vst_nlink");
1642*e3723e1fSApple OSS Distributions 	T_EXPECT_NE_ULLONG(pvninfo.pvi_cdir.vip_vi.vi_stat.vst_ino, 0ULL, "PROC_PIDVNODEPATHINFO returns valid value for vst_ino");
1643*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_UINT(pvninfo.pvi_cdir.vip_vi.vi_stat.vst_uid, 0U, "PROC_PIDVNODEPATHINFO returns valid value for vst_uid");
1644*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_UINT(pvninfo.pvi_cdir.vip_vi.vi_stat.vst_gid, 0U, "PROC_PIDVNODEPATHINFO returns valid value for vst_gid");
1645*e3723e1fSApple OSS Distributions 	T_EXPECT_GT_LLONG(pvninfo.pvi_cdir.vip_vi.vi_stat.vst_size, 0LL, "PROC_PIDVNODEPATHINFO returns valid value for vst_size");
1646*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_LLONG(pvninfo.pvi_cdir.vip_vi.vi_stat.vst_blocks, 0LL, "PROC_PIDVNODEPATHINFO returns valid value for vst_blocks");
1647*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_UINT(pvninfo.pvi_cdir.vip_vi.vi_stat.vst_blksize, CONF_BLK_SIZE,
1648*e3723e1fSApple OSS Distributions 	    "PROC_PIDVNODEPATHINFO returns valid value for vst_blksize");
1649*e3723e1fSApple OSS Distributions 
1650*e3723e1fSApple OSS Distributions 	free_proc_info(proc_info, 1);
1651*e3723e1fSApple OSS Distributions }
1652*e3723e1fSApple OSS Distributions /*
1653*e3723e1fSApple OSS Distributions  * The remaining tests break from the pattern of the other PROC_INFO_CALL_PIDINFO tests.
1654*e3723e1fSApple OSS Distributions  * We call proc_info directly as it's more efficient
1655*e3723e1fSApple OSS Distributions  */
1656*e3723e1fSApple OSS Distributions 
1657*e3723e1fSApple OSS Distributions T_DECL(proc_info_pidinfo_proc_pidlistfds,
1658*e3723e1fSApple OSS Distributions     "proc_info API tests to verify PROC_INFO_CALL_PIDINFO/PROC_PIDLISTFDS",
1659*e3723e1fSApple OSS Distributions     T_META_ASROOT(true), T_META_TAG_VM_PREFERRED)
1660*e3723e1fSApple OSS Distributions {
1661*e3723e1fSApple OSS Distributions 	int retval;
1662*e3723e1fSApple OSS Distributions 	int orig_nfiles              = 0;
1663*e3723e1fSApple OSS Distributions 	struct proc_fdinfo * fd_info = NULL;
1664*e3723e1fSApple OSS Distributions 
1665*e3723e1fSApple OSS Distributions 	T_LOG("Test to verify PROC_PIDLISTFDS returns sane number of open files");
1666*e3723e1fSApple OSS Distributions 	retval      = __proc_info(PROC_INFO_CALL_PIDINFO, getpid(), PROC_PIDLISTFDS, (uint32_t)0, (user_addr_t)0, (uint32_t)0);
1667*e3723e1fSApple OSS Distributions 	orig_nfiles = retval / (int)sizeof(struct proc_fdinfo);
1668*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_INT(orig_nfiles, CONF_OPN_FILE_COUNT, "The number of open files is lower than expected.");
1669*e3723e1fSApple OSS Distributions 
1670*e3723e1fSApple OSS Distributions 	/*
1671*e3723e1fSApple OSS Distributions 	 * Allocate a buffer of expected size + 1 to ensure that
1672*e3723e1fSApple OSS Distributions 	 * the API still returns expected size
1673*e3723e1fSApple OSS Distributions 	 * i.e. 3 + 1 = 4 open fds
1674*e3723e1fSApple OSS Distributions 	 */
1675*e3723e1fSApple OSS Distributions 	T_LOG("Test to verify PROC_PIDLISTFDS returns valid fd information");
1676*e3723e1fSApple OSS Distributions 	fd_info = malloc(sizeof(*fd_info) * 5);
1677*e3723e1fSApple OSS Distributions 	tmp_fd = CONF_TMP_FILE_OPEN(NULL);
1678*e3723e1fSApple OSS Distributions 	T_LOG("tmp_fd val:%d", tmp_fd);
1679*e3723e1fSApple OSS Distributions 	T_QUIET;
1680*e3723e1fSApple OSS Distributions 	T_EXPECT_POSIX_SUCCESS(tmp_fd, "open() for PROC_PIDLISTFDS");
1681*e3723e1fSApple OSS Distributions 
1682*e3723e1fSApple OSS Distributions 	retval = __proc_info(PROC_INFO_CALL_PIDINFO, getpid(), PROC_PIDLISTFDS, (uint32_t)0, (user_addr_t)fd_info,
1683*e3723e1fSApple OSS Distributions 	    (uint32_t)(sizeof(*fd_info) * 5));
1684*e3723e1fSApple OSS Distributions 	retval = retval / (int)sizeof(struct proc_fdinfo);
1685*e3723e1fSApple OSS Distributions 
1686*e3723e1fSApple OSS Distributions 	close(tmp_fd);
1687*e3723e1fSApple OSS Distributions 
1688*e3723e1fSApple OSS Distributions 	for (int i = 0; i < retval; i++) {
1689*e3723e1fSApple OSS Distributions 		/*
1690*e3723e1fSApple OSS Distributions 		 * Check only for the fd that we control.
1691*e3723e1fSApple OSS Distributions 		 */
1692*e3723e1fSApple OSS Distributions 		if (tmp_fd != fd_info[i].proc_fd) {
1693*e3723e1fSApple OSS Distributions 			continue;
1694*e3723e1fSApple OSS Distributions 		}
1695*e3723e1fSApple OSS Distributions 		T_EXPECT_EQ_UINT(fd_info[i].proc_fdtype, (unsigned int)PROX_FDTYPE_VNODE, "Correct proc_fdtype for returned fd");
1696*e3723e1fSApple OSS Distributions 	}
1697*e3723e1fSApple OSS Distributions 
1698*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_INT(retval, 4, "Correct number of fds was returned.");
1699*e3723e1fSApple OSS Distributions 
1700*e3723e1fSApple OSS Distributions 	tmp_fd = -1;
1701*e3723e1fSApple OSS Distributions 	free(fd_info);
1702*e3723e1fSApple OSS Distributions 	fd_info = NULL;
1703*e3723e1fSApple OSS Distributions }
1704*e3723e1fSApple OSS Distributions 
1705*e3723e1fSApple OSS Distributions T_DECL(proc_info_proc_pidpathinfo,
1706*e3723e1fSApple OSS Distributions     "Test to verify PROC_PIDPATHINFO returns valid information about the process",
1707*e3723e1fSApple OSS Distributions     T_META_ASROOT(true), T_META_TAG_VM_PREFERRED)
1708*e3723e1fSApple OSS Distributions {
1709*e3723e1fSApple OSS Distributions 	char * pid_path = NULL;
1710*e3723e1fSApple OSS Distributions 	pid_path        = malloc(sizeof(char) * PROC_PIDPATHINFO_MAXSIZE);
1711*e3723e1fSApple OSS Distributions 	T_EXPECT_NOTNULL(pid_path, "malloc for PROC_PIDPATHINFO");
1712*e3723e1fSApple OSS Distributions 	int retval = __proc_info(PROC_INFO_CALL_PIDINFO, getpid(), PROC_PIDPATHINFO, (uint64_t)0, (user_addr_t)pid_path,
1713*e3723e1fSApple OSS Distributions 	    (uint32_t)PROC_PIDPATHINFO_MAXSIZE);
1714*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(retval, 0, "__proc_info call for PROC_PIDPATHINFO");
1715*e3723e1fSApple OSS Distributions 
1716*e3723e1fSApple OSS Distributions 	T_EXPECT_NE_PTR((void *)(strcasestr(pid_path, CONF_CMD_NAME)), NULL, "PROC_PIDPATHINFOreturns valid value for pid_path");
1717*e3723e1fSApple OSS Distributions 	free(pid_path);
1718*e3723e1fSApple OSS Distributions 	pid_path = NULL;
1719*e3723e1fSApple OSS Distributions }
1720*e3723e1fSApple OSS Distributions 
1721*e3723e1fSApple OSS Distributions T_DECL(proc_info_proc_pidlistfileports,
1722*e3723e1fSApple OSS Distributions     "Test to verify PROC_PIDLISTFILEPORTS returns valid information about the process",
1723*e3723e1fSApple OSS Distributions     T_META_ASROOT(true), T_META_TAG_VM_PREFERRED)
1724*e3723e1fSApple OSS Distributions {
1725*e3723e1fSApple OSS Distributions 	struct proc_fileportinfo * fileport_info = NULL;
1726*e3723e1fSApple OSS Distributions 	mach_port_t tmp_file_port                = MACH_PORT_NULL;
1727*e3723e1fSApple OSS Distributions 	proc_config_t proc_config                = spawn_child_processes(1, proc_info_call_pidinfo_handler);
1728*e3723e1fSApple OSS Distributions 	int child_pid                            = proc_config->child_pids[0];
1729*e3723e1fSApple OSS Distributions 
1730*e3723e1fSApple OSS Distributions 	/*
1731*e3723e1fSApple OSS Distributions 	 * Create a file port
1732*e3723e1fSApple OSS Distributions 	 */
1733*e3723e1fSApple OSS Distributions 	tmp_fd     = CONF_TMP_FILE_OPEN(NULL);
1734*e3723e1fSApple OSS Distributions 	int retval = fileport_makeport(tmp_fd, &tmp_file_port);
1735*e3723e1fSApple OSS Distributions 	T_EXPECT_POSIX_SUCCESS(retval, "fileport_makeport() for PROC_PIDLISTFILEPORTS");
1736*e3723e1fSApple OSS Distributions 
1737*e3723e1fSApple OSS Distributions 	/*
1738*e3723e1fSApple OSS Distributions 	 * Like the other APIs, this returns the actual count + 20. Hence we expect it to be atleast 1 (that we created)
1739*e3723e1fSApple OSS Distributions 	 */
1740*e3723e1fSApple OSS Distributions 	retval = __proc_info(PROC_INFO_CALL_PIDINFO, getpid(), PROC_PIDLISTFILEPORTS, (uint64_t)0, (user_addr_t)0, (uint32_t)0);
1741*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_INT(retval / (int)sizeof(fileport_info), 1,
1742*e3723e1fSApple OSS Distributions 	    "__proc_info call for PROC_PIDLISTFILEPORTS to get total ports in parent");
1743*e3723e1fSApple OSS Distributions 
1744*e3723e1fSApple OSS Distributions 	/*
1745*e3723e1fSApple OSS Distributions 	 * Child doesn't have any fileports, should return zero
1746*e3723e1fSApple OSS Distributions 	 */
1747*e3723e1fSApple OSS Distributions 	retval = __proc_info(PROC_INFO_CALL_PIDINFO, child_pid, PROC_PIDLISTFILEPORTS, (uint64_t)0, (user_addr_t)0, (uint32_t)0);
1748*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(retval / (int)sizeof(fileport_info), 0,
1749*e3723e1fSApple OSS Distributions 	    "__proc_info call for PROC_PIDLISTFILEPORTS to get total ports in child");
1750*e3723e1fSApple OSS Distributions 
1751*e3723e1fSApple OSS Distributions 	fileport_info = malloc(sizeof(*fileport_info) * (size_t)retval);
1752*e3723e1fSApple OSS Distributions 	retval        = __proc_info(PROC_INFO_CALL_PIDINFO, getpid(), PROC_PIDLISTFILEPORTS, (uint64_t)0, (user_addr_t)fileport_info,
1753*e3723e1fSApple OSS Distributions 	    (uint32_t)sizeof(*fileport_info));
1754*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(retval, (int)sizeof(*fileport_info), "__proc_info call for PROC_PIDLISTFILEPORTS");
1755*e3723e1fSApple OSS Distributions 
1756*e3723e1fSApple OSS Distributions 	T_EXPECT_NE_UINT(fileport_info->proc_fileport, (uint32_t)0, "PROC_PIDLISTFILEPORTS returns valid value for proc_fileport");
1757*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(fileport_info->proc_fdtype, (uint32_t)PROX_FDTYPE_VNODE,
1758*e3723e1fSApple OSS Distributions 	    "PROC_PIDLISTFILEPORTS returns valid value for proc_fdtype");
1759*e3723e1fSApple OSS Distributions 
1760*e3723e1fSApple OSS Distributions 	/*
1761*e3723e1fSApple OSS Distributions 	 * Cleanup for the fileport
1762*e3723e1fSApple OSS Distributions 	 */
1763*e3723e1fSApple OSS Distributions 	mach_port_deallocate(mach_task_self(), tmp_file_port);
1764*e3723e1fSApple OSS Distributions 	tmp_file_port = MACH_PORT_NULL;
1765*e3723e1fSApple OSS Distributions 	free(fileport_info);
1766*e3723e1fSApple OSS Distributions 	fileport_info = NULL;
1767*e3723e1fSApple OSS Distributions 	close(tmp_fd);
1768*e3723e1fSApple OSS Distributions 	tmp_fd = -1;
1769*e3723e1fSApple OSS Distributions 	free_proc_config(proc_config);
1770*e3723e1fSApple OSS Distributions }
1771*e3723e1fSApple OSS Distributions 
1772*e3723e1fSApple OSS Distributions T_DECL(proc_info_proc_pidcoalitioninfo,
1773*e3723e1fSApple OSS Distributions     "Test to verify PROC_PIDCOALITIONINFO returns valid information about the process",
1774*e3723e1fSApple OSS Distributions     T_META_ASROOT(true), T_META_TAG_VM_PREFERRED)
1775*e3723e1fSApple OSS Distributions {
1776*e3723e1fSApple OSS Distributions 	proc_config_t proc_config = spawn_child_processes(1, proc_info_call_pidinfo_handler);
1777*e3723e1fSApple OSS Distributions 	int child_pid             = proc_config->child_pids[0];
1778*e3723e1fSApple OSS Distributions 
1779*e3723e1fSApple OSS Distributions 	struct proc_pidcoalitioninfo pci_parent;
1780*e3723e1fSApple OSS Distributions 	struct proc_pidcoalitioninfo pci_child;
1781*e3723e1fSApple OSS Distributions 	int retval = __proc_info(PROC_INFO_CALL_PIDINFO, getpid(), PROC_PIDCOALITIONINFO, (uint64_t)0, (user_addr_t)&pci_parent,
1782*e3723e1fSApple OSS Distributions 	    (uint32_t)sizeof(pci_parent));
1783*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(retval, (int)sizeof(pci_parent), "__proc_info call for PROC_PIDCOALITIONINFO (parent)");
1784*e3723e1fSApple OSS Distributions 	retval = __proc_info(PROC_INFO_CALL_PIDINFO, child_pid, PROC_PIDCOALITIONINFO, (uint64_t)0, (user_addr_t)&pci_child,
1785*e3723e1fSApple OSS Distributions 	    (uint32_t)sizeof(pci_child));
1786*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(retval, (int)sizeof(pci_child), "__proc_info call for PROC_PIDCOALITIONINFO (child)");
1787*e3723e1fSApple OSS Distributions 
1788*e3723e1fSApple OSS Distributions 	/*
1789*e3723e1fSApple OSS Distributions 	 * Coalition IDs should match for child and parent
1790*e3723e1fSApple OSS Distributions 	 */
1791*e3723e1fSApple OSS Distributions 	for (int i = 0; i < COALITION_NUM_TYPES; i++) {
1792*e3723e1fSApple OSS Distributions 		T_EXPECT_EQ_ULLONG(pci_parent.coalition_id[i], pci_child.coalition_id[i],
1793*e3723e1fSApple OSS Distributions 		    "PROC_PIDCOALITIONINFO returns valid value for coalition_id");
1794*e3723e1fSApple OSS Distributions 	}
1795*e3723e1fSApple OSS Distributions 
1796*e3723e1fSApple OSS Distributions 	free_proc_config(proc_config);
1797*e3723e1fSApple OSS Distributions }
1798*e3723e1fSApple OSS Distributions 
1799*e3723e1fSApple OSS Distributions T_DECL(proc_info_proc_pidworkqueueinfo,
1800*e3723e1fSApple OSS Distributions     "Test to verify PROC_PIDWORKQUEUEINFO returns valid information about the process",
1801*e3723e1fSApple OSS Distributions     T_META_ASROOT(true), T_META_TAG_VM_PREFERRED)
1802*e3723e1fSApple OSS Distributions {
1803*e3723e1fSApple OSS Distributions 	proc_config_t proc_config = spawn_child_processes(1, proc_info_call_pidinfo_handler);
1804*e3723e1fSApple OSS Distributions 	int child_pid             = proc_config->child_pids[0];
1805*e3723e1fSApple OSS Distributions 	send_action_to_child_processes(proc_config, ACT_PHASE5);
1806*e3723e1fSApple OSS Distributions 
1807*e3723e1fSApple OSS Distributions 	struct proc_workqueueinfo pwqinfo;
1808*e3723e1fSApple OSS Distributions 	usleep(10000);
1809*e3723e1fSApple OSS Distributions 	int retval = __proc_info(PROC_INFO_CALL_PIDINFO, child_pid, PROC_PIDWORKQUEUEINFO, (uint64_t)0, (user_addr_t)&pwqinfo,
1810*e3723e1fSApple OSS Distributions 	    (uint32_t)sizeof(pwqinfo));
1811*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(retval, (int)sizeof(pwqinfo), "__proc_info call for PROC_PIDWORKQUEUEINFO");
1812*e3723e1fSApple OSS Distributions 
1813*e3723e1fSApple OSS Distributions 	int ncpu         = 0;
1814*e3723e1fSApple OSS Distributions 	size_t ncpu_size = sizeof(ncpu);
1815*e3723e1fSApple OSS Distributions 	retval           = sysctlbyname("hw.ncpu", (void *)&ncpu, &ncpu_size, NULL, 0);
1816*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(retval, 0, "sysctl() for PROC_PIDWORKQUEUEINFO");
1817*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_UINT(pwqinfo.pwq_nthreads, (uint32_t)1, "PROC_PIDWORKQUEUEINFO returns valid value for pwq_nthreads");
1818*e3723e1fSApple OSS Distributions 	T_EXPECT_GE_UINT(pwqinfo.pwq_blockedthreads + pwqinfo.pwq_runthreads, (uint32_t)1,
1819*e3723e1fSApple OSS Distributions 	    "PROC_PIDWORKQUEUEINFO returns valid value for pwqinfo.pwq_runthreads/pwq_blockedthreads");
1820*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(pwqinfo.pwq_state, (uint32_t)0, "PROC_PIDWORKQUEUEINFO returns valid value for pwq_state");
1821*e3723e1fSApple OSS Distributions 
1822*e3723e1fSApple OSS Distributions 	kill_child_processes(proc_config);
1823*e3723e1fSApple OSS Distributions 	free_proc_config(proc_config);
1824*e3723e1fSApple OSS Distributions }
1825*e3723e1fSApple OSS Distributions T_DECL(proc_info_proc_pidnoteexit,
1826*e3723e1fSApple OSS Distributions     "Test to verify PROC_PIDNOTEEXIT returns valid information about the process",
1827*e3723e1fSApple OSS Distributions     T_META_ASROOT(true), T_META_TAG_VM_PREFERRED)
1828*e3723e1fSApple OSS Distributions {
1829*e3723e1fSApple OSS Distributions 	/*
1830*e3723e1fSApple OSS Distributions 	 * Ask the child to close pipe and quit, cleanup pipes for parent
1831*e3723e1fSApple OSS Distributions 	 */
1832*e3723e1fSApple OSS Distributions 	proc_config_t proc_config = spawn_child_processes(1, proc_info_call_pidinfo_handler);
1833*e3723e1fSApple OSS Distributions 	int child_pid             = proc_config->child_pids[0];
1834*e3723e1fSApple OSS Distributions 	send_action_to_child_processes(proc_config, ACT_EXIT);
1835*e3723e1fSApple OSS Distributions 
1836*e3723e1fSApple OSS Distributions 	uint32_t exit_data = 0;
1837*e3723e1fSApple OSS Distributions 	int retval = __proc_info(PROC_INFO_CALL_PIDINFO, child_pid, PROC_PIDNOTEEXIT, (uint64_t)(NOTE_EXITSTATUS | NOTE_EXIT_DETAIL),
1838*e3723e1fSApple OSS Distributions 	    (user_addr_t)&exit_data, (uint32_t)sizeof(exit_data));
1839*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(retval, (int)sizeof(exit_data), "__proc_info call for PROC_PIDNOTEEXIT");
1840*e3723e1fSApple OSS Distributions 
1841*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_UINT(exit_data, 0U, "PROC_PIDNOTEEXIT returned valid value for exit_data");
1842*e3723e1fSApple OSS Distributions 
1843*e3723e1fSApple OSS Distributions 	free_proc_config(proc_config);
1844*e3723e1fSApple OSS Distributions }
1845*e3723e1fSApple OSS Distributions 
1846*e3723e1fSApple OSS Distributions T_DECL(proc_info_negative_tests,
1847*e3723e1fSApple OSS Distributions     "Test to validate PROC_INFO_CALL_PIDINFO for invalid arguments",
1848*e3723e1fSApple OSS Distributions     T_META_ASROOT(true), T_META_TAG_VM_PREFERRED)
1849*e3723e1fSApple OSS Distributions {
1850*e3723e1fSApple OSS Distributions 	proc_config_t proc_config = spawn_child_processes(1, proc_info_call_pidinfo_handler);
1851*e3723e1fSApple OSS Distributions 	int child_pid             = proc_config->child_pids[0];
1852*e3723e1fSApple OSS Distributions 	uint32_t exit_data        = 0;
1853*e3723e1fSApple OSS Distributions 
1854*e3723e1fSApple OSS Distributions 	int retval =
1855*e3723e1fSApple OSS Distributions 	    __proc_info(PROC_INFO_CALL_PIDINFO, child_pid, PROC_PIDNOTEEXIT, (uint64_t)0, (user_addr_t)&exit_data, (uint32_t)0);
1856*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(errno, ENOMEM, "PROC_INFO_CALL_PIDINFO call should fail with ENOMEM if buffersize is zero");
1857*e3723e1fSApple OSS Distributions 	retval = __proc_info(PROC_INFO_CALL_PIDINFO, child_pid, PROC_PIDPATHINFO, (uint64_t)0, (user_addr_t)&exit_data,
1858*e3723e1fSApple OSS Distributions 	    (uint32_t)PROC_PIDPATHINFO_MAXSIZE + 1);
1859*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(errno, EOVERFLOW,
1860*e3723e1fSApple OSS Distributions 	    "PROC_INFO_CALL_PIDINFO call should fail with EOVERFLOW if buffersize is larger than PROC_PIDPATHINFO_MAXSIZE");
1861*e3723e1fSApple OSS Distributions 	retval = __proc_info(PROC_INFO_CALL_PIDINFO, -1, PROC_PIDNOTEEXIT, (uint64_t)0, (user_addr_t)&exit_data,
1862*e3723e1fSApple OSS Distributions 	    (uint32_t)sizeof(exit_data));
1863*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(errno, ESRCH, "PROC_INFO_CALL_PIDINFO call should fail with ESRCH for invalid process id");
1864*e3723e1fSApple OSS Distributions 	retval = __proc_info(PROC_INFO_CALL_PIDINFO, child_pid, -1U, (uint64_t)0, (user_addr_t)&exit_data, (uint32_t)sizeof(exit_data));
1865*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(errno, EINVAL, "PROC_INFO_CALL_PIDINFO call should fail with EINVAL for invalid flavor");
1866*e3723e1fSApple OSS Distributions 	retval = __proc_info(PROC_INFO_CALL_PIDINFO, 0, PROC_PIDWORKQUEUEINFO, (uint64_t)0, (user_addr_t)0, (uint32_t)0);
1867*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_INT(errno, EINVAL,
1868*e3723e1fSApple OSS Distributions 	    "PROC_INFO_CALL_PIDINFO call should fail with EINVAL if flavor is PROC_PIDWORKQUEUEINFO and pid=0");
1869*e3723e1fSApple OSS Distributions 
1870*e3723e1fSApple OSS Distributions 	free_proc_config(proc_config);
1871*e3723e1fSApple OSS Distributions }
1872*e3723e1fSApple OSS Distributions 
1873*e3723e1fSApple OSS Distributions /*
1874*e3723e1fSApple OSS Distributions  * END PROC_INFO_CALL_PIDINFO DECLs
1875*e3723e1fSApple OSS Distributions  */
1876*e3723e1fSApple OSS Distributions 
1877*e3723e1fSApple OSS Distributions #pragma mark proc_list_uptrs
1878*e3723e1fSApple OSS Distributions 
1879*e3723e1fSApple OSS Distributions #define NUPTRS 4
1880*e3723e1fSApple OSS Distributions static uint64_t uptrs[NUPTRS] = {0x1122334455667788ULL, 0x99aabbccddeeff00ULL, 0xaabbaaddccaaffeeULL, 0xcc000011ccaa7755ULL};
1881*e3723e1fSApple OSS Distributions 
1882*e3723e1fSApple OSS Distributions static const char * uptr_names[NUPTRS];
1883*e3723e1fSApple OSS Distributions 
1884*e3723e1fSApple OSS Distributions static void
print_uptrs(int argc,char * const * argv)1885*e3723e1fSApple OSS Distributions print_uptrs(int argc, char * const * argv)
1886*e3723e1fSApple OSS Distributions {
1887*e3723e1fSApple OSS Distributions 	for (int i = 0; i < argc; i++) {
1888*e3723e1fSApple OSS Distributions 		char * end;
1889*e3723e1fSApple OSS Distributions 		unsigned long pid = strtoul(argv[i], &end, 0);
1890*e3723e1fSApple OSS Distributions 		if (pid > INT_MAX) {
1891*e3723e1fSApple OSS Distributions 			printf("error: pid '%lu' would overflow an integer\n", pid);
1892*e3723e1fSApple OSS Distributions 		}
1893*e3723e1fSApple OSS Distributions 		if (end == argv[i]) {
1894*e3723e1fSApple OSS Distributions 			printf("error: could not parse '%s' as a pid\n", argv[i]);
1895*e3723e1fSApple OSS Distributions 			continue;
1896*e3723e1fSApple OSS Distributions 		}
1897*e3723e1fSApple OSS Distributions 		int uptrs_count = proc_list_uptrs((int)pid, NULL, 0);
1898*e3723e1fSApple OSS Distributions 		if (uptrs_count == 0) {
1899*e3723e1fSApple OSS Distributions 			printf("no uptrs for process %d\n", (int)pid);
1900*e3723e1fSApple OSS Distributions 			return;
1901*e3723e1fSApple OSS Distributions 		}
1902*e3723e1fSApple OSS Distributions 
1903*e3723e1fSApple OSS Distributions 		/* extra space */
1904*e3723e1fSApple OSS Distributions 		unsigned int uptrs_len = (unsigned int)uptrs_count + 32;
1905*e3723e1fSApple OSS Distributions 
1906*e3723e1fSApple OSS Distributions 		uint64_t * uptrs_alloc = malloc(sizeof(uint64_t) * uptrs_len);
1907*e3723e1fSApple OSS Distributions 		os_assert(uptrs_alloc != NULL);
1908*e3723e1fSApple OSS Distributions 
1909*e3723e1fSApple OSS Distributions 		uptrs_count = proc_list_uptrs((int)pid, uptrs_alloc, (uint32_t)(sizeof(uint64_t) * uptrs_len));
1910*e3723e1fSApple OSS Distributions 		printf("process %d has %d uptrs:\n", (int)pid, uptrs_count);
1911*e3723e1fSApple OSS Distributions 		if (uptrs_count > (int)uptrs_len) {
1912*e3723e1fSApple OSS Distributions 			uptrs_count = (int)uptrs_len;
1913*e3723e1fSApple OSS Distributions 		}
1914*e3723e1fSApple OSS Distributions 		for (int j = 0; j < uptrs_count; j++) {
1915*e3723e1fSApple OSS Distributions 			printf("%#17" PRIx64 "\n", uptrs_alloc[j]);
1916*e3723e1fSApple OSS Distributions 		}
1917*e3723e1fSApple OSS Distributions 	}
1918*e3723e1fSApple OSS Distributions }
1919*e3723e1fSApple OSS Distributions 
1920*e3723e1fSApple OSS Distributions T_DECL(proc_list_uptrs, "the kernel should return any up-pointers it knows about", T_META_TAG_VM_PREFERRED)
1921*e3723e1fSApple OSS Distributions {
1922*e3723e1fSApple OSS Distributions 	if (argc > 0) {
1923*e3723e1fSApple OSS Distributions 		print_uptrs(argc, argv);
1924*e3723e1fSApple OSS Distributions 		T_SKIP("command line invocation of tool, not test");
1925*e3723e1fSApple OSS Distributions 	}
1926*e3723e1fSApple OSS Distributions 
1927*e3723e1fSApple OSS Distributions 	unsigned int cur_uptr = 0;
1928*e3723e1fSApple OSS Distributions 
1929*e3723e1fSApple OSS Distributions 	int kq = kqueue();
1930*e3723e1fSApple OSS Distributions 	T_QUIET;
1931*e3723e1fSApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(kq, "kqueue");
1932*e3723e1fSApple OSS Distributions 
1933*e3723e1fSApple OSS Distributions 	/*
1934*e3723e1fSApple OSS Distributions 	 * Should find uptrs on file-type knotes and generic knotes (two
1935*e3723e1fSApple OSS Distributions 	 * different search locations, internally).
1936*e3723e1fSApple OSS Distributions 	 */
1937*e3723e1fSApple OSS Distributions 	struct kevent64_s events[2];
1938*e3723e1fSApple OSS Distributions 	memset(events, 0, sizeof(events));
1939*e3723e1fSApple OSS Distributions 
1940*e3723e1fSApple OSS Distributions 	uptr_names[cur_uptr] = "kqueue file-backed knote";
1941*e3723e1fSApple OSS Distributions 	events[0].filter     = EVFILT_WRITE;
1942*e3723e1fSApple OSS Distributions 	events[0].ident      = STDOUT_FILENO;
1943*e3723e1fSApple OSS Distributions 	events[0].flags      = EV_ADD;
1944*e3723e1fSApple OSS Distributions 	events[0].udata      = uptrs[cur_uptr++];
1945*e3723e1fSApple OSS Distributions 
1946*e3723e1fSApple OSS Distributions 	uptr_names[cur_uptr] = "kqueue non-file-backed knote";
1947*e3723e1fSApple OSS Distributions 	events[1].filter     = EVFILT_USER;
1948*e3723e1fSApple OSS Distributions 	events[1].ident      = 1;
1949*e3723e1fSApple OSS Distributions 	events[1].flags      = EV_ADD;
1950*e3723e1fSApple OSS Distributions 	events[1].udata      = uptrs[cur_uptr++];
1951*e3723e1fSApple OSS Distributions 
1952*e3723e1fSApple OSS Distributions 	int kev_err = kevent64(kq, events, sizeof(events) / sizeof(events[0]), NULL, 0, KEVENT_FLAG_IMMEDIATE, NULL);
1953*e3723e1fSApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(kev_err, "register events with kevent64");
1954*e3723e1fSApple OSS Distributions 
1955*e3723e1fSApple OSS Distributions 	/*
1956*e3723e1fSApple OSS Distributions 	 * Should find uptrs both on a kevent_id kqueue and in a workloop
1957*e3723e1fSApple OSS Distributions 	 * kqueue's knote's udata field.
1958*e3723e1fSApple OSS Distributions 	 */
1959*e3723e1fSApple OSS Distributions 	uptr_names[cur_uptr] = "dynamic kqueue non-file-backed knote";
1960*e3723e1fSApple OSS Distributions 	struct kevent_qos_s events_id[] = {{
1961*e3723e1fSApple OSS Distributions 						   .filter = EVFILT_USER,
1962*e3723e1fSApple OSS Distributions 						   .ident = 1,
1963*e3723e1fSApple OSS Distributions 						   .flags = EV_ADD,
1964*e3723e1fSApple OSS Distributions 						   .qos = (int)_pthread_qos_class_encode(QOS_CLASS_DEFAULT, 0, 0),
1965*e3723e1fSApple OSS Distributions 						   .udata = uptrs[cur_uptr++]
1966*e3723e1fSApple OSS Distributions 					   }};
1967*e3723e1fSApple OSS Distributions 
1968*e3723e1fSApple OSS Distributions 	uptr_names[cur_uptr] = "dynamic kqueue ID";
1969*e3723e1fSApple OSS Distributions 	kev_err = kevent_id(uptrs[cur_uptr++], events_id, 1, NULL, 0, NULL, NULL, KEVENT_FLAG_WORKLOOP | KEVENT_FLAG_IMMEDIATE);
1970*e3723e1fSApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(kev_err, "register event with kevent_id");
1971*e3723e1fSApple OSS Distributions 
1972*e3723e1fSApple OSS Distributions 	errno           = 0;
1973*e3723e1fSApple OSS Distributions 	int uptrs_count = proc_list_uptrs(getpid(), NULL, 0);
1974*e3723e1fSApple OSS Distributions 	T_QUIET;
1975*e3723e1fSApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(uptrs_count, "proc_list_uptrs");
1976*e3723e1fSApple OSS Distributions 	T_QUIET;
1977*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ(uptrs_count, NUPTRS, "should see correct number of up-pointers");
1978*e3723e1fSApple OSS Distributions 
1979*e3723e1fSApple OSS Distributions 	uint64_t uptrs_obs[NUPTRS] = {0};
1980*e3723e1fSApple OSS Distributions 	uptrs_count                = proc_list_uptrs(getpid(), uptrs_obs, sizeof(uptrs_obs));
1981*e3723e1fSApple OSS Distributions 	T_QUIET;
1982*e3723e1fSApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(uptrs_count, "proc_list_uptrs");
1983*e3723e1fSApple OSS Distributions 
1984*e3723e1fSApple OSS Distributions 	for (int i = 0; i < uptrs_count; i++) {
1985*e3723e1fSApple OSS Distributions 		int found = -1;
1986*e3723e1fSApple OSS Distributions 		for (int j = 0; j < NUPTRS; j++) {
1987*e3723e1fSApple OSS Distributions 			if (uptrs_obs[i] == uptrs[j]) {
1988*e3723e1fSApple OSS Distributions 				found = j;
1989*e3723e1fSApple OSS Distributions 				goto next;
1990*e3723e1fSApple OSS Distributions 			}
1991*e3723e1fSApple OSS Distributions 		}
1992*e3723e1fSApple OSS Distributions 		T_FAIL("unexpected up-pointer found: %#" PRIx64, uptrs_obs[i]);
1993*e3723e1fSApple OSS Distributions next:           ;
1994*e3723e1fSApple OSS Distributions 		if (found != -1) {
1995*e3723e1fSApple OSS Distributions 			T_PASS("found up-pointer for %s", uptr_names[found]);
1996*e3723e1fSApple OSS Distributions 		}
1997*e3723e1fSApple OSS Distributions 	}
1998*e3723e1fSApple OSS Distributions 
1999*e3723e1fSApple OSS Distributions 	uint64_t up_overflow[2] = {0};
2000*e3723e1fSApple OSS Distributions 	uptrs_count = proc_list_uptrs(getpid(), up_overflow, sizeof(uint64_t) + 1);
2001*e3723e1fSApple OSS Distributions 	T_ASSERT_EQ(up_overflow[1], (uint64_t)0, "overflow check");
2002*e3723e1fSApple OSS Distributions }
2003*e3723e1fSApple OSS Distributions 
2004*e3723e1fSApple OSS Distributions #pragma mark dynamic kqueue info
2005*e3723e1fSApple OSS Distributions 
2006*e3723e1fSApple OSS Distributions #define EXPECTED_ID UINT64_C(0x1122334455667788)
2007*e3723e1fSApple OSS Distributions #define EXPECTED_UDATA UINT64_C(0x99aabbccddeeff00)
2008*e3723e1fSApple OSS Distributions #ifndef KQ_WORKLOOP
2009*e3723e1fSApple OSS Distributions #define KQ_WORKLOOP 0x80
2010*e3723e1fSApple OSS Distributions #endif
2011*e3723e1fSApple OSS Distributions 
2012*e3723e1fSApple OSS Distributions static void
setup_kevent_id(kqueue_id_t id)2013*e3723e1fSApple OSS Distributions setup_kevent_id(kqueue_id_t id)
2014*e3723e1fSApple OSS Distributions {
2015*e3723e1fSApple OSS Distributions 	struct kevent_qos_s events_id[] = {{
2016*e3723e1fSApple OSS Distributions 						   .filter = EVFILT_USER,
2017*e3723e1fSApple OSS Distributions 						   .ident = 1,
2018*e3723e1fSApple OSS Distributions 						   .flags = EV_ADD,
2019*e3723e1fSApple OSS Distributions 						   .qos = (int)_pthread_qos_class_encode(QOS_CLASS_DEFAULT, 0, 0),
2020*e3723e1fSApple OSS Distributions 						   .udata = EXPECTED_UDATA
2021*e3723e1fSApple OSS Distributions 					   }};
2022*e3723e1fSApple OSS Distributions 
2023*e3723e1fSApple OSS Distributions 	int err = kevent_id(id, events_id, 1, NULL, 0, NULL, NULL, KEVENT_FLAG_WORKLOOP | KEVENT_FLAG_IMMEDIATE);
2024*e3723e1fSApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(err, "register event with kevent_id");
2025*e3723e1fSApple OSS Distributions }
2026*e3723e1fSApple OSS Distributions 
2027*e3723e1fSApple OSS Distributions static kqueue_id_t *
list_kqids(pid_t pid,int * nkqids_out)2028*e3723e1fSApple OSS Distributions list_kqids(pid_t pid, int * nkqids_out)
2029*e3723e1fSApple OSS Distributions {
2030*e3723e1fSApple OSS Distributions 	int kqids_len = 256;
2031*e3723e1fSApple OSS Distributions 	int nkqids;
2032*e3723e1fSApple OSS Distributions 	kqueue_id_t * kqids = NULL;
2033*e3723e1fSApple OSS Distributions 	uint32_t kqids_size;
2034*e3723e1fSApple OSS Distributions 
2035*e3723e1fSApple OSS Distributions retry:
2036*e3723e1fSApple OSS Distributions 	if (os_mul_overflow(sizeof(kqueue_id_t), kqids_len, &kqids_size)) {
2037*e3723e1fSApple OSS Distributions 		T_QUIET;
2038*e3723e1fSApple OSS Distributions 		T_ASSERT_GT(kqids_len, PROC_PIDDYNKQUEUES_MAX, NULL);
2039*e3723e1fSApple OSS Distributions 		kqids_len = PROC_PIDDYNKQUEUES_MAX;
2040*e3723e1fSApple OSS Distributions 		goto retry;
2041*e3723e1fSApple OSS Distributions 	}
2042*e3723e1fSApple OSS Distributions 	if (!kqids) {
2043*e3723e1fSApple OSS Distributions 		kqids = malloc(kqids_size);
2044*e3723e1fSApple OSS Distributions 		T_QUIET;
2045*e3723e1fSApple OSS Distributions 		T_ASSERT_NOTNULL(kqids, "malloc(%" PRIu32 ")", kqids_size);
2046*e3723e1fSApple OSS Distributions 	}
2047*e3723e1fSApple OSS Distributions 
2048*e3723e1fSApple OSS Distributions 	nkqids = proc_list_dynkqueueids(pid, kqids, kqids_size);
2049*e3723e1fSApple OSS Distributions 	if (nkqids > kqids_len && kqids_len < PROC_PIDDYNKQUEUES_MAX) {
2050*e3723e1fSApple OSS Distributions 		kqids_len *= 2;
2051*e3723e1fSApple OSS Distributions 		if (kqids_len > PROC_PIDDYNKQUEUES_MAX) {
2052*e3723e1fSApple OSS Distributions 			kqids_len = PROC_PIDDYNKQUEUES_MAX;
2053*e3723e1fSApple OSS Distributions 		}
2054*e3723e1fSApple OSS Distributions 		free(kqids);
2055*e3723e1fSApple OSS Distributions 		kqids = NULL;
2056*e3723e1fSApple OSS Distributions 		goto retry;
2057*e3723e1fSApple OSS Distributions 	}
2058*e3723e1fSApple OSS Distributions 
2059*e3723e1fSApple OSS Distributions 	*nkqids_out = nkqids;
2060*e3723e1fSApple OSS Distributions 	return kqids;
2061*e3723e1fSApple OSS Distributions }
2062*e3723e1fSApple OSS Distributions 
2063*e3723e1fSApple OSS Distributions T_DECL(list_dynamic_kqueues, "the kernel should list IDs of dynamic kqueues", T_META_ALL_VALID_ARCHS(true), T_META_TAG_VM_PREFERRED)
2064*e3723e1fSApple OSS Distributions {
2065*e3723e1fSApple OSS Distributions 	int nkqids;
2066*e3723e1fSApple OSS Distributions 	bool found = false;
2067*e3723e1fSApple OSS Distributions 
2068*e3723e1fSApple OSS Distributions 	setup_kevent_id(EXPECTED_ID);
2069*e3723e1fSApple OSS Distributions 	kqueue_id_t * kqids = list_kqids(getpid(), &nkqids);
2070*e3723e1fSApple OSS Distributions 	T_ASSERT_GE(nkqids, 1, "at least one dynamic kqueue is listed");
2071*e3723e1fSApple OSS Distributions 	for (int i = 0; i < nkqids; i++) {
2072*e3723e1fSApple OSS Distributions 		if (kqids[i] == EXPECTED_ID) {
2073*e3723e1fSApple OSS Distributions 			found = true;
2074*e3723e1fSApple OSS Distributions 			T_PASS("found expected dynamic kqueue ID");
2075*e3723e1fSApple OSS Distributions 		} else {
2076*e3723e1fSApple OSS Distributions 			T_LOG("found another dynamic kqueue with ID %#" PRIx64, kqids[i]);
2077*e3723e1fSApple OSS Distributions 		}
2078*e3723e1fSApple OSS Distributions 	}
2079*e3723e1fSApple OSS Distributions 
2080*e3723e1fSApple OSS Distributions 	if (!found) {
2081*e3723e1fSApple OSS Distributions 		T_FAIL("could not find dynamic ID of kqueue created");
2082*e3723e1fSApple OSS Distributions 	}
2083*e3723e1fSApple OSS Distributions 
2084*e3723e1fSApple OSS Distributions 	free(kqids);
2085*e3723e1fSApple OSS Distributions }
2086*e3723e1fSApple OSS Distributions 
2087*e3723e1fSApple OSS Distributions T_DECL(dynamic_kqueue_basic_info, "the kernel should report valid basic dynamic kqueue info", T_META_ALL_VALID_ARCHS(true), T_META_TAG_VM_PREFERRED)
2088*e3723e1fSApple OSS Distributions {
2089*e3723e1fSApple OSS Distributions 	struct kqueue_info kqinfo;
2090*e3723e1fSApple OSS Distributions 	int ret;
2091*e3723e1fSApple OSS Distributions 
2092*e3723e1fSApple OSS Distributions 	setup_kevent_id(EXPECTED_ID);
2093*e3723e1fSApple OSS Distributions 	ret = proc_piddynkqueueinfo(getpid(), PROC_PIDDYNKQUEUE_INFO, EXPECTED_ID, &kqinfo, sizeof(kqinfo));
2094*e3723e1fSApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(ret, "proc_piddynkqueueinfo(... PROC_PIDDYNKQUEUE_INFO ...)");
2095*e3723e1fSApple OSS Distributions 	T_QUIET;
2096*e3723e1fSApple OSS Distributions 	T_ASSERT_GE(ret, (int)sizeof(kqinfo), "PROC_PIDDYNKQUEUE_INFO should return the right size");
2097*e3723e1fSApple OSS Distributions 
2098*e3723e1fSApple OSS Distributions 	T_EXPECT_NE(kqinfo.kq_state & KQ_WORKLOOP, 0U, "kqueue info should be for a workloop kqueue");
2099*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ(kqinfo.kq_stat.vst_ino, EXPECTED_ID, "inode field should be the kqueue's ID");
2100*e3723e1fSApple OSS Distributions }
2101*e3723e1fSApple OSS Distributions 
2102*e3723e1fSApple OSS Distributions T_DECL(dynamic_kqueue_extended_info, "the kernel should report valid extended dynamic kqueue info", T_META_ALL_VALID_ARCHS(true), T_META_TAG_VM_PREFERRED)
2103*e3723e1fSApple OSS Distributions {
2104*e3723e1fSApple OSS Distributions 	struct kevent_extinfo kqextinfo[1];
2105*e3723e1fSApple OSS Distributions 	int ret;
2106*e3723e1fSApple OSS Distributions 
2107*e3723e1fSApple OSS Distributions 	setup_kevent_id(EXPECTED_ID);
2108*e3723e1fSApple OSS Distributions 	ret = proc_piddynkqueueinfo(getpid(), PROC_PIDDYNKQUEUE_EXTINFO, EXPECTED_ID, kqextinfo, sizeof(kqextinfo));
2109*e3723e1fSApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(ret, "proc_piddynkqueueinfo(... PROC_PIDDYNKQUEUE_EXTINFO ...)");
2110*e3723e1fSApple OSS Distributions 	T_QUIET;
2111*e3723e1fSApple OSS Distributions 	T_ASSERT_EQ(ret, 1, "PROC_PIDDYNKQUEUE_EXTINFO should return a single knote");
2112*e3723e1fSApple OSS Distributions 
2113*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ(kqextinfo[0].kqext_kev.ident, 1ULL, "kevent identifier matches what was configured");
2114*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ(kqextinfo[0].kqext_kev.filter, (short)EVFILT_USER, "kevent filter matches what was configured");
2115*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ(kqextinfo[0].kqext_kev.udata, EXPECTED_UDATA, "kevent udata matches what was configured");
2116*e3723e1fSApple OSS Distributions }
2117*e3723e1fSApple OSS Distributions 
2118*e3723e1fSApple OSS Distributions #pragma mark proc_listpids
2119*e3723e1fSApple OSS Distributions 
2120*e3723e1fSApple OSS Distributions T_DECL(list_kdebug_pids, "the kernel should report processes that are filtered by kdebug",
2121*e3723e1fSApple OSS Distributions     T_META_ASROOT(YES), T_META_RUN_CONCURRENTLY(false), T_META_TAG_VM_PREFERRED)
2122*e3723e1fSApple OSS Distributions {
2123*e3723e1fSApple OSS Distributions 	int mib[4] = {CTL_KERN, KERN_KDEBUG};
2124*e3723e1fSApple OSS Distributions 	int npids;
2125*e3723e1fSApple OSS Distributions 	int pids[1];
2126*e3723e1fSApple OSS Distributions 	int ret;
2127*e3723e1fSApple OSS Distributions 	kd_regtype reg;
2128*e3723e1fSApple OSS Distributions 	size_t regsize = sizeof(reg);
2129*e3723e1fSApple OSS Distributions 
2130*e3723e1fSApple OSS Distributions 	mib[2] = KERN_KDREMOVE;
2131*e3723e1fSApple OSS Distributions 	ret    = sysctl(mib, 3, NULL, NULL, NULL, 0);
2132*e3723e1fSApple OSS Distributions 	T_QUIET;
2133*e3723e1fSApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(ret, "KERN_KDREMOVE sysctl");
2134*e3723e1fSApple OSS Distributions 
2135*e3723e1fSApple OSS Distributions 	mib[2] = KERN_KDSETBUF;
2136*e3723e1fSApple OSS Distributions 	mib[3] = 100000;
2137*e3723e1fSApple OSS Distributions 	ret    = sysctl(mib, 4, NULL, NULL, NULL, 0);
2138*e3723e1fSApple OSS Distributions 	T_QUIET;
2139*e3723e1fSApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(ret, "KERN_KDSETBUF sysctl");
2140*e3723e1fSApple OSS Distributions 
2141*e3723e1fSApple OSS Distributions 	mib[2] = KERN_KDSETUP;
2142*e3723e1fSApple OSS Distributions 	ret    = sysctl(mib, 3, NULL, NULL, NULL, 0);
2143*e3723e1fSApple OSS Distributions 	T_QUIET;
2144*e3723e1fSApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(ret, "KERN_KDSETUP sysctl");
2145*e3723e1fSApple OSS Distributions 
2146*e3723e1fSApple OSS Distributions 	npids = proc_listpids(PROC_KDBG_ONLY, 0, pids, sizeof(pids));
2147*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ(npids, 0, "no processes should be filtered initially");
2148*e3723e1fSApple OSS Distributions 
2149*e3723e1fSApple OSS Distributions 	reg.type   = KDBG_TYPENONE;
2150*e3723e1fSApple OSS Distributions 	reg.value1 = (unsigned int)getpid();
2151*e3723e1fSApple OSS Distributions 	reg.value2 = 1; /* set the pid in the filter */
2152*e3723e1fSApple OSS Distributions 	mib[2]     = KERN_KDPIDTR;
2153*e3723e1fSApple OSS Distributions 	ret        = sysctl(mib, 3, &reg, &regsize, NULL, 0);
2154*e3723e1fSApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(ret, "KERN_KDPIDTR sysctl to set a pid in the filter");
2155*e3723e1fSApple OSS Distributions 
2156*e3723e1fSApple OSS Distributions 	npids = proc_listpids(PROC_KDBG_ONLY, 0, pids, sizeof(pids));
2157*e3723e1fSApple OSS Distributions 	npids /= 4;
2158*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ(npids, 1, "a process should be filtered");
2159*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ(pids[0], getpid(), "process filtered should be the one that was set");
2160*e3723e1fSApple OSS Distributions 
2161*e3723e1fSApple OSS Distributions 	mib[2] = KERN_KDREMOVE;
2162*e3723e1fSApple OSS Distributions 	ret    = sysctl(mib, 3, NULL, NULL, NULL, 0);
2163*e3723e1fSApple OSS Distributions 	T_QUIET;
2164*e3723e1fSApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(ret, "KERN_KDREMOVE sysctl");
2165*e3723e1fSApple OSS Distributions }
2166*e3723e1fSApple OSS Distributions 
2167*e3723e1fSApple OSS Distributions #pragma mark misc
2168*e3723e1fSApple OSS Distributions 
2169*e3723e1fSApple OSS Distributions static int prf_fd;
2170*e3723e1fSApple OSS Distributions static char prf_path[PATH_MAX];
2171*e3723e1fSApple OSS Distributions static void
prf_end(void)2172*e3723e1fSApple OSS Distributions prf_end(void)
2173*e3723e1fSApple OSS Distributions {
2174*e3723e1fSApple OSS Distributions 	close(prf_fd);
2175*e3723e1fSApple OSS Distributions 	unlink(prf_path);
2176*e3723e1fSApple OSS Distributions }
2177*e3723e1fSApple OSS Distributions 
2178*e3723e1fSApple OSS Distributions T_DECL(proc_regionfilename, "proc_regionfilename() should work", T_META_TAG_VM_PREFERRED)
2179*e3723e1fSApple OSS Distributions {
2180*e3723e1fSApple OSS Distributions 	static char expected[] = "'very rigorous maritime engineering standards' && the front fell off";
2181*e3723e1fSApple OSS Distributions 	static char real[sizeof(expected)];
2182*e3723e1fSApple OSS Distributions 	int rc;
2183*e3723e1fSApple OSS Distributions 	void *addr;
2184*e3723e1fSApple OSS Distributions 
2185*e3723e1fSApple OSS Distributions 	prf_fd = CONF_TMP_FILE_OPEN(prf_path);
2186*e3723e1fSApple OSS Distributions 	T_ATEND(prf_end);
2187*e3723e1fSApple OSS Distributions 
2188*e3723e1fSApple OSS Distributions 	rc = (int) write(prf_fd, expected, sizeof(expected));
2189*e3723e1fSApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(rc, "write to tmpfile");
2190*e3723e1fSApple OSS Distributions 
2191*e3723e1fSApple OSS Distributions 	addr = mmap(0, 0x1000, PROT_READ, MAP_PRIVATE, prf_fd, 0);
2192*e3723e1fSApple OSS Distributions 	T_WITH_ERRNO;
2193*e3723e1fSApple OSS Distributions 	T_ASSERT_NE_PTR(addr, MAP_FAILED, "mmap of tmpfile");
2194*e3723e1fSApple OSS Distributions 
2195*e3723e1fSApple OSS Distributions 	T_WITH_ERRNO;
2196*e3723e1fSApple OSS Distributions 	T_ASSERT_GT(proc_regionfilename(getpid(), (uint64_t) addr, real, MAXPATHLEN), 0, "proc_regionfilename");
2197*e3723e1fSApple OSS Distributions 	T_EXPECT_EQ_STR(basename(prf_path), basename(real), "filename");
2198*e3723e1fSApple OSS Distributions }
2199*e3723e1fSApple OSS Distributions 
2200*e3723e1fSApple OSS Distributions T_DECL(proc_regionpath, "PROC_PIDREGIONPATH should return addr, length and path", T_META_TAG_VM_PREFERRED)
2201*e3723e1fSApple OSS Distributions {
2202*e3723e1fSApple OSS Distributions 	int rc;
2203*e3723e1fSApple OSS Distributions 	struct proc_regionpath path;
2204*e3723e1fSApple OSS Distributions 	static char some_text[] = "'very rigorous maritime engineering standards' && the front fell off";
2205*e3723e1fSApple OSS Distributions 	unsigned long rounded_length = (sizeof(some_text) & (unsigned long) ~(PAGE_SIZE - 1)) + PAGE_SIZE;
2206*e3723e1fSApple OSS Distributions 	void *addr;
2207*e3723e1fSApple OSS Distributions 
2208*e3723e1fSApple OSS Distributions 	prf_fd = CONF_TMP_FILE_OPEN(prf_path);
2209*e3723e1fSApple OSS Distributions 	T_ATEND(prf_end);
2210*e3723e1fSApple OSS Distributions 
2211*e3723e1fSApple OSS Distributions 	rc = (int) write(prf_fd, some_text, sizeof(some_text));
2212*e3723e1fSApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(rc, "write to tmpfile");
2213*e3723e1fSApple OSS Distributions 
2214*e3723e1fSApple OSS Distributions 	addr = mmap(0, PAGE_SIZE, PROT_READ, MAP_PRIVATE, prf_fd, 0);
2215*e3723e1fSApple OSS Distributions 	T_WITH_ERRNO;
2216*e3723e1fSApple OSS Distributions 	T_ASSERT_NE_PTR(addr, MAP_FAILED, "mmap of tmpfile");
2217*e3723e1fSApple OSS Distributions 
2218*e3723e1fSApple OSS Distributions 	rc = proc_pidinfo(getpid(), PROC_PIDREGIONPATH, (uint64_t)addr, &path, sizeof(struct proc_regionpath));
2219*e3723e1fSApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(rc, "proc_pidinfo");
2220*e3723e1fSApple OSS Distributions 
2221*e3723e1fSApple OSS Distributions 	T_ASSERT_EQ((unsigned long) path.prpo_regionlength, rounded_length, "regionlength must match");
2222*e3723e1fSApple OSS Distributions 	T_ASSERT_EQ_PTR((void *) path.prpo_addr, addr, "addr must match");
2223*e3723e1fSApple OSS Distributions 
2224*e3723e1fSApple OSS Distributions 	rc = proc_pidinfo(getpid(), PROC_PIDREGIONPATH, (uint64_t)((char *) addr + 20), &path, sizeof(struct proc_regionpath));
2225*e3723e1fSApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(rc, "proc_pidinfo 20 bytes past the base address");
2226*e3723e1fSApple OSS Distributions 
2227*e3723e1fSApple OSS Distributions 	T_ASSERT_EQ((unsigned long) path.prpo_regionlength, rounded_length, "regionlength must match, even when 20 bytes past the base address");
2228*e3723e1fSApple OSS Distributions 	T_ASSERT_EQ_PTR((void *) path.prpo_addr, addr, "addr must match, even when 20 bytes past the base address");
2229*e3723e1fSApple OSS Distributions }
2230*e3723e1fSApple OSS Distributions 
2231*e3723e1fSApple OSS Distributions #ifndef ARRAY_SIZE
2232*e3723e1fSApple OSS Distributions #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
2233*e3723e1fSApple OSS Distributions #endif
2234*e3723e1fSApple OSS Distributions T_DECL(proc_pidinfo_kernel_task_fail, "calling proc_pidinfo for certain flavors on the kernel task should fail",
2235*e3723e1fSApple OSS Distributions     T_META_ASROOT(YES), T_META_TAG_VM_PREFERRED)
2236*e3723e1fSApple OSS Distributions {
2237*e3723e1fSApple OSS Distributions 	int flavors[] = {PROC_PIDREGIONPATH, PROC_PIDREGIONINFO, PROC_PIDREGIONPATHINFO, PROC_PIDREGIONPATHINFO2, PROC_PIDREGIONPATHINFO3};
2238*e3723e1fSApple OSS Distributions 	for (int f = 0; f < ARRAY_SIZE(flavors); f++) {
2239*e3723e1fSApple OSS Distributions 		int rc = proc_pidinfo(0, flavors[f], 0, 0, 0);
2240*e3723e1fSApple OSS Distributions 		T_ASSERT_EQ(rc, 0, "proc_pidinfo returned %d for flavor %d", rc, flavors[f]);
2241*e3723e1fSApple OSS Distributions 		T_EXPECT_EQ_INT(errno, EPERM, "proc_pidinfo errno expected=%d actual=%d", EPERM, errno);
2242*e3723e1fSApple OSS Distributions 	}
2243*e3723e1fSApple OSS Distributions }
2244